How to play a span/framerange of animations and stop/pause at the last frame of the range?

Hi.

I want to play animations partially, by spans from timestamp to timestamp. So I’m looking for a solution to play a frame range and stop at the end of the range.

Ideally, I would like to rather pause animation at the last frame, so that animatables are not destroyed, current frame is not reset and it could smoothly resume animation from that point to a next timestamp.

In the playground, I have animations defined from 0 to 60, and i want to play them from 15 to 45 and stop/pause at 45.

I tried to use on(Before|After)AnimationsObservable to pause. But the current frame is fractional and it’s not clear how to catch it right before animation stops/resets.

I also tried onAnimationGroupEndObservable to restart animation, immediately pause and then rewind to desired frame. But that resets animation anyway and produces flicker.

Any ideas?

P.S.
Or. maybe it’s possible to split animation into spans and play them sequentially?
They’re going to be loaded from gltf wth lots of channels tho.

cc @Evgeni_Popov

Okay

Apparently,

this behavior is encoded in this piece of _interpolate:

It returns the highLimitValue taken from maximal key/frame here:

Babylon.js/packages/dev/core/src/Animations/runtimeAnimation.ts at 4854e9307beb5e2cdf84cb527343eab6218f75e3 · BabylonJS/Babylon.js · GitHub

So, the ..._CONSTANT animations are not designed to be playeed [from, to]

Surprizingly,

If loopMode = ..._CYCLE but it started with loop = false they stop correctly at the range final frame without reset.

Irregardlessly,

I need to implement my own animation player/controller to track last/current frame when undelying animations are stopped/destroyed.

ok well good job ;D

You could use an event to pause the animation at frame 45:

const ev = new BABYLON.AnimationEvent(45, () => {
    scene.onAfterAnimationsObservable.addOnce(() => {
        animGroup.start();
        animGroup.goToFrame(45);
        animGroup.pause();
    });
}, false);

animY.addEvent(ev);

It’s a bit complicated, because frame 45 is also the frame the animation is stopped, and the action code linked to the event is run before the code that stops the animation. So, we have to execute our code after this code (hence the fact we add it to scene.onAfterAnimationsObservable), and we also have to restart/pause the animation.

1 Like

Hi.

That’s interesting approach. But it seems complicated indeed.

Especially in context of animaions loaded from gltf and in use case where users constatly play their fragments back and forth (with predefined timestamps though).

Maybe, it makes sense to add some fake empty animation track just to trigger events and observables on certain timestamps?
I need something like that anyway to indicate animation spans’ labels and possible descriptions.

2 Likes