2
0
Эх сурвалжийг харах

AnimationUtils: Fix bug with track merging.

Don McCurdy 6 жил өмнө
parent
commit
b70fc019a6

+ 13 - 1
src/animation/AnimationUtils.js

@@ -317,11 +317,23 @@ var AnimationUtils = {
 
 			}
 
-			var sourceKeyframeIndex = 0;
 			var mergedKeyframeIndex = 0;
+			var sourceKeyframeIndex = 0;
+			var sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) );
 
 			mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
 
+			// For every existing keyframe of the merged track, write a (possibly
+			// interpolated) value from the source track.
+			for ( var j = 0; j < mergedTrack.times.length; j ++ ) {
+
+				mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] );
+
+			}
+
+			// For every existing keyframe of the source track, write a (possibly
+			// new) keyframe to the merged track. Values from the previous loop may
+			// be written again, but keyframes are de-duplicated.
 			for ( var j = 0; j < sourceTrack.times.length; j ++ ) {
 
 				var keyframeIndex = THREE.AnimationUtils.insertKeyframe( mergedTrack, sourceTrack.times[ j ] );

+ 49 - 0
test/unit/src/animation/AnimationUtils.tests.js

@@ -4,6 +4,7 @@
 /* global QUnit */
 
 import { AnimationUtils } from '../../../../src/animation/AnimationUtils';
+import { NumberKeyframeTrack } from '../../../../src/animation/tracks/NumberKeyframeTrack';
 import { VectorKeyframeTrack } from '../../../../src/animation/tracks/VectorKeyframeTrack';
 import {
 	InterpolateLinear,
@@ -69,6 +70,54 @@ export default QUnit.module( 'Animation', () => {
 
 		} );
 
+		QUnit.test( 'mergeMorphTargetTracks', ( assert ) => {
+
+			var trackA = new NumberKeyframeTrack(
+				'foo.morphTargetInfluences[a]',
+				[ 5, 10, 15, 20, 25, 30 ],
+				[ 0, 0.2, 0.4, 0.6, 0.8, 1.0 ],
+				InterpolateLinear
+			);
+
+			var trackB = new NumberKeyframeTrack(
+				'foo.morphTargetInfluences[b]',
+				[ 10, 50 ],
+				[ 0.25, 0.75 ],
+				InterpolateLinear
+			);
+
+			var geometry = new THREE.BufferGeometry();
+			var position = new THREE.BufferAttribute( new Float32Array( [ 0, 0, 0, 0, 0, 1, 1, 0, 1 ] ), 3 );
+			geometry.addAttribute( 'position',  position );
+			geometry.morphAttributes.position = [ position, position ];
+
+			var mesh = new THREE.Mesh( geometry );
+			mesh.name = 'foo';
+			mesh.morphTargetDictionary.a = 0;
+			mesh.morphTargetDictionary.b = 1;
+
+			var root = new THREE.Object3D();
+			root.add( mesh );
+
+			var clip = new THREE.AnimationClip( 'waltz', undefined, [ trackA, trackB ] );
+			clip = AnimationUtils.mergeMorphTargetTracks( clip, root );
+
+			assert.equal( clip.tracks.length, 1, 'tracks are merged' );
+
+			var track = clip.tracks[ 0 ];
+
+			assert.smartEqual( Array.from( track.times ), [ 5, 10, 15, 20, 25, 30, 50 ], 'all keyframes are present' );
+
+			var expectedValues = [ 0, 0.25, 0.2, 0.25, 0.4, 0.3125, 0.6, 0.375, 0.8, 0.4375, 1.0, 0.5, 1.0, 0.75 ];
+
+			for ( var i = 0; i < track.values.length; i ++ ) {
+
+				assert.numEqual( track.values[ i ], expectedValues[ i ], 'all values are merged or interpolated - ' + i );
+
+			}
+
+		} );
+
 		QUnit.todo( "arraySlice", ( assert ) => {
 
 			assert.ok( false, "everything's gonna be alright" );