Browse Source

FBXLoader2: Refactored (sub)deformers code.

Mr.doob 8 years ago
parent
commit
0461d6d495
1 changed files with 66 additions and 50 deletions
  1. 66 50
      examples/js/loaders/FBXLoader2.js

+ 66 - 50
examples/js/loaders/FBXLoader2.js

@@ -110,9 +110,9 @@
 			var connections = parseConnections( FBXTree );
 			var textures = parseTextures( FBXTree, new THREE.TextureLoader( this.manager ).setPath( resourceDirectory ) );
 			var materials = parseMaterials( FBXTree, textures, connections );
-			var deformerMap = parseDeformers( FBXTree, connections );
-			var geometryMap = parseGeometries( FBXTree, connections, deformerMap );
-			var sceneGraph = parseScene( FBXTree, connections, deformerMap, geometryMap, materials );
+			var deformers = parseDeformers( FBXTree, connections );
+			var geometryMap = parseGeometries( FBXTree, connections, deformers );
+			var sceneGraph = parseScene( FBXTree, connections, deformers, geometryMap, materials );
 
 			return sceneGraph;
 
@@ -392,20 +392,23 @@
 	 */
 	function parseDeformers( FBXTree, connections ) {
 
-		var skeletonMap = new Map();
+		var deformers = {};
 
 		if ( 'Deformer' in FBXTree.Objects.subNodes ) {
 
 			var DeformerNodes = FBXTree.Objects.subNodes.Deformer;
+
 			for ( var nodeID in DeformerNodes ) {
 
 				var deformerNode = DeformerNodes[ nodeID ];
+
 				if ( deformerNode.attrType === 'Skin' ) {
 
 					var conns = connections.get( parseInt( nodeID ) );
 					var skeleton = parseSkeleton( conns, DeformerNodes );
 					skeleton.FBX_ID = parseInt( nodeID );
-					skeletonMap.set( parseInt( nodeID ), skeleton );
+
+					deformers[ parseInt( nodeID ) ] = skeleton;
 
 				}
 
@@ -413,7 +416,7 @@
 
 		}
 
-		return skeletonMap;
+		return deformers;
 
 	}
 
@@ -425,35 +428,38 @@
 	 */
 	function parseSkeleton( connections, DeformerNodes ) {
 
-		var subDeformers = new Map();
-		var subDeformerArray = [];
-		for ( var childrenIndex = 0, childrenLength = connections.children.length; childrenIndex < childrenLength; ++ childrenIndex ) {
+		var subDeformers = {};
+		var children = connections.children;
+
+		for ( var i = 0, l = children.length; i < l; ++ i ) {
 
-			var child = connections.children[ childrenIndex ];
+			var child = children[ i ];
 
 			var subDeformerNode = DeformerNodes[ child.ID ];
+
 			var subDeformer = {
 				FBX_ID: child.ID,
+				index: i,
 				indices: [],
 				weights: [],
 				transform: parseMatrixArray( subDeformerNode.subNodes.Transform.properties.a ),
 				transformLink: parseMatrixArray( subDeformerNode.subNodes.TransformLink.properties.a ),
 				linkMode: subDeformerNode.properties.Mode
 			};
+
 			if ( 'Indexes' in subDeformerNode.subNodes ) {
 
 				subDeformer.indices = parseIntArray( subDeformerNode.subNodes.Indexes.properties.a );
 				subDeformer.weights = parseFloatArray( subDeformerNode.subNodes.Weights.properties.a );
 
 			}
-			subDeformers.set( child.ID, subDeformer );
-			subDeformerArray.push( subDeformer );
+
+			subDeformers[ child.ID ] = subDeformer;
 
 		}
 
 		return {
 			map: subDeformers,
-			array: subDeformerArray,
 			bones: []
 		};
 
@@ -463,20 +469,21 @@
 	 * Generates Buffer geometries from geometry information in FBXTree, and generates map of THREE.BufferGeometries
 	 * @param {{Objects: {subNodes: {Geometry: Object.<number, FBXGeometryNode}}}} FBXTree
 	 * @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} connections
-	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[], skeleton: THREE.Skeleton|null}>} deformerMap
+	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[], skeleton: THREE.Skeleton|null}>} deformers
 	 * @returns {Map<number, THREE.BufferGeometry>}
 	 */
