Change playback position of animation arbitrarily

I haven’t been able to find much on the matter, but I’m wondering if it’s possible to change an animation’s playback “time” arbitrarily in an AnimationMixer or through some other method.

Instead of simple continuous forward or reverse “playback”, I require a bit more control. I need to jump to a specific time or keyframe in a sequence. Not sure how I could go about achieving this with the current API, but then again Three.js is still fresh for me. Hoping somebody can point me in the right direction!

For what it’s worth, this is my current animation code, which loops through the sequence.

const mixer = new AnimationMixer(entities.parent)
mixer.clipAction(imported.animations[0]).play()

// ...

function onRender(clock) {
  // ...
  mixer.update(clock.getDelta())
}

I also took a shot in the dark and attempted passing in a negative value to the mixer.update() call, but that didn’t work as I hoped.

Please have a look at the following doc pages:

https://threejs.org/docs/index.html#manual/introduction/Animation-system
https://threejs.org/docs/index.html#api/animation/AnimationAction

An AnimationAction controls the playback of a single animation clip. You can use AnimationAction.time to control the current time value of the animation. It’s also possible to scale this value with AnimationAction.timeScale.

Demo: https://jsfiddle.net/f2Lommf5/4624/

Notice, how the code applies an offset to the playback via AnimationAction.time.

2 Likes

Related, I would have expected negative values in mixer.update(t) to work just fine… maybe worth creating a simple demo or filing a bug if not? But setting time on the actions might be easier.

1 Like

Thanks @donmccurdy. You’re right. This was unexpected for me as well, but I eventually found https://github.com/mrdoob/three.js/issues/8931 (last comment). Once I change the loop mode from the default to LoopRepeat, I was able to use a negative update value as expected.

this.entities.action = this.entities.mixer
    .clipAction(imported.animations[0])
    .play()
    .setLoop(LoopRepeat)

Thanks @Mugen87. Amazing! not sure how I missed that property in the documentation. This is exactly what I was looking for.