Explorar el Código

Animation Update (#8918)

* AnimationClip name to uuid to avoiding conflicts of names

- Changes by @sunag, see #8909.

* Removed unused .getClipByName.

* Fixed wrong variable name in action.halt.

* Find animation clips by name on objects.

- See discussion with @bhouston on #8909.
tschw hace 9 años
padre
commit
60ef1a6523

+ 6 - 23
examples/js/MD2Character.js

@@ -80,21 +80,6 @@ THREE.MD2Character = function () {
 				scope.weapons[ index ] = mesh;
 				scope.meshWeapon = mesh;
 
-
-				// the animation system requires unique names, so append the
-				// uuid of the source geometry:
-
-				var geometry = mesh.geometry,
-					animations = geometry.animations;
-
-				for ( var i = 0, n = animations.length; i !== n; ++ i ) {
-
-					var animation = animations[ i ];
-					animation.name += geometry.uuid;
-
-				}
-
-
 				checkLoadingComplete();
 
 			}
@@ -172,11 +157,10 @@ THREE.MD2Character = function () {
 				this.meshBody.activeAction = null;
 			}
 
-			var clip = THREE.AnimationClip.findByName( this.meshBody.geometry.animations, clipName );
-			if( clip ) {
+			var action = this.mixer.clipAction( clipName, this.meshBody );
+			if( action ) {
 
-				this.meshBody.activeAction =
-						this.mixer.clipAction( clip, this.meshBody ).play();
+				this.meshBody.activeAction = action.play();
 
 			}
 
@@ -202,12 +186,11 @@ THREE.MD2Character = function () {
 			var geometry = this.meshWeapon.geometry,
 				animations = geometry.animations;
 
-			var clip = THREE.AnimationClip.findByName( animations, clipName + geometry.uuid );
-			if( clip ) {
+			var action = this.mixer.clipAction( clipName, this.meshWeapon );
+			if( action ) {
 
 				this.meshWeapon.activeAction =
-						this.mixer.clipAction( clip, this.meshWeapon ).
-							syncWith( this.meshBody.activeAction ).play();
+						action.syncWith( this.meshBody.activeAction ).play();
 
 			}
 

+ 1 - 1
examples/js/MorphAnimMesh.js

@@ -36,7 +36,7 @@ THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
 		
 	}
 
-	var clip = THREE.AnimationClip.findByName( this.geometry.animations, label );
+	var clip = THREE.AnimationClip.findByName( this, label );
 
 	if ( clip ) {
 

+ 1 - 1
src/animation/AnimationAction.js

@@ -270,7 +270,7 @@ THREE.AnimationAction._new.prototype = {
 
 	halt: function( duration ) {
 
-		return this.warp( this._currentTimeScale, 0, duration );
+		return this.warp( this._effectiveTimeScale, 0, duration );
 
 	},
 

+ 13 - 2
src/animation/AnimationClip.js

@@ -8,10 +8,12 @@
 
 THREE.AnimationClip = function ( name, duration, tracks ) {
 
-	this.name = name || THREE.Math.generateUUID();
+	this.name = name;
 	this.tracks = tracks;
 	this.duration = ( duration !== undefined ) ? duration : -1;
 
+	this.uuid = THREE.Math.generateUUID();
+
 	// this means it should figure out its duration by scanning the tracks
 	if ( this.duration < 0 ) {
 
@@ -160,7 +162,16 @@ Object.assign( THREE.AnimationClip, {
 
 	},
 
-	findByName: function( clipArray, name ) {
+	findByName: function( objectOrClipArray, name ) {
+
+		var clipArray = objectOrClipArray;
+
+		if ( ! Array.isArray( objectOrClipArray ) ) {
+
+			var o = objectOrClipArray;
+			clipArray = o.geometry && o.geometry.animations || o.animations;
+
+		}
 
 		for ( var i = 0; i < clipArray.length; i ++ ) {
 

+ 31 - 29
src/animation/AnimationMixer.js

@@ -29,11 +29,14 @@ Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype,
 
 		var root = optionalRoot || this._root,
 			rootUuid = root.uuid,
-			clipName = ( typeof clip === 'string' ) ? clip : clip.name,
-			clipObject = ( clip !== clipName ) ? clip : null,
 
-			actionsForClip = this._actionsByClip[ clipName ],
-			prototypeAction;
+			clipObject = typeof clip === 'string' ?
+					THREE.AnimationClip.findByName( root, clip ) : clip,
+
+			clipUuid = clipObject !== null ? clipObject.uuid : clip,
+
+			actionsForClip = this._actionsByClip[ clipUuid ],
+			prototypeAction = null;
 
 		if ( actionsForClip !== undefined ) {
 
@@ -51,14 +54,8 @@ Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype,
 			prototypeAction = actionsForClip.knownActions[ 0 ];
 
 			// also, take the clip from the prototype action
-			clipObject = prototypeAction._clip;
-
-			if ( clip !== clipName && clip !== clipObject ) {
-
-				throw new Error(
-						"Different clips with the same name detected!" );
-
-			}
+			if ( clipObject === null )
+				clipObject = prototypeAction._clip;
 
 		}
 
@@ -72,7 +69,7 @@ Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype,
 		this._bindAction( newAction, prototypeAction );
 
 		// and make the action known to the memory manager
-		this._addInactiveAction( newAction, clipName, rootUuid );
+		this._addInactiveAction( newAction, clipUuid, rootUuid );
 
 		return newAction;
 
@@ -83,8 +80,13 @@ Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype,
 
 		var root = optionalRoot || this._root,
 			rootUuid = root.uuid,
-			clipName = ( typeof clip === 'string' ) ? clip : clip.name,
-			actionsForClip = this._actionsByClip[ clipName ];
+
+			clipObject = typeof clip === 'string' ?
+					THREE.AnimationClip.findByName( root, clip ) : clip,
+
+			clipUuid = clipObject ? clipObject.uuid : clip,
+
+			actionsForClip = this._actionsByClip[ clipUuid ];
 
 		if ( actionsForClip !== undefined ) {
 
@@ -176,9 +178,9 @@ Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype,
 	uncacheClip: function( clip ) {
 
 		var actions = this._actions,
-			clipName = clip.name,
+			clipUuid = clip.uuid,
 			actionsByClip = this._actionsByClip,
-			actionsForClip = actionsByClip[ clipName ];
+			actionsForClip = actionsByClip[ clipUuid ];
 
 		if ( actionsForClip !== undefined ) {
 
@@ -208,7 +210,7 @@ Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype,
 
 			}
 
-			delete actionsByClip[ clipName ];
+			delete actionsByClip[ clipUuid ];
 
 		}
 
@@ -220,9 +222,9 @@ Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype,
 		var rootUuid = root.uuid,
 			actionsByClip = this._actionsByClip;
 
-		for ( var clipName in actionsByClip ) {
+		for ( var clipUuid in actionsByClip ) {
 
-			var actionByRoot = actionsByClip[ clipName ].actionByRoot,
+			var actionByRoot = actionsByClip[ clipUuid ].actionByRoot,
 				action = actionByRoot[ rootUuid ];
 
 			if ( action !== undefined ) {
@@ -350,13 +352,13 @@ Object.assign( THREE.AnimationMixer.prototype, {
 				// appears to be still using it -> rebind
 
 				var rootUuid = ( action._localRoot || this._root ).uuid,
-					clipName = action._clip.name,
-					actionsForClip = this._actionsByClip[ clipName ];
+					clipUuid = action._clip.uuid,
+					actionsForClip = this._actionsByClip[ clipUuid ];
 
 				this._bindAction( action,
 						actionsForClip && actionsForClip.knownActions[ 0 ] );
 
-				this._addInactiveAction( action, clipName, rootUuid );
+				this._addInactiveAction( action, clipUuid, rootUuid );
 
 			}
 
@@ -462,11 +464,11 @@ Object.assign( THREE.AnimationMixer.prototype, {
 
 	},
 
-	_addInactiveAction: function( action, clipName, rootUuid ) {
+	_addInactiveAction: function( action, clipUuid, rootUuid ) {
 
 		var actions = this._actions,
 			actionsByClip = this._actionsByClip,
-			actionsForClip = actionsByClip[ clipName ];
+			actionsForClip = actionsByClip[ clipUuid ];
 
 		if ( actionsForClip === undefined ) {
 
@@ -479,7 +481,7 @@ Object.assign( THREE.AnimationMixer.prototype, {
 
 			action._byClipCacheIndex = 0;
 
-			actionsByClip[ clipName ] = actionsForClip;
+			actionsByClip[ clipUuid ] = actionsForClip;
 
 		} else {
 
@@ -510,9 +512,9 @@ Object.assign( THREE.AnimationMixer.prototype, {
 		action._cacheIndex = null;
 
 
-		var clipName = action._clip.name,
+		var clipUuid = action._clip.uuid,
 			actionsByClip = this._actionsByClip,
-			actionsForClip = actionsByClip[ clipName ],
+			actionsForClip = actionsByClip[ clipUuid ],
 			knownActionsForClip = actionsForClip.knownActions,
 
 			lastKnownAction =
@@ -534,7 +536,7 @@ Object.assign( THREE.AnimationMixer.prototype, {
 
 		if ( knownActionsForClip.length === 0 ) {
 
-			delete actionsByClip[ clipName ];
+			delete actionsByClip[ clipUuid ];
 
 		}