Browse Source

Merge pull request #10721 from Kyle-Larson/feature/Issues/10703

FBXLoader2: Support for PreRotation
Mr.doob 8 năm trước cách đây
mục cha
commit
09db6d49c9

+ 94 - 26
examples/js/loaders/FBXLoader2.js

@@ -59,23 +59,22 @@
 
 
 			this.fileLoader.load( url, function ( text ) {
 			this.fileLoader.load( url, function ( text ) {
 
 
-				if ( ! isFbxFormatASCII( text ) ) {
+				try {
 
 
-					console.error( 'FBXLoader: FBX Binary format not supported.' );
-					self.manager.itemError( url );
-					return;
+					var scene = self.parse( text, resourceDirectory );
+					onLoad( scene );
 
 
-				}
-				if ( getFbxVersion( text ) < 7000 ) {
+				} catch ( error ) {
 
 
-					console.error( 'FBXLoader: FBX version not supported for file at ' + url + ', FileVersion: ' + getFbxVersion( text ) );
-					self.manager.itemError( url );
-					return;
+					window.setTimeout( function () {
 
 
-				}
+						if ( onError ) onError( error );
+
+						self.manager.itemError( url );
+
+					}, 0 );
 
 
-				var scene = self.parse( text, resourceDirectory );
-				onLoad( scene );
+				}
 
 
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
@@ -93,6 +92,24 @@
 
 
 			var loader = this;
 			var loader = this;
 
 
+			if ( ! isFbxFormatASCII( FBXText ) ) {
+
+				throw new Error( 'FBXLoader: FBX Binary format not supported.' );
+				self.manager.itemError( url );
+				return;
+
+				//TODO: Support Binary parsing.  Hopefully in the future,
+				//we call var FBXTree = new BinaryParser().parse( FBXText );
+
+			}
+			if ( getFbxVersion( FBXText ) < 7000 ) {
+
+				throw new Error( 'FBXLoader: FBX version not supported for file at ' + url + ', FileVersion: ' + getFbxVersion( text ) );
+				self.manager.itemError( url );
+				return;
+
+			}
+
 			var FBXTree = new TextParser().parse( FBXText );
 			var FBXTree = new TextParser().parse( FBXText );
 
 
 			var connections = parseConnections( FBXTree );
 			var connections = parseConnections( FBXTree );
@@ -1193,11 +1210,7 @@
 
 
 					if ( 'Lcl_Rotation' in node.properties ) {
 					if ( 'Lcl_Rotation' in node.properties ) {
 
 
-						var rotation = parseFloatArray( node.properties.Lcl_Rotation.value ).map( function ( value ) {
-
-							return value * Math.PI / 180;
-
-						} );
+						var rotation = parseFloatArray( node.properties.Lcl_Rotation.value ).map( degreeToRadian );
 						rotation.push( 'ZYX' );
 						rotation.push( 'ZYX' );
 						model.rotation.fromArray( rotation );
 						model.rotation.fromArray( rotation );
 
 
@@ -1209,6 +1222,16 @@
 
 
 					}
 					}
 
 
+					if ( 'PreRotation' in node.properties ) {
+
+						var preRotations = new THREE.Euler().setFromVector3( parseVector3( node.properties.PreRotation ).multiplyScalar( Math.PI / 180 ), 'ZYX' );
+						preRotations = new THREE.Quaternion().setFromEuler( preRotations );
+						var currentRotation = new THREE.Quaternion().setFromEuler( model.rotation );
+						preRotations.multiply( currentRotation );
+						model.rotation.setFromQuaternion( preRotations, 'ZYX' );
+
+					}
+
 					var conns = connections.get( model.FBX_ID );
 					var conns = connections.get( model.FBX_ID );
 					for ( var parentIndex = 0; parentIndex < conns.parents.length; parentIndex ++ ) {
 					for ( var parentIndex = 0; parentIndex < conns.parents.length; parentIndex ++ ) {
 
 
@@ -1333,11 +1356,7 @@
 
 
 					if ( 'Lcl_Rotation' in node.properties ) {
 					if ( 'Lcl_Rotation' in node.properties ) {
 
 
-						var rotation = parseFloatArray( node.properties.Lcl_Rotation.value ).map( function ( value ) {
-
-							return value * Math.PI / 180;
-
-						} );
+						var rotation = parseFloatArray( node.properties.Lcl_Rotation.value ).map( degreeToRadian );
 						rotation.push( 'ZYX' );
 						rotation.push( 'ZYX' );
 						model.rotation.fromArray( rotation );
 						model.rotation.fromArray( rotation );
 
 
@@ -1349,6 +1368,16 @@
 
 
 					}
 					}
 
 
+					if ( 'PreRotation' in node.properties ) {
+
+						var preRotations = new THREE.Euler().setFromVector3( parseVector3( node.properties.PreRotation ).multiplyScalar( Math.PI / 180 ), 'ZYX' );
+						preRotations = new THREE.Quaternion().setFromEuler( preRotations );
+						var currentRotation = new THREE.Quaternion().setFromEuler( model.rotation );
+						preRotations.multiply( currentRotation );
+						model.rotation.setFromQuaternion( preRotations, 'ZYX' );
+
+					}
+
 				}
 				}
 
 
 				// Silly hack with the animation parsing.  We're gonna pretend the scene graph has a skeleton
 				// Silly hack with the animation parsing.  We're gonna pretend the scene graph has a skeleton
@@ -1377,6 +1406,7 @@
 				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 {{
@@ -1890,6 +1920,33 @@
 
 
 					}
 					}
 					returnObject.curves.get( id )[ curveNode.attr ] = curveNode;
 					returnObject.curves.get( id )[ curveNode.attr ] = curveNode;
+					if ( curveNode.attr === 'R' ) {
+
+						var curves = curveNode.curves;
+						curves.x.values = curves.x.values.map( degreeToRadian );
+						curves.y.values = curves.y.values.map( degreeToRadian );
+						curves.z.values = curves.z.values.map( degreeToRadian );
+
+						if ( curveNode.preRotations !== null ) {
+
+							var preRotations = new THREE.Euler().setFromVector3( curveNode.preRotations, 'ZYX' );
+							preRotations = new THREE.Quaternion().setFromEuler( preRotations );
+							var frameRotation = new THREE.Euler();
+							var frameRotationQuaternion = new THREE.Quaternion();
+							for ( var frame = 0; frame < curves.x.times.length; ++ frame ) {
+
+								frameRotation.set( curves.x.values[ frame ], curves.y.values[ frame ], curves.z.values[ frame ], 'ZYX' );
+								frameRotationQuaternion.setFromEuler( frameRotation ).premultiply( preRotations );
+								frameRotation.setFromQuaternion( frameRotationQuaternion, 'ZYX' );
+								curves.x.values[ frame ] = frameRotation.x;
+								curves.y.values[ frame ] = frameRotation.y;
+								curves.z.values[ frame ] = frameRotation.z;
+
+							}
+
+						}
+
+					}
 
 
 				} );
 				} );
 
 
