mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 17:56:04 +08:00
Fixed events not firing sometimes.
http://www.esotericsoftware.com/forum/viewtopic.php?f=9&t=1462
This commit is contained in:
parent
87af7aa4f9
commit
af5ff6c11f
@ -55,18 +55,19 @@ public class EventTimeline implements Timeline {
|
|||||||
events[frameIndex] = event;
|
events[frameIndex] = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Fires events for frames > lastTime and <= time. */
|
||||||
public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
||||||
if (!firedEvents) return;
|
if (!firedEvents) return;
|
||||||
|
|
||||||
if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
|
|
||||||
|
|
||||||
if (lastTime > time) { // Fire events after last time for looped animations.
|
if (lastTime > time) { // Fire events after last time for looped animations.
|
||||||
apply(skeleton, lastTime, int.MAX_VALUE, firedEvents, alpha);
|
apply(skeleton, lastTime, int.MAX_VALUE, firedEvents, alpha);
|
||||||
lastTime = 0;
|
lastTime = -1;
|
||||||
}
|
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
||||||
|
return;
|
||||||
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
var frameIndex:int;
|
var frameIndex:int;
|
||||||
if (lastTime <= frames[0] || frameCount == 1)
|
if (lastTime < frames[0])
|
||||||
frameIndex = 0;
|
frameIndex = 0;
|
||||||
else {
|
else {
|
||||||
frameIndex = Animation.binarySearch(frames, lastTime, 1);
|
frameIndex = Animation.binarySearch(frames, lastTime, 1);
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public class TrackEntry {
|
|||||||
internal var previous:TrackEntry;
|
internal var previous:TrackEntry;
|
||||||
public var animation:Animation;
|
public var animation:Animation;
|
||||||
public var loop:Boolean;
|
public var loop:Boolean;
|
||||||
public var delay:Number, time:Number = 0, lastTime:Number = 0, endTime:Number, timeScale:Number = 1;
|
public var delay:Number, time:Number = 0, lastTime:Number = -1, endTime:Number, timeScale:Number = 1;
|
||||||
internal var mixTime:Number, mixDuration:Number;
|
internal var mixTime:Number, mixDuration:Number;
|
||||||
public var onStart:Function, onEnd:Function, onComplete:Function, onEvent:Function;
|
public var onStart:Function, onEnd:Function, onComplete:Function, onEvent:Function;
|
||||||
|
|
||||||
|
|||||||
@ -514,21 +514,21 @@ void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex,
|
|||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
|
/** Fires events for frames > lastTime and <= time. */
|
||||||
void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventCount, float alpha) {
|
int* eventCount, float alpha) {
|
||||||
spEventTimeline* self = (spEventTimeline*)timeline;
|
spEventTimeline* self = (spEventTimeline*)timeline;
|
||||||
int frameIndex;
|
int frameIndex;
|
||||||
if (!firedEvents) return;
|
if (!firedEvents) return;
|
||||||
|
|
||||||
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. */
|
||||||
|
|
||||||
if (lastTime > time) {
|
|
||||||
/* Fire events after last time for looped animations. */
|
|
||||||
_spEventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventCount, alpha);
|
_spEventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventCount, alpha);
|
||||||
lastTime = 0;
|
lastTime = -1;
|
||||||
}
|
} else if (lastTime >= self->frames[self->framesLength - 1]) /* Last time is after last frame. */
|
||||||
|
return;
|
||||||
|
if (time < self->frames[0]) return; /* Time is before first frame. */
|
||||||
|
|
||||||
if (lastTime <= self->frames[0] || self->framesLength == 1)
|
if (lastTime < self->frames[0])
|
||||||
frameIndex = 0;
|
frameIndex = 0;
|
||||||
else {
|
else {
|
||||||
float frame;
|
float frame;
|
||||||
|
|||||||
@ -43,6 +43,7 @@
|
|||||||
spTrackEntry* _spTrackEntry_create () {
|
spTrackEntry* _spTrackEntry_create () {
|
||||||
spTrackEntry* entry = NEW(spTrackEntry);
|
spTrackEntry* entry = NEW(spTrackEntry);
|
||||||
entry->timeScale = 1;
|
entry->timeScale = 1;
|
||||||
|
entry->lastTime = -1;
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +233,6 @@ spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIn
|
|||||||
entry = _spTrackEntry_create();
|
entry = _spTrackEntry_create();
|
||||||
entry->animation = animation;
|
entry->animation = animation;
|
||||||
entry->loop = loop;
|
entry->loop = loop;
|
||||||
entry->time = 0;
|
|
||||||
entry->endTime = animation->duration;
|
entry->endTime = animation->duration;
|
||||||
_spAnimationState_setCurrent(self, trackIndex, entry);
|
_spAnimationState_setCurrent(self, trackIndex, entry);
|
||||||
return entry;
|
return entry;
|
||||||
@ -251,7 +251,6 @@ spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIn
|
|||||||
spTrackEntry* entry = _spTrackEntry_create();
|
spTrackEntry* entry = _spTrackEntry_create();
|
||||||
entry->animation = animation;
|
entry->animation = animation;
|
||||||
entry->loop = loop;
|
entry->loop = loop;
|
||||||
entry->time = 0;
|
|
||||||
entry->endTime = animation->duration;
|
entry->endTime = animation->duration;
|
||||||
|
|
||||||
last = _spAnimationState_expandToIndex(self, trackIndex);
|
last = _spAnimationState_expandToIndex(self, trackIndex);
|
||||||
|
|||||||
@ -459,20 +459,21 @@ namespace Spine {
|
|||||||
events[frameIndex] = e;
|
events[frameIndex] = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Fires events for frames > lastTime and <= time.</summary>
|
||||||
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||||
if (firedEvents == null) return;
|
if (firedEvents == null) return;
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
int frameCount = frames.Length;
|
int frameCount = frames.Length;
|
||||||
|
|
||||||
if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
|
|
||||||
|
|
||||||
if (lastTime > time) { // Fire events after last time for looped animations.
|
if (lastTime > time) { // Fire events after last time for looped animations.
|
||||||
Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha);
|
apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha);
|
||||||
lastTime = 0;
|
lastTime = -1f;
|
||||||
}
|
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
||||||
|
return;
|
||||||
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
int frameIndex;
|
int frameIndex;
|
||||||
if (lastTime <= frames[0] || frameCount == 1)
|
if (lastTime < frames[0])
|
||||||
frameIndex = 0;
|
frameIndex = 0;
|
||||||
else {
|
else {
|
||||||
frameIndex = Animation.binarySearch(frames, lastTime, 1);
|
frameIndex = Animation.binarySearch(frames, lastTime, 1);
|
||||||
|
|||||||
@ -275,7 +275,7 @@ namespace Spine {
|
|||||||
internal TrackEntry next, previous;
|
internal TrackEntry next, previous;
|
||||||
internal Animation animation;
|
internal Animation animation;
|
||||||
internal bool loop;
|
internal bool loop;
|
||||||
internal float delay, time, lastTime, endTime, timeScale = 1;
|
internal float delay, time, lastTime = -1, endTime, timeScale = 1;
|
||||||
internal float mixTime, mixDuration;
|
internal float mixTime, mixDuration;
|
||||||
|
|
||||||
public Animation Animation { get { return animation; } }
|
public Animation Animation { get { return animation; } }
|
||||||
|
|||||||
@ -532,20 +532,22 @@ spine.EventTimeline.prototype = {
|
|||||||
this.frames[frameIndex] = time;
|
this.frames[frameIndex] = time;
|
||||||
this.events[frameIndex] = event;
|
this.events[frameIndex] = event;
|
||||||
},
|
},
|
||||||
|
/** Fires events for frames > lastTime and <= time. */
|
||||||
apply: function (skeleton, lastTime, time, firedEvents, alpha) {
|
apply: function (skeleton, lastTime, time, firedEvents, alpha) {
|
||||||
if (!firedEvents) return;
|
if (!firedEvents) return;
|
||||||
|
|
||||||
var frames = this.frames;
|
var frames = this.frames;
|
||||||
var frameCount = frames.length;
|
var frameCount = frames.length;
|
||||||
if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
|
|
||||||
|
|
||||||
if (lastTime > time) { // Fire events after last time for looped animations.
|
if (lastTime > time) { // Fire events after last time for looped animations.
|
||||||
this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha);
|
apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha);
|
||||||
lastTime = 0;
|
lastTime = -1f;
|
||||||
}
|
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
||||||
|
return;
|
||||||
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
var frameIndex;
|
var frameIndex;
|
||||||
if (lastTime <= frames[0] || frameCount == 1)
|
if (lastTime < frames[0])
|
||||||
frameIndex = 0;
|
frameIndex = 0;
|
||||||
else {
|
else {
|
||||||
frameIndex = spine.binarySearch(frames, lastTime, 1);
|
frameIndex = spine.binarySearch(frames, lastTime, 1);
|
||||||
@ -947,7 +949,7 @@ spine.TrackEntry.prototype = {
|
|||||||
next: null, previous: null,
|
next: null, previous: null,
|
||||||
animation: null,
|
animation: null,
|
||||||
loop: false,
|
loop: false,
|
||||||
delay: 0, time: 0, lastTime: 0, endTime: 0,
|
delay: 0, time: 0, lastTime: -1, endTime: 0,
|
||||||
timeScale: 1,
|
timeScale: 1,
|
||||||
mixTime: 0, mixDuration: 0,
|
mixTime: 0, mixDuration: 0,
|
||||||
onStart: null, onEnd: null, onComplete: null, onEvent: null
|
onStart: null, onEnd: null, onComplete: null, onEvent: null
|
||||||
|
|||||||
@ -533,20 +533,21 @@ public class Animation {
|
|||||||
events[frameIndex] = event;
|
events[frameIndex] = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Fires events for frames > lastTime and <= time. */
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> firedEvents, float alpha) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> firedEvents, float alpha) {
|
||||||
if (firedEvents == null) return;
|
if (firedEvents == null) return;
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
int frameCount = frames.length;
|
int frameCount = frames.length;
|
||||||
|
|
||||||
if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
|
|
||||||
|
|
||||||
if (lastTime > time) { // Fire events after last time for looped animations.
|
if (lastTime > time) { // Fire events after last time for looped animations.
|
||||||
apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha);
|
apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha);
|
||||||
lastTime = 0;
|
lastTime = -1f;
|
||||||
}
|
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
||||||
|
return;
|
||||||
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
int frameIndex;
|
int frameIndex;
|
||||||
if (lastTime <= frames[0] || frameCount == 1)
|
if (lastTime < frames[0])
|
||||||
frameIndex = 0;
|
frameIndex = 0;
|
||||||
else {
|
else {
|
||||||
frameIndex = binarySearch(frames, lastTime, 1);
|
frameIndex = binarySearch(frames, lastTime, 1);
|
||||||
|
|||||||
@ -297,7 +297,7 @@ public class AnimationState {
|
|||||||
animation = null;
|
animation = null;
|
||||||
listener = null;
|
listener = null;
|
||||||
timeScale = 1;
|
timeScale = 1;
|
||||||
lastTime = 0;
|
lastTime = -1;
|
||||||
time = 0;
|
time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,198 @@
|
|||||||
|
|
||||||
|
package com.esotericsoftware.spine;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Animation.EventTimeline;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.StringBuilder;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/** Unit tests for {@link EventTimeline}. */
|
||||||
|
public class EventTimelineTests {
|
||||||
|
private final SkeletonData skeletonData;
|
||||||
|
private final Skeleton skeleton;
|
||||||
|
private final Array<Event> firedEvents = new Array();
|
||||||
|
private EventTimeline timeline = new EventTimeline(0);
|
||||||
|
private char[] events;
|
||||||
|
private float[] frames;
|
||||||
|
|
||||||
|
public EventTimelineTests () {
|
||||||
|
skeletonData = new SkeletonData();
|
||||||
|
skeleton = new Skeleton(skeletonData);
|
||||||
|
|
||||||
|
test(0);
|
||||||
|
test(1);
|
||||||
|
test(1, 1);
|
||||||
|
test(1, 2);
|
||||||
|
test(1, 2);
|
||||||
|
test(1, 2, 3);
|
||||||
|
test(1, 2, 3);
|
||||||
|
test(0, 0, 0);
|
||||||
|
test(0, 0, 1);
|
||||||
|
test(0, 1, 1);
|
||||||
|
test(1, 1, 1);
|
||||||
|
test(1, 2, 3, 4);
|
||||||
|
test(0, 2, 3, 4);
|
||||||
|
test(0, 2, 2, 4);
|
||||||
|
test(0, 0, 0, 0);
|
||||||
|
test(2, 2, 2, 2);
|
||||||
|
test(0.1f);
|
||||||
|
test(0.1f, 0.1f);
|
||||||
|
test(0.1f, 50f);
|
||||||
|
test(0.1f, 0.2f, 0.3f, 0.4f);
|
||||||
|
test(1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 11.01f, 12, 12, 12, 12);
|
||||||
|
|
||||||
|
System.out.println("All tests passed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void test (float... frames) {
|
||||||
|
int eventCount = frames.length;
|
||||||
|
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
for (int i = 0; i < eventCount; i++)
|
||||||
|
buffer.append((char)('a' + i));
|
||||||
|
|
||||||
|
this.events = buffer.toString().toCharArray();
|
||||||
|
this.frames = frames;
|
||||||
|
timeline = new EventTimeline(eventCount);
|
||||||
|
|
||||||
|
float maxFrame = 0;
|
||||||
|
int distinctCount = 0;
|
||||||
|
float lastFrame = -1;
|
||||||
|
for (int i = 0; i < eventCount; i++) {
|
||||||
|
float frame = frames[i];
|
||||||
|
Event event = new Event(new EventData("" + events[i]));
|
||||||
|
timeline.setFrame(i, frame, event);
|
||||||
|
maxFrame = Math.max(maxFrame, frame);
|
||||||
|
if (lastFrame != frame) distinctCount++;
|
||||||
|
lastFrame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
run(0, 99, 0.1f);
|
||||||
|
run(0, maxFrame, 0.1f);
|
||||||
|
run(frames[0], 999, 2f);
|
||||||
|
run(frames[0], maxFrame, 0.1f);
|
||||||
|
run(0, maxFrame, (float)Math.ceil(maxFrame / 100));
|
||||||
|
run(0, 99, 0.1f);
|
||||||
|
run(0, 999, 100f);
|
||||||
|
if (distinctCount > 1) {
|
||||||
|
float epsilon = 0.02f;
|
||||||
|
// Ending before last.
|
||||||
|
run(frames[0], maxFrame - epsilon, 0.1f);
|
||||||
|
run(0, maxFrame - epsilon, 0.1f);
|
||||||
|
// Starting after first.
|
||||||
|
run(frames[0] + epsilon, maxFrame, 0.1f);
|
||||||
|
run(frames[0] + epsilon, 99, 0.1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void run (float startTime, float endTime, float timeStep) {
|
||||||
|
timeStep = Math.max(timeStep, 0.00001f);
|
||||||
|
boolean loop = false;
|
||||||
|
try {
|
||||||
|
fire(startTime, endTime, timeStep, loop, false);
|
||||||
|
loop = true;
|
||||||
|
fire(startTime, endTime, timeStep, loop, false);
|
||||||
|
} catch (FailException ignored) {
|
||||||
|
try {
|
||||||
|
fire(startTime, endTime, timeStep, loop, true);
|
||||||
|
} catch (FailException ex) {
|
||||||
|
System.out.println(ex.getMessage());
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fire (float timeStart, float timeEnd, float timeStep, boolean loop, boolean print) {
|
||||||
|
if (print) {
|
||||||
|
System.out.println("events: " + Arrays.toString(events));
|
||||||
|
System.out.println("frames: " + Arrays.toString(frames));
|
||||||
|
System.out.println("timeStart: " + timeStart);
|
||||||
|
System.out.println("timeEnd: " + timeEnd);
|
||||||
|
System.out.println("timeStep: " + timeStep);
|
||||||
|
System.out.println("loop: " + loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected starting event.
|
||||||
|
int eventIndex = 0;
|
||||||
|
while (frames[eventIndex] < timeStart)
|
||||||
|
eventIndex++;
|
||||||
|
|
||||||
|
// Expected number of events when not looping.
|
||||||
|
int eventsCount = frames.length;
|
||||||
|
while (frames[eventsCount - 1] > timeEnd)
|
||||||
|
eventsCount--;
|
||||||
|
eventsCount -= eventIndex;
|
||||||
|
|
||||||
|
float duration = frames[eventIndex + eventsCount - 1];
|
||||||
|
if (loop && duration > 0) { // When looping timeStep can't be > nyquist.
|
||||||
|
while (timeStep > duration / 2f)
|
||||||
|
timeStep /= 2f;
|
||||||
|
}
|
||||||
|
// duration *= 2; // Everything should still pass with this uncommented.
|
||||||
|
|
||||||
|
firedEvents.clear();
|
||||||
|
int i = 0;
|
||||||
|
float lastTime = timeStart - 0.00001f;
|
||||||
|
float timeLooped, lastTimeLooped;
|
||||||
|
while (true) {
|
||||||
|
float time = Math.min(timeStart + timeStep * i, timeEnd);
|
||||||
|
lastTimeLooped = lastTime;
|
||||||
|
timeLooped = time;
|
||||||
|
if (loop && duration != 0) {
|
||||||
|
lastTimeLooped %= duration;
|
||||||
|
timeLooped %= duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
int beforeCount = firedEvents.size;
|
||||||
|
Array<Event> original = new Array(firedEvents);
|
||||||
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, firedEvents, 1);
|
||||||
|
|
||||||
|
while (beforeCount < firedEvents.size) {
|
||||||
|
char fired = firedEvents.get(beforeCount).getData().getName().charAt(0);
|
||||||
|
if (loop) {
|
||||||
|
eventIndex %= events.length;
|
||||||
|
} else {
|
||||||
|
if (firedEvents.size > eventsCount) {
|
||||||
|
if (print) System.out.println(lastTimeLooped + "->" + timeLooped + ": " + fired + " == ?");
|
||||||
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, original, 1);
|
||||||
|
fail("Too many events fired.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (print) {
|
||||||
|
System.out.println(lastTimeLooped + "->" + timeLooped + ": " + fired + " == " + events[eventIndex]);
|
||||||
|
}
|
||||||
|
if (fired != events[eventIndex]) {
|
||||||
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, original, 1);
|
||||||
|
fail("Wrong event fired.");
|
||||||
|
}
|
||||||
|
eventIndex++;
|
||||||
|
beforeCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time >= timeEnd) break;
|
||||||
|
lastTime = time;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (firedEvents.size < eventsCount) {
|
||||||
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, firedEvents, 1);
|
||||||
|
if (print) System.out.println(firedEvents);
|
||||||
|
fail("Event not fired: " + events[eventIndex] + ", " + frames[eventIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fail (String message) {
|
||||||
|
throw new FailException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FailException extends RuntimeException {
|
||||||
|
public FailException (String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public void main (String[] args) throws Exception {
|
||||||
|
new EventTimelineTests();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -463,21 +463,23 @@ function Animation.EventTimeline.new ()
|
|||||||
self.events[frameIndex] = event
|
self.events[frameIndex] = event
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Fires events for frames > lastTime and <= time.
|
||||||
function self:apply (skeleton, lastTime, time, firedEvents, alpha)
|
function self:apply (skeleton, lastTime, time, firedEvents, alpha)
|
||||||
if not firedEvents then return end
|
if not firedEvents then return end
|
||||||
|
|
||||||
local frames = self.frames
|
local frames = self.frames
|
||||||
local frameCount = #frames
|
local frameCount = #frames
|
||||||
if lastTime >= frames[frameCount] then return end -- Last time is after last frame.
|
|
||||||
frameCount = frameCount + 1
|
|
||||||
|
|
||||||
if lastTime > time then -- Fire events after last time for looped animations.
|
if lastTime > time then -- Fire events after last time for looped animations.
|
||||||
self:apply(skeleton, lastTime, 999999, firedEvents, alpha)
|
self:apply(skeleton, lastTime, 999999, firedEvents, alpha)
|
||||||
lastTime = 0
|
lastTime = -1
|
||||||
|
elseif lastTime >= frames[frameCount - 1] then -- Last time is after last frame.
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
if time < frames[0] then return end -- Time is before first frame.
|
||||||
|
|
||||||
local frameIndex
|
local frameIndex
|
||||||
if lastTime <= frames[0] or frameCount == 1 then
|
if lastTime < frames[0] then
|
||||||
frameIndex = 0
|
frameIndex = 0
|
||||||
else
|
else
|
||||||
frameIndex = binarySearch(frames, lastTime, 1)
|
frameIndex = binarySearch(frames, lastTime, 1)
|
||||||
|
|||||||
@ -225,7 +225,7 @@ function AnimationState.TrackEntry.new (data)
|
|||||||
next = nil, previous = nil,
|
next = nil, previous = nil,
|
||||||
animation = nil,
|
animation = nil,
|
||||||
loop = false,
|
loop = false,
|
||||||
delay = 0, time = 0, lastTime = 0, endTime = 0,
|
delay = 0, time = 0, lastTime = -1, endTime = 0,
|
||||||
timeScale = 1,
|
timeScale = 1,
|
||||||
mixTime = 0, mixDuration = 0,
|
mixTime = 0, mixDuration = 0,
|
||||||
onStart = nil, onEnd = nil, onComplete = nil, onEvent = nil
|
onStart = nil, onEnd = nil, onComplete = nil, onEvent = nil
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user