Browse Source

only update scene graph values if actually different, only call triggerDirty if values changed. Use bone names.

Ben Houston 10 years ago
parent
commit
876eda7e0b

+ 3 - 1
examples/webgl_animation_track_clip_mixer.html

@@ -276,7 +276,9 @@
 
 
 				var clip8 = THREE.AnimationClip.FromJSONLoaderAnimation( geometry );
 				var clip8 = THREE.AnimationClip.FromJSONLoaderAnimation( geometry );
 				mixer.addAction( new THREE.AnimationAction( clip8, 0, 1, 1, true ) );
 				mixer.addAction( new THREE.AnimationAction( clip8, 0, 1, 1, true ) );
-				
+
+				console.log( clip8.getAt( 0 ) );
+
 			}
 			}
 
 
 			function initGUI() {
 			function initGUI() {

+ 33 - 28
src/animation/AnimationClip.js

@@ -16,6 +16,8 @@ THREE.AnimationClip = function ( name, duration, tracks ) {
 	// but leaving these here during development as this ensures a lot of testing of these functions
 	// but leaving these here during development as this ensures a lot of testing of these functions
 	//this.trim();
 	//this.trim();
 	//this.optimize();
 	//this.optimize();
+
+	this.results = {};
 	
 	
 };
 };
 
 
@@ -27,25 +29,23 @@ THREE.AnimationClip.prototype = {
 
 
 		clipTime = Math.max( 0, Math.min( clipTime, this.duration ) );
 		clipTime = Math.max( 0, Math.min( clipTime, this.duration ) );
 
 
-		var results = {};
-
-		for( var trackIndex in this.tracks ) {
+		for( var i = 0; i < this.tracks.length; i ++ ) {
 
 
-			var track = this.tracks[ trackIndex ];
+			var track = this.tracks[ i ];
 			//console.log( 'track', track );
 			//console.log( 'track', track );
 
 
-			results[ track.name ] = track.getAt( clipTime );
+			this.results[ track.name ] = track.getAt( clipTime );
 
 
 		}
 		}
 
 
-		return results;
+		return this.results;
 	},
 	},
 
 
 	trim: function() {
 	trim: function() {
 
 
-		for( var trackIndex in this.tracks ) {
+		for( var i = 0; i < this.tracks.length; i ++ ) {
 
 
-			this.tracks[ trackIndex ].trim( this.duration );
+			this.tracks[ i ].trim( this.duration );
 
 
 		}
 		}
 
 
@@ -53,9 +53,9 @@ THREE.AnimationClip.prototype = {
 
 
 	optimize: function() {
 	optimize: function() {
 
 
-		for( var trackIndex in this.tracks ) {	
+		for( var i = 0; i < this.tracks.length; i ++ ) {
 
 
-			this.tracks[ trackIndex ].optimize();
+			this.tracks[ i ].optimize();
 
 
 		}
 		}
 
 
@@ -83,7 +83,7 @@ THREE.AnimationClip.prototype = {
 
 
 THREE.AnimationClip.FromJSONLoaderAnimation = function( jsonLoader ) {
 THREE.AnimationClip.FromJSONLoaderAnimation = function( jsonLoader ) {
 
 
-	var animation = jsonLoader['animation'];
+	var animation = jsonLoader.animation;
 	if( ! animation ) {
 	if( ! animation ) {
 		console.error( "  no animation in JSONLoader data" );
 		console.error( "  no animation in JSONLoader data" );
 		return null;
 		return null;
@@ -121,11 +121,11 @@ THREE.AnimationClip.FromJSONLoaderAnimation = function( jsonLoader ) {
 
 
 	var tracks = [];
 	var tracks = [];
 
 
+	var boneList = jsonLoader.bones;
 	var animationTracks = animation.hierarchy;
 	var animationTracks = animation.hierarchy;
 
 
 	for ( var h = 0; h < animationTracks.length; h ++ ) {
 	for ( var h = 0; h < animationTracks.length; h ++ ) {
 
 
-		var boneName = '.bone[' + h + ']';
 		var animationKeys = animationTracks[ h ].keys;
 		var animationKeys = animationTracks[ h ].keys;
 
 
 		// skip empty tracks
 		// skip empty tracks
@@ -170,28 +170,33 @@ THREE.AnimationClip.FromJSONLoaderAnimation = function( jsonLoader ) {
 			}
 			}
 
 
 		}
 		}
+		else {
+
+			var boneName = '.bone[' + boneList[ h ].name + ']';
+			console.log( 'boneName', boneName );
 		
 		
-		// track contains positions...
-		var positionTrack = convertTrack( boneName + '.position', animationKeys, 'pos', function( animationKey ) {
-				return new THREE.Vector3().fromArray( animationKey.pos )
-			} );
+			// track contains positions...
+			var positionTrack = convertTrack( boneName + '.position', animationKeys, 'pos', function( animationKey ) {
+					return new THREE.Vector3().fromArray( animationKey.pos )
+				} );
 
 
-		if( positionTrack ) tracks.push( positionTrack );
+			if( positionTrack ) tracks.push( positionTrack );
+			
+			// track contains quaternions...
+			var quaternionTrack = convertTrack( boneName + '.quaternion', animationKeys, 'rot', function( animationKey ) {
+					return new THREE.Quaternion().fromArray( animationKey.rot )
+				} );
 
 
-		
-		// track contains quaternions...
-		var quaternionTrack = convertTrack( boneName + '.quaternion', animationKeys, 'rot', function( animationKey ) {
-				return new THREE.Quaternion().fromArray( animationKey.rot )
-			} );
+			if( quaternionTrack ) tracks.push( quaternionTrack );
 
 
-		if( quaternionTrack ) tracks.push( quaternionTrack );
+			// track contains quaternions...
+			var scaleTrack = convertTrack( boneName + '.scale', animationKeys, 'scl', function( animationKey ) {
+					return new THREE.Vector3().fromArray( animationKey.scl )
+				} );
 
 
-		// track contains quaternions...
-		var scaleTrack = convertTrack( boneName + '.quaternion', animationKeys, 'scl', function( animationKey ) {
-				return new THREE.Vector3().fromArray( animationKey.scl )
-			} );
+			if( scaleTrack ) tracks.push( scaleTrack );
 
 
-		if( scaleTrack ) tracks.push( scaleTrack );
+		}
 	}
 	}
 
 
 	var clip = new THREE.AnimationClip( clipName, duration, tracks );
 	var clip = new THREE.AnimationClip( clipName, duration, tracks );

+ 14 - 7
src/animation/AnimationMixer.js

@@ -15,6 +15,7 @@ THREE.AnimationMixer = function( root ) {
 	this.timeScale = 1.0;
 	this.timeScale = 1.0;
 	this.actions = [];
 	this.actions = [];
 	this.propertyBindings = {};
 	this.propertyBindings = {};
+	this.propertyBindingsArray = [];
 
 
 };
 };
 
 
@@ -27,12 +28,18 @@ THREE.AnimationMixer.prototype = {
 
 
 		this.actions.push( action );
 		this.actions.push( action );
 
 
-		for( var trackID in action.clip.tracks ) {
+		var tracks = action.clip.tracks;
+
+		for( var i = 0; i < tracks.length; i ++ ) {
+
+			var track = tracks[ i ];
 
 
-			var track = action.clip.tracks[ trackID ];
 			if( ! this.propertyBindings[ track.name ] ) {
 			if( ! this.propertyBindings[ track.name ] ) {
 			
 			
-				this.propertyBindings[ track.name ] = new THREE.PropertyBinding( this.root, track.name );
+				var propertyBinding = new THREE.PropertyBinding( this.root, track.name );
+				this.propertyBindings[ track.name ] = propertyBinding;
+
+				this.propertyBindingsArray.push( propertyBinding );
 			
 			
 			}
 			}
 		}
 		}
@@ -57,9 +64,9 @@ THREE.AnimationMixer.prototype = {
 
 
 		//console.log( this.root.name + ".AnimationMixer.update( " + time + " )" );
 		//console.log( this.root.name + ".AnimationMixer.update( " + time + " )" );
 
 
-		for ( var name in this.propertyBindings ) {
+		for ( var i = 0; i < this.propertyBindingsArray.length; i ++ ) {
 
 
-			this.propertyBindings[ name ].reset();
+			this.propertyBindingsArray[ i ].reset();
 
 
 		}
 		}
 
 
@@ -80,9 +87,9 @@ THREE.AnimationMixer.prototype = {
 		}
 		}
 	
 	
 		// apply to nodes
 		// apply to nodes
-		for ( var name in this.propertyBindings ) {
+		for ( var i = 0; i < this.propertyBindingsArray.length; i ++ ) {
 
 
-			this.propertyBindings[ name ].apply();
+			this.propertyBindingsArray[ i ].apply();
 			
 			
 		}
 		}
 	}
 	}

+ 1 - 1
src/animation/AnimationUtils.js

@@ -5,7 +5,7 @@
 
 
  THREE.AnimationUtils = {
  THREE.AnimationUtils = {
 
 
- 	equalsFunc: function( exemplarValue ) {
+ 	getEqualsFunc: function( exemplarValue ) {
 
 
 		if( exemplarValue.equals ) {
 		if( exemplarValue.equals ) {
 			return function( a, b ) {
 			return function( a, b ) {

+ 1 - 1
src/animation/KeyframeTrack.js

@@ -145,7 +145,7 @@ THREE.KeyframeTrack.prototype = {
 		var prevKey = this.keys[0];
 		var prevKey = this.keys[0];
 		newKeys.push( prevKey );
 		newKeys.push( prevKey );
 
 
-		var equalsFunc = THREE.AnimationUtils.equalsFunc( prevKey.value );
+		var equalsFunc = THREE.AnimationUtils.getEqualsFunc( prevKey.value );
 
 
 		for( var i = 1; i < this.keys.length - 1; i ++ ) {
 		for( var i = 1; i < this.keys.length - 1; i ++ ) {
 			var currKey = this.keys[i];
 			var currKey = this.keys[i];

+ 21 - 6
src/animation/PropertyBinding.js

@@ -70,6 +70,8 @@ THREE.PropertyBinding.prototype = {
 
 
 			 //console.log( "PropertyBinding.set( " + value + ")" );
 			 //console.log( "PropertyBinding.set( " + value + ")" );
 
 
+			 var equalsFunc = THREE.AnimationUtils.getEqualsFunc( this.cumulativeValue );
+
 			 var targetObject = this.node;
 			 var targetObject = this.node;
 
 
 	 		// ensure there is a value node
 	 		// ensure there is a value node
@@ -162,14 +164,22 @@ THREE.PropertyBinding.prototype = {
 
 
 				//console.log( '  update property array ' + this.propertyName + '[' + this.propertyIndex + '] via assignment.' );				
 				//console.log( '  update property array ' + this.propertyName + '[' + this.propertyIndex + '] via assignment.' );				
 				this.internalApply = function() {
 				this.internalApply = function() {
-					nodeProperty[ this.propertyIndex ] = this.cumulativeValue;
+					if( ! equalsFunc( nodeProperty[ this.propertyIndex ], this.cumulativeValue ) ) {
+						nodeProperty[ this.propertyIndex ] = this.cumulativeValue;
+						return true;
+					}
+					return false;
 				};
 				};
 			}
 			}
 			// must use copy for Object3D.Euler/Quaternion		
 			// must use copy for Object3D.Euler/Quaternion		
 			else if( nodeProperty.copy ) {
 			else if( nodeProperty.copy ) {
 				//console.log( '  update property ' + this.name + '.' + this.propertyName + ' via a set() function.' );				
 				//console.log( '  update property ' + this.name + '.' + this.propertyName + ' via a set() function.' );				
 				this.internalApply = function() {
 				this.internalApply = function() {
-					nodeProperty.copy( this.cumulativeValue );
+					if( ! equalsFunc( nodeProperty, this.cumulativeValue ) ) {
+						nodeProperty.copy( this.cumulativeValue );
+						return true;
+					}
+					return false;
 				}
 				}
 			}
 			}
 			// otherwise just set the property directly on the node (do not use nodeProperty as it may not be a reference object)
 			// otherwise just set the property directly on the node (do not use nodeProperty as it may not be a reference object)
@@ -177,7 +187,11 @@ THREE.PropertyBinding.prototype = {
 
 
 				//console.log( '  update property ' + this.name + '.' + this.propertyName + ' via assignment.' );				
 				//console.log( '  update property ' + this.name + '.' + this.propertyName + ' via assignment.' );				
 				this.internalApply = function() {
 				this.internalApply = function() {
-					targetObject[ this.propertyName ] = this.cumulativeValue;	
+					if( ! equalsFunc( targetObject[ this.propertyName ], this.cumulativeValue ) ) {
+						targetObject[ this.propertyName ] = this.cumulativeValue;	
+						return true;
+					}
+					return false;
 				}
 				}
 			}
 			}
 
 
@@ -202,9 +216,9 @@ THREE.PropertyBinding.prototype = {
 			return;
 			return;
 		}
 		}
 
 
-		this.internalApply();
+		var valueChanged = this.internalApply();
 
 
-		if( this.triggerDirty ) {
+		if( valueChanged && this.triggerDirty ) {
 			this.triggerDirty();
 			this.triggerDirty();
 		}
 		}
 	},
 	},
@@ -228,9 +242,10 @@ THREE.PropertyBinding.parseTrackName = function( trackName ) {
 	//    uuid.objectName[objectIndex].propertyName[propertyIndex]
 	//    uuid.objectName[objectIndex].propertyName[propertyIndex]
 	//    parentName/nodeName.property
 	//    parentName/nodeName.property
 	//    parentName/parentName/nodeName.property[index]
 	//    parentName/parentName/nodeName.property[index]
+	//	  .bone[Armature.DEF_cog].position
 	// created and tested via https://regex101.com/#javascript
 	// created and tested via https://regex101.com/#javascript
 
 
-	var re = /^(([\w]+\/)*)([\w-]+)?(\.([\w]+)(\[([\w]+)\])?)?(\.([\w]+)(\[([\w]+)\])?)$/; 
+	var re = /^(([\w]+\/)*)([\w-]+)?(\.([\w]+)(\[([\w.]+)\])?)?(\.([\w.]+)(\[([\w]+)\])?)$/; 
 	var matches = re.exec(trackName);
 	var matches = re.exec(trackName);
 
 
 	if( ! matches ) {
 	if( ! matches ) {