-	function parseGeometries( FBXTree, connections, deformerMap ) {
+	function parseGeometries( FBXTree, connections, deformers ) {
 
 		var geometryMap = new Map();
 
 		if ( 'Geometry' in FBXTree.Objects.subNodes ) {
 
 			var geometryNodes = FBXTree.Objects.subNodes.Geometry;
+
 			for ( var nodeID in geometryNodes ) {
 
 				var relationships = connections.get( parseInt( nodeID ) );
-				var geo = parseGeometry( geometryNodes[ nodeID ], relationships, deformerMap );
+				var geo = parseGeometry( geometryNodes[ nodeID ], relationships, deformers );
 				geometryMap.set( parseInt( nodeID ), geo );
 
 			}
@@ -491,19 +498,19 @@
 	 * Generates BufferGeometry from FBXGeometryNode.
 	 * @param {FBXGeometryNode} geometryNode
 	 * @param {{parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}} relationships
-	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[]}>} deformerMap
+	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[]}>} deformers
 	 * @returns {THREE.BufferGeometry}
 	 */
-	function parseGeometry( geometryNode, relationships, deformerMap ) {
+	function parseGeometry( geometryNode, relationships, deformers ) {
 
 		switch ( geometryNode.attrType ) {
 
 			case 'Mesh':
-				return parseMeshGeometry( geometryNode, relationships, deformerMap );
+				return parseMeshGeometry( geometryNode, relationships, deformers );
 				break;
 
 			case 'NurbsCurve':
-				return parseNurbsGeometry( geometryNode, relationships, deformerMap );
+				return parseNurbsGeometry( geometryNode );
 				break;
 
 		}
@@ -514,21 +521,15 @@
 	 * Specialty function for parsing Mesh based Geometry Nodes.
 	 * @param {FBXGeometryNode} geometryNode
 	 * @param {{parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}} relationships - Object representing relationships between specific geometry node and other nodes.
-	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[]}>} deformerMap - Map object of deformers and subDeformers by ID.
+	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[]}>} deformers - Map object of deformers and subDeformers by ID.
 	 * @returns {THREE.BufferGeometry}
 	 */
