Kaynağa Gözat

FBXLoader2: Refactored parseAnimations.

Mr.doob 8 yıl önce
ebeveyn
işleme
30da0beb74
1 değiştirilmiş dosya ile 309 ekleme ve 307 silme
  1. 309 307
      examples/js/loaders/FBXLoader2.js

+ 309 - 307
examples/js/loaders/FBXLoader2.js

@@ -1467,7 +1467,6 @@
 		var rawCurves = FBXTree.Objects.subNodes.AnimationCurve;
 		var rawCurves = FBXTree.Objects.subNodes.AnimationCurve;
 		var rawLayers = FBXTree.Objects.subNodes.AnimationLayer;
 		var rawLayers = FBXTree.Objects.subNodes.AnimationLayer;
 		var rawStacks = FBXTree.Objects.subNodes.AnimationStack;
 		var rawStacks = FBXTree.Objects.subNodes.AnimationStack;
-		var rawModels = FBXTree.Objects.subNodes.Model;
 
 
 		/**
 		/**
 		 * @type {{
 		 * @type {{
@@ -2136,6 +2135,7 @@
 			 */
 			 */
 			var layer = [];
 			var layer = [];
 			var children = connections.get( parseInt( nodeID ) ).children;
 			var children = connections.get( parseInt( nodeID ) ).children;
