Просмотр исходного кода

USDLoader: Preserve USDA animation timing metadata (#33560)

Co-authored-by: mrdoob <info@mrdoob.com>
Michael Blix 1 месяц назад
Родитель
Сommit
0e4366f96e

+ 12 - 0
examples/jsm/loaders/usd/USDAParser.js

@@ -460,6 +460,18 @@ class USDAParser {
 
 			}
 
+			if ( header.framesPerSecond !== undefined ) {
+
+				rootFields.framesPerSecond = parseFloat( header.framesPerSecond );
+
+			}
+
+			if ( header.timeCodesPerSecond !== undefined ) {
+
+				rootFields.timeCodesPerSecond = parseFloat( header.timeCodesPerSecond );
+
+			}
+
 		}
 
 		specsByPath[ '/' ] = { specType: SpecType.Prim, fields: rootFields };

+ 1 - 1
examples/jsm/loaders/usd/USDComposer.js

@@ -109,7 +109,7 @@ class USDComposer {
 		// Get FPS from root spec
 		const rootSpec = this.specsByPath[ '/' ];
 		const rootFields = rootSpec ? rootSpec.fields : {};
-		this.fps = rootFields.framesPerSecond || rootFields.timeCodesPerSecond || 30;
+		this.fps = rootFields.timeCodesPerSecond || rootFields.framesPerSecond || 24;
 
 		const group = new Group();
 		this._buildHierarchy( group, '/' );

+ 52 - 0
test/unit/addons/loaders/USDLoader.tests.js

@@ -0,0 +1,52 @@
+import { USDLoader } from '../../../../examples/jsm/loaders/USDLoader.js';
+
+export default QUnit.module( 'Addons', () => {
+
+	QUnit.module( 'Loaders', () => {
+
+		QUnit.module( 'USDLoader', () => {
+
+			QUnit.test( 'uses timeCodesPerSecond for USDA animation timing', ( assert ) => {
+
+				const usda = `#usda 1.0
+(
+	defaultPrim = "Root"
+	framesPerSecond = 24
+	timeCodesPerSecond = 60
+)
+
+def Xform "Root"
+{
+	def Xform "Animated"
+	{
+		float3 xformOp:translate = (0, 0, 0)
+		float3 xformOp:translate.timeSamples = {
+			0: (0, 0, 0),
+			60: (1, 0, 0),
+		}
+		uniform token[] xformOpOrder = ["xformOp:translate"]
+	}
+}`;
+
+				const loader = new USDLoader();
+				const scene = loader.parse( usda );
+				const clip = scene.animations[ 0 ];
+				const track = clip.tracks[ 0 ];
+
+				assert.strictEqual( scene.animations.length, 1, 'One animation clip is created.' );
+				assert.strictEqual( clip.name, 'TransformAnimation', 'Transform animation is created.' );
+				assert.closeTo( clip.duration, 1, 0.000001, 'Animation duration uses timeCodesPerSecond.' );
+				assert.strictEqual( track.name, 'Animated.position', 'Track targets the animated Xform.' );
+				assert.deepEqual(
+					Array.from( track.times ),
+					[ 0, 1 ],
+					'Time samples are converted to seconds.'
+				);
+
+			} );
+
+		} );
+
+	} );
+
+} );

+ 1 - 0
test/unit/three.addons.unit.js

@@ -5,4 +5,5 @@ import './addons/utils/ColorUtils.tests.js';
 import './addons/math/ColorSpaces.tests.js';
 import './addons/curves/NURBSCurve.tests.js';
 import './addons/loaders/HDRLoader.tests.js';
+import './addons/loaders/USDLoader.tests.js';
 import './addons/exporters/USDZExporter.tests.js';

粤ICP备19079148号