Browse Source

refactor JSONLoader's loading of clips. Load morph sequences into clips. morphnormals and morphtarget_horse examples updated to new clip reader structure.

Ben Houston 10 years ago
parent
commit
ce70dc6ea4

+ 14 - 12
examples/js/BlendCharacter.js

@@ -4,7 +4,7 @@
 
 THREE.BlendCharacter = function () {
 
-	this.animations = {};
+	this.clips = {};
 	this.weightSchedule = [];
 	this.warpSchedule = [];
 
@@ -23,11 +23,12 @@ THREE.BlendCharacter = function () {
 			scope.mixer = new THREE.AnimationMixer( scope );
 
 			// Create the animations
+			console.log( geometry );
+			
+			for ( var i = 0; i < geometry.clips.length; ++ i ) {
 
-			for ( var i = 0; i < geometry.animations.length; ++ i ) {
-
-				var animName = geometry.animations[ i ].name;
-				scope.animations[ animName ] = THREE.AnimationClip.FromJSONLoaderAnimation( geometry.animations[ i ], geometry.bones );
+				var animName = geometry.clips[ i ].name;
+				scope.clips[ animName ] = geometry.clips[ i ];
 
 			}
 
@@ -48,7 +49,7 @@ THREE.BlendCharacter = function () {
 
 		this.mixer.removeAllActions();
 		
-		this.mixer.play( new THREE.AnimationAction( this.animations[ animName ], 0, 1, 1, true ) );
+		this.mixer.play( new THREE.AnimationAction( this.clips[ animName ], 0, 1, 1, true ) );
 
 	};
 
@@ -56,8 +57,8 @@ THREE.BlendCharacter = function () {
 
 		this.mixer.removeAllActions();
  
-		var fromAction = new THREE.AnimationAction( this.animations[ fromAnimName ], 0, 1, 1, true );
-		var toAction = new THREE.AnimationAction( this.animations[ toAnimName ], 0, 1, 1, true );
+		var fromAction = new THREE.AnimationAction( this.clips[ fromAnimName ], 0, 1, 1, true );
+		var toAction = new THREE.AnimationAction( this.clips[ toAnimName ], 0, 1, 1, true );
 
 		this.mixer.play( fromAction );
 		this.mixer.play( toAction );
@@ -70,8 +71,8 @@ THREE.BlendCharacter = function () {
 
 		this.mixer.removeAllActions();
 
-		var fromAction = new THREE.AnimationAction( this.animations[ fromAnimName ], 0, 1, 1, true );
-		var toAction = new THREE.AnimationAction( this.animations[ toAnimName ], 0, 1, 1, true );
+		var fromAction = new THREE.AnimationAction( this.clips[ fromAnimName ], 0, 1, 1, true );
+		var toAction = new THREE.AnimationAction( this.clips[ toAnimName ], 0, 1, 1, true );
 
 		this.mixer.play( fromAction );
 		this.mixer.play( toAction );
@@ -82,8 +83,9 @@ THREE.BlendCharacter = function () {
 
 	this.applyWeight = function( animName, weight ) {
 
-		if( this.mixer[ animName ] ) {
-			this.mixer[ animName ].weight = weight;
+		var action = this.mixer.findActionByName( animName );
+		if( action ) {
+			action.weight = weight;
 		}
 
 	};

+ 21 - 17
examples/webgl_morphnormals.html

@@ -36,8 +36,8 @@
 
 			var container, stats;
 			var camera, scene1, scene2, renderer;
+			var mixers = [];
 
-			var morphs = [];
 			var clock = new THREE.Clock();
 
 			init();
@@ -87,21 +87,24 @@
 
 				//
 
+				
 				var loader = new THREE.JSONLoader();
 				loader.load( "models/animated/flamingo.js", function( geometry ) {
 
 					morphColorsToFaceColors( geometry );
 
 					var material = new THREE.MeshPhongMaterial( { color: 0xffffff, morphTargets: true, vertexColors: THREE.FaceColors, shading: THREE.FlatShading } );
-					var meshAnim = new THREE.MorphAnimMesh( geometry, material );
+					var mesh = new THREE.Mesh( geometry, material );
 
-					meshAnim.duration = 5000;
+					mesh.scale.set( 1.5, 1.5, 1.5 );
+					mesh.position.y = 150;
 
-					meshAnim.scale.set( 1.5, 1.5, 1.5 );
-					meshAnim.position.y = 150;
+					scene1.add( mesh );
 
-					scene1.add( meshAnim );
-					morphs.push( meshAnim );
+					var mixer = new THREE.AnimationMixer( mesh );
+					mixer.addAction( new THREE.AnimationAction( geometry.clips[ 0 ] ) );
+
+					mixers.push( mixer );
 
 				} );
 
@@ -112,15 +115,17 @@
 					geometry.computeMorphNormals();
 
 					var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0xffffff, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.SmoothShading } );
-					var meshAnim = new THREE.MorphAnimMesh( geometry, material );
+					var mesh = new THREE.Mesh( geometry, material );
+					
+					mesh.scale.set( 1.5, 1.5, 1.5 );
+					mesh.position.y = 150;
 
-					meshAnim.duration = 5000;
+					scene2.add( mesh );
 
-					meshAnim.scale.set( 1.5, 1.5, 1.5 );
-					meshAnim.position.y = 150;
+					var mixer = new THREE.AnimationMixer( mesh );
+					mixer.addAction( new THREE.AnimationAction( geometry.clips[ 0 ] ) );
 
-					scene2.add( meshAnim );
-					morphs.push( meshAnim );
+					mixers.push( mixer );
 
 				} );
 
@@ -205,10 +210,9 @@
 
 				var delta = clock.getDelta();
 
-				for ( var i = 0; i < morphs.length; i ++ ) {
-
-					morph = morphs[ i ];
-					morph.updateAnimation( 1000 * delta );
+   				console.log( mixers );
+				for ( var i = 0; i < mixers.length; i ++ ) {
+					mixers[ i ].update( delta );
 
 				}
 

+ 2 - 2
examples/webgl_morphtargets_horse.html

@@ -68,8 +68,8 @@
 
 					mixer = new THREE.AnimationMixer( mesh );
 
-					var clipMorphTargets = THREE.AnimationClipCreator.CreateMorphAnimation( geometry.morphTargets, 1.0 );
-					mixer.addAction( new THREE.AnimationAction( clipMorphTargets, 0, 1, 1, true ) );
+					var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
+					mixer.addAction( new THREE.AnimationAction( clip, 0, 1, 1, true ) );
 
 				} );
 

+ 1 - 1
src/animation/AnimationAction.js

@@ -13,7 +13,7 @@ THREE.AnimationAction = function ( clip, startTime, timeScale, weight, loop ) {
 	this.startTime = startTime || 0;
 	this.timeScale = timeScale || 1;
 	this.weight = weight || 1;
-	this.loop = loop || clip.loop || false;
+	this.loop = loop || clip.loop || true;
 	this.loopCount = 0;
 	this.enabled = true;	// allow for easy disabling of the action.
 

+ 2 - 1
src/animation/AnimationClip.js

@@ -110,7 +110,8 @@ THREE.AnimationClip.CreateClipsFromMorphTargetSequences = function( morphTargets
 	
 	var animationToMorphTargets = {};
 
-	var pattern = /([a-z]+)_?(\d+)/;
+	// tested with https://regex101.com/ on trick sequences such flamingo_flyA_003 and flamingo_run1_003
+	var pattern = /^([\w-]*[a-zA-Z-_]+)([\d]+)$/;
 
 	// sort morph target names into animation groups based patterns like Walk_001, Walk_002, Run_001, Run_002
 	for ( var i = 0, il = morphTargets.length; i < il; i ++ ) {

+ 45 - 35
src/loaders/JSONLoader.js

@@ -75,6 +75,7 @@ THREE.JSONLoader.prototype = {
 
 		parseSkin();
 		parseMorphing( scale );
+		parseClips();
 
 		geometry.computeFaceNormals();
 		geometry.computeBoundingSphere();
@@ -422,41 +423,6 @@ THREE.JSONLoader.prototype = {
 
 			}
 
-			geometry.clips = [];
-
-			// parse old style Bone/Hierarchy animations
-			var animations = [];
-			if( json.animation !== undefined ) {
-				animations.push( json.animation );
-			}
-			if( json.animations !== undefined ) {
-				if( json.animations.length ) {
-					animations = animations.concat( json.animations );
-				}
-				else {
-					animations.push( json.animations );
-				}
-			}
-
-			for( var i = 0; i < animations.length; i ++ ) {
-
-				var clip = THREE.AnimationClip.parseAnimation( animations[i], geometry.bones );
-				if( clip ) geometry.clips.push( clip );
-
-			}
-
-			// parse new style Clips
-			var clips = json.clips || [];
-
-			for( var i = 0; i < clips.length; i ++ ) {
-
-				var clip = THREE.AnimationClip.parse( clips[i] );
-				if( clip ) geometry.clips.push( clip );
-
-			}
-
-			console.log( geometry.clips );
-
 		};
 
 		function parseMorphing( scale ) {
@@ -513,6 +479,50 @@ THREE.JSONLoader.prototype = {
 				}
 
 			}
+		}
+
+		function parseClips() {
+
+			geometry.clips = [];
+
+			// parse new style Clips
+			var clips = json.clips || [];
+
+			for( var i = 0; i < clips.length; i ++ ) {
+
+				var clip = THREE.AnimationClip.parse( clips[i] );
+				if( clip ) geometry.clips.push( clip );
+
+			}
+
+			// parse old style Bone/Hierarchy animations
+			var animations = [];
+			if( json.animation !== undefined ) {
+				animations.push( json.animation );
+			}
+			if( json.animations !== undefined ) {
+				if( json.animations.length ) {
+					animations = animations.concat( json.animations );
+				}
+				else {
+					animations.push( json.animations );
+				}
+			}
+
+			for( var i = 0; i < animations.length; i ++ ) {
+
+				var clip = THREE.AnimationClip.parseAnimation( animations[i], geometry.bones );
+				if( clip ) geometry.clips.push( clip );
+
+			}
+
+			// parse implicit morph animations
+			if( geometry.morphTargets ) {
+
+				var morphAnimationClips = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
+				geometry.clips = geometry.clips.concat( morphAnimationClips );
+
+			}
 
 		};
 

+ 4 - 15
src/objects/MorphAnimMesh.js

@@ -8,8 +8,6 @@ THREE.MorphAnimMesh = function ( geometry, material ) {
 
 	this.type = 'MorphAnimMesh';
 
-	// API
-
 	this.mixer = new THREE.AnimationMixer( this );
 
 };
@@ -29,21 +27,14 @@ THREE.MorphAnimMesh.prototype.setDirectionBackward = function () {
 
 };
 
-THREE.MorphAnimMesh.prototype.parseAnimations = function () {
-
-	this.animationClips = THREE.AnimationClip.FromImplicitMorphTargetAnimations( this.geometry.morphTargets, 20 );
-	this.firstAnimationClip = this.animationClips[0];
-
-};
-
 THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
 
 	this.mixer.removeAllActions();
 
 	var clip = null;
-	for( var i = 0; i < this.animationClips.length; i ++ ) {
-		if( this.animationClips[ i ].name === label ) {
-			clip = this.animationClips[ i ];
+	for( var i = 0; i < this.geometry.clips.length; i ++ ) {
+		if( this.geometry.clips[ i ].name === label ) {
+			clip = this.geometry.clips[ i ];
 			break;
 		}
 	}
@@ -56,7 +47,7 @@ THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
 
 	} else {
 
-		throw new Error( 'THREE.MorphAnimMesh: animationClips[' + label + '] undefined in .playAnimation()' );
+		throw new Error( 'THREE.MorphAnimMesh: clips[' + label + '] undefined in .playAnimation()' );
 
 	}
 
@@ -88,8 +79,6 @@ THREE.MorphAnimMesh.prototype.copy = function ( source ) {
 	THREE.Mesh.prototype.copy.call( this, source );
 
 	this.mixer = new THREE.AnimationMixer( this );
-	this.animationClips = source.animationClips;
-	this.firstAnimationClips = source.firstAnimationClips;
 
 	return this;