@@ -2350,7 +2407,12 @@
 							x: null,
 							x: null,
 							y: null,
 							y: null,
 							z: null
 							z: null
-						}
+						},
+
+						/**
+						 * @type {number[]}
+						 */
+						preRotations: null
 					};
 					};
 
 
 					if ( returnObject.attr.match( /S|R|T/ ) ) {
 					if ( returnObject.attr.match( /S|R|T/ ) ) {
@@ -2395,6 +2457,12 @@
 
 
 							returnObject.containerBoneID = boneID;
 							returnObject.containerBoneID = boneID;
 							returnObject.containerID = containerIndices[ containerIndicesIndex ].ID;
 							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;
 							break;
 
 
 						}
 						}
@@ -2905,9 +2973,9 @@
 
 
 							if ( hasCurve( animationNode, 'R' ) && hasKeyOnFrame( animationNode.R, frame ) ) {
 							if ( hasCurve( animationNode, 'R' ) && hasKeyOnFrame( animationNode.R, frame ) ) {
 
 
-								var rotationX = degreeToRadian( animationNode.R.curves.x.values[ frame ] );
-								var rotationY = degreeToRadian( animationNode.R.curves.y.values[ frame ] );
-								var rotationZ = degreeToRadian( animationNode.R.curves.z.values[ frame ] );
+								var rotationX = animationNode.R.curves.x.values[ frame ];
+								var rotationY = animationNode.R.curves.y.values[ frame ];
+								var rotationZ = animationNode.R.curves.z.values[ frame ];
 								var euler = new THREE.Euler( rotationX, rotationY, rotationZ, 'ZYX' );
 								var euler = new THREE.Euler( rotationX, rotationY, rotationZ, 'ZYX' );
 								key.rot = new THREE.Quaternion().setFromEuler( euler ).toArray();
 								key.rot = new THREE.Quaternion().setFromEuler( euler ).toArray();
 
 

+ 3 - 0
examples/webgl_loader_fbx.html

@@ -92,6 +92,9 @@
 				};
 				};
 
 
 				var onError = function( xhr ) {
 				var onError = function( xhr ) {
+
+					console.error( xhr );
+
 				};
 				};
 
 
 				var loader = new THREE.FBXLoader( manager );
 				var loader = new THREE.FBXLoader( manager );