Browse Source

TrackBinding -> PropertyBinding. Add example clips.

Ben Houston 10 years ago
parent
commit
bbe37cc014

+ 1 - 1
src/animation/AnimationAction.js

@@ -12,7 +12,7 @@ THREE.AnimationAction = function ( clip, startTime, timeScale, weight, loop ) {
 	this.startTime = startTime || 0;
 	this.timeScale = timeScale || 1;
 	this.weight = weight || 1;
-	this.loop = loop || false;
+	this.loop = loop || clip.loop || false;
 	this.enabled = true;	// allow for easy disabling of the action.
 
 	this.cache = {}; // track name, track, last evaluated time, last evaluated value (with weight included), keyIndex.

+ 64 - 18
src/animation/AnimationClip.js

@@ -8,11 +8,11 @@
  * @author David Sarno / http://lighthaus.us/
  */
 
-THREE.AnimationClip = function ( name, duration, tracks ) {
+THREE.AnimationClip = function ( name, tracks, duration ) {
 
-	this.name = name || "";
-	this.duration = duration || 0;
-	this.tracks = tracks || [];
+	this.name = name;
+	this.tracks = tracks;
+	this.duration = duration;
 
 };
 
@@ -22,13 +22,13 @@ THREE.AnimationClip.prototype = {
 
 	getAt: function( clipTime ) {
 
-		var results = [];
+		clipTime = Math.max( 0, Math.min( clipTime, duration ) );
 
-		for( var i = 0; i < this.tracks.length; i ++ ) {
+		var results = {};
 
-			var track = this.tracks[i];
+		for( var track in this.tracks ) {
 
-			results.push( { name: track.name, value: this.getAt( time ) } );
+			results[ track.name ] = track.getAt( time );
 
 		}
 
@@ -161,21 +161,67 @@ THREE.AnimationClip.CreateMorphAnimation = function( morphTargetNames, duration
 	//  - one track per morphTarget name.
 };
 
-THREE.AnimationClip.CreateRotationAnimation = function( node, period ) {
-	// TODO
-	//  - create a single track representing the rotation
-	//  - create a few quaternion keys representing the rotation path
+THREE.AnimationClip.CreateRotationAnimation = function( node, period, axis ) {
+
+	var keys = [];
+	keys.push( { time: 0, value: 0 } );
+	keys.push( { time: period, value: 360 } );
+
+	axis = axis || 'x';
+	var trackName = node.name + '.rotation[' + axis + ']';
+
+	var track = new THREE.KeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'rotate.x', 10, [ track ] );
+	console.log( 'rotateClip', clip );
+
+	return clip;
 };
 
 THREE.AnimationClip.CreateShakeAnimation = function( node, duration, shakeScale ) {
-	// TODO
-	//  - create a single track representing the shake
-	//  - multiple random vector by shake scalar/vector
+
+	var keys = [];
+
+	for( var i = 0; i < duration * 10; i ++ ) {
+
+		keys.push( { 
+			time: ( i / 10.0 ),
+			value: new THREE.Vector3( Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0 ).multiply( shakeScale )
+		} );
+
+	}
+
+	var trackName = node.name + '.position';
+
+	var track = new THREE.KeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'shake' + duration, trackName, [ track ] );
+	console.log( 'shakeClip', clip );
+
+	return clip;
 };
 
 
 THREE.AnimationClip.CreatePulsationAnimation = function( node, duration, pulseScale ) {
-	// TODO
-	//  - create a single track representing the shake
-	//  - multiple random vector by pulse scalar/vector
+
+	var keys = [];
+
+	for( var i = 0; i < duration * 10; i ++ ) {
+
+		var scaleFactor = Math.random() * pulseScale;
+		keys.push( {
+			time: ( i / 10.0 ),
+			value: new THREE.Vector3( scaleFactor, scaleFactor, scaleFactor )
+		} );
+
+	}
+
+	var trackName = node.name + '.scale';
+
+	var track = new THREE.KeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'scale' + duration, trackName, [ track ] );
+	console.log( 'scaleClip', clip );
+
+	return clip;
 };

+ 20 - 12
src/animation/AnimationMixer.js

@@ -12,7 +12,7 @@ THREE.AnimationMixer = function( root ) {
 
 	this.root = root;
 	this.actions = [];
-	this.trackBindings = {};
+	this.propertyBindings = {};
 
 };
 
@@ -26,8 +26,11 @@ THREE.AnimationMixer.prototype = {
 		this.actions.push( action );
 
 		for( var track in action.tracks ) {
-			if( ! this.trackBindings[track.name] ) {
-				this.trackBindings[track.name] = new THREE.TrackBinding( this.root, track.name );
+
+			if( ! this.propertyBindings[ track.name ] ) {
+			
+				this.propertyBindings[ track.name ] = new THREE.PropertyBinding( this.root, track.name );
+			
 			}
 		}
 
@@ -58,33 +61,38 @@ THREE.AnimationMixer.prototype = {
 
 			var actionResults = action.getAt( time );
 
-			for( var j = 0; j < actionResults.length; j ++ ) {
+			for( var actionResult in actionResults ) {
 
-				var actionResult = actionResults[j];
+				var mixerResult = mixerResults[actionResult.name];
 
-				// TODO: do iterative linear interpolator based on cumulative weight ratios
-				if( ! mixerResults[ actionResult.name ] ) {
+				if( ! mixerResult ) {
 
 					mixerResults[actionResult.name] = {
-						name: actionResult.name
+						name: actionResult.name,
+						cumulativeValue: actionResult.value,
+						cumulativeWeight: action.weight
 					};
+
 				}
+				else {
 
-				mixerResults[actionResult.name].value = result.value;
+					var lerpAlpha = action.weight / ( mixerResult.cumulativeWeight + action.weight );
+					mixerResult.cumulativeValue = AnimationUtils.lerp( mixerResult.cumulativeValue, result.value, lerpAlpha );
+					mixerResult.cumulativeWeight += action.weight;
 
+				}
 			}
 
 		}
 	    console.log( "  mixerResults: ", mixerResults );
 	
-
 		// apply to nodes
 		for ( var name in mixerResults ) {
 
 			var mixerResult = mixerResults[ name ];
 
-			var trackBinding = this.trackBindings[ name ];
-			trackBinding.set( mixerResult.value );
+			var propertyBinding = this.propertyBindings[ name ];
+			propertyBinding.set( mixerResult.value );
 			
 		}
 	}

+ 9 - 9
src/animation/TrackBinding.js → src/animation/PropertyBinding.js

@@ -6,29 +6,29 @@
  * @author David Sarno / http://lighthaus.us/
  */
 
-THREE.TrackBinding = function ( rootNode, trackName ) {
+THREE.PropertyBinding = function ( rootNode, trackName ) {
 
 	this.rootNode = rootNode;
 	this.trackName = trackName;
 
-	var parseResults = THREE.TrackBinding.parseTrackName( trackName );
+	var parseResults = THREE.PropertyBinding.parseTrackName( trackName );
 
 	this.directoryName = parseResults.directoryName || null;
 	this.nodeName = parseResults.nodeName;
 	this.propertyName = parseResults.propertyName || null;
 	this.propertyArrayIndex = parseResults.propertyArrayIndex || -1;
 
-	this.node = THREE.TrackBinding.findNode( rootNode, this.nodeName );
+	this.node = THREE.PropertyBinding.findNode( rootNode, this.nodeName );
 
 };
 
-THREE.TrackBinding.prototype = {
+THREE.PropertyBinding.prototype = {
 
-	constructor: THREE.TrackBinding,
+	constructor: THREE.PropertyBinding,
 
 	set: function( value ) {
 
-		 console.log( "TrackBinding.set( " + value + ")" );
+		 console.log( "PropertyBinding.set( " + value + ")" );
 
  		// ensure there is a value node
 		if( ! this.node ) {
@@ -80,7 +80,7 @@ THREE.TrackBinding.prototype = {
 };
 
 
-THREE.TrackBinding.parseTrackName = function( trackName ) {
+THREE.PropertyBinding.parseTrackName = function( trackName ) {
 
 	// matches strings in the form of:
 	//    directory/directory/directory/filename.property[index]
@@ -104,14 +104,14 @@ THREE.TrackBinding.parseTrackName = function( trackName ) {
 		propertySubElement: m[6]
 	};
 
-	console.log( "TrackBinding.parseTrackName", trackName, parseResults );
+	console.log( "PropertyBinding.parseTrackName", trackName, parseResults );
 
 	return parseResults;
 
 };
 
 // TODO: Cache this at some point
-THREE.TrackBinding.findNode = function( root, nodeName ) {
+THREE.PropertyBinding.findNode = function( root, nodeName ) {
 
 	console.log( 'AnimationUtils.findNode( ' + root.name + ', nodeName: ' + nodeName + ')');