瀏覽代碼

Refactored AnimationHandler.

Mr.doob 11 年之前
父節點
當前提交
f3bee6d1de

+ 16 - 30
examples/webgl_loader_collada.html

@@ -47,14 +47,24 @@
 
 			var camera, scene, renderer, objects;
 			var particleLight, pointLight;
-			var dae, skin;
+			var dae;
 
 			var loader = new THREE.ColladaLoader();
 			loader.options.convertUpAxis = true;
 			loader.load( './models/collada/monster/monster.dae', function ( collada ) {
 
 				dae = collada.scene;
-				skin = collada.skins[ 0 ];
+
+				dae.traverse( function ( child ) {
+
+					if ( child instanceof THREE.SkinnedMesh ) {
+
+						var animation = new THREE.Animation( child );
+						animation.play();
+
+					}
+
+				} );
 
 				dae.scale.x = dae.scale.y = dae.scale.z = 0.002;
 				dae.updateMatrix();
@@ -143,43 +153,17 @@
 
 			//
 
-			var t = 0;
-			var clock = new THREE.Clock();
-
 			function animate() {
 
-				var delta = clock.getDelta();
-
 				requestAnimationFrame( animate );
 
-				if ( t > 1 ) t = 0;
-
-				if ( skin ) {
-
-					// guess this can be done smarter...
-
-					// (Indeed, there are way more frames than needed and interpolation is not used at all
-					//  could be something like - one morph per each skinning pose keyframe, or even less,
-					//  animation could be resampled, morphing interpolation handles sparse keyframes quite well.
-					//  Simple animation cycles like this look ok with 10-15 frames instead of 100 ;)
-
-					for ( var i = 0; i < skin.morphTargetInfluences.length; i++ ) {
-
-						skin.morphTargetInfluences[ i ] = 0;
-
-					}
-
-					skin.morphTargetInfluences[ Math.floor( t * 30 ) ] = 1;
-
-					t += delta;
-
-				}
-
 				render();
 				stats.update();
 
 			}
 
+			var clock = new THREE.Clock();
+
 			function render() {
 
 				var timer = Date.now() * 0.0005;
@@ -194,6 +178,8 @@
 				particleLight.position.y = Math.cos( timer * 5 ) * 4000;
 				particleLight.position.z = Math.cos( timer * 4 ) * 3009;
 
+				THREE.AnimationHandler.update( clock.getDelta() );
+
 				renderer.render( scene, camera );
 
 			}

+ 2 - 4
examples/webgl_loader_collada_keyframe.html

@@ -87,14 +87,12 @@
 
 				// KeyFrame Animations
 
-				var animHandler = THREE.AnimationHandler;
-
 				for ( var i = 0; i < kfAnimationsLength; ++i ) {
 
 					var animation = animations[ i ];
-					animHandler.add( animation );
+					THREE.AnimationHandler.add( animation );
 
-					var kfAnimation = new THREE.KeyFrameAnimation( animation.node, animation.name );
+					var kfAnimation = new THREE.KeyFrameAnimation( animation );
 					kfAnimation.timeScale = 1;
 					kfAnimations.push( kfAnimation );
 

+ 11 - 13
examples/webgl_loader_collada_skinning.html

@@ -82,23 +82,21 @@
 				var loader = new THREE.ColladaLoader();
 				loader.load( "./models/collada/avatar.dae", function ( collada ) {
 				
-					scene.add( collada.scene );
+					collada.scene.traverse( function ( child ) {
+
+						if ( child instanceof THREE.SkinnedMesh ) {
+
+							var animation = new THREE.Animation( child );
+							animation.play();
 
-					// T.P. adapted this to use un-flattened DAE hierarchy; see ColladaLoader.js
-					// for more information
-					var skin = collada.scene.children[0].children[1].children[0];
-					camera.lookAt(skin.position);
+							camera.lookAt( child.position );
 
-					
-					if ( skin.geometry.animation ) {
+						}
 
-						THREE.AnimationHandler.add( skin.geometry.animation );
+					} );
+
+					scene.add( collada.scene );
 
-						var animation = new THREE.Animation( skin, skin.geometry.animation.name );
-						// animation.loop = false;
-						animation.play();
-						
-					}
 				} );
 
 				window.addEventListener( 'resize', onWindowResize, false );

+ 15 - 30
examples/webgl_loader_json_blender.html

@@ -53,7 +53,7 @@
 
 			var camera, scene, renderer, objects;
 			var particleLight, pointLight;
-			var dae, skin;
+			var dae;
 
 			var clock = new THREE.Clock();
 			var morphs = [];
@@ -65,7 +65,17 @@
 			loader.load( 'models/collada/monster/monster.dae', function ( collada ) {
 
 				dae = collada.scene;
-				skin = collada.skins[ 0 ];
+
+				dae.traverse( function ( child ) {
+
+					if ( child instanceof THREE.SkinnedMesh ) {
+
+						var animation = new THREE.Animation( child );
+						animation.play();
+
+					}
+
+				} );
 
 				dae.scale.x = dae.scale.y = dae.scale.z = 0.002;
 				dae.position.x = -1;
@@ -183,46 +193,21 @@
 
 			//
 
-			var t = 0;
 			function animate() {
 
 				requestAnimationFrame( animate );
 
-				// animate Collada model
-
-				if ( t > 30 ) t = 0;
-
-				if ( skin ) {
-
-					// guess this can be done smarter...
-
-					// (Indeed, there are way more frames than needed and interpolation is not used at all
-					//  could be something like - one morph per each skinning pose keyframe, or even less,
-					//  animation could be resampled, morphing interpolation handles sparse keyframes quite well.
-					//  Simple animation cycles like this look ok with 10-15 frames instead of 100 ;)
-
-					for ( var i = 0; i < skin.morphTargetInfluences.length; i++ ) {
-
-						skin.morphTargetInfluences[ i ] = 0;
-
-					}
-
-					skin.morphTargetInfluences[ Math.floor( t ) ] = 1;
-
-					t += 0.5;
-
-				}
+				var delta = clock.getDelta();
 
-				// animate morphs
+				// animate Collada model
 
-				var delta = clock.getDelta();
+				THREE.AnimationHandler.update( delta );
 
 				if ( morphs.length ) {
 
 					for ( var i = 0; i < morphs.length; i ++ )
 						morphs[ i ].updateAnimation( 1000 * delta );
 
-
 				}
 
 				render();

+ 5 - 24
src/extras/animation/Animation.js

@@ -4,17 +4,16 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.Animation = function ( root, name ) {
+THREE.Animation = function ( root ) {
 
 	this.root = root;
-	this.data = THREE.AnimationHandler.get( name );
+	this.data = THREE.AnimationHandler.init( root.geometry.animation );
 	this.hierarchy = THREE.AnimationHandler.parse( root );
 
 	this.currentTime = 0;
 	this.timeScale = 1;
 
 	this.isPlaying = false;
-	this.isPaused = true;
 	this.loop = true;
 	this.weight = 0;
 
@@ -32,28 +31,10 @@ THREE.Animation.prototype.play = function ( startTime, weight ) {
 	this.weight = weight !== undefined ? weight: 1;
 
 	this.isPlaying = true;
-	this.isPaused = false;
 
 	this.reset();
 
-	THREE.AnimationHandler.addToUpdate( this );
-
-};
-
-
-THREE.Animation.prototype.pause = function() {
-
-	if ( this.isPaused === true ) {
-
-		THREE.AnimationHandler.addToUpdate( this );
-
-	} else {
-
-		THREE.AnimationHandler.removeFromUpdate( this );
-
-	}
-
-	this.isPaused = !this.isPaused;
+	THREE.AnimationHandler.play( this );
 
 };
 
@@ -61,8 +42,8 @@ THREE.Animation.prototype.pause = function() {
 THREE.Animation.prototype.stop = function() {
 
 	this.isPlaying = false;
-	this.isPaused  = false;
-	THREE.AnimationHandler.removeFromUpdate( this );
+
+	THREE.AnimationHandler.stop( this );
 
 };
 

+ 77 - 123
src/extras/animation/AnimationHandler.js

@@ -2,129 +2,25 @@
  * @author mikael emtinger / http://gomo.se/
  */
 
-THREE.AnimationHandler = ( function () {
+THREE.AnimationHandler = {
 
-	var playing = [];
-	var library = {};
-	var that    = {};
+	LINEAR: 0,
+	CATMULLROM: 1,
+	CATMULLROM_FORWARD: 2,
 
-	that.update = function ( deltaTimeMS ) {
+	//
 
-		for ( var i = 0; i < playing.length; i ++ ) {
+	add: function () { console.warn( 'THREE.AnimationHandler.add() has been deprecated.' ); },
+	get: function () { console.warn( 'THREE.AnimationHandler.get() has been deprecated.' ); },
+	remove: function () { console.warn( 'THREE.AnimationHandler.remove() has been deprecated.' ); },
 
-			playing[ i ].update( deltaTimeMS );
+	//
 
-		}
-
-	};
-
-	that.addToUpdate = function ( animation ) {
-
-		if ( playing.indexOf( animation ) === -1 ) {
-
-			playing.push( animation );
-
-		}
-
-	};
-
-	that.removeFromUpdate = function ( animation ) {
-
-		var index = playing.indexOf( animation );
-
-		if ( index !== -1 ) {
-
-			playing.splice( index, 1 );
-
-		}
-
-	};
-
-	that.add = function ( data ) {
-
-		if ( library[ data.name ] !== undefined ) {
-
-			console.log( "THREE.AnimationHandler.add: Warning! " + data.name + " already exists in library. Overwriting." );
-
-		}
-
-		library[ data.name ] = data;
-		initData( data );
-
-	};
-
-	that.remove = function ( name ) {
-
-		if ( library[ name ] === undefined ) {
-
-			console.log( "THREE.AnimationHandler.add: Warning! " + name + " doesn't exists in library. Doing nothing." );
-
-		}
-
-		library[ name ] = undefined;
-
-	};
-
-	that.get = function ( name ) {
-
-		if ( typeof name === "string" ) {
-
-			if ( library[ name ] ) {
-
-				return library[ name ];
-
-			} else {
-
-				return null;
-
-			}
-
-		} else {
-
-			// todo: add simple tween library
-
-		}
-
-	};
-
-	that.parse = function ( root ) {
-
-		// setup hierarchy
-
-		var hierarchy = [];
-
-		if ( root instanceof THREE.SkinnedMesh ) {
-
-			for ( var b = 0; b < root.skeleton.bones.length; b++ ) {
-
-				hierarchy.push( root.skeleton.bones[ b ] );
-
-			}
-
-		} else {
-
-			parseRecurseHierarchy( root, hierarchy );
-
-		}
-
-		return hierarchy;
-
-	};
+	animations: [],
 
-	var parseRecurseHierarchy = function ( root, hierarchy ) {
-
-		hierarchy.push( root );
-
-		for ( var c = 0; c < root.children.length; c++ )
-			parseRecurseHierarchy( root.children[ c ], hierarchy );
-
-	}
-
-	var initData = function ( data ) {
-
-		if ( data.initialized === true )
-			return;
+	init: function ( data ) {
 
+		if ( data.initialized === true ) return;
 
 		// loop through all keys
 
@@ -234,15 +130,73 @@ THREE.AnimationHandler = ( function () {
 
 		data.initialized = true;
 
-	};
+		return data;
+
+	},
+
+	parse: function ( root ) {
+
+		var parseRecurseHierarchy = function ( root, hierarchy ) {
+
+			hierarchy.push( root );
+
+			for ( var c = 0; c < root.children.length; c++ )
+				parseRecurseHierarchy( root.children[ c ], hierarchy );
+
+		};
+
+		// setup hierarchy
+
+		var hierarchy = [];
+
+		if ( root instanceof THREE.SkinnedMesh ) {
+
+			for ( var b = 0; b < root.skeleton.bones.length; b++ ) {
+
+				hierarchy.push( root.skeleton.bones[ b ] );
+
+			}
+
+		} else {
+
+			parseRecurseHierarchy( root, hierarchy );
 
+		}
 
-	// interpolation types
+		return hierarchy;
+
+	},
+
+	play: function ( animation ) {
+
+		if ( this.animations.indexOf( animation ) === -1 ) {
+
+			this.animations.push( animation );
+
+		}
 
-	that.LINEAR = 0;
-	that.CATMULLROM = 1;
-	that.CATMULLROM_FORWARD = 2;
+	},
 
-	return that;
+	stop: function ( animation ) {
+
+		var index = this.animations.indexOf( animation );
+
+		if ( index !== -1 ) {
+
+			this.animations.splice( index, 1 );
+
+		}
+
+	},
+
+	update: function ( deltaTimeMS ) {
+
+		for ( var i = 0; i < this.animations.length; i ++ ) {
+
+			this.animations[ i ].update( deltaTimeMS );
+
+		}
+
+	}
 
-}() );
+};

+ 6 - 29
src/extras/animation/KeyFrameAnimation.js

@@ -6,11 +6,11 @@
  * @author erik kitson
  */
 
-THREE.KeyFrameAnimation = function ( root, data ) {
+THREE.KeyFrameAnimation = function ( data ) {
 
-	this.root = root;
-	this.data = THREE.AnimationHandler.get( data );
-	this.hierarchy = THREE.AnimationHandler.parse( root );
+	this.root = data.node;
+	this.data = THREE.AnimationHandler.init( data );
+	this.hierarchy = THREE.AnimationHandler.parse( this.root );
 	this.currentTime = 0;
 	this.timeScale = 0.001;
 	this.isPlaying = false;
@@ -50,7 +50,6 @@ THREE.KeyFrameAnimation = function ( root, data ) {
 
 };
 
-// Play
 
 THREE.KeyFrameAnimation.prototype.play = function ( startTime ) {
 
@@ -100,39 +99,17 @@ THREE.KeyFrameAnimation.prototype.play = function ( startTime ) {
 
 	this.isPaused = false;
 
-	THREE.AnimationHandler.addToUpdate( this );
+	THREE.AnimationHandler.play( this );
 
 };
 
 
-
-// Pause
-
-THREE.KeyFrameAnimation.prototype.pause = function() {
-
-	if( this.isPaused ) {
-
-		THREE.AnimationHandler.addToUpdate( this );
-
-	} else {
-
-		THREE.AnimationHandler.removeFromUpdate( this );
-
-	}
-
-	this.isPaused = !this.isPaused;
-
-};
-
-
-// Stop
-
 THREE.KeyFrameAnimation.prototype.stop = function() {
 
 	this.isPlaying = false;
 	this.isPaused  = false;
 
-	THREE.AnimationHandler.removeFromUpdate( this );
+	THREE.AnimationHandler.stop( this );
 
 	// reset JIT matrix and remove cache
 

+ 1 - 0
src/extras/animation/MorphAnimation.js

@@ -25,6 +25,7 @@ THREE.MorphAnimation.prototype = {
 	pause: function () {
 
 		this.isPlaying = false;
+
 	},
 
 	update: ( function () {