فهرست منبع

GLTFLoader: Remove extra Object3D around nodes.

Don McCurdy 7 سال پیش
والد
کامیت
dedf099d73
1فایلهای تغییر یافته به همراه123 افزوده شده و 131 حذف شده
  1. 123 131
      examples/js/loaders/GLTFLoader.js

+ 123 - 131
examples/js/loaders/GLTFLoader.js

@@ -1197,6 +1197,59 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
+	/**
+	 * TODO(donmccurdy): Why is all this necessary, again?
+	 * @param {GLTF.Node} nodeDef
+	 * @param {THREE.Group} group
+	 * @param {Array<THREE.Object3D>} nodes
+	 * @param {Array<Object} skins
+	 */
+	function deepCloneMeshGroup( group ) {
+
+		// Clone group's children manually.
+		var clonedGroup = group.clone( false );
+
+		for ( var i = 0; i < group.children.length; i ++ ) {
+
+			var child = group.children[ i ];
+			var clonedChild;
+
+			switch ( child.type ) {
+
+				case 'LineSegments':
+					clonedChild = new THREE.LineSegments( child.geometry, child.material );
+					break;
+
+				case 'LineLoop':
+					clonedChild = new THREE.LineLoop( child.geometry, child.material );
+					break;
+
+				case 'Line':
+					clonedChild = new THREE.Line( child.geometry, child.material );
+					break;
+
+				case 'Points':
+					clonedChild = new THREE.Points( child.geometry, child.material );
+					break;
+
+				default:
+					clonedChild = new THREE.Mesh( child.geometry, child.material );
+					clonedChild.drawMode = child.drawMode;
+
+			}
+
+			clonedChild.morphTargetInfluences = child.morphTargetInfluences;
+			clonedChild.userData = child.userData;
+			clonedChild.name = child.name;
+
+			clonedGroup.add( clonedChild );
+
+		}
+
+		return clonedGroup;
+
+	}
+
 	/* GLTF PARSER */
 
 	function GLTFParser( json, extensions, options ) {
@@ -2133,198 +2186,137 @@ THREE.GLTFLoader = ( function () {
 
 		} );
 
-		return _each( json.nodes, function ( node ) {
-
-			var matrix = new THREE.Matrix4();
+		return scope._withDependencies( [
 
-			var _node = node.isBone === true ? new THREE.Bone() : new THREE.Object3D();
+			'meshes',
+			'skins',
+			'cameras'
 
-			if ( node.name !== undefined ) {
-
-				_node.name = THREE.PropertyBinding.sanitizeNodeName( node.name );
-
-			}
-
-			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 deepCloneMeshGroup( dependencies.meshes[ nodeDef.mesh ] );
 
-				}
+				} 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 ) {
+			} ).then( function ( __nodes ) {
 
-					var node = json.nodes[ nodeId ];
+				return _each( __nodes, function ( node, nodeIndex ) {
 
-					var mesh = node.mesh;
+					var nodeDef = json.nodes[ nodeIndex ];
 
-					if ( mesh !== undefined ) {
+					if ( nodeDef.name !== undefined ) {
 
-						var group = dependencies.meshes[ mesh ];
+						node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name );
 
-						if ( group !== undefined ) {
-
-							// do not clone children as they will be replaced anyway
-							var clonedgroup = group.clone( false );
-
-							for ( var i = 0; i < group.children.length; i ++ ) {
-
-								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 );
-
-						} else {
+							child.bind( new THREE.Skeleton( bones, boneInverses ), child.matrixWorld );
 
-							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;
 
 				} );