• Runtimes
  • Animation loop offset in spine-c

Hello!

Some of the looping animations we have created in Spine have some kind of "prologue" and looping part starts with an offset. In Spine i can set Loop Start and Loop End parameters to make an animation looping correctly. But when i started to work with runtimes, C runtime specifically, i couldn't find equivalents of such parameters. Of course, we can move the prologue part into a separate animation, but if there is some way to set Loop Start and Loop End parameters in code, i'd prefer that solution.

Anyway, Spine is awesome 🙂

Related Discussions
...

The Animation class in the runtimes provides a low level API for applying animations. You could build a wrapper to have that work however you like.

If you are using AnimationState (a convenience class built on top of Animation), you can start an animation at a specific time. Get the TrackEntry from add/setAnimation (or getCurrent) then set the time field.

Looping happens using the animation duration, which defaults to the last key. You can set the animation duration yourself, but this would affect all usage of the animation. AnimationState could be augmented to loop a portion of an animation, eg the TrackEntry already has endTime, it could use that to loop. AnimationState would pass false to Animation_apply for loop.
https://trello.com/c/yl08UgMv/61-animat ... -animation

Thank you for your reply!

I have come up with a solution based on the AnimationStateListener and setting the time field of the TrackEntry:

void animationStateListener(spAnimationState* state, int trackIndex, spEventType type, spEvent *event, int loopCount) {
   if (type == SP_ANIMATION_COMPLETE) {
      spTrackEntry *entry = spAnimationState_getCurrent(state, trackIndex);
      if (entry) {
         entry->time = 8.0f / 30;
      }
   }
}

Is it a normal solution or there are better ways to achieve that? And is 30 some kind of standard FPS for spine animations?

Also it causes some flickering between loops. It still updates to the initial pose first and after that to the 8th frame after i set it in listener.

Spine uses 30 fps. It isn't configurable yet.

It flickers because complete is called after the animation loops. AnimationState has already posed the skeleton using the beginning of the animation. You could fix this by doing entry->time += 8.0f / 30;, which will preserve the amount of time that went past the end of the animation, then you need to pose the skeleton at this time. One way to do that could be to call spAnimationState_apply again, but that might cause issues with AnimationState's internal state. You could also just apply the animation:

int eventCount;
spAnimation_apply(entry->animation, skeleton, entry->lastTime, entry->time, 0, 0, &eventCount);

This passes 0 for events, so no events will be fired. Since the AnimationState already applied at the beginning of the animation, it could have fired events from the beginning of the animation which might be unexpected.

Another way to do it is either edit AnimationState or before calling spAnimationState_apply see if the delta would cause the TrackEntry to loop and adjust the time before AnimationState applies the animation.

A version with applying animation directly seems working. Thank you very much for your help!