Browse Source

Merge pull request #12244 from donmccurdy/feat-gltf-shallower

GLTFLoader: Remove extra Object3D wrappers on nodes.
Mr.doob 7 years ago
parent
commit
5e78337be1
3 changed files with 96 additions and 137 deletions
  1. 73 136
      examples/js/loaders/GLTFLoader.js
  2. 11 1
      examples/webgl_loader_gltf.html
  3. 12 0
      src/objects/Mesh.js

+ 73 - 136
examples/js/loaders/GLTFLoader.js

@@ -1807,13 +1807,10 @@ THREE.GLTFLoader = ( function () {
 
 		] ).then( function ( dependencies ) {
 
-			return _each( json.meshes, function ( meshDef ) {
+			return _each( json.meshes, function ( meshDef, meshIndex ) {
 
 				var group = new THREE.Group();
 
-				if ( meshDef.name !== undefined ) group.name = meshDef.name;
-				if ( meshDef.extras ) group.userData = meshDef.extras;
-
 				var primitives = meshDef.primitives || [];
 
 				return scope.loadGeometries( primitives ).then( function ( geometries ) {
@@ -1896,7 +1893,8 @@ THREE.GLTFLoader = ( function () {
 
 						}
 
-						mesh.name = group.name + '_' + i;
+						mesh.name = meshDef.name || ( 'mesh_' + meshIndex );
+						mesh.name += i > 0 ? ( '_' + i ) : '';
 
 						if ( primitive.targets !== undefined ) {
 
@@ -2133,198 +2131,137 @@ THREE.GLTFLoader = ( function () {
 
 		} );
 
-		return _each( json.nodes, function ( node ) {
-
-			var matrix = new THREE.Matrix4();
-
-			var _node = node.isBone === true ? new THREE.Bone() : new THREE.Object3D();
+		return scope._withDependencies( [
 
-			if ( node.name !== undefined ) {
-
-				_node.name = THREE.PropertyBinding.sanitizeNodeName( node.name );
-
-			}
+			'meshes',
+			'skins',
+			'cameras'
 
-			if ( node.extras ) _node.userData = node.extras;
+		] ).then( function ( dependencies ) {
 
-			if ( node.matrix !== undefined ) {
+			return _each( json.nodes, function ( nodeDef ) {
 
-				matrix.fromArray( node.matrix );
-				_node.applyMatrix( matrix );
+				if ( nodeDef.isBone === true ) {
 
-			} else {
+					return new THREE.Bone();
 
-				if ( node.translation !== undefined ) {
+				} else if ( nodeDef.mesh !== undefined ) {
 
-					_node.position.fromArray( node.translation );
+					return dependencies.meshes[ nodeDef.mesh ].clone();
 
-				}
+				} else if ( nodeDef.camera !== undefined ) {
 
-				if ( node.rotation !== undefined ) {
+					return dependencies.cameras[ nodeDef.camera ];
 
-					_node.quaternion.fromArray( node.rotation );
+				} else if ( nodeDef.extensions
+								 && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS ]
+								 && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS ].light !== undefined ) {
 
-				}
+					var lights = extensions[ EXTENSIONS.KHR_LIGHTS ].lights;
+					return lights[ nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS ].light ];
 
-				if ( node.scale !== undefined ) {
+				} else {
 
-					_node.scale.fromArray( node.scale );
+					return new THREE.Object3D();
 
 				}
 
-			}
-
-			return _node;
-
-		} ).then( function ( __nodes ) {
-
-			return scope._withDependencies( [
-
-				'meshes',
-				'skins',
-				'cameras'
-
-			] ).then( function ( dependencies ) {
-
-				return _each( __nodes, function ( _node, nodeId ) {
-
-					var node = json.nodes[ nodeId ];
-
-					var mesh = node.mesh;
-
-					if ( mesh !== undefined ) {
+			} ).then( function ( __nodes ) {
 
-						var group = dependencies.meshes[ mesh ];
+				return _each( __nodes, function ( node, nodeIndex ) {
 
-						if ( group !== undefined ) {
+					var nodeDef = json.nodes[ nodeIndex ];
 
-							// do not clone children as they will be replaced anyway
-							var clonedgroup = group.clone( false );
+					if ( nodeDef.name !== undefined ) {
 
-							for ( var i = 0; i < group.children.length; i ++ ) {
+						node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name );
 
-								var child = group.children[ i ];
-								var originalChild = child;
-
-								// clone Mesh to add to _node
+					}
 
-								var originalMaterial = child.material;
-								var originalGeometry = child.geometry;
-								var originalInfluences = child.morphTargetInfluences;
-								var originalUserData = child.userData;
-								var originalName = child.name;
+					if ( nodeDef.extras ) node.userData = nodeDef.extras;
 
-								var material = originalMaterial;
+					if ( nodeDef.matrix !== undefined ) {
 
-								switch ( child.type ) {
+						var matrix = new THREE.Matrix4();
+						matrix.fromArray( nodeDef.matrix );
+						node.applyMatrix( matrix );
 
-									case 'LineSegments':
-										child = new THREE.LineSegments( originalGeometry, material );
-										break;
+					} else {
 
-									case 'LineLoop':
-										child = new THREE.LineLoop( originalGeometry, material );
-										break;
+						if ( nodeDef.translation !== undefined ) {
 
-									case 'Line':
-										child = new THREE.Line( originalGeometry, material );
-										break;
+							node.position.fromArray( nodeDef.translation );
 
-									case 'Points':
-										child = new THREE.Points( originalGeometry, material );
-										break;
+						}
 
-									default:
-										child = new THREE.Mesh( originalGeometry, material );
-										child.drawMode = originalChild.drawMode;
+						if ( nodeDef.rotation !== undefined ) {
 
-								}
+							node.quaternion.fromArray( nodeDef.rotation );
 
-								child.castShadow = true;
-								child.morphTargetInfluences = originalInfluences;
-								child.userData = originalUserData;
-								child.name = originalName;
+						}
 
-								var skinEntry;
+						if ( nodeDef.scale !== undefined ) {
 
-								if ( node.skin !== undefined ) {
+							node.scale.fromArray( nodeDef.scale );
 
-									skinEntry = dependencies.skins[ node.skin ];
+						}
 
-								}
+					}
 
-								// Replace Mesh with SkinnedMesh in library
-								if ( skinEntry ) {
+					if ( nodeDef.skin !== undefined ) {
 
-									var geometry = originalGeometry;
-									material = originalMaterial;
-									material.skinning = true;
+						var skinnedMeshes = [];
 
-									child = new THREE.SkinnedMesh( geometry, material );
-									child.castShadow = true;
-									child.userData = originalUserData;
-									child.name = originalName;
+						for ( var i = 0; i < node.children.length; i ++ ) {
 
-									var bones = [];
-									var boneInverses = [];
+							var skinEntry = dependencies.skins[ nodeDef.skin ];
 
-									for ( var i = 0, l = skinEntry.joints.length; i < l; i ++ ) {
+							// Replace Mesh with SkinnedMesh.
+							var geometry = node.children[ i ].geometry;
+							var material = node.children[ i ].material;
+							material.skinning = true;
 
-										var jointId = skinEntry.joints[ i ];
-										var jointNode = __nodes[ jointId ];
+							var child = new THREE.SkinnedMesh( geometry, material );
+							child.morphTargetInfluences = node.children[ i ].morphTargetInfluences;
+							child.userData = node.children[ i ].userData;
+							child.name = node.children[ i ].name;
 
-										if ( jointNode ) {
+							var bones = [];
+							var boneInverses = [];
 
-											bones.push( jointNode );
+							for ( var j = 0, l = skinEntry.joints.length; j < l; j ++ ) {
 
-											var m = skinEntry.inverseBindMatrices.array;
-											var mat = new THREE.Matrix4().fromArray( m, i * 16 );
-											boneInverses.push( mat );
+								var jointId = skinEntry.joints[ j ];
+								var jointNode = __nodes[ jointId ];
 
-										} else {
+								if ( jointNode ) {
 
-											console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', jointId );
+									bones.push( jointNode );
 
-										}
+									var m = skinEntry.inverseBindMatrices.array;
+									var mat = new THREE.Matrix4().fromArray( m, j * 16 );
+									boneInverses.push( mat );
 
-									}
+								} else {
 
-									child.bind( new THREE.Skeleton( bones, boneInverses ), child.matrixWorld );
+									console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', jointId );
 
 								}
 
-								clonedgroup.add( child );
-
 							}
 
-							_node.add( clonedgroup );
+							child.bind( new THREE.Skeleton( bones, boneInverses ), child.matrixWorld );
 
-						} else {
-
-							console.warn( 'THREE.GLTFLoader: Could not find node "' + mesh + '".' );
+							skinnedMeshes.push( child );
 
 						}
 
-					}
-
-					if ( node.camera !== undefined ) {
-
-						var camera = dependencies.cameras[ node.camera ];
-
-						_node.add( camera );
-
-					}
-
-					if ( node.extensions
-							 && node.extensions[ EXTENSIONS.KHR_LIGHTS ]
-							 && node.extensions[ EXTENSIONS.KHR_LIGHTS ].light !== undefined ) {
-
-						var lights = extensions[ EXTENSIONS.KHR_LIGHTS ].lights;
-						_node.add( lights[ node.extensions[ EXTENSIONS.KHR_LIGHTS ].light ] );
+						node.remove.apply( node, node.children );
+						node.add.apply( node, skinnedMeshes );
 
 					}
 
-					return _node;
+					return node;
 
 				} );
 

+ 11 - 1
examples/webgl_loader_gltf.html

@@ -274,6 +274,12 @@
 
 					}
 
+					object.traverse( function ( node ) {
+
+						if ( node.isMesh ) node.castShadow = true;
+
+					} );
+
 					cameraIndex = 0;
 					cameras = [];
 					cameraNames = [];
@@ -332,7 +338,11 @@
 					scene.add( object );
 					onWindowResize();
 
-				});
+				}, undefined, function ( error ) {
+
+					console.error( error );
+
+				} );
 
 			orbitControls = new THREE.OrbitControls(defaultCamera, renderer.domElement);
 

+ 12 - 0
src/objects/Mesh.js

@@ -50,6 +50,18 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		this.drawMode = source.drawMode;
 
+		if ( source.morphTargetInfluences !== undefined ) {
+
+			this.morphTargetInfluences = source.morphTargetInfluences.slice();
+
+		}
+
+		if ( source.morphTargetDictionary !== undefined ) {
+
+			this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary );
+
+		}
+
 		return this;
 
 	},