Clear a track if the last entry is non-looping and reached endTime.

This commit is contained in:
NathanSweet 2013-09-28 21:28:01 +02:00
parent 4852fdca14
commit 3797b7b7b0
4 changed files with 62 additions and 45 deletions

View File

@ -85,8 +85,7 @@ TrackEntry* AnimationState_setAnimationByName (AnimationState* self, int trackIn
TrackEntry* AnimationState_setAnimation (AnimationState* self, int trackIndex, Animation* animation, int/*bool*/loop);
/** Adds an animation to be played delay seconds after the current or last queued animation, taking into account any mix
* duration.
* @param animation May be 0 to queue clearing the AnimationState. */
* duration. */
TrackEntry* AnimationState_addAnimationByName (AnimationState* self, int trackIndex, const char* animationName, int/*bool*/loop,
float delay);
TrackEntry* AnimationState_addAnimation (AnimationState* self, int trackIndex, Animation* animation, int/*bool*/loop,

View File

@ -39,7 +39,6 @@
#include <spine/Skeleton.h>
#include <spine/SkeletonData.h>
#include <string.h>
#include <limits.h>
TrackEntry* _TrackEntry_create () {
TrackEntry* entry = NEW(TrackEntry);
@ -110,11 +109,11 @@ void AnimationState_update (AnimationState* self, float delta) {
if (self->listener) self->listener(self, i, ANIMATION_COMPLETE, 0, count);
}
if (current->next && time >= current->next->delay) {
if (current->next->animation)
_AnimationState_setCurrent(self, i, current->next);
else
AnimationState_clearTrack(self, i);
if (current->next) {
if (time >= 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);
}
}
}
@ -124,6 +123,7 @@ void AnimationState_apply (AnimationState* self, Skeleton* skeleton) {
int i, ii;
int eventCount;
float time;
TrackEntry* previous;
for (i = 0; i < self->trackCount; i++) {
TrackEntry* current = self->tracks[i];
@ -131,19 +131,26 @@ void AnimationState_apply (AnimationState* self, Skeleton* skeleton) {
eventCount = 0;
time = current->time;
if (!current->loop && time > current->endTime) time = current->endTime;
previous = current->previous;
if (!previous) {
Animation_apply(current->animation, skeleton, current->lastTime, current->time, current->loop, internal->events,
Animation_apply(current->animation, skeleton, current->lastTime, time, current->loop, internal->events,
&eventCount);
} else {
float alpha = current->mixTime / current->mixDuration;
Animation_apply(previous->animation, skeleton, (float)INT_MAX, previous->time, previous->loop, 0, 0);
float previousTime = previous->time;
if (!previous->loop && previousTime > previous->endTime) previousTime = previous->endTime;
Animation_apply(previous->animation, skeleton, previousTime, previousTime, previous->loop, 0, 0);
if (alpha >= 1) {
alpha = 1;
_TrackEntry_dispose(current->previous);
current->previous = 0;
}
Animation_mix(current->animation, skeleton, current->lastTime, current->time, current->loop, internal->events,
Animation_mix(current->animation, skeleton, current->lastTime, time, current->loop, internal->events,
&eventCount, alpha);
}

View File

@ -79,11 +79,11 @@ namespace Spine {
}
TrackEntry next = current.next;
if (next != null && time >= next.delay) {
if (next.animation != null)
SetCurrent(i, next);
else
Clear(i);
if (next != null) {
if (time >= 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);
}
}
}
@ -97,17 +97,24 @@ namespace Spine {
events.Clear();
float time = current.time;
bool loop = current.loop;
if (!loop && time > current.endTime) time = current.endTime;
TrackEntry previous = current.previous;
if (previous == null)
current.animation.Apply(skeleton, current.lastTime, current.time, current.loop, events);
current.animation.Apply(skeleton, current.lastTime, time, loop, events);
else {
previous.animation.Apply(skeleton, int.MaxValue, previous.time, previous.loop, null);
float previousTime = previous.time;
if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
previous.animation.Apply(skeleton, previousTime, previousTime, previous.loop, null);
float alpha = current.mixTime / current.mixDuration;
if (alpha >= 1) {
alpha = 1;
current.previous = null;
}
current.animation.Mix(skeleton, current.lastTime, current.time, current.loop, events, alpha);
current.animation.Mix(skeleton, current.lastTime, time, loop, events, alpha);
}
for (int ii = 0, nn = events.Count; ii < nn; ii++) {
@ -120,13 +127,13 @@ namespace Spine {
}
}
public void Clear () {
public void ClearTracks () {
for (int i = 0, n = tracks.Count; i < n; i++)
Clear(i);
ClearTrack(i);
tracks.Clear();
}
public void Clear (int trackIndex) {
public void ClearTrack (int trackIndex) {
if (trackIndex >= tracks.Count) return;
TrackEntry current = tracks[trackIndex];
if (current == null) return;
@ -195,7 +202,7 @@ namespace Spine {
entry.animation = animation;
entry.loop = loop;
entry.time = 0;
entry.endTime = animation != null ? animation.Duration : 0;
entry.endTime = animation.Duration;
TrackEntry last = ExpandToIndex(trackIndex);
if (last != null) {
@ -206,10 +213,9 @@ namespace Spine {
tracks[trackIndex] = entry;
if (delay <= 0) {
if (last != null) {
delay += last.endTime;
if (animation != null) delay -= data.GetMix(last.animation, animation);
} else
if (last != null)
delay += last.endTime - data.GetMix(last.animation, animation);
else
delay = 0;
}
entry.delay = delay;

View File

@ -43,7 +43,7 @@ public class AnimationState {
private Array<TrackEntry> tracks = new Array();
private final Array<Event> events = new Array();
private final Array<AnimationStateListener> listeners = new Array();
private float timeScale;
private float timeScale = 1;
public AnimationState (AnimationStateData data) {
if (data == null) throw new IllegalArgumentException("data cannot be null.");
@ -75,11 +75,11 @@ public class AnimationState {
}
TrackEntry next = current.next;
if (next != null && time >= next.delay) {
if (next.animation != null)
setCurrent(i, next);
else
clear(i);
if (next != null) {
if (time >= 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);
}
}
}
@ -94,18 +94,25 @@ public class AnimationState {
events.size = 0;
float time = current.time;
boolean loop = current.loop;
if (!loop && time > current.endTime) time = current.endTime;
TrackEntry previous = current.previous;
if (previous == null)
current.animation.apply(skeleton, current.lastTime, current.time, current.loop, events);
current.animation.apply(skeleton, current.lastTime, time, loop, events);
else {
previous.animation.apply(skeleton, Integer.MAX_VALUE, previous.time, previous.loop, null);
float previousTime = previous.time;
if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
float alpha = current.mixTime / current.mixDuration;
if (alpha >= 1) {
alpha = 1;
Pools.free(previous);
current.previous = null;
}
current.animation.mix(skeleton, current.lastTime, current.time, current.loop, events, alpha);
current.animation.mix(skeleton, current.lastTime, time, loop, events, alpha);
}
for (int ii = 0, nn = events.size; ii < nn; ii++) {
@ -119,13 +126,13 @@ public class AnimationState {
}
}
public void clear () {
public void clearTracks () {
for (int i = 0, n = tracks.size; i < n; i++)
clear(i);
clearTrack(i);
tracks.clear();
}
public void clear (int trackIndex) {
public void clearTrack (int trackIndex) {
if (trackIndex >= tracks.size) return;
TrackEntry current = tracks.get(trackIndex);
if (current == null) return;
@ -210,14 +217,13 @@ public class AnimationState {
}
/** Adds an animation to be played delay seconds after the current or last queued animation.
* @param animation May be null to queue clearing the AnimationState.
* @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
public TrackEntry addAnimation (int trackIndex, Animation animation, boolean loop, float delay) {
TrackEntry entry = Pools.obtain(TrackEntry.class);
entry.animation = animation;
entry.loop = loop;
entry.time = 0;
entry.endTime = animation != null ? animation.getDuration() : 0;
entry.endTime = animation.getDuration();
TrackEntry last = expandToIndex(trackIndex);
if (last != null) {
@ -228,10 +234,9 @@ public class AnimationState {
tracks.set(trackIndex, entry);
if (delay <= 0) {
if (last != null) {
delay += last.endTime;
if (animation != null) delay -= data.getMix(last.animation, animation);
} else
if (last != null)
delay += last.endTime - data.getMix(last.animation, animation);
else
delay = 0;
}
entry.delay = delay;