ThreeJS - how to set the current time in an animation

I am using skinning / skeletal animation in ThreeJS. I have an animation, and I want to be able to move back and forth through it and move to another place inside it, rather than the usual loop behavior.

The animation is created in the same way as in the example:

var animation = new THREE.Animation( mesh, geometry.animation.name ); 

I tried updating the animation with negative deltas as well as directly setting the .currentTime animation:

 animation.currentTime = animationLocation; 

It seems that they only work if I move forward in time, but if I go back, the animation will break and I get an error message:

 THREE.Animation.update: Warning! Scale out of bounds: ... on bone ... 

One thing that really works without errors is to call stop() and then play() with a new start time:

 animation.stop(); animation.play( true, animationLocation ); 

... however, when I look at what these functions actually do, they include many function calls, looping, resetting conversions, etc. This seems like a terrible way to do it, even if it works like a hack.

Perhaps this functionality does not exist yet, in which case I will try to delve into and create a function that performs the minimum amount of work, but I hope there is another way found.

Can anyone help with this?

[UPDATE]

As an update of my progress, I will post the best solution that I currently have ...

I pulled out the contents of the stop() and play() functions and removed everything I could, making some assumptions that certain values ​​had already been set using the play () function.

It still seems like this is probably not the best way to do this, but it works a little less than just calling stop() , then play() .

This is what I could get so that:

 THREE.Animation.prototype.gotoTime = function( time ) { //clamp to duration of the animation: time = THREE.Math.clamp( time, 0, this.length ); this.currentTime = time; // reset key cache var h, hl = this.hierarchy.length, object; for ( h = 0; h < hl; h ++ ) { object = this.hierarchy[ h ]; var prevKey = object.animationCache.prevKey; var nextKey = object.animationCache.nextKey; prevKey.pos = this.data.hierarchy[ h ].keys[ 0 ]; prevKey.rot = this.data.hierarchy[ h ].keys[ 0 ]; prevKey.scl = this.data.hierarchy[ h ].keys[ 0 ]; nextKey.pos = this.getNextKeyWith( "pos", h, 1 ); nextKey.rot = this.getNextKeyWith( "rot", h, 1 ); nextKey.scl = this.getNextKeyWith( "scl", h, 1 ); } //isPlaying must be true for update to work due to "early out" //so remember the current play state: var wasPlaying = this.isPlaying; this.isPlaying = true; //update with a delta time of zero: this.update( 0 ); //reset the play state: this.isPlaying = wasPlaying; } 

The main limitation of a function in terms of utility is that you cannot interpolate from one arbitrary time to another. You can just simply scrub around the animation.

+7
source share
1 answer

You can use THREE.Clock and assign startTime , oldTime , elapsedTime .

+2
source

All Articles