Fixed event timeline missing first event.

This commit is contained in:
NathanSweet 2013-09-29 22:51:08 +02:00
parent 5390d40093
commit 308e18b376
7 changed files with 46 additions and 41 deletions

View File

@ -515,23 +515,22 @@ void AttachmentTimeline_setFrame (AttachmentTimeline* self, int frameIndex, floa
void _EventTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float lastTime, float time, Event** firedEvents,
int* eventCount, float alpha) {
int frameIndex;
EventTimeline* self = (EventTimeline*)timeline;
int frameIndex;
if (time < self->frames[0]) return; /* Time is before first 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;
}
if (self->framesLength == 1)
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) {

View File

@ -471,26 +471,24 @@ namespace Spine {
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame.
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.
Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha);
lastTime = 0;
}
int frameIndex;
if (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 the same frame and events that occurred at lastTime.
// Fire multiple events with same frame and events that occurred at lastTime.
if (lastFrame != frame && lastFrame != lastTime) break;
frameIndex--;
}

View File

@ -114,7 +114,8 @@ public class Animation {
return name;
}
/** @param target After the first and before the last entry. */
/** @param target After the first and before the last value.
* @return index of first value greater than the target. */
static int binarySearch (float[] values, float target, int step) {
int low = 0;
int high = values.length / step - 2;
@ -544,21 +545,19 @@ public class Animation {
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> firedEvents, float alpha) {
float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame.
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.
apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha);
lastTime = 0;
}
int frameIndex;
if (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) {

View File

@ -85,7 +85,7 @@ public class AnimationStateTest extends ApplicationAdapter {
System.out.println(trackIndex + " end: " + state.getCurrent(trackIndex));
}
});
state.setAnimation(0, "walk", true);
state.setAnimation(0, "drawOrder", true);
skeleton = new Skeleton(skeletonData);
skeleton.setX(250);
@ -110,7 +110,7 @@ public class AnimationStateTest extends ApplicationAdapter {
}
public void render () {
state.update(Gdx.graphics.getDeltaTime() / 3);
state.update(Gdx.graphics.getDeltaTime());
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

View File

@ -95,7 +95,7 @@ void spineboy () {
Slot* headSlot = Skeleton_findSlot(skeleton, "head");
drawable->state->listener = callback;
if (false) {
if (true) {
AnimationState_setAnimationByName(drawable->state, 0, "drawOrder", true);
} else {
AnimationState_setAnimationByName(drawable->state, 0, "walk", true);

View File

@ -34,14 +34,21 @@
using UnityEngine;
using System.Collections;
using Spine;
using System;
public class Spineboy : MonoBehaviour {
private SkeletonAnimation skeleton;
void Start() {
skeleton = GetComponent<SkeletonAnimation>();
skeleton.state.Event += new EventHandler<EventTriggeredArgs>(Event);
}
public void Event (object sender, EventTriggeredArgs e) {
Debug.Log(e.TrackIndex + " " + skeleton.state.GetCurrent(e.TrackIndex) + ": event " + e.Event + ", " + e.Event.Int);
}
void LateUpdate() {
if (skeleton.loop) return;

View File

@ -280,10 +280,12 @@
}
},
"events": [
{ "time": 0, "name": "headPop", "string": "pop.wav" },
{ "time": 1.3103, "name": "behind" },
{ "time": 2.9655, "name": "behind" },
{ "time": 4, "name": "headAttach", "string": "attach.wav" }
{ "time": 0.3333, "name": "headPop", "int": 1 },
{ "time": 0.5, "name": "headPop", "int": 2 },
{ "time": 0.6666, "name": "headPop", "int": 3 },
{ "time": 0.8333, "name": "headPop", "int": 4 },
{ "time": 1, "name": "headPop", "int": 5 },
{ "time": 1.1666, "name": "headPop", "int": 6 }
],
"draworder": [
{