-	function parseMeshGeometry( geometryNode, relationships, deformerMap ) {
+	function parseMeshGeometry( geometryNode, relationships, deformers ) {
 
-		var FBX_ID = geometryNode.id;
-		var name = geometryNode.attrName;
 		for ( var i = 0; i < relationships.children.length; ++ i ) {
 
-			if ( deformerMap.has( relationships.children[ i ].ID ) ) {
-
-				var deformer = deformerMap.get( relationships.children[ i ].ID );
-				break;
-
-			}
+			var deformer = deformers[ relationships.children[ i ].ID ];
+			if ( deformer !== undefined ) break;
 
 		}
 
@@ -598,11 +599,11 @@
 
 			if ( deformer ) {
 
-				var array = deformer.array;
+				var subDeformers = deformer.map;
 
-				for ( var i = 0; i < array.length; i ++ ) {
+				for ( var key in subDeformers ) {
 
-					var subDeformer = array[ i ];
+					var subDeformer = subDeformers[ key ];
 					var indices = subDeformer.indices;
 
 					for ( var j = 0; j < indices.length; j ++ ) {
@@ -612,7 +613,7 @@
 						if ( index === vertexIndex ) {
 
 							weights.push( subDeformer.weights[ j ] );
-							weightIndices.push( i );
+							weightIndices.push( subDeformer.index );
 
 							break;
 
@@ -1044,7 +1045,7 @@
 	 * @param {{parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}} relationships
 	 * @returns {THREE.BufferGeometry}
 	 */
-	function parseNurbsGeometry( geometryNode, relationships ) {
+	function parseNurbsGeometry( geometryNode ) {
 
 		if ( THREE.NURBSCurve === undefined ) {
 
@@ -1115,12 +1116,12 @@
 	 * Finally generates Scene graph and Scene graph Objects.
 	 * @param {{Objects: {subNodes: {Model: Object.<number, FBXModelNode>}}}} FBXTree
 	 * @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} connections
-	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[], skeleton: THREE.Skeleton|null}>} deformerMap
+	 * @param {Map<number, {map: Map<number, {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}>, array: {FBX_ID: number, indices: number[], weights: number[], transform: number[], transformLink: number[], linkMode: string}[], skeleton: THREE.Skeleton|null}>} deformers
 	 * @param {Map<number, THREE.BufferGeometry>} geometryMap
 	 * @param {Map<number, THREE.Material>} materialMap
 	 * @returns {THREE.Group}
 	 */
-	function parseScene( FBXTree, connections, deformerMap, geometryMap, materialMap ) {
+	function parseScene( FBXTree, connections, deformers, geometryMap, materialMap ) {
 
 		var sceneGraph = new THREE.Group();
 
@@ -1142,25 +1143,37 @@
 			var node = ModelNode[ nodeID ];
 			var conns = connections.get( id );
 			var model = null;
+
 			for ( var i = 0; i < conns.parents.length; ++ i ) {
 
-				deformerMap.forEach( function ( deformer ) {
+				for ( var FBX_ID in deformers ) {
+
+					var deformer = deformers[ FBX_ID ];
+					var subDeformers = deformer.map;
 
-					if ( deformer.map.has( conns.parents[ i ].ID ) ) {
+					if ( subDeformers[ conns.parents[ i ].ID ] !== undefined ) {
 
 						model = new THREE.Bone();
-						var index = findIndex( deformer.array, function ( subDeformer ) {
 
-							return subDeformer.FBX_ID === conns.parents[ i ].ID;
+						for ( var key in subDeformers ) {
 
-						} );
-						deformer.bones[ index ] = model;
+							var subDeformer = subDeformers[ key ];
+
+							if ( subDeformer.FBX_ID === conns.parents[ i ].ID ) {
+
+								deformer.bones[ subDeformer.index ] = model;
+								break;
+
+							}
+
+						}
 
 					}
 
-				} );
+				}
 
 			}
+
 			if ( ! model ) {
 
 				switch ( node.attrType ) {
@@ -1366,12 +1379,15 @@
 
 		}
 
-		deformerMap.forEach( function ( deformer, FBX_ID ) {
+		for ( var FBX_ID in deformers ) {
 
-			for ( var deformerArrayIndex = 0, deformerArrayLength = deformer.array.length; deformerArrayIndex < deformerArrayLength; ++ deformerArrayIndex ) {
+			var deformer = deformers[ FBX_ID ];
+			var subDeformers = deformer.map;
 
-				//var subDeformer = deformer.array[ deformerArrayIndex ];
-				var subDeformerIndex = deformerArrayIndex;
+			for ( var key in subDeformers ) {
+
+				var subDeformer = subDeformers[ key ];
+				var subDeformerIndex = subDeformer.index;
 
 				/**
 				 * @type {THREE.Bone}
@@ -1389,7 +1405,7 @@
 
 			// Now that skeleton is in bind pose, bind to model.
 			deformer.skeleton = new THREE.Skeleton( deformer.bones );
-			var conns = connections.get( FBX_ID );
+			var conns = connections.get( parseInt( FBX_ID ) );
 			for ( var parentsIndex = 0, parentsLength = conns.parents.length; parentsIndex < parentsLength; ++ parentsIndex ) {
 
 				var parent = conns.parents[ parentsIndex ];
@@ -1415,7 +1431,7 @@
 
 			}
 
-		} );
+		}
 
 		//Skeleton is now bound, return objects to starting
 		//world positions.