+
 			for ( var childIndex = 0; childIndex < children.length; childIndex ++ ) {
 			for ( var childIndex = 0; childIndex < children.length; childIndex ++ ) {
 
 
 				// Skip lockInfluenceWeights
 				// Skip lockInfluenceWeights
@@ -2167,8 +2167,8 @@
 
 
 			var layers = [];
 			var layers = [];
 			var children = connections.get( parseInt( nodeID ) ).children;
 			var children = connections.get( parseInt( nodeID ) ).children;
-			var maxTimeStamp = 0;
-			var minTimeStamp = Number.MAX_VALUE;
+			var timestamps = { max: 0, min: Number.MAX_VALUE };
+
 			for ( var childIndex = 0; childIndex < children.length; ++ childIndex ) {
 			for ( var childIndex = 0; childIndex < children.length; ++ childIndex ) {
 
 
 				var currentLayer = returnObject.layers[ children[ childIndex ].ID ];
 				var currentLayer = returnObject.layers[ children[ childIndex ].ID ];
@@ -2183,214 +2183,7 @@
 
 
 						if ( layer ) {
 						if ( layer ) {
 
 
-							getCurveNodeMaxMinTimeStamps( layer );
-
-						}
-
-						/**
-						 * Sets the maxTimeStamp and minTimeStamp variables if it has timeStamps that are either larger or smaller
-						 * than the max or min respectively.
-						 * @param {{
-									T: {
-											id: number,
-											attr: string,
-											internalID: number,
-											attrX: boolean,
-											attrY: boolean,
-											attrZ: boolean,
-											containerBoneID: number,
-											containerID: number,
-											curves: {
-													x: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-													y: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-													z: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-											},
-									},
-									R: {
-											id: number,
-											attr: string,
-											internalID: number,
-											attrX: boolean,
-											attrY: boolean,
-											attrZ: boolean,
-											containerBoneID: number,
-											containerID: number,
-											curves: {
-													x: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-													y: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-													z: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-											},
-									},
-									S: {
-											id: number,
-											attr: string,
-											internalID: number,
-											attrX: boolean,
-											attrY: boolean,
-											attrZ: boolean,
-											containerBoneID: number,
-											containerID: number,
-											curves: {
-													x: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-													y: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-													z: {
-															version: any,
-															id: number,
-															internalID: number,
-															times: number[],
-															values: number[],
-															attrFlag: number[],
-															attrData: number[],
-													},
-											},
-									},
-							}} layer
-						 */
-						function getCurveNodeMaxMinTimeStamps( layer ) {
-
-							/**
-							 * Sets the maxTimeStamp and minTimeStamp if one of the curve's time stamps
-							 * exceeds the maximum or minimum.
-							 * @param {{
-										x: {
-												version: any,
-												id: number,
-												internalID: number,
-												times: number[],
-												values: number[],
-												attrFlag: number[],
-												attrData: number[],
-										},
-										y: {
-												version: any,
-												id: number,
-												internalID: number,
-												times: number[],
-												values: number[],
-												attrFlag: number[],
-												attrData: number[],
-										},
-										z: {
-												version: any,
-												id: number,
-												internalID: number,
-												times: number[],
-												values: number[],
-												attrFlag: number[],
-												attrData: number[],
-										}
-								}} curve
-							 */
-							function getCurveMaxMinTimeStamp( curve ) {
-
-								/**
-								 * Sets the maxTimeStamp and minTimeStamp if one of its timestamps exceeds the maximum or minimum.
-								 * @param {{times: number[]}} axis
-								 */
-								function getCurveAxisMaxMinTimeStamps( axis ) {
-
-									maxTimeStamp = axis.times[ axis.times.length - 1 ] > maxTimeStamp ? axis.times[ axis.times.length - 1 ] : maxTimeStamp;
-									minTimeStamp = axis.times[ 0 ] < minTimeStamp ? axis.times[ 0 ] : minTimeStamp;
-
-								}
-
-								if ( curve.x ) {
-
-									getCurveAxisMaxMinTimeStamps( curve.x );
-
-								}
-								if ( curve.y ) {
-
-									getCurveAxisMaxMinTimeStamps( curve.y );
-
-								}
-								if ( curve.z ) {
-
-									getCurveAxisMaxMinTimeStamps( curve.z );
-
-								}
-
-							}
-
-							if ( layer.R ) {
-
-								getCurveMaxMinTimeStamp( layer.R.curves );
-
-							}
-							if ( layer.S ) {
-
-								getCurveMaxMinTimeStamp( layer.S.curves );
-
-							}
-							if ( layer.T ) {
-
-								getCurveMaxMinTimeStamp( layer.T.curves );
-
-							}
+							getCurveNodeMaxMinTimeStamps( layer, timestamps );
 
 
 						}
 						}
 
 
@@ -2401,13 +2194,13 @@
 			}
 			}
 
 
 			// Do we have an animation clip with actual length?
 			// Do we have an animation clip with actual length?
-			if ( maxTimeStamp > minTimeStamp ) {
+			if ( timestamps.max > timestamps.min ) {
 
 
 				returnObject.stacks[ nodeID ] = {
 				returnObject.stacks[ nodeID ] = {
 					name: rawStacks[ nodeID ].attrName,
 					name: rawStacks[ nodeID ].attrName,
 					layers: layers,
 					layers: layers,
-					length: maxTimeStamp - minTimeStamp,
-					frames: ( maxTimeStamp - minTimeStamp ) * 30
+					length: timestamps.max - timestamps.min,
+					frames: ( timestamps.max - timestamps.min ) * 30
 				};
 				};
 
 
 			}
 			}
@@ -2416,142 +2209,351 @@
 
 
 		return returnObject;
 		return returnObject;
 
 
-		/**
-		 * @param {Object} FBXTree
-		 * @param {{id: number, attrName: string, properties: Object<string, any>}} animationCurveNode
-		 * @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} connections
-		 * @param {{skeleton: {bones: {FBX_ID: number}[]}}} sceneGraph
-		 */
-		function parseAnimationNode( FBXTree, animationCurveNode, connections, sceneGraph ) {
-
-			var returnObject = {
-				/**
-				 * @type {number}
-				 */
-				id: animationCurveNode.id,
+	}
 
 
-				/**
-				 * @type {string}
-				 */
-				attr: animationCurveNode.attrName,
+	/**
+	 * @param {Object} FBXTree
+	 * @param {{id: number, attrName: string, properties: Object<string, any>}} animationCurveNode
+	 * @param {Map<number, {parents: {ID: number, relationship: string}[], children: {ID: number, relationship: string}[]}>} connections
+	 * @param {{skeleton: {bones: {FBX_ID: number}[]}}} sceneGraph
+	 */
+	function parseAnimationNode( FBXTree, animationCurveNode, connections, sceneGraph ) {
 
 
-				/**
-				 * @type {number}
-				 */
-				internalID: animationCurveNode.id,
+		var rawModels = FBXTree.Objects.subNodes.Model;
 
 
-				/**
-				 * @type {boolean}
-				 */
-				attrX: false,
+		var returnObject = {
+			/**
+			 * @type {number}
+			 */
+			id: animationCurveNode.id,
 
 
-				/**
-				 * @type {boolean}
-				 */
-				attrY: false,
+			/**
+			 * @type {string}
+			 */
+			attr: animationCurveNode.attrName,
 
 
-				/**
-				 * @type {boolean}
-				 */
-				attrZ: false,
+			/**
+			 * @type {number}
+			 */
+			internalID: animationCurveNode.id,
 
 
-				/**
-				 * @type {number}
-				 */
-				containerBoneID: - 1,
+			/**
+			 * @type {boolean}
+			 */
+			attrX: false,
 
 
-				/**
-				 * @type {number}
-				 */
-				containerID: - 1,
+			/**
+			 * @type {boolean}
+			 */
+			attrY: false,
 
 
-				curves: {
-					x: null,
-					y: null,
-					z: null
-				},
+			/**
+			 * @type {boolean}
+			 */
+			attrZ: false,
 
 
-				/**
-				 * @type {number[]}
-				 */
-				preRotations: null
-			};
+			/**
+			 * @type {number}
+			 */
+			containerBoneID: - 1,
 
 
-			if ( returnObject.attr.match( /S|R|T/ ) ) {
+			/**
+			 * @type {number}
+			 */
+			containerID: - 1,
 
 
-				for ( var attributeKey in animationCurveNode.properties ) {
+			curves: {
+				x: null,
+				y: null,
+				z: null
+			},
 
 
-					if ( attributeKey.match( /X/ ) ) {
+			/**
+			 * @type {number[]}
+			 */
+			preRotations: null
+		};
 
 
-						returnObject.attrX = true;
+		if ( returnObject.attr.match( /S|R|T/ ) ) {
 
 
-					}
-					if ( attributeKey.match( /Y/ ) ) {
+			for ( var attributeKey in animationCurveNode.properties ) {
 
 
-						returnObject.attrY = true;
+				if ( attributeKey.match( /X/ ) ) {
 
 
-					}
-					if ( attributeKey.match( /Z/ ) ) {
+					returnObject.attrX = true;
 
 
-						returnObject.attrZ = true;
+				}
+				if ( attributeKey.match( /Y/ ) ) {
 
 
-					}
+					returnObject.attrY = true;
 
 
 				}
 				}
+				if ( attributeKey.match( /Z/ ) ) {
 
 
-			} else {
+					returnObject.attrZ = true;
 
 
-				return null;
+				}
 
 
 			}
 			}
 
 
-			var conns = connections.get( returnObject.id );
-			var containerIndices = conns.parents;
+		} else {
 
 
-			for ( var containerIndicesIndex = containerIndices.length - 1; containerIndicesIndex >= 0; -- containerIndicesIndex ) {
+			return null;
 
 
-				var boneID = findIndex( sceneGraph.skeleton.bones, function ( bone ) {
+		}
 
 
-					return bone.FBX_ID === containerIndices[ containerIndicesIndex ].ID;
+		var conns = connections.get( returnObject.id );
+		var containerIndices = conns.parents;
 
 
-				} );
-				if ( boneID > - 1 ) {
+		for ( var containerIndicesIndex = containerIndices.length - 1; containerIndicesIndex >= 0; -- containerIndicesIndex ) {
 
 
-					returnObject.containerBoneID = boneID;
-					returnObject.containerID = containerIndices[ containerIndicesIndex ].ID;
-					var model = rawModels[ returnObject.containerID.toString() ];
-					if ( 'PreRotation' in model.properties ) {
+			var boneID = findIndex( sceneGraph.skeleton.bones, function ( bone ) {
 
 
-						returnObject.preRotations = parseVector3( model.properties.PreRotation ).multiplyScalar( Math.PI / 180 );
+				return bone.FBX_ID === containerIndices[ containerIndicesIndex ].ID;
 
 
-					}
-					break;
+			} );
+			if ( boneID > - 1 ) {
+
+				returnObject.containerBoneID = boneID;
+				returnObject.containerID = containerIndices[ containerIndicesIndex ].ID;
+				var model = rawModels[ returnObject.containerID.toString() ];
+				if ( 'PreRotation' in model.properties ) {
+
+					returnObject.preRotations = parseVector3( model.properties.PreRotation ).multiplyScalar( Math.PI / 180 );
 
 
 				}
 				}
+				break;
 
 
 			}
 			}
 
 
-			return returnObject;
+		}
+
+		return returnObject;
+
+	}
+
+	/**
+	 * @param {{id: number, subNodes: {KeyTime: {properties: {a: string}}, KeyValueFloat: {properties: {a: string}}, KeyAttrFlags: {properties: {a: string}}, KeyAttrDataFloat: {properties: {a: string}}}}} animationCurve
+	 */
+	function parseAnimationCurve( animationCurve ) {
+
+		return {
+			version: null,
+			id: animationCurve.id,
+			internalID: animationCurve.id,
+			times: parseFloatArray( animationCurve.subNodes.KeyTime.properties.a ).map( convertFBXTimeToSeconds ),
+			values: parseFloatArray( animationCurve.subNodes.KeyValueFloat.properties.a ),
+
+			attrFlag: parseIntArray( animationCurve.subNodes.KeyAttrFlags.properties.a ),
+			attrData: parseFloatArray( animationCurve.subNodes.KeyAttrDataFloat.properties.a )
+		};
+
+	}
+
+	/**
+	 * Sets the maxTimeStamp and minTimeStamp variables if it has timeStamps that are either larger or smaller
+	 * than the max or min respectively.
+	 * @param {{
+				T: {
+						id: number,
+						attr: string,
+						internalID: number,
+						attrX: boolean,
+						attrY: boolean,
+						attrZ: boolean,
+						containerBoneID: number,
+						containerID: number,
+						curves: {
+								x: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+								y: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+								z: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+						},
+				},
+				R: {
+						id: number,
+						attr: string,
+						internalID: number,
+						attrX: boolean,
+						attrY: boolean,
+						attrZ: boolean,
+						containerBoneID: number,
+						containerID: number,
+						curves: {
+								x: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+								y: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+								z: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+						},
+				},
+				S: {
+						id: number,
+						attr: string,
+						internalID: number,
+						attrX: boolean,
+						attrY: boolean,
+						attrZ: boolean,
+						containerBoneID: number,
+						containerID: number,
+						curves: {
+								x: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+								y: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+								z: {
+										version: any,
+										id: number,
+										internalID: number,
+										times: number[],
+										values: number[],
+										attrFlag: number[],
+										attrData: number[],
+								},
+						},
+				},
+		}} layer
+	 */
+	function getCurveNodeMaxMinTimeStamps( layer, timestamps ) {
+
+		if ( layer.R ) {
+
+			getCurveMaxMinTimeStamp( layer.R.curves, timestamps );
 
 
 		}
 		}
+		if ( layer.S ) {
 
 
-		/**
-		 * @param {{id: number, subNodes: {KeyTime: {properties: {a: string}}, KeyValueFloat: {properties: {a: string}}, KeyAttrFlags: {properties: {a: string}}, KeyAttrDataFloat: {properties: {a: string}}}}} animationCurve
-		 */
-		function parseAnimationCurve( animationCurve ) {
+			getCurveMaxMinTimeStamp( layer.S.curves, timestamps );
 
 
-			return {
-				version: null,
-				id: animationCurve.id,
-				internalID: animationCurve.id,
-				times: parseFloatArray( animationCurve.subNodes.KeyTime.properties.a ).map( convertFBXTimeToSeconds ),
-				values: parseFloatArray( animationCurve.subNodes.KeyValueFloat.properties.a ),
-
-				attrFlag: parseIntArray( animationCurve.subNodes.KeyAttrFlags.properties.a ),
-				attrData: parseFloatArray( animationCurve.subNodes.KeyAttrDataFloat.properties.a )
-			};
+		}
+		if ( layer.T ) {
+
+			getCurveMaxMinTimeStamp( layer.T.curves, timestamps );
+
+		}
+
+	}
+
+	/**
+	 * Sets the maxTimeStamp and minTimeStamp if one of the curve's time stamps
+	 * exceeds the maximum or minimum.
+	 * @param {{
+				x: {
+						version: any,
+						id: number,
+						internalID: number,
+						times: number[],
+						values: number[],
+						attrFlag: number[],
+						attrData: number[],
+				},
+				y: {
+						version: any,
+						id: number,
+						internalID: number,
+						times: number[],
+						values: number[],
+						attrFlag: number[],
+						attrData: number[],
+				},
+				z: {
+						version: any,
+						id: number,
+						internalID: number,
+						times: number[],
+						values: number[],
+						attrFlag: number[],
+						attrData: number[],
+				}
+		}} curve
+	 */
+	function getCurveMaxMinTimeStamp( curve, timestamps ) {
+
+		if ( curve.x ) {
+
+			getCurveAxisMaxMinTimeStamps( curve.x, timestamps );
 
 
 		}
 		}
+		if ( curve.y ) {
+
+			getCurveAxisMaxMinTimeStamps( curve.y, timestamps );
+
+		}
+		if ( curve.z ) {
+
+			getCurveAxisMaxMinTimeStamps( curve.z, timestamps );
+
+		}
+
+	}
+
+	/**
+	 * Sets the maxTimeStamp and minTimeStamp if one of its timestamps exceeds the maximum or minimum.
+	 * @param {{times: number[]}} axis
+	 */
+	function getCurveAxisMaxMinTimeStamps( axis, timestamps ) {
+
+		timestamps.max = axis.times[ axis.times.length - 1 ] > timestamps.max ? axis.times[ axis.times.length - 1 ] : timestamps.max;
+		timestamps.min = axis.times[ 0 ] < timestamps.min ? axis.times[ 0 ] : timestamps.min;
 
 
 	}
 	}