Sfoglia il codice sorgente

faster KeyframeTrack.getAt - local walk from last value.

Ben Houston 10 anni fa
parent
commit
cc3684acad
2 ha cambiato i file con 33 aggiunte e 67 eliminazioni
  1. 32 66
      src/animation/KeyframeTrack.js
  2. 1 1
      src/animation/PropertyBinding.js

+ 32 - 66
src/animation/KeyframeTrack.js

@@ -10,6 +10,8 @@
 
 
 THREE.KeyframeTrack = function ( name, keys ) {
 THREE.KeyframeTrack = function ( name, keys ) {
 
 
+	if( keys === undefined || keys.length === 0 ) throw new Error( "no keys in track named " + name );
+
 	this.name = name;
 	this.name = name;
 	this.keys = keys;	// time in seconds, value as value
 	this.keys = keys;	// time in seconds, value as value
 
 
@@ -17,7 +19,7 @@ THREE.KeyframeTrack = function ( name, keys ) {
 	this.result = THREE.AnimationUtils.clone( this.keys[0].value );
 	this.result = THREE.AnimationUtils.clone( this.keys[0].value );
 	//console.log( 'constructor result', this.result )
 	//console.log( 'constructor result', this.result )
 
 
-	this.lastIndex = -1;
+	this.lastIndex = 0;
 
 
 	this.sort();
 	this.sort();
 	this.validate();
 	this.validate();
@@ -32,83 +34,47 @@ THREE.KeyframeTrack.prototype = {
 	//    should be optimized.
 	//    should be optimized.
 	getAt: function( time ) {
 	getAt: function( time ) {
 		//console.log( 'KeyframeTrack[' + this.name + '].getAt( ' + time + ' )' );
 		//console.log( 'KeyframeTrack[' + this.name + '].getAt( ' + time + ' )' );
+		
+		// this can not go higher than this.keys.length.
+		while( ( this.lastIndex < this.keys.length ) && ( time >= this.keys[this.lastIndex].time ) ) {
+			this.lastIndex ++;
+		};
 
 
-		if( this.keys.length == 0 ) throw new Error( "no keys in track named " + this.name );
-
-		// fast early exit	
-		if( this.lastIndex >= 0 ) {
-			if( ( time <= this.keys[this.lastIndex].time ) && ( this.keys[this.lastIndex-1].time < time ) ) {
-
-				var i = this.lastIndex;
-
-				var alpha = ( time - this.keys[ i - 1 ].time ) / ( this.keys[ i ].time - this.keys[ i - 1 ].time );
-
-				this.setResult( this.keys[ i - 1 ].value );
-
-				this.result = this.lerp( this.result, this.keys[ i ].value, alpha );
-
-				return this.result;
-
-			}
-
-			this.lastIndex = -1;
-		}
-
-		//console.log( "keys", this.keys );
-		// before the start of the track, return the first key value
-		if( this.keys[0].time >= time ) {
-
-			//console.log( '   before: ' + this.keys[0].value );
-			this.setResult( this.keys[0].value );
-
-			//console.log( 'first result', this.result )
+		if( this.lastIndex >= this.keys.length ) {
 
 
+			this.setResult( this.keys[ this.lastIndex - 1 ].value );
 			return this.result;
 			return this.result;
 
 
 		}
 		}
 
 
-		// past the end of the track, return the last key value
-		if( this.keys[ this.keys.length - 1 ].time <= time ) {
-
-			//console.log( '   after: ' + this.keys[ this.keys.length - 1 ].value );
-			this.setResult( this.keys[ this.keys.length - 1 ].value );
-
-			//console.log( 'last result', this.result )
-
-			return this.result;
-
+		// this can not go lower than 0.
+		while( ( this.lastIndex > 0 ) && ( time < this.keys[this.lastIndex - 1].time ) ) {
+			this.lastIndex --;			
 		}
 		}
 
 
-		// interpolate to the required time
-		// TODO: Optimize this better than a linear search for each key.
-		for( var i = 1; i < this.keys.length; i ++ ) {
-
-			if( time <= this.keys[ i ].time ) {
-
-				// linear interpolation to start with
-				var alpha = ( time - this.keys[ i - 1 ].time ) / ( this.keys[ i ].time - this.keys[ i - 1 ].time );
-
-				this.setResult( this.keys[ i - 1 ].value );
-
-				this.result = this.lerp( this.result, this.keys[ i ].value, alpha );
-				//console.log( 'lerp result', this.result )
-				/*console.log( '   interpolated: ', {
-					value: interpolatedValue, 
-					alpha: alpha,
-					time0: this.keys[ i - 1 ].time,
-					time1: this.keys[ i ].time,
-					value0: this.keys[ i - 1 ].value,
-					value1: this.keys[ i ].value
-				} );*/
+		if( this.lastIndex === 0 ) {
 
 
-				this.lastIndex = i;
-
-				return this.result;
+			this.setResult( this.keys[ 0 ].value );
+			return this.result;
 
 
-			}
 		}
 		}
 
 
-		throw new Error( "should never get here." );
+		// linear interpolation to start with
+		var alpha = ( time - this.keys[ this.lastIndex - 1 ].time ) / ( this.keys[ this.lastIndex ].time - this.keys[ this.lastIndex - 1 ].time );
+
+		this.setResult( this.keys[ this.lastIndex - 1 ].value );
+		this.result = this.lerp( this.result, this.keys[ this.lastIndex ].value, alpha );
+		//console.log( 'lerp result', this.result )
+		/*console.log( '   interpolated: ', {
+			value: interpolatedValue, 
+			alpha: alpha,
+			time0: this.keys[ i - 1 ].time,
+			time1: this.keys[ i ].time,
+			value0: this.keys[ i - 1 ].value,
+			value1: this.keys[ i ].value
+		} );*/
+
+		return this.result;
 
 
 	},
 	},
 	setResult: function( value ) {
 	setResult: function( value ) {

+ 1 - 1
src/animation/PropertyBinding.js

@@ -269,7 +269,7 @@ THREE.PropertyBinding.prototype = {
 
 
 				var remainingWeight = 1 - this.cumulativeWeight;
 				var remainingWeight = 1 - this.cumulativeWeight;
 				var lerpAlpha = remainingWeight / ( this.cumulativeWeight + remainingWeight );
 				var lerpAlpha = remainingWeight / ( this.cumulativeWeight + remainingWeight );
-				this.cumulativeValue = this.lerpValueler( this.cumulativeValue, this.originalValue, lerpAlpha );
+				this.cumulativeValue = this.lerpValue( this.cumulativeValue, this.originalValue, lerpAlpha );
 
 
 			}
 			}