From af5aca8b66607cf14dec1fad3d14c4deff0fa500 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Sun, 29 Sep 2013 23:22:55 +0200 Subject: [PATCH] Changed when events are fired. Events are now fired from lastTime (exclusive) to time (inclusive). This allows an event at the end of an animation to be fired before the next animation starts. The "complete" callback will happen before the event though, because "complete" happens in update() and events are triggered in apply(). Note events are not fired for the previous animation during mixing (crossfading). --- spine-c/src/spine/Animation.c | 25 ++++++++----------- spine-c/src/spine/AnimationState.c | 2 +- spine-csharp/src/Animation.cs | 22 +++++++--------- spine-csharp/src/AnimationState.cs | 2 +- .../com/esotericsoftware/spine/Animation.java | 22 +++++++--------- .../spine/AnimationState.java | 2 +- 6 files changed, 31 insertions(+), 44 deletions(-) diff --git a/spine-c/src/spine/Animation.c b/spine-c/src/spine/Animation.c index b1c00f9ed..76bb3e308 100644 --- a/spine-c/src/spine/Animation.c +++ b/spine-c/src/spine/Animation.c @@ -518,29 +518,24 @@ void _EventTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float l EventTimeline* self = (EventTimeline*)timeline; int frameIndex; - if (lastTime <= self->frames[0] || self->framesLength == 1) + if (lastTime > time) { + /* Fire events after last time for looped animations. */ + _EventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventCount, alpha); + lastTime = 0; + } else if (lastTime >= self->frames[self->framesLength - 1]) return; /* Last time is after last frame. */ + + if (lastTime < self->frames[0] || self->framesLength == 1) frameIndex = 0; else { float frame; - - if (lastTime >= self->frames[self->framesLength - 1]) return; /* Last time is after last frame. */ - - if (lastTime > time) { - /* Fire events after last time for looped animations. */ - _EventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventCount, alpha); - lastTime = 0; - } - frameIndex = binarySearch(self->frames, self->framesLength, lastTime, 1); frame = self->frames[frameIndex]; - while (frameIndex > 0) { - float lastFrame = self->frames[frameIndex - 1]; - /* Fire multiple events with the same frame and events that occurred at lastTime. */ - if (lastFrame != frame && lastFrame != lastTime) break; + while (frameIndex > 0) { /* Fire multiple events with the same frame. */ + if (self->frames[frameIndex - 1] != frame) break; frameIndex--; } } - for (; frameIndex < self->framesLength && time > self->frames[frameIndex]; frameIndex++) { + for (; frameIndex < self->framesLength && time >= self->frames[frameIndex]; frameIndex++) { firedEvents[*eventCount] = self->events[frameIndex]; (*eventCount)++; } diff --git a/spine-c/src/spine/AnimationState.c b/spine-c/src/spine/AnimationState.c index 7be03b52b..015fbb600 100644 --- a/spine-c/src/spine/AnimationState.c +++ b/spine-c/src/spine/AnimationState.c @@ -110,7 +110,7 @@ void AnimationState_update (AnimationState* self, float delta) { } if (current->next) { - if (time >= current->next->delay) _AnimationState_setCurrent(self, i, current->next); + if (time - trackDelta >= current->next->delay) _AnimationState_setCurrent(self, i, current->next); } else { /* End non-looping animation when it reaches its end time and there is no next entry. */ if (!current->loop && current->lastTime >= current->endTime) AnimationState_clearTrack(self, i); diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index 292d51825..3328185bc 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -473,27 +473,23 @@ namespace Spine { float[] frames = this.frames; int frameCount = frames.Length; + if (lastTime > time) { // Fire events after last time for looped animations. + Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha); + lastTime = 0; + } else if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame. + int frameIndex; - if (lastTime <= frames[0] || frameCount == 1) + if (lastTime < frames[0] || frameCount == 1) frameIndex = 0; else { - if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame. - - if (lastTime > time) { // Fire events after last time for looped animations. - Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha); - lastTime = 0; - } - frameIndex = Animation.binarySearch(frames, lastTime, 1); float frame = frames[frameIndex]; - while (frameIndex > 0) { - float lastFrame = frames[frameIndex - 1]; - // Fire multiple events with same frame and events that occurred at lastTime. - if (lastFrame != frame && lastFrame != lastTime) break; + while (frameIndex > 0) { // Fire multiple events with the same frame. + if (frames[frameIndex - 1] != frame) break; frameIndex--; } } - for (; frameIndex < frameCount && time > frames[frameIndex]; frameIndex++) + for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++) firedEvents.Add(events[frameIndex]); } } diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index d9c8c0a77..3667b92a0 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -80,7 +80,7 @@ namespace Spine { TrackEntry next = current.next; if (next != null) { - if (time >= next.delay) SetCurrent(i, next); + if (time - trackDelta >= next.delay) SetCurrent(i, next); } else { // End non-looping animation when it reaches its end time and there is no next entry. if (!current.loop && current.lastTime >= current.endTime) ClearTrack(i); diff --git a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index e10f8b3cb..ac6429615 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -547,27 +547,23 @@ public class Animation { float[] frames = this.frames; int frameCount = frames.length; + if (lastTime > time) { // Fire events after last time for looped animations. + apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha); + lastTime = 0; + } else if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame. + int frameIndex; - if (lastTime <= frames[0] || frameCount == 1) + if (lastTime < frames[0] || frameCount == 1) frameIndex = 0; else { - if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame. - - if (lastTime > time) { // Fire events after last time for looped animations. - apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha); - lastTime = 0; - } - frameIndex = binarySearch(frames, lastTime, 1); float frame = frames[frameIndex]; - while (frameIndex > 0) { - float lastFrame = frames[frameIndex - 1]; - // Fire multiple events with the same frame and events that occurred at lastTime. - if (lastFrame != frame && lastFrame != lastTime) break; + while (frameIndex > 0) { // Fire multiple events with the same frame. + if (frames[frameIndex - 1] != frame) break; frameIndex--; } } - for (; frameIndex < frameCount && time > frames[frameIndex]; frameIndex++) + for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++) firedEvents.add(events[frameIndex]); } } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java b/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java index 6c42d52cd..365c47f50 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java @@ -76,7 +76,7 @@ public class AnimationState { TrackEntry next = current.next; if (next != null) { - if (time >= next.delay) setCurrent(i, next); + if (time - trackDelta > next.delay) setCurrent(i, next); } else { // End non-looping animation when it reaches its end time and there is no next entry. if (!current.loop && current.lastTime >= current.endTime) clearTrack(i);