Material对象:
var materialId = 0;
function Material() {
Object.defineProperty( this, 'id', { value: materialId ++ } );
this.uuid = _Math.generateUUID();
this.name = '';
this.type = 'Material';
this.fog = true;
this.lights = true;
this.blending = NormalBlending;
this.side = FrontSide;
this.flatShading = false;
。。。
Material对象的toJSON:
toJSON: function ( meta ) {
var isRoot = ( meta === undefined || typeof meta === 'string' );
if (isRoot) {
meta = {
textures: {},
images: {}
};
}
var data = {
metadata: {
version: 4.5,
type: 'Material',
generator: 'Material.toJSON'
}
};
// standard Material serialization
data.uuid = this.uuid;
data.type = this.type;
if (this.name !== '') data.name = this.name;
if (this.color && this.color.isColor) data.color = this.color.getHex();
if (this.roughness !== undefined) data.roughness = this.roughness;
if (this.metalness !== undefined) data.metalness = this.metalness;
if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex();
if (this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity;
if (this.specular && this.specular.isColor) data.specular = this.specular.getHex();
if (this.shininess !== undefined) data.shininess = this.shininess;
if (this.clearCoat !== undefined) data.clearCoat = this.clearCoat;
if (this.clearCoatRoughness !== undefined) data.clearCoatRoughness = this.clearCoatRoughness;
if (this.map && this.map.isTexture) data.map = this.map.toJSON( meta ).uuid;
if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
if (this.lightMap && this.lightMap.isTexture) data.lightMap = this.lightMap.toJSON( meta ).uuid;
if (this.bumpMap && this.bumpMap.isTexture) {
data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
data.bumpScale = this.bumpScale;
}
if (this.normalMap && this.normalMap.isTexture) {
data.normalMap = this.normalMap.toJSON( meta ).uuid;
data.normalScale = this.normalScale.toArray();
}
if (this.displacementMap && this.displacementMap.isTexture) {
data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
data.displacementScale = this.displacementScale;
data.displacementBias = this.displacementBias;
}
if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON( meta ).uuid;
if (this.envMap && this.envMap.isTexture) {
data.envMap = this.envMap.toJSON( meta ).uuid;
data.reflectivity = this.reflectivity; // Scale behind envMap
}
if (this.gradientMap && this.gradientMap.isTexture) {
data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
}
if (this.size !== undefined) data.size = this.size;
if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation;
if (this.blending !== NormalBlending) data.blending = this.blending;
if (this.flatShading === true) data.flatShading = this.flatShading;
if (this.side !== FrontSide) data.side = this.side;
if (this.vertexColors !== NoColors) data.vertexColors = this.vertexColors;
if (this.opacity < 1) data.opacity = this.opacity;
if (this.transparent === true) data.transparent = this.transparent;
data.depthFunc = this.depthFunc;
data.depthTest = this.depthTest;
data.depthWrite = this.depthWrite;
// rotation (SpriteMaterial)
if (this.rotation !== 0) data.rotation = this.rotation;
if (this.linewidth !== 1) data.linewidth = this.linewidth;
if (this.dashSize !== undefined) data.dashSize = this.dashSize;
if (this.gapSize !== undefined) data.gapSize = this.gapSize;
if (this.scale !== undefined) data.scale = this.scale;
if (this.dithering === true) data.dithering = true;
if (this.alphaTest > 0) data.alphaTest = this.alphaTest;
if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha;
if (this.wireframe === true) data.wireframe = this.wireframe;
if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth;
if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap;
if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin;
if (this.morphTargets === true) data.morphTargets = true;
if (this.skinning === true) data.skinning = true;
if (this.visible === false) data.visible = false;
if (JSON.stringify( this.userData ) !== '{}') data.userData = this.userData;
// TODO: Copied from Object3D.toJSON
function extractFromCache( cache ) {
var values = [];
for (var key in cache) {
var data = cache[key];
delete data.metadata;
values.push( data );
}
return values;
}
if (isRoot) {
var textures = extractFromCache( meta.textures );
var images = extractFromCache( meta.images );
if (textures.length > 0) data.textures = textures;
if (images.length > 0) data.images = images;
}
return data;
},
Object3d方法
Object.defineProperty( this, 'id', { value: object3DId ++ } );
this.uuid = _Math.generateUUID();
this.name = '';
this.type = 'Object3D';
this.parent = null;
this.children = [];
this.up = Object3D.DefaultUp.clone();
Object.defineProperties( this, {
position: {
enumerable: true,
value: position
},
rotation: {
enumerable: true,
value: rotation
},
quaternion: {
enumerable: true,
value: quaternion
},
scale: {
enumerable: true,
value: scale
},
modelViewMatrix: {
value: new Matrix4()
},
normalMatrix: {
value: new Matrix3()
}
} );
this.matrix = new Matrix4();
this.matrixWorld = new Matrix4();
this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
this.matrixWorldNeedsUpdate = false;
this.layers = new Layers();
this.visible = true;
this.castShadow = false;
this.receiveShadow = false;
this.frustumCulled = true;
this.renderOrder = 0;
this.userData = {};
Object3D的原型方法
copy方法:
copy: function ( source, recursive ) {
if ( recursive === undefined ) recursive = true;
this.name = source.name;
this.up.copy( source.up );
this.position.copy( source.position );
this.quaternion.copy( source.quaternion );
this.scale.copy( source.scale );
this.matrix.copy( source.matrix );
this.matrixWorld.copy( source.matrixWorld );
this.matrixAutoUpdate = source.matrixAutoUpdate;
this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
this.layers.mask = source.layers.mask;
this.visible = source.visible;
this.castShadow = source.castShadow;
this.receiveShadow = source.receiveShadow;
this.frustumCulled = source.frustumCulled;
this.renderOrder = source.renderOrder;
this.userData = JSON.parse( JSON.stringify( source.userData ) );
if ( recursive === true ) {
for ( var i = 0; i < source.children.length; i ++ ) {
var child = source.children[ i ];
this.add( child.clone() );
}
}
return this;
}
toJSON方法:
toJSON: function ( meta ) {
// meta is a string when called from JSON.stringify
var isRootObject = ( meta === undefined || typeof meta === 'string' );
var output = {};
// meta is a hash used to collect geometries, materials.
// not providing it implies that this is the root object
// being serialized.
if ( isRootObject ) {
// initialize meta obj
meta = {
geometries: {},
materials: {},
textures: {},
images: {},
shapes: {}
};
output.metadata = {
version: 4.5,
type: 'Object',
generator: 'Object3D.toJSON'
};
}
// standard Object3D serialization
var object = {};
object.uuid = this.uuid;
object.type = this.type;
if ( this.name !== '' ) object.name = this.name;
if ( this.castShadow === true ) object.castShadow = true;
if ( this.receiveShadow === true ) object.receiveShadow = true;
if ( this.visible === false ) object.visible = false;
if ( this.frustumCulled === false ) object.frustumCulled = false;
if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
object.matrix = this.matrix.toArray();
//
function serialize( library, element ) {
if ( library[ element.uuid ] === undefined ) {
library[ element.uuid ] = element.toJSON( meta );
}
return element.uuid;
}
if ( this.geometry !== undefined ) {
object.geometry = serialize( meta.geometries, this.geometry );
var parameters = this.geometry.parameters;
if ( parameters !== undefined && parameters.shapes !== undefined ) {
var shapes = parameters.shapes;
if ( Array.isArray( shapes ) ) {
for ( var i = 0, l = shapes.length; i < l; i ++ ) {
var shape = shapes[ i ];
serialize( meta.shapes, shape );
}
} else {
serialize( meta.shapes, shapes );
}
}
}
if ( this.material !== undefined ) {
if ( Array.isArray( this.material ) ) {
var uuids = [];
for ( var i = 0, l = this.material.length; i < l; i ++ ) {
uuids.push( serialize( meta.materials, this.material[ i ] ) );
}
object.material = uuids;
} else {
object.material = serialize( meta.materials, this.material );
}
}
//
if ( this.children.length > 0 ) {
object.children = [];
for ( var i = 0; i < this.children.length; i ++ ) {
object.children.push( this.children[ i ].toJSON( meta ).object );
}
}
if ( isRootObject ) {
var geometries = extractFromCache( meta.geometries );
var materials = extractFromCache( meta.materials );
var textures = extractFromCache( meta.textures );
var images = extractFromCache( meta.images );
var shapes = extractFromCache( meta.shapes );
if ( geometries.length > 0 ) output.geometries = geometries;
if ( materials.length > 0 ) output.materials = materials;
if ( textures.length > 0 ) output.textures = textures;
if ( images.length > 0 ) output.images = images;
if ( shapes.length > 0 ) output.shapes = shapes;
}
output.object = object;
return output;
// extract data from the cache hash
// remove metadata on each item
// and return as array
function extractFromCache( cache ) {
var values = [];
for ( var key in cache ) {
var data = cache[ key ];
delete data.metadata;
values.push( data );
}
return values;
}
},
Scene对象:
function Scene() {
Object3D.call( this ); //构造方法当成一个普通方法来使用
this.type = 'Scene';
this.background = null;
this.fog = null;
this.overrideMaterial = null;
this.autoUpdate = true; // checked by the renderer
}
Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Scene,
copy: function ( source, recursive ) {
Object3D.prototype.copy.call( this, source, recursive );
if ( source.background !== null ) this.background = source.background.clone();
if ( source.fog !== null ) this.fog = source.fog.clone();
if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
this.autoUpdate = source.autoUpdate;
this.matrixAutoUpdate = source.matrixAutoUpdate;
return this;
},
toJSON: function ( meta ) {
var data = Object3D.prototype.toJSON.call( this, meta );
if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
return data;
}
} );
Camera对象:
function Camera() {
Object3D.call( this );
this.type = 'Camera';
//视图矩阵
this.matrixWorldInverse = new Matrix4();
//投影矩阵
this.projectionMatrix = new Matrix4();
// 相机对象本质就是视图矩阵和投影矩阵,顶点坐标经过平移旋转缩放模型变换以后
// 还需要经过视图、投影变换才能显示到画布上
}
Camera.prototype = Object.assign( Object.create( Object3D.prototype ), {
注意Camera对象的没有自己的toJSON,使用的父对象的
FR:徐海涛(hunk Xu)
QQ技术交流群:386476712