From 308e18b376bbd364ba55dd97bb6dac78d2bddcf0 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Sun, 29 Sep 2013 22:51:08 +0200 Subject: [PATCH] Fixed event timeline missing first event. --- spine-c/src/spine/Animation.c | 23 +++++++++---------- spine-csharp/src/Animation.cs | 20 ++++++++-------- .../com/esotericsoftware/spine/Animation.java | 21 ++++++++--------- .../spine/AnimationStateTest.java | 4 ++-- spine-sfml/example/main.cpp | 2 +- .../Assets/examples/spineboy/Spineboy.cs | 7 ++++++ .../examples/spineboy/spineboy.json.txt | 10 ++++---- 7 files changed, 46 insertions(+), 41 deletions(-) diff --git a/spine-c/src/spine/Animation.c b/spine-c/src/spine/Animation.c index f7dce43a9..b1c00f9ed 100644 --- a/spine-c/src/spine/Animation.c +++ b/spine-c/src/spine/Animation.c @@ -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) { diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index 21195ad9f..292d51825 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -471,26 +471,24 @@ namespace Spine { public void Apply (Skeleton skeleton, float lastTime, float time, List 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--; } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index 3705528ab..e10f8b3cb 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -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 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) { diff --git a/spine-libgdx/test/com/esotericsoftware/spine/AnimationStateTest.java b/spine-libgdx/test/com/esotericsoftware/spine/AnimationStateTest.java index e5c7fe9a9..1fa0e325f 100644 --- a/spine-libgdx/test/com/esotericsoftware/spine/AnimationStateTest.java +++ b/spine-libgdx/test/com/esotericsoftware/spine/AnimationStateTest.java @@ -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); diff --git a/spine-sfml/example/main.cpp b/spine-sfml/example/main.cpp index 223a95b14..b36ed1867 100644 --- a/spine-sfml/example/main.cpp +++ b/spine-sfml/example/main.cpp @@ -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); diff --git a/spine-tk2d/Assets/examples/spineboy/Spineboy.cs b/spine-tk2d/Assets/examples/spineboy/Spineboy.cs index 14168e2c7..ba261ba3f 100644 --- a/spine-tk2d/Assets/examples/spineboy/Spineboy.cs +++ b/spine-tk2d/Assets/examples/spineboy/Spineboy.cs @@ -34,14 +34,21 @@ using UnityEngine; using System.Collections; using Spine; +using System; public class Spineboy : MonoBehaviour { private SkeletonAnimation skeleton; void Start() { skeleton = GetComponent(); + + skeleton.state.Event += new EventHandler(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; diff --git a/spine-tk2d/Assets/examples/spineboy/spineboy.json.txt b/spine-tk2d/Assets/examples/spineboy/spineboy.json.txt index 113e72c33..2131b9fad 100644 --- a/spine-tk2d/Assets/examples/spineboy/spineboy.json.txt +++ b/spine-tk2d/Assets/examples/spineboy/spineboy.json.txt @@ -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": [ {