Browse Source

Fix for additive animation on clips with non-numeric tracks

Point _mixBufferRegionAdditive to _mixBufferRegion and bufferAdditive to buffer so that additive actions containing both numeric and non-numeric tracks will be supported.
Christine Morten 5 years ago
parent
commit
f504177f2b
3 changed files with 38 additions and 48 deletions
  1. 4 13
      src/animation/AnimationAction.js
  2. 1 1
      src/animation/PropertyMixer.d.ts
  3. 33 34
      src/animation/PropertyMixer.js

+ 4 - 13
src/animation/AnimationAction.js

@@ -368,21 +368,12 @@ Object.assign( AnimationAction.prototype, {
 		// note: _updateTime may disable the action resulting in
 		// an effective weight of 0
 
-		var accuParamA, accuParamB, accuFn,
+		var accuFn,
 			weight = this._updateWeight( time );
 
-		if ( this.isAdditive ) {
+		if ( this.isAdditive ) accuFn = 'accumulateAdditive';
 
-			accuFn = 'accumulateAdditive';
-			accuParamA = weight;
-
-		} else {
-
-			accuFn = 'accumulate';
-			accuParamA = accuIndex;
-			accuParamB = weight;
-
-		}
+		else accuFn = 'accumulate';
 
 		if ( weight > 0 ) {
 
@@ -392,7 +383,7 @@ Object.assign( AnimationAction.prototype, {
 			for ( var j = 0, m = interpolants.length; j !== m; ++ j ) {
 
 				interpolants[ j ].evaluate( clipTime );
-				propertyMixers[ j ][ accuFn ]( accuParamA, accuParamB );
+				propertyMixers[ j ][ accuFn ]( accuIndex, weight );
 
 			}
 

+ 1 - 1
src/animation/PropertyMixer.d.ts

@@ -12,7 +12,7 @@ export class PropertyMixer {
 	referenceCount: number;
 
 	accumulate( accuIndex: number, weight: number ): void;
-	accumulateAdditive( weight: number ): void;
+	accumulateAdditive( accuIndex: number, weight: number ): void;
 	apply( accuIndex: number ): void;
 	saveOriginalState(): void;
 	restoreOriginalState(): void;

+ 33 - 34
src/animation/PropertyMixer.js

@@ -15,17 +15,41 @@ function PropertyMixer( binding, typeName, valueSize ) {
 	this.binding = binding;
 	this.valueSize = valueSize;
 
-	var bufferType = Float64Array,
-		mixFunction,
+	var mixFunction,
 		mixFunctionAdditive;
 
+	// buffer layout: [ incoming | accu0 | accu1 | orig ]
+	//
+	// interpolators can use .buffer as their .result
+	// the data then goes to 'incoming'
+	//
+	// 'accu0' and 'accu1' are used frame-interleaved for
+	// the cumulative result and are compared to detect
+	// changes
+	//
+	// 'orig' stores the original state of the property
+
+
+	// additiveBuffer layout: [ incoming | accu | identity | ( optional work ) ]
+	//
+	// interpolators can use .additiveBuffer as their .result
+	// the data then goes to 'incoming'
+	//
+	// 'accu' is used frame-interleaved for the cumulative result
+	//
+	// 'identity' stores the zeroed out state of the property
+	//
+	// optional work is only valid for quaternions. It is used to store
+	// intermediate quaternion muliplication results.
+
 	switch ( typeName ) {
 
 		case 'quaternion':
 			mixFunction = this._slerp;
 			mixFunctionAdditive = this._slerpAdditive;
 
-			this.bufferAdditive = new bufferType( 16 );
+			this.buffer = new Float64Array( 16 );
+			this.bufferAdditive = new Float64Array( 16 );
 			this.bufferAdditive.fill( 0 );
 			this.bufferAdditive[ 3 ] = 1;
 			this.bufferAdditive[ 7 ] = 1;
@@ -35,50 +59,25 @@ function PropertyMixer( binding, typeName, valueSize ) {
 
 		case 'string':
 		case 'bool':
-			bufferType = Array;
 			mixFunction = this._select;
+			this.buffer = new Array( valueSize * 4 );
 
-			// Use the regular mix function for additive on these types,
+			// Use the regular mix function and buffer for additive on these types,
 			// additive is not relevant for non-numeric types
 			mixFunctionAdditive = this._select;
-			this.bufferAdditive = [];
+			this.bufferAdditive = this.buffer;
 			break;
 
 		default:
 			mixFunction = this._lerp;
 			mixFunctionAdditive = this._lerpAdditive;
 
-			this.bufferAdditive = new bufferType( valueSize * 3 );
+			this.buffer = new Float64Array( valueSize * 4 );
+			this.bufferAdditive = new Float64Array( valueSize * 3 );
 			this.bufferAdditive.fill( 0 );
 
 	}
 
-	this.buffer = new bufferType( valueSize * 4 );
-	// buffer layout: [ incoming | accu0 | accu1 | orig ]
-	//
-	// interpolators can use .buffer as their .result
-	// the data then goes to 'incoming'
-	//
-	// 'accu0' and 'accu1' are used frame-interleaved for
-	// the cumulative result and are compared to detect
-	// changes
-	//
-	// 'orig' stores the original state of the property
-
-
-	// additiveBuffer layout: [ incoming | accu | identity | ( optional work ) ]
-	//
-	// interpolators can use .additiveBuffer as their .result
-	// the data then goes to 'incoming'
-	//
-	// 'accu' is used frame-interleaved for the cumulative result
-	//
-	// 'identity' stores the zeroed out state of the property
-	//
-	// optional work is only valid for quaternions. It is used to store
-	// intermediate quaternion muliplication results.
-
-
 	this._mixBufferRegion = mixFunction;
 	this._mixBufferRegionAdditive = mixFunctionAdditive;
 
@@ -130,7 +129,7 @@ Object.assign( PropertyMixer.prototype, {
 
 	},
 
-	accumulateAdditive: function ( weight ) {
+	accumulateAdditive: function ( accuIndex, weight ) {
 
 		// note: happily accumulating nothing when weight = 0, the caller knows
 		// the weight and shouldn't have made the call in the first place