Prechádzať zdrojové kódy

Fix errors in setting bone transforms

Lewy Blue 7 rokov pred
rodič
commit
0dbdd90362
1 zmenil súbory, kde vykonal 33 pridanie a 24 odobranie
  1. 33 24
      examples/js/loaders/FBXLoader.js

+ 33 - 24
examples/js/loaders/FBXLoader.js

@@ -463,7 +463,6 @@
 	// Also parse the texture map and return any textures associated with the material
 	// Also parse the texture map and return any textures associated with the material
 	function parseParameters( FBXTree, properties, textureMap, ID, connections ) {
 	function parseParameters( FBXTree, properties, textureMap, ID, connections ) {
 
 
-
 		var parameters = {};
 		var parameters = {};
 
 
 		if ( properties.BumpFactor ) {
 		if ( properties.BumpFactor ) {
@@ -644,10 +643,12 @@
 				ID: child.ID,
 				ID: child.ID,
 				indices: [],
 				indices: [],
 				weights: [],
 				weights: [],
+
+				// the global initial transform of the geometry node this bone is connected to
 				transform: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.Transform.properties.a ),
 				transform: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.Transform.properties.a ),
 
 
-				//currently not used
-				// transformLink: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.TransformLink.properties.a ),
+				// the global initial transform of this bone
+				transformLink: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.TransformLink.properties.a ),
 
 
 			};
 			};
 
 
@@ -1540,7 +1541,7 @@
 			var node = modelNodes[ nodeID ];
 			var node = modelNodes[ nodeID ];
 			var relationships = connections.get( id );
 			var relationships = connections.get( id );
 
 
-			var model = buildSkeleton( relationships, skeletons );
+			var model = buildSkeleton( relationships, skeletons, id, node.attrName );
 
 
 			if ( ! model ) {
 			if ( ! model ) {
 
 
@@ -1558,7 +1559,7 @@
 					case 'NurbsCurve':
 					case 'NurbsCurve':
 						model = createCurve( relationships, geometryMap );
 						model = createCurve( relationships, geometryMap );
 						break;
 						break;
-					case 'LimbNode':
+					case 'LimbNode': // usually associated with a bone, however if one was not created we'll make a Group instead
 					case 'Null':
 					case 'Null':
 					default:
 					default:
 						model = new THREE.Group();
 						model = new THREE.Group();
@@ -1566,28 +1567,23 @@
 
 
 				}
 				}
 
 
-			}
-
-			if ( model ) {
-
-				setModelTransforms( FBXTree, model, node );
-
 				model.name = THREE.PropertyBinding.sanitizeNodeName( node.attrName );
 				model.name = THREE.PropertyBinding.sanitizeNodeName( node.attrName );
 				model.ID = id;
 				model.ID = id;
 
 
-				modelMap.set( id, model );
-
 			}
 			}
 
 
+			setModelTransforms( FBXTree, model, node );
+			modelMap.set( id, model );
+
 		}
 		}
 
 
 		return modelMap;
 		return modelMap;
 
 
 	}
 	}
 
 
-	function buildSkeleton( relationships, skeletons ) {
+	function buildSkeleton( relationships, skeletons, id, name ) {
 
 
-		var model = null;
+		var bone = null;
 
 
 		relationships.parents.forEach( function ( parent ) {
 		relationships.parents.forEach( function ( parent ) {
 
 
@@ -1599,16 +1595,20 @@
 
 
 					if ( rawBone.ID === parent.ID ) {
 					if ( rawBone.ID === parent.ID ) {
 
 
-						var model2 = model;
-						model = new THREE.Bone();
-						skeleton.bones[ i ] = model;
+						var subBone = bone;
+						bone = new THREE.Bone();
+
+						// set name and id here - otherwise in cases where "subBone" is created it will not have a name / id
+						bone.name = THREE.PropertyBinding.sanitizeNodeName( name );
+						bone.ID = id;
+
+						skeleton.bones[ i ] = bone;
 
 
 						// In cases where a bone is shared between multiple meshes
 						// In cases where a bone is shared between multiple meshes
-						// model will already be defined and we'll hit this case
-						// TODO: currently doesn't work correctly
-						if ( model2 !== null ) {
+						// duplicate the bone here and and it as a child of the first bone
+						if ( subBone !== null ) {
 
 
-							model.add( model2 );
+							bone.add( subBone );
 
 
 						}
 						}
 
 
@@ -1620,7 +1620,7 @@
 
 
 		} );
 		} );
 
 
-		return model;
+		return bone;
 
 
 	}
 	}
 
 
@@ -1983,6 +1983,8 @@
 	// parse the model node for transform details and apply them to the model
 	// parse the model node for transform details and apply them to the model
 	function setModelTransforms( FBXTree, model, modelNode ) {
 	function setModelTransforms( FBXTree, model, modelNode ) {
 
 
+		// console.log( modelNode, model )
+
 		// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
 		// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
 		if ( 'RotationOrder' in modelNode.properties ) {
 		if ( 'RotationOrder' in modelNode.properties ) {
 
 
@@ -2093,14 +2095,21 @@
 
 
 			var skeleton = skeletons[ ID ];
 			var skeleton = skeletons[ ID ];
 
 
-			skeleton.bones.forEach( function ( bone ) {
+			skeleton.bones.forEach( function ( bone, i ) {
 
 
+				// if the bone's initial transform is set in a poseNode, copy that
 				if ( worldMatrices.has( bone.ID ) ) {
 				if ( worldMatrices.has( bone.ID ) ) {
 
 
 					var mat = worldMatrices.get( bone.ID );
 					var mat = worldMatrices.get( bone.ID );
 					bone.matrixWorld.copy( mat );
 					bone.matrixWorld.copy( mat );
 
 
 				}
 				}
+				// otherwise use the transform from the rawBone
+				else {
+
+					bone.matrixWorld.copy( skeleton.rawBones[ i ].transformLink )
+
+				}
 
 
 			} );
 			} );