engine icon indicating copy to clipboard operation
engine copied to clipboard

AnimEvents not dispatched after activeStateCurrentTime updated

Open vogloblinsky opened this issue 2 years ago • 3 comments

Project : https://playcanvas.com/project/970223/overview/debug-seeking-animation

I want to be able to seek inside an animation. For now i just use activeStateCurrentTime.

For the use-case :

  • i have added manually 3 AnimEvents of type "trick_step" with code in anim.js file
  • an AnimEvent of type "animation_frame" is added for each 0.1s of the duration of the animation
  • a final AnimEvent for the end of the animation (type "animation_end")

Steps to reproduce the working use-case :

  • open JS console
  • click on "load ollie"
  • wait a little, you should see logs of AnimEvents frames, and the animation will stop on event "trick_step" with status "step_0"
  • click on play, animation continue to event "trick_step" with status "step_0b"
  • click play , and animation continue to event "trick_step" with status "step_1"
  • click on play and after the animation ends.

Steps to reproduce the issue :

  • click on "load ollie"
  • wait a little, the animation will stop on event "trick_step" with status "step_0"
  • click on "Next 2.7", the animation move to event "trick_step" with status "step_0b "(i just updated activeStateCurrentTime)
  • click on play and after the animation ends but no logs for AnimEvents. But it is strange, they restarted a few seconds later...

vogloblinsky avatar Aug 16 '22 21:08 vogloblinsky

Looks like there is an issue where it's possible for the anim clip this.eventCursor to be out of sync with the anim layer activeStateCurrentTime causing this line to fail:

https://github.com/playcanvas/engine/blob/main/src/anim/evaluator/anim-clip.js#L119

eg. If the animation is stopped on 2.6 secs and this.track.events[this.eventCursor].time is 2.6 When the activeStateCurrentTime is moved to 2.7, this line fails because the next event that is being targeted is in the past.

yaustar avatar Aug 22 '22 16:08 yaustar

Here is my questionable workaround for this that advances the eventCursor forward when the time is set: https://playcanvas.com/project/972398/overview/f-debug-seeking-animation

Anim.prototype.nextStep = function(time) {
    console.log(time);
    const floatTime = parseFloat(time);
    this.entity.anim.baseLayer.activeStateCurrentTime = floatTime;

    // Work around that really shouldn't be used (+_+)
    // Get to the animation clip(s) and advance the eventCursor forward
    const clips = this.entity.anim.baseLayer._controller._animEvaluator._clips;
    for (let i = 0; i < clips.length; ++i) {
        const clip = clips[i];
        if (clip.blendWeight > 0.0) {
            while(clip.track.events[clip.eventCursor] && clip.track.events[clip.eventCursor].time < floatTime) {
                clip.eventCursor++;
            }
        }
    }
};

yaustar avatar Aug 22 '22 17:08 yaustar

@ellthompson If you need help or enhancements on my repro project, don't hesitate to ping me.

vogloblinsky avatar Aug 26 '22 09:08 vogloblinsky

Any news ? thanks

vogloblinsky avatar Oct 21 '22 12:10 vogloblinsky

This looks like a bug in the AnimClip class. The clip's eventCursor is currently being aligned to the initial time of the clip in the class constructor. We should also be realigning the cursor whenever the a clip's time property is updated externally. I'll submit a PR to fix this tomorrow after testing this a bit more.

ellthompson avatar Oct 24 '22 16:10 ellthompson

Cool thanks for the quick fix. I will have a look and see if it works on my use-case.

vogloblinsky avatar Oct 25 '22 11:10 vogloblinsky

@ellthompson I confirm the fix works well ! Thanks 🙏🏻

vogloblinsky avatar Oct 25 '22 14:10 vogloblinsky