diff --git a/editor/index.html b/editor/index.html index a9110d97ac0b83f732e82358f830ecc5b6b3ddc1..ccc967f5c48903192946b36d4f641237efcab61d 100644 --- a/editor/index.html +++ b/editor/index.html @@ -26,7 +26,6 @@ - @@ -35,11 +34,6 @@ - - - - - @@ -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 ); diff --git a/editor/js/Menubar.File.js b/editor/js/Menubar.File.js index 066cfd2b52166f377bb45d5d734ee4bb52df4529..16c9b0eeabcc2211c867379fb7a5686d902fd88d 100644 --- a/editor/js/Menubar.File.js +++ b/editor/js/Menubar.File.js @@ -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 ); diff --git a/examples/js/exporters/BufferGeometryExporter.js b/examples/js/exporters/BufferGeometryExporter.js deleted file mode 100644 index 1a2728619b19a25920f2e21a6eeafaa0627c4939..0000000000000000000000000000000000000000 --- a/examples/js/exporters/BufferGeometryExporter.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @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; - - } - -}; diff --git a/examples/js/exporters/GeometryExporter.js b/examples/js/exporters/GeometryExporter.js deleted file mode 100644 index ce1e08cb4faa9cc8ac9b7dc9d8fdb3aaa1213ced..0000000000000000000000000000000000000000 --- a/examples/js/exporters/GeometryExporter.js +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @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; - - } - -}; diff --git a/examples/js/exporters/HTMLExporter.js b/examples/js/exporters/HTMLExporter.js deleted file mode 100644 index 50e6cd7f906a90e6e2a162198b19c06eab2ba6d3..0000000000000000000000000000000000000000 --- a/examples/js/exporters/HTMLExporter.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.HTMLExporter = function () {}; - -THREE.HTMLExporter.prototype = { - - constructor: THREE.HTMLExporter, - - parse: function ( scene ) { - - return output; - - } - -} diff --git a/examples/js/exporters/MaterialExporter.js b/examples/js/exporters/MaterialExporter.js deleted file mode 100644 index 8142a2b9549f571a1aaf7f73918f5bedcc35bcd0..0000000000000000000000000000000000000000 --- a/examples/js/exporters/MaterialExporter.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @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; - - } - -}; diff --git a/examples/js/exporters/ObjectExporter.js b/examples/js/exporters/ObjectExporter.js deleted file mode 100644 index 19846d6cc2c43f78451bec1a09a83bcb4c672e74..0000000000000000000000000000000000000000 --- a/examples/js/exporters/ObjectExporter.js +++ /dev/null @@ -1,268 +0,0 @@ -/** - * @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; - - } - -} diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index f6373abc70f7a9658c3f8afce66bbe539530b3aa..9b9e890595e06b72c0662795ed3dbe6ce17ac8a9 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -1,5 +1,6 @@ /** * @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(); diff --git a/src/core/Geometry.js b/src/core/Geometry.js index 51bc5f7017989adb5b806a4846d07b090f2c1727..1beb186e82c8e69a30d3e5959605345259683953 100644 --- a/src/core/Geometry.js +++ b/src/core/Geometry.js @@ -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(); diff --git a/src/core/Object3D.js b/src/core/Object3D.js index ea6f58564bc2a49f4e049d15e11f92041921a0a2..862688fccccb26d6fe246e8bc6e64a81a559f199 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -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(); diff --git a/src/loaders/MaterialLoader.js b/src/loaders/MaterialLoader.js index c93dc0110a2b8c5dcde9b6cf3860897479863ccd..0db6564dbc0c3db16ebf4b107a6a155a7ec59528 100644 --- a/src/loaders/MaterialLoader.js +++ b/src/loaders/MaterialLoader.js @@ -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; diff --git a/src/materials/Material.js b/src/materials/Material.js index b5da1c4825372617f0f3c90ea85d0189a673fc00..16eeeb09e75267bd5a7be61378f3a6831ac86dc2 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -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(); diff --git a/src/materials/MeshFaceMaterial.js b/src/materials/MeshFaceMaterial.js index a9eafe6d06534b6a6ca8277163f35cc75de31125..46dbac2befa6319114cb2e84827d9943101545de 100644 --- a/src/materials/MeshFaceMaterial.js +++ b/src/materials/MeshFaceMaterial.js @@ -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; + + } };