|
@@ -10,105 +10,51 @@ THREE.MorphAnimMesh = function ( geometry, material ) {
|
|
|
|
|
|
// API
|
|
|
|
|
|
- this.duration = 1000; // milliseconds
|
|
|
- this.mirroredLoop = false;
|
|
|
- this.time = 0;
|
|
|
-
|
|
|
- // internals
|
|
|
-
|
|
|
- this.lastKeyframe = 0;
|
|
|
- this.currentKeyframe = 0;
|
|
|
-
|
|
|
- this.direction = 1;
|
|
|
- this.directionBackwards = false;
|
|
|
-
|
|
|
- this.setFrameRange( 0, geometry.morphTargets.length - 1 );
|
|
|
+ this.mixer = new THREE.AnimationMixer( this );
|
|
|
|
|
|
};
|
|
|
|
|
|
THREE.MorphAnimMesh.prototype = Object.create( THREE.Mesh.prototype );
|
|
|
THREE.MorphAnimMesh.prototype.constructor = THREE.MorphAnimMesh;
|
|
|
|
|
|
-THREE.MorphAnimMesh.prototype.setFrameRange = function ( start, end ) {
|
|
|
-
|
|
|
- this.startKeyframe = start;
|
|
|
- this.endKeyframe = end;
|
|
|
-
|
|
|
- this.length = this.endKeyframe - this.startKeyframe + 1;
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
THREE.MorphAnimMesh.prototype.setDirectionForward = function () {
|
|
|
|
|
|
- this.direction = 1;
|
|
|
- this.directionBackwards = false;
|
|
|
+ this.mixer.timeScale = 1.0;
|
|
|
|
|
|
};
|
|
|
|
|
|
THREE.MorphAnimMesh.prototype.setDirectionBackward = function () {
|
|
|
|
|
|
- this.direction = - 1;
|
|
|
- this.directionBackwards = true;
|
|
|
+ this.mixer.timeScale = -1.0;
|
|
|
|
|
|
};
|
|
|
|
|
|
THREE.MorphAnimMesh.prototype.parseAnimations = function () {
|
|
|
|
|
|
- var geometry = this.geometry;
|
|
|
-
|
|
|
- if ( ! geometry.animations ) geometry.animations = {};
|
|
|
-
|
|
|
- var firstAnimation, animations = geometry.animations;
|
|
|
-
|
|
|
- var pattern = /([a-z]+)_?(\d+)/;
|
|
|
-
|
|
|
- for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var morph = geometry.morphTargets[ i ];
|
|
|
- var parts = morph.name.match( pattern );
|
|
|
-
|
|
|
- if ( parts && parts.length > 1 ) {
|
|
|
-
|
|
|
- var label = parts[ 1 ];
|
|
|
+ this.animationClips = THREE.AnimationClip.FromImplicitMorphTargetAnimations( this.geometry.morphTargets, 20 );
|
|
|
+ this.firstAnimationClip = this.animationClips[0];
|
|
|
|
|
|
- if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: - Infinity };
|
|
|
-
|
|
|
- var animation = animations[ label ];
|
|
|
+};
|
|
|
|
|
|
- if ( i < animation.start ) animation.start = i;
|
|
|
- if ( i > animation.end ) animation.end = i;
|
|
|
+THREE.MorphAnimMesh.prototype.playAnimation = function ( label ) {
|
|
|
|
|
|
- if ( ! firstAnimation ) firstAnimation = label;
|
|
|
+ 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 ];
|
|
|
+ break;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
+
|
|
|
+ if ( clip ) {
|
|
|
|
|
|
- geometry.firstAnimation = firstAnimation;
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-THREE.MorphAnimMesh.prototype.setAnimationLabel = function ( label, start, end ) {
|
|
|
-
|
|
|
- if ( ! this.geometry.animations ) this.geometry.animations = {};
|
|
|
-
|
|
|
- this.geometry.animations[ label ] = { start: start, end: end };
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
|
|
|
-
|
|
|
- var animation = this.geometry.animations[ label ];
|
|
|
-
|
|
|
- if ( animation ) {
|
|
|
-
|
|
|
- this.setFrameRange( animation.start, animation.end );
|
|
|
- this.duration = 1000 * ( ( animation.end - animation.start ) / fps );
|
|
|
- this.time = 0;
|
|
|
+ this.mixer.addAction( new THREE.AnimationAction( clip, 0, 1, 1, true ) );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- console.warn( 'THREE.MorphAnimMesh: animation[' + label + '] undefined in .playAnimation()' );
|
|
|
+ throw new Error( 'THREE.MorphAnimMesh: animationClips[' + label + '] undefined in .playAnimation()' );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -116,65 +62,7 @@ THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
|
|
|
|
|
|
THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) {
|
|
|
|
|
|
- var frameTime = this.duration / this.length;
|
|
|
-
|
|
|
- this.time += this.direction * delta;
|
|
|
-
|
|
|
- if ( this.mirroredLoop ) {
|
|
|
-
|
|
|
- if ( this.time > this.duration || this.time < 0 ) {
|
|
|
-
|
|
|
- this.direction *= - 1;
|
|
|
-
|
|
|
- if ( this.time > this.duration ) {
|
|
|
-
|
|
|
- this.time = this.duration;
|
|
|
- this.directionBackwards = true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.time < 0 ) {
|
|
|
-
|
|
|
- this.time = 0;
|
|
|
- this.directionBackwards = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- this.time = this.time % this.duration;
|
|
|
-
|
|
|
- if ( this.time < 0 ) this.time += this.duration;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var keyframe = this.startKeyframe + THREE.Math.clamp( Math.floor( this.time / frameTime ), 0, this.length - 1 );
|
|
|
-
|
|
|
- var influences = this.morphTargetInfluences;
|
|
|
-
|
|
|
- if ( keyframe !== this.currentKeyframe ) {
|
|
|
-
|
|
|
- influences[ this.lastKeyframe ] = 0;
|
|
|
- influences[ this.currentKeyframe ] = 1;
|
|
|
- influences[ keyframe ] = 0;
|
|
|
-
|
|
|
- this.lastKeyframe = this.currentKeyframe;
|
|
|
- this.currentKeyframe = keyframe;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var mix = ( this.time % frameTime ) / frameTime;
|
|
|
-
|
|
|
- if ( this.directionBackwards ) {
|
|
|
-
|
|
|
- mix = 1 - mix;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- influences[ this.currentKeyframe ] = mix;
|
|
|
- influences[ this.lastKeyframe ] = 1 - mix;
|
|
|
+ this.mixer.update( delta );
|
|
|
|
|
|
};
|
|
|
|
|
@@ -202,15 +90,9 @@ THREE.MorphAnimMesh.prototype.clone = function () {
|
|
|
|
|
|
THREE.MorphAnimMesh.prototype.copy = function ( source ) {
|
|
|
|
|
|
- this.duration = source.duration;
|
|
|
- this.mirroredLoop = source.mirroredLoop;
|
|
|
- this.time = source.time;
|
|
|
-
|
|
|
- this.lastKeyframe = source.lastKeyframe;
|
|
|
- this.currentKeyframe = source.currentKeyframe;
|
|
|
-
|
|
|
- this.direction = source.direction;
|
|
|
- this.directionBackwards = source.directionBackwards;
|
|
|
+ this.mixer.copy( source.mixer );
|
|
|
+ this.animationClips = source.animationClips;
|
|
|
+ this.firstAnimationClips = source.firstAnimationClips;
|
|
|
|
|
|
THREE.Mesh.prototype.copy.call( this, source );
|
|
|
|