提交 f8ecbb15 编写于 作者: M Mr.doob

Moved *Exporter code to the objects themselves. See #4621.

上级 2efc87a0
......@@ -26,7 +26,6 @@
<script src="../examples/js/loaders/ctm/lzma.js"></script>
<script src="../examples/js/loaders/ctm/ctm.js"></script>
<script src="../examples/js/loaders/ctm/CTMLoader.js"></script>
<script src="../examples/js/exporters/SceneExporter.js"></script>
<script src="../examples/js/exporters/OBJExporter.js"></script>
<script src="../examples/js/exporters/STLExporter.js"></script>
<script src="../examples/js/renderers/RaytracingRenderer.js"></script>
......@@ -35,11 +34,6 @@
<!-- WIP -->
<script src="../examples/js/exporters/BufferGeometryExporter.js"></script>
<script src="../examples/js/exporters/TypedGeometryExporter.js"></script>
<script src="../examples/js/exporters/GeometryExporter.js"></script>
<script src="../examples/js/exporters/MaterialExporter.js"></script>
<script src="../examples/js/exporters/ObjectExporter.js"></script>
<script src="../examples/js/renderers/WebGLRenderer3.js"></script>
<script src="js/libs/signals.min.js"></script>
......@@ -130,7 +124,6 @@
//
var timeout;
var exporter = new THREE.ObjectExporter();
var saveState = function ( scene ) {
......@@ -138,7 +131,7 @@
timeout = setTimeout( function () {
editor.storage.set( exporter.parse( editor.scene ) );
editor.storage.set( editor.scene.toJSON() );
}, 1000 );
......
......@@ -86,15 +86,11 @@ Menubar.File = function ( editor ) {
}
if ( geometry instanceof THREE.BufferGeometry ) {
exportGeometry( THREE.BufferGeometryExporter );
} else if ( geometry instanceof THREE.Geometry ) {
exportGeometry( THREE.GeometryExporter );
var output = geometry.toJSON();
output = JSON.stringify( output, null, '\t' );
output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
}
exportString( output );
} );
options.add( option );
......@@ -106,14 +102,20 @@ Menubar.File = function ( editor ) {
option.setTextContent( 'Export Object' );
option.onClick( function () {
if ( editor.selected === null ) {
var object = editor.selected;
if ( object === null ) {
alert( 'No object selected' );
return;
}
exportObject( THREE.ObjectExporter );
var output = object.toJSON();
output = JSON.stringify( output, null, '\t' );
output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
exportString( output );
} );
options.add( option );
......@@ -125,7 +127,11 @@ Menubar.File = function ( editor ) {
option.setTextContent( 'Export Scene' );
option.onClick( function () {
exportScene( THREE.ObjectExporter );
var output = editor.scene.toJSON();
output = JSON.stringify( output, null, '\t' );
output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
exportString( output );
} );
options.add( option );
......@@ -137,7 +143,27 @@ Menubar.File = function ( editor ) {
option.setTextContent( 'Export OBJ' );
option.onClick( function () {
exportGeometry( THREE.OBJExporter );
var object = editor.selected;
if ( object === null ) {
alert( 'No object selected.' );
return;
}
var geometry = object.geometry;
if ( geometry === undefined ) {
alert( 'The selected object doesn\'t have geometry.' );
return;
}
var exporter = new OBJExporter();
exportString( exporter.parse( geometry ) );
} );
options.add( option );
......@@ -149,7 +175,9 @@ Menubar.File = function ( editor ) {
option.setTextContent( 'Export STL' );
option.onClick( function () {
exportScene( THREE.STLExporter );
var exporter = new STLExporter();
exportString( exporter.parse( editor.scene ) );
} );
options.add( option );
......@@ -158,6 +186,8 @@ Menubar.File = function ( editor ) {
options.add( new UI.HorizontalRule() );
/*
// Test
var option = new UI.Panel();
......@@ -170,61 +200,22 @@ Menubar.File = function ( editor ) {
} );
options.add( option );
*/
// Publish
//
var exportGeometry = function ( exporterClass ) {
var object = editor.selected;
var exporter = new exporterClass();
var output = exporter.parse( object.geometry );
if ( exporter instanceof THREE.BufferGeometryExporter ||
exporter instanceof THREE.GeometryExporter ) {
output = JSON.stringify( output, null, '\t' );
output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
}
var blob = new Blob( [ output ], { type: 'text/plain' } );
var objectURL = URL.createObjectURL( blob );
window.open( objectURL, '_blank' );
window.focus();
};
var exportObject = function ( exporterClass ) {
var object = editor.selected;
var exporter = new exporterClass();
var output = JSON.stringify( exporter.parse( object ), null, '\t' );
output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
var blob = new Blob( [ output ], { type: 'text/plain' } );
var objectURL = URL.createObjectURL( blob );
window.open( objectURL, '_blank' );
window.focus();
};
var exportScene = function ( exporterClass ) {
var exporter = new exporterClass();
var option = new UI.Panel();
option.setClass( 'option' );
option.setTextContent( 'Publish' );
option.onClick( function () {
var output = exporter.parse( editor.scene );
} );
options.add( option );
if ( exporter instanceof THREE.ObjectExporter ) {
output = JSON.stringify( output, null, '\t' );
output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
//
}
var exportString = function ( output ) {
var blob = new Blob( [ output ], { type: 'text/plain' } );
var objectURL = URL.createObjectURL( blob );
......
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.BufferGeometryExporter = function () {};
THREE.BufferGeometryExporter.prototype = {
constructor: THREE.BufferGeometryExporter,
parse: function ( geometry ) {
var output = {
metadata: {
version: 4.0,
type: 'BufferGeometry',
generator: 'BufferGeometryExporter'
},
attributes: {
}
};
var attributes = geometry.attributes;
var offsets = geometry.offsets;
var boundingSphere = geometry.boundingSphere;
for ( var key in attributes ) {
var attribute = attributes[ key ];
var array = [], typeArray = attribute.array;
for ( var i = 0, l = typeArray.length; i < l; i ++ ) {
array[ i ] = typeArray[ i ];
}
output.attributes[ key ] = {
itemSize: attribute.itemSize,
type: attribute.array.constructor.name,
array: array
}
}
if ( offsets.length > 0 ) {
output.offsets = JSON.parse( JSON.stringify( offsets ) );
}
if ( boundingSphere !== null ) {
output.boundingSphere = {
center: boundingSphere.center.toArray(),
radius: boundingSphere.radius
}
}
return output;
}
};
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.GeometryExporter = function () {};
THREE.GeometryExporter.prototype = {
constructor: THREE.GeometryExporter,
parse: function ( geometry ) {
var output = {
metadata: {
version: 4.0,
type: 'geometry',
generator: 'GeometryExporter'
}
};
var vertices = [];
for ( var i = 0; i < geometry.vertices.length; i ++ ) {
var vertex = geometry.vertices[ i ];
vertices.push( vertex.x, vertex.y, vertex.z );
}
var faces = [];
var normals = [];
var normalsHash = {};
var colors = [];
var colorsHash = {};
var uvs = [];
var uvsHash = {};
for ( var i = 0; i < geometry.faces.length; i ++ ) {
var face = geometry.faces[ i ];
var hasMaterial = false; // face.materialIndex !== undefined;
var hasFaceUv = false; // deprecated
var hasFaceVertexUv = geometry.faceVertexUvs[ 0 ][ i ] !== undefined;
var hasFaceNormal = face.normal.length() > 0;
var hasFaceVertexNormal = face.vertexNormals.length > 0;
var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
var hasFaceVertexColor = face.vertexColors.length > 0;
var faceType = 0;
faceType = setBit( faceType, 0, 0 );
faceType = setBit( faceType, 1, hasMaterial );
faceType = setBit( faceType, 2, hasFaceUv );
faceType = setBit( faceType, 3, hasFaceVertexUv );
faceType = setBit( faceType, 4, hasFaceNormal );
faceType = setBit( faceType, 5, hasFaceVertexNormal );
faceType = setBit( faceType, 6, hasFaceColor );
faceType = setBit( faceType, 7, hasFaceVertexColor );
faces.push( faceType );
faces.push( face.a, face.b, face.c );
/*
if ( hasMaterial ) {
faces.push( face.materialIndex );
}
*/
if ( hasFaceVertexUv ) {
var faceVertexUvs = geometry.faceVertexUvs[ 0 ][ i ];
faces.push(
getUvIndex( faceVertexUvs[ 0 ] ),
getUvIndex( faceVertexUvs[ 1 ] ),
getUvIndex( faceVertexUvs[ 2 ] )
);
}
if ( hasFaceNormal ) {
faces.push( getNormalIndex( face.normal ) );
}
if ( hasFaceVertexNormal ) {
var vertexNormals = face.vertexNormals;
faces.push(
getNormalIndex( vertexNormals[ 0 ] ),
getNormalIndex( vertexNormals[ 1 ] ),
getNormalIndex( vertexNormals[ 2 ] )
);
}
if ( hasFaceColor ) {
faces.push( getColorIndex( face.color ) );
}
if ( hasFaceVertexColor ) {
var vertexColors = face.vertexColors;
faces.push(
getColorIndex( vertexColors[ 0 ] ),
getColorIndex( vertexColors[ 1 ] ),
getColorIndex( vertexColors[ 2 ] )
);
}
}
function setBit( value, position, enabled ) {
return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position) );
}
function getNormalIndex( normal ) {
var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
if ( normalsHash[ hash ] !== undefined ) {
return normalsHash[ hash ];
}
normalsHash[ hash ] = normals.length / 3;
normals.push( normal.x, normal.y, normal.z );
return normalsHash[ hash ];
}
function getColorIndex( color ) {
var hash = color.r.toString() + color.g.toString() + color.b.toString();
if ( colorsHash[ hash ] !== undefined ) {
return colorsHash[ hash ];
}
colorsHash[ hash ] = colors.length;
colors.push( color.getHex() );
return colorsHash[ hash ];
}
function getUvIndex( uv ) {
var hash = uv.x.toString() + uv.y.toString();
if ( uvsHash[ hash ] !== undefined ) {
return uvsHash[ hash ];
}
uvsHash[ hash ] = uvs.length / 2;
uvs.push( uv.x, uv.y );
return uvsHash[ hash ];
}
output.vertices = vertices;
output.normals = normals;
if ( colors.length > 0 ) output.colors = colors;
if ( uvs.length > 0 ) output.uvs = [ uvs ]; // temporal backward compatibility
output.faces = faces;
//
return output;
}
};
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.HTMLExporter = function () {};
THREE.HTMLExporter.prototype = {
constructor: THREE.HTMLExporter,
parse: function ( scene ) {
return output;
}
}
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.MaterialExporter = function () {};
THREE.MaterialExporter.prototype = {
constructor: THREE.MaterialExporter,
parse: function ( material ) {
var output = {
metadata: {
version: 4.2,
type: 'material',
generator: 'MaterialExporter'
}
};
output.uuid = material.uuid;
if ( material.name !== "" ) output.name = material.name;
if ( material instanceof THREE.MeshBasicMaterial ) {
output.type = 'MeshBasicMaterial';
output.color = material.color.getHex();
if ( material.vertexColors !== THREE.NoColors ) output.vertexColors = material.vertexColors;
if ( material.blending !== THREE.NormalBlending ) output.blending = material.blending;
if ( material.side !== THREE.FrontSide ) output.side = material.side;
output.opacity = material.opacity;
output.transparent = material.transparent;
output.wireframe = material.wireframe;
} else if ( material instanceof THREE.MeshLambertMaterial ) {
output.type = 'MeshLambertMaterial';
output.color = material.color.getHex();
output.ambient = material.ambient.getHex();
output.emissive = material.emissive.getHex();
if ( material.vertexColors !== THREE.NoColors ) output.vertexColors = material.vertexColors;
if ( material.blending !== THREE.NormalBlending ) output.blending = material.blending;
if ( material.side !== THREE.FrontSide ) output.side = material.side;
output.opacity = material.opacity;
output.transparent = material.transparent;
output.wireframe = material.wireframe;
} else if ( material instanceof THREE.MeshPhongMaterial ) {
output.type = 'MeshPhongMaterial';
output.color = material.color.getHex();
output.ambient = material.ambient.getHex();
output.emissive = material.emissive.getHex();
output.specular = material.specular.getHex();
output.shininess = material.shininess;
if ( material.vertexColors !== THREE.NoColors ) output.vertexColors = material.vertexColors;
if ( material.blending !== THREE.NormalBlending ) output.blending = material.blending;
if ( material.side !== THREE.FrontSide ) output.side = material.side;
output.opacity = material.opacity;
output.transparent = material.transparent;
output.wireframe = material.wireframe;
} else if ( material instanceof THREE.MeshNormalMaterial ) {
output.type = 'MeshNormalMaterial';
if ( material.blending !== THREE.NormalBlending ) output.blending = material.blending;
if ( material.side !== THREE.FrontSide ) output.side = material.side;
output.opacity = material.opacity;
output.transparent = material.transparent;
output.wireframe = material.wireframe;
} else if ( material instanceof THREE.MeshDepthMaterial ) {
output.type = 'MeshDepthMaterial';
if ( material.blending !== THREE.NormalBlending ) output.blending = material.blending;
if ( material.side !== THREE.FrontSide ) output.side = material.side;
output.opacity = material.opacity;
output.transparent = material.transparent;
output.wireframe = material.wireframe;
} else if ( material instanceof THREE.MeshFaceMaterial ) {
output.type = 'MeshFaceMaterial';
output.materials = [];
for ( var i = 0, l = material.materials.length; i < l; i ++ ) {
output.materials.push( this.parse( material.materials[ i ] ) );
}
} else if ( material instanceof THREE.ShaderMaterial ) {
output.type = 'ShaderMaterial';
output.uniforms = material.uniforms;
output.vertexShader = material.vertexShader;
output.fragmentShader = material.fragmentShader;
} else if ( material instanceof THREE.SpriteMaterial ) {
output.type = 'SpriteMaterial';
output.color = material.color.getHex();
output.opacity = material.opacity;
output.transparent = material.transparent;
}
return output;
}
};
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.ObjectExporter = function () {};
THREE.ObjectExporter.prototype = {
constructor: THREE.ObjectExporter,
parse: function ( object ) {
// console.log( object );
var output = {
metadata: {
version: 4.3,
type: 'Object',
generator: 'ObjectExporter'
}
};
//
var geometries = {};
var geometryExporter = new THREE.GeometryExporter();
var bufferGeometryExporter = new THREE.BufferGeometryExporter();
var parseGeometry = function ( geometry ) {
if ( output.geometries === undefined ) {
output.geometries = [];
}
if ( geometries[ geometry.uuid ] === undefined ) {
var data = {};
data.uuid = geometry.uuid;
if ( geometry.name !== "" ) data.name = geometry.name;
var handleParameters = function ( parameters ) {
for ( var i = 0; i < parameters.length; i ++ ) {
var parameter = parameters[ i ];
if ( geometry.parameters[ parameter ] !== undefined ) {
data[ parameter ] = geometry.parameters[ parameter ];
}
}
};
if ( geometry instanceof THREE.PlaneGeometry ) {
data.type = 'PlaneGeometry';
handleParameters( [ 'width', 'height', 'widthSegments', 'heightSegments' ] );
} else if ( geometry instanceof THREE.BoxGeometry ) {
data.type = 'BoxGeometry';
handleParameters( [ 'width', 'height', 'depth', 'widthSegments', 'heightSegments', 'depthSegments' ] );
} else if ( geometry instanceof THREE.CircleGeometry ) {
data.type = 'CircleGeometry';
handleParameters( [ 'radius', 'segments' ] );
} else if ( geometry instanceof THREE.CylinderGeometry ) {
data.type = 'CylinderGeometry';
handleParameters( [ 'radiusTop', 'radiusBottom', 'height', 'radialSegments', 'heightSegments', 'openEnded' ] );
} else if ( geometry instanceof THREE.SphereGeometry ) {
data.type = 'SphereGeometry';
handleParameters( [ 'radius', 'widthSegments', 'heightSegments', 'phiStart', 'phiLength', 'thetaStart', 'thetaLength' ] );
} else if ( geometry instanceof THREE.IcosahedronGeometry ) {
data.type = 'IcosahedronGeometry';
handleParameters( [ 'radius', 'detail' ] );
} else if ( geometry instanceof THREE.TorusGeometry ) {
data.type = 'TorusGeometry';
handleParameters( [ 'radius', 'tube', 'radialSegments', 'tubularSegments', 'arc' ] );
} else if ( geometry instanceof THREE.TorusKnotGeometry ) {
data.type = 'TorusKnotGeometry';
handleParameters( [ 'radius', 'tube', 'radialSegments', 'tubularSegments', 'p', 'q', 'heightScale' ] );
} else if ( geometry instanceof THREE.BufferGeometry ) {
data.type = 'BufferGeometry';
data.data = bufferGeometryExporter.parse( geometry );
delete data.data.metadata;
} else if ( geometry instanceof THREE.Geometry ) {
data.type = 'Geometry';
data.data = geometryExporter.parse( geometry );
delete data.data.metadata;
}
geometries[ geometry.uuid ] = data;
output.geometries.push( data );
}
return geometry.uuid;
};
//
var materials = {};
var materialExporter = new THREE.MaterialExporter();
var parseMaterial = function ( material ) {
if ( output.materials === undefined ) {
output.materials = [];
}
if ( materials[ material.uuid ] === undefined ) {
var data = materialExporter.parse( material );
delete data.metadata;
materials[ material.uuid ] = data;
output.materials.push( data );
}
return material.uuid;
};
//
var parseObject = function ( object ) {
var data = {};
data.uuid = object.uuid;
if ( object.name !== '' ) data.name = object.name;
if ( JSON.stringify( object.userData ) !== '{}' ) data.userData = object.userData;
if ( object.visible !== true ) data.visible = object.visible;
if ( object instanceof THREE.Scene ) {
data.type = 'Scene';
} else if ( object instanceof THREE.PerspectiveCamera ) {
data.type = 'PerspectiveCamera';
data.fov = object.fov;
data.aspect = object.aspect;
data.near = object.near;
data.far = object.far;
} else if ( object instanceof THREE.OrthographicCamera ) {
data.type = 'OrthographicCamera';
data.left = object.left;
data.right = object.right;
data.top = object.top;
data.bottom = object.bottom;
data.near = object.near;
data.far = object.far;
} else if ( object instanceof THREE.AmbientLight ) {
data.type = 'AmbientLight';
data.color = object.color.getHex();
} else if ( object instanceof THREE.DirectionalLight ) {
data.type = 'DirectionalLight';
data.color = object.color.getHex();
data.intensity = object.intensity;
} else if ( object instanceof THREE.PointLight ) {
data.type = 'PointLight';
data.color = object.color.getHex();
data.intensity = object.intensity;
data.distance = object.distance;
} else if ( object instanceof THREE.SpotLight ) {
data.type = 'SpotLight';
data.color = object.color.getHex();
data.intensity = object.intensity;
data.distance = object.distance;
data.angle = object.angle;
data.exponent = object.exponent;
} else if ( object instanceof THREE.HemisphereLight ) {
data.type = 'HemisphereLight';
data.color = object.color.getHex();
data.groundColor = object.groundColor.getHex();
} else if ( object instanceof THREE.Mesh ) {
data.type = 'Mesh';
data.geometry = parseGeometry( object.geometry );
data.material = parseMaterial( object.material );
} else if ( object instanceof THREE.Sprite ) {
data.type = 'Sprite';
data.material = parseMaterial( object.material );
} else if ( object instanceof THREE.Group ) {
data.type = 'Group';
} else {
data.type = 'Object3D';
}
data.matrix = object.matrix.toArray();
if ( object.children.length > 0 ) {
data.children = [];
for ( var i = 0; i < object.children.length; i ++ ) {
data.children.push( parseObject( object.children[ i ] ) );
}
}
return data;
}
output.object = parseObject( object );
return output;
}
}
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
*/
THREE.BufferGeometry = function () {
......@@ -869,6 +870,64 @@ THREE.BufferGeometry.prototype = {
}
},
toJSON: function () {
var output = {
metadata: {
version: 4.0,
type: 'BufferGeometry',
generator: 'BufferGeometryExporter'
},
uuid: this.uuid,
type: this.type,
data: {
attributes: {}
}
};
var attributes = this.attributes;
var offsets = this.offsets;
var boundingSphere = this.boundingSphere;
for ( var key in attributes ) {
var attribute = attributes[ key ];
var array = [], typeArray = attribute.array;
for ( var i = 0, l = typeArray.length; i < l; i ++ ) {
array[ i ] = typeArray[ i ];
}
output.data.attributes[ key ] = {
itemSize: attribute.itemSize,
type: attribute.array.constructor.name,
array: array
}
}
if ( offsets.length > 0 ) {
output.data.offsets = JSON.parse( JSON.stringify( offsets ) );
}
if ( boundingSphere !== null ) {
output.data.boundingSphere = {
center: boundingSphere.center.toArray(),
radius: boundingSphere.radius
}
}
return output;
},
clone: function () {
var geometry = new THREE.BufferGeometry();
......
......@@ -732,6 +732,207 @@ THREE.Geometry.prototype = {
} )(),
toJSON: function () {
var output = {
metadata: {
version: 4.0,
type: 'BufferGeometry',
generator: 'BufferGeometryExporter'
},
uuid: this.uuid,
type: this.type
};
if ( this.name !== "" ) output.name = this.name;
if ( this.parameters !== undefined ) {
var parameters = this.parameters;
for ( var key in parameters ) {
if ( parameters[ key ] !== undefined ) output[ key ] = parameters[ key ];
}
return output;
}
var vertices = [];
for ( var i = 0; i < this.vertices.length; i ++ ) {
var vertex = this.vertices[ i ];
vertices.push( vertex.x, vertex.y, vertex.z );
}
var faces = [];
var normals = [];
var normalsHash = {};
var colors = [];
var colorsHash = {};
var uvs = [];
var uvsHash = {};
for ( var i = 0; i < this.faces.length; i ++ ) {
var face = this.faces[ i ];
var hasMaterial = false; // face.materialIndex !== undefined;
var hasFaceUv = false; // deprecated
var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;
var hasFaceNormal = face.normal.length() > 0;
var hasFaceVertexNormal = face.vertexNormals.length > 0;
var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
var hasFaceVertexColor = face.vertexColors.length > 0;
var faceType = 0;
faceType = setBit( faceType, 0, 0 );
faceType = setBit( faceType, 1, hasMaterial );
faceType = setBit( faceType, 2, hasFaceUv );
faceType = setBit( faceType, 3, hasFaceVertexUv );
faceType = setBit( faceType, 4, hasFaceNormal );
faceType = setBit( faceType, 5, hasFaceVertexNormal );
faceType = setBit( faceType, 6, hasFaceColor );
faceType = setBit( faceType, 7, hasFaceVertexColor );
faces.push( faceType );
faces.push( face.a, face.b, face.c );
/*
if ( hasMaterial ) {
faces.push( face.materialIndex );
}
*/
if ( hasFaceVertexUv ) {
var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];
faces.push(
getUvIndex( faceVertexUvs[ 0 ] ),
getUvIndex( faceVertexUvs[ 1 ] ),
getUvIndex( faceVertexUvs[ 2 ] )
);
}
if ( hasFaceNormal ) {
faces.push( getNormalIndex( face.normal ) );
}
if ( hasFaceVertexNormal ) {
var vertexNormals = face.vertexNormals;
faces.push(
getNormalIndex( vertexNormals[ 0 ] ),
getNormalIndex( vertexNormals[ 1 ] ),
getNormalIndex( vertexNormals[ 2 ] )
);
}
if ( hasFaceColor ) {
faces.push( getColorIndex( face.color ) );
}
if ( hasFaceVertexColor ) {
var vertexColors = face.vertexColors;
faces.push(
getColorIndex( vertexColors[ 0 ] ),
getColorIndex( vertexColors[ 1 ] ),
getColorIndex( vertexColors[ 2 ] )
);
}
}
function setBit( value, position, enabled ) {
return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position) );
}
function getNormalIndex( normal ) {
var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
if ( normalsHash[ hash ] !== undefined ) {
return normalsHash[ hash ];
}
normalsHash[ hash ] = normals.length / 3;
normals.push( normal.x, normal.y, normal.z );
return normalsHash[ hash ];
}
function getColorIndex( color ) {
var hash = color.r.toString() + color.g.toString() + color.b.toString();
if ( colorsHash[ hash ] !== undefined ) {
return colorsHash[ hash ];
}
colorsHash[ hash ] = colors.length;
colors.push( color.getHex() );
return colorsHash[ hash ];
}
function getUvIndex( uv ) {
var hash = uv.x.toString() + uv.y.toString();
if ( uvsHash[ hash ] !== undefined ) {
return uvsHash[ hash ];
}
uvsHash[ hash ] = uvs.length / 2;
uvs.push( uv.x, uv.y );
return uvsHash[ hash ];
}
output.data = {};
output.data.vertices = vertices;
output.data.normals = normals;
if ( colors.length > 0 ) output.data.colors = colors;
if ( uvs.length > 0 ) output.data.uvs = [ uvs ]; // temporal backward compatibility
output.data.faces = faces;
//
return output;
},
clone: function () {
var geometry = new THREE.Geometry();
......
......@@ -500,6 +500,164 @@ THREE.Object3D.prototype = {
},
toJSON: function () {
var output = {
metadata: {
version: 4.3,
type: 'Object',
generator: 'ObjectExporter'
}
};
//
var geometries = {};
var parseGeometry = function ( geometry ) {
if ( output.geometries === undefined ) {
output.geometries = [];
}
if ( geometries[ geometry.uuid ] === undefined ) {
var json = geometry.toJSON();
delete json.metadata;
geometries[ geometry.uuid ] = json;
output.geometries.push( json );
}
return geometry.uuid;
};
//
var materials = {};
var parseMaterial = function ( material ) {
if ( output.materials === undefined ) {
output.materials = [];
}
if ( materials[ material.uuid ] === undefined ) {
var json = material.toJSON();
delete json.metadata;
materials[ material.uuid ] = json;
output.materials.push( json );
}
return material.uuid;
};
//
var parseObject = function ( object ) {
var data = {};
data.uuid = object.uuid;
data.type = object.type;
if ( object.name !== '' ) data.name = object.name;
if ( JSON.stringify( object.userData ) !== '{}' ) data.userData = object.userData;
if ( object.visible !== true ) data.visible = object.visible;
if ( object instanceof THREE.PerspectiveCamera ) {
data.fov = object.fov;
data.aspect = object.aspect;
data.near = object.near;
data.far = object.far;
} else if ( object instanceof THREE.OrthographicCamera ) {
data.left = object.left;
data.right = object.right;
data.top = object.top;
data.bottom = object.bottom;
data.near = object.near;
data.far = object.far;
} else if ( object instanceof THREE.AmbientLight ) {
data.color = object.color.getHex();
} else if ( object instanceof THREE.DirectionalLight ) {
data.color = object.color.getHex();
data.intensity = object.intensity;
} else if ( object instanceof THREE.PointLight ) {
data.color = object.color.getHex();
data.intensity = object.intensity;
data.distance = object.distance;
} else if ( object instanceof THREE.SpotLight ) {
data.color = object.color.getHex();
data.intensity = object.intensity;
data.distance = object.distance;
data.angle = object.angle;
data.exponent = object.exponent;
} else if ( object instanceof THREE.HemisphereLight ) {
data.color = object.color.getHex();
data.groundColor = object.groundColor.getHex();
} else if ( object instanceof THREE.Mesh ) {
data.geometry = parseGeometry( object.geometry );
data.material = parseMaterial( object.material );
} else if ( object instanceof THREE.Sprite ) {
data.material = parseMaterial( object.material );
}
data.matrix = object.matrix.toArray();
if ( object.children.length > 0 ) {
data.children = [];
for ( var i = 0; i < object.children.length; i ++ ) {
data.children.push( parseObject( object.children[ i ] ) );
}
}
return data;
}
output.object = parseObject( this );
return output;
},
clone: function ( object, recursive ) {
if ( object === undefined ) object = new THREE.Object3D();
......
......@@ -45,6 +45,7 @@ THREE.MaterialLoader.prototype = {
if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;
if ( json.shading !== undefined ) material.shading = json.shading;
if ( json.blending !== undefined ) material.blending = json.blending;
if ( json.side !== undefined ) material.side = json.side;
if ( json.opacity !== undefined ) material.opacity = json.opacity;
......
......@@ -85,6 +85,78 @@ THREE.Material.prototype = {
},
toJSON: function () {
var output = {
metadata: {
version: 4.2,
type: 'material',
generator: 'MaterialExporter'
},
uuid: this.uuid,
type: this.type
};
if ( this.name !== "" ) output.name = this.name;
if ( this instanceof THREE.MeshBasicMaterial ) {
output.color = this.color.getHex();
if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors;
if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending;
if ( this.side !== THREE.FrontSide ) output.side = this.side;
} else if ( this instanceof THREE.MeshLambertMaterial ) {
output.color = this.color.getHex();
output.ambient = this.ambient.getHex();
output.emissive = this.emissive.getHex();
if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors;
if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending;
if ( this.side !== THREE.FrontSide ) output.side = this.side;
} else if ( this instanceof THREE.MeshPhongMaterial ) {
output.color = this.color.getHex();
output.ambient = this.ambient.getHex();
output.emissive = this.emissive.getHex();
output.specular = this.specular.getHex();
output.shininess = this.shininess;
if ( this.vertexColors !== THREE.NoColors ) output.vertexColors = this.vertexColors;
if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending;
if ( this.side !== THREE.FrontSide ) output.side = this.side;
} else if ( this instanceof THREE.MeshNormalMaterial ) {
if ( this.shading !== THREE.FlatShading ) output.shading = this.shading;
if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending;
if ( this.side !== THREE.FrontSide ) output.side = this.side;
} else if ( this instanceof THREE.MeshDepthMaterial ) {
if ( this.blending !== THREE.NormalBlending ) output.blending = this.blending;
if ( this.side !== THREE.FrontSide ) output.side = this.side;
} else if ( this instanceof THREE.ShaderMaterial ) {
output.uniforms = this.uniforms;
output.vertexShader = this.vertexShader;
output.fragmentShader = this.fragmentShader;
} else if ( this instanceof THREE.SpriteMaterial ) {
output.color = this.color.getHex();
}
if ( this.opacity < 1 ) output.opacity = this.opacity;
if ( this.transparent !== false ) output.transparent = this.transparent;
if ( this.wireframe !== false ) output.wireframe = this.wireframe;
return output;
},
clone: function ( material ) {
if ( material === undefined ) material = new THREE.Material();
......
......@@ -4,21 +4,53 @@
THREE.MeshFaceMaterial = function ( materials ) {
this.uuid = THREE.Math.generateUUID();
this.type = 'MeshFaceMaterial';
this.materials = materials instanceof Array ? materials : [];
};
THREE.MeshFaceMaterial.prototype.clone = function () {
THREE.MeshFaceMaterial.prototype = {
var material = new THREE.MeshFaceMaterial();
constructor: THREE.MeshFaceMaterial,
for ( var i = 0; i < this.materials.length; i ++ ) {
toJSON: function () {
material.materials.push( this.materials[ i ].clone() );
var output = {
metadata: {
version: 4.2,
type: 'material',
generator: 'MaterialExporter'
},
uuid: this.uuid,
type: this.type,
materials: []
};
}
for ( var i = 0, l = this.materials.length; i < l; i ++ ) {
output.materials.push( this.materials[ i ].toJSON() );
}
return output;
},
clone: function () {
return material;
var material = new THREE.MeshFaceMaterial();
for ( var i = 0; i < this.materials.length; i ++ ) {
material.materials.push( this.materials[ i ].clone() );
}
return material;
}
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册