Procházet zdrojové kódy

set up postrotation and euler order

Lewy Blue před 7 roky
rodič
revize
62d2db8f5c
1 změnil soubory, kde provedl 79 přidání a 36 odebrání
  1. 79 36
      examples/js/loaders/FBXLoader.js

+ 79 - 36
examples/js/loaders/FBXLoader.js

@@ -9,9 +9,6 @@
  *
  * Needs Support:
  *  Morph normals / blend shape normals
- *  Animation tracks for morph targets
- *
- *	Euler rotation order
  *
  * FBX format references:
  * 	https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure
@@ -100,7 +97,7 @@
 
 			}
 
-			// console.log( FBXTree );
+			console.log( FBXTree );
 
 			var textureLoader = new THREE.TextureLoader( this.manager ).setPath( resourceDirectory ).setCrossOrigin( this.crossOrigin );
 
@@ -828,9 +825,16 @@
 
 		if ( 'GeometricRotation' in modelNode ) {
 
-			var array = modelNode.GeometricRotation.value.map( THREE.Math.degToRad );
-			array[ 3 ] = 'ZYX';
+			var eulerOrder = 'ZYX';
+
+			if ( 'RotationOrder' in modelNode ) {
+
+				eulerOrder = getEulerOrder( parseInt( modelNode.RotationOrder.value ) );
+
+			}
 
+			var array = modelNode.GeometricRotation.value.map( THREE.Math.degToRad );
+			array.push( eulerOrder );
 			preTransform.makeRotationFromEuler( new THREE.Euler().fromArray( array ) );
 
 		}
@@ -2146,71 +2150,109 @@
 
 	}
 
+	var tempMat = new THREE.Matrix4();
+	var tempEuler = new THREE.Euler();
+	var tempVec = new THREE.Vector3();
 	// parse the model node for transform details and apply them to the model
 	function setModelTransforms( FBXTree, model, modelNode ) {
 
+		var transform = new THREE.Matrix4();
+
+		var translation = new THREE.Vector3();
+
+		var rotation = new THREE.Matrix4();
+
 		// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
 		if ( 'RotationOrder' in modelNode ) {
 
-			var enums = [
-				'XYZ', // default
-				'XZY',
-				'YZX',
-				'ZXY',
-				'YXZ',
-				'ZYX',
-				'SphericXYZ',
-			];
+			model.rotation.order = getEulerOrder( parseInt( modelNode.RotationOrder.value ) );
 
-			var value = parseInt( modelNode.RotationOrder.value, 10 );
+		} else {
 
-			if ( value > 0 && value < 6 ) {
+			model.rotation.order = getEulerOrder( 0 );
 
-				// model.rotation.order = enums[ value ];
+		}
 
-				// Note: Euler order other than XYZ is currently not supported, so just display a warning for now
-				console.warn( 'THREE.FBXLoader: unsupported Euler Order: %s. Currently only XYZ order is supported. Animations and rotations may be incorrect.', enums[ value ] );
+		if ( 'Lcl_Translation' in modelNode ) {
 
-			} else if ( value === 6 ) {
+			translation.fromArray( modelNode.Lcl_Translation.value );
 
-				console.warn( 'THREE.FBXLoader: unsupported Euler Order: Spherical XYZ. Animations and rotations may be incorrect.' );
+		}
 
-			}
+		if ( 'RotationOffset' in modelNode ) {
+
+			translation.add( tempVec.fromArray( modelNode.RotationOffset.value ) );
 
 		}
 
-		if ( 'Lcl_Translation' in modelNode ) {
+		if ( 'Lcl_Rotation' in modelNode ) {
+
+			var array = modelNode.Lcl_Rotation.value.map( THREE.Math.degToRad );
 
-			model.position.fromArray( modelNode.Lcl_Translation.value );
+			array.push( model.rotation.order );
+
+			rotation.makeRotationFromEuler( tempEuler.fromArray( array ) );
 
 		}
 
-		if ( 'Lcl_Rotation' in modelNode ) {
+		if ( 'PreRotation' in modelNode ) {
+
+			var array = modelNode.PreRotation.value.map( THREE.Math.degToRad );
+
+			array.push( model.rotation.order );
+			tempMat.makeRotationFromEuler( tempEuler.fromArray( array ) );
+
+			rotation.premultiply( tempMat );
+
+		}
+
+		if ( 'PostRotation' in modelNode ) {
+
+			var array = modelNode.PostRotation.value.map( THREE.Math.degToRad );
+
+			array.push( model.rotation.order );
+			array.push( model.rotation.order );
 
-			var rotation = modelNode.Lcl_Rotation.value.map( THREE.Math.degToRad );
-			rotation.push( 'ZYX' );
-			model.quaternion.setFromEuler( new THREE.Euler().fromArray( rotation ) );
+			tempMat.makeRotationFromEuler( tempEuler.fromArray( array ) );
+
+			rotation.multiply( tempMat );
 
 		}
 
 		if ( 'Lcl_Scaling' in modelNode ) {
 
-			model.scale.fromArray( modelNode.Lcl_Scaling.value );
+			transform.scale( tempVec.fromArray( modelNode.Lcl_Scaling.value ) );
 
 		}
 
-		if ( 'PreRotation' in modelNode ) {
+		transform.setPosition( translation );
+		transform.multiply( rotation );
 
-			var array = modelNode.PreRotation.value.map( THREE.Math.degToRad );
-			array[ 3 ] = 'ZYX';
+		model.applyMatrix( transform );
 
-			var preRotations = new THREE.Euler().fromArray( array );
+	}
 
-			preRotations = new THREE.Quaternion().setFromEuler( preRotations );
-			model.quaternion.premultiply( preRotations );
+	function getEulerOrder( order ) {
+
+		var enums = [
+			'ZYX', // -> XYZ in FBX
+			'YXZ',
+			'ZXY',
+			'YZX',
+			'XZY',
+			'XYZ',
+			//'SphericXYZ', // not possible to support
+		];
+
+		if ( order === 6 ) {
+
+			console.warn( 'THREE.FBXLoader: unsupported Euler Order: Spherical XYZ. Animations and rotations may be incorrect.' );
+			return enums[ 0 ];
 
 		}
 
+		return enums[ order ];
+
 	}
 
 	function bindSkeleton( FBXTree, skeletons, geometryMap, modelMap, connections ) {
@@ -2604,6 +2646,7 @@
 		}
 
 		if ( rawTracks.DeformPercent !== undefined ) {
+
 			var morphTrack = generateMorphTrack( rawTracks, sceneGraph );
 			if ( morphTrack !== undefined ) tracks.push( morphTrack );