mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Fixed AttachmentTimeline from missing first key.
http://esotericsoftware.com/forum/viewtopic.php?p=16600#p16600
This commit is contained in:
parent
7aadd9bce7
commit
e5d3d380c7
@ -53,14 +53,15 @@ public class AttachmentTimeline implements Timeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 (time < frames[0])
|
var frames:Vector.<Number> = this.frames;
|
||||||
return; // Time is before first frame.
|
if (time < frames[0]) {
|
||||||
|
if (lastTime > time) apply(skeleton, lastTime, int.MAX_VALUE, null, 0);
|
||||||
|
return;
|
||||||
|
} else if (lastTime > time) //
|
||||||
|
lastTime = -1;
|
||||||
|
|
||||||
var frameIndex:int;
|
var frameIndex:int = time >= frames[frames.length - 1] ? frames.length - 1 : Animation.binarySearch1(frames, time) - 1;
|
||||||
if (time >= frames[int(frames.length - 1)]) // Time is after last frame.
|
if (frames[frameIndex] < lastTime) return;
|
||||||
frameIndex = frames.length - 1;
|
|
||||||
else
|
|
||||||
frameIndex = Animation.binarySearch(frames, time, 1) - 1;
|
|
||||||
|
|
||||||
var attachmentName:String = attachmentNames[frameIndex];
|
var attachmentName:String = attachmentNames[frameIndex];
|
||||||
skeleton.slots[slotIndex].attachment = attachmentName == null ? null : skeleton.getAttachmentForSlotIndex(slotIndex, attachmentName);
|
skeleton.slots[slotIndex].attachment = attachmentName == null ? null : skeleton.getAttachmentForSlotIndex(slotIndex, attachmentName);
|
||||||
|
|||||||
@ -479,7 +479,7 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
|
|||||||
|
|
||||||
frameIndex = time >= self->frames[self->framesCount - 1] ?
|
frameIndex = time >= self->frames[self->framesCount - 1] ?
|
||||||
self->framesCount - 1 : binarySearch1(self->frames, self->framesCount, time) - 1;
|
self->framesCount - 1 : binarySearch1(self->frames, self->framesCount, time) - 1;
|
||||||
if (self->frames[frameIndex] <= lastTime) return;
|
if (self->frames[frameIndex] < lastTime) return;
|
||||||
|
|
||||||
attachmentName = self->attachmentNames[frameIndex];
|
attachmentName = self->attachmentNames[frameIndex];
|
||||||
spSlot_setAttachment(skeleton->slots[self->slotIndex],
|
spSlot_setAttachment(skeleton->slots[self->slotIndex],
|
||||||
|
|||||||
@ -444,7 +444,7 @@ namespace Spine {
|
|||||||
lastTime = -1;
|
lastTime = -1;
|
||||||
|
|
||||||
int frameIndex = time >= frames[frames.Length - 1] ? frames.Length - 1 : Animation.binarySearch(frames, time) - 1;
|
int frameIndex = time >= frames[frames.Length - 1] ? frames.Length - 1 : Animation.binarySearch(frames, time) - 1;
|
||||||
if (frames[frameIndex] <= lastTime) return;
|
if (frames[frameIndex] < lastTime) return;
|
||||||
|
|
||||||
String attachmentName = attachmentNames[frameIndex];
|
String attachmentName = attachmentNames[frameIndex];
|
||||||
skeleton.slots[slotIndex].Attachment =
|
skeleton.slots[slotIndex].Attachment =
|
||||||
|
|||||||
@ -86,8 +86,8 @@ public class Animation {
|
|||||||
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
|
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
|
||||||
|
|
||||||
if (loop && duration != 0) {
|
if (loop && duration != 0) {
|
||||||
lastTime %= duration;
|
|
||||||
time %= duration;
|
time %= duration;
|
||||||
|
lastTime %= duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<Timeline> timelines = this.timelines;
|
Array<Timeline> timelines = this.timelines;
|
||||||
@ -468,8 +468,8 @@ public class Animation {
|
|||||||
|
|
||||||
static public class AttachmentTimeline implements Timeline {
|
static public class AttachmentTimeline implements Timeline {
|
||||||
int slotIndex;
|
int slotIndex;
|
||||||
private final float[] frames; // time, ...
|
final float[] frames; // time, ...
|
||||||
private final String[] attachmentNames;
|
final String[] attachmentNames;
|
||||||
|
|
||||||
public AttachmentTimeline (int frameCount) {
|
public AttachmentTimeline (int frameCount) {
|
||||||
frames = new float[frameCount];
|
frames = new float[frameCount];
|
||||||
@ -511,7 +511,7 @@ public class Animation {
|
|||||||
lastTime = -1;
|
lastTime = -1;
|
||||||
|
|
||||||
int frameIndex = (time >= frames[frames.length - 1] ? frames.length : binarySearch(frames, time)) - 1;
|
int frameIndex = (time >= frames[frames.length - 1] ? frames.length : binarySearch(frames, time)) - 1;
|
||||||
if (frames[frameIndex] <= lastTime) return;
|
if (frames[frameIndex] < lastTime) return;
|
||||||
|
|
||||||
String attachmentName = attachmentNames[frameIndex];
|
String attachmentName = attachmentNames[frameIndex];
|
||||||
skeleton.slots.get(slotIndex).setAttachment(
|
skeleton.slots.get(slotIndex).setAttachment(
|
||||||
|
|||||||
@ -304,7 +304,7 @@ public class AnimationState {
|
|||||||
TrackEntry next, previous;
|
TrackEntry next, previous;
|
||||||
Animation animation;
|
Animation animation;
|
||||||
boolean loop;
|
boolean loop;
|
||||||
float delay, time, lastTime, endTime, timeScale = 1;
|
float delay, time, lastTime = -1, endTime, timeScale = 1;
|
||||||
float mixTime, mixDuration;
|
float mixTime, mixDuration;
|
||||||
AnimationStateListener listener;
|
AnimationStateListener listener;
|
||||||
float mix = 1;
|
float mix = 1;
|
||||||
|
|||||||
@ -0,0 +1,101 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes Software License
|
||||||
|
* Version 2.1
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Esoteric Software
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||||
|
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||||
|
* Software (the "Software") solely for internal use. Without the written
|
||||||
|
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||||
|
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||||
|
* improvements of the Software or develop new applications using the Software
|
||||||
|
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||||
|
* trademark, patent or other intellectual property or proprietary rights
|
||||||
|
* notices on or in the Software, including any copy thereof. Redistributions
|
||||||
|
* in binary or source form must include this license and terms.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
package com.esotericsoftware.spine;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.esotericsoftware.spine.Animation.AttachmentTimeline;
|
||||||
|
import com.esotericsoftware.spine.Animation.Timeline;
|
||||||
|
import com.esotericsoftware.spine.attachments.Attachment;
|
||||||
|
|
||||||
|
/** Unit tests for {@link AttachmentTimeline}. */
|
||||||
|
public class AttachmentTimelineTests {
|
||||||
|
private final SkeletonData skeletonData;
|
||||||
|
private final Skeleton skeleton;
|
||||||
|
private Slot slot;
|
||||||
|
private AnimationState state;
|
||||||
|
|
||||||
|
public AttachmentTimelineTests () {
|
||||||
|
skeletonData = new SkeletonData();
|
||||||
|
|
||||||
|
BoneData boneData = new BoneData("bone", null);
|
||||||
|
skeletonData.getBones().add(boneData);
|
||||||
|
|
||||||
|
skeletonData.getSlots().add(new SlotData("slot", boneData));
|
||||||
|
|
||||||
|
Attachment attachment1 = new Attachment("attachment1") {};
|
||||||
|
Attachment attachment2 = new Attachment("attachment2") {};
|
||||||
|
|
||||||
|
Skin skin = new Skin("skin");
|
||||||
|
skin.addAttachment(0, "attachment1", attachment1);
|
||||||
|
skin.addAttachment(0, "attachment2", attachment2);
|
||||||
|
skeletonData.setDefaultSkin(skin);
|
||||||
|
|
||||||
|
skeleton = new Skeleton(skeletonData);
|
||||||
|
slot = skeleton.findSlot("slot");
|
||||||
|
|
||||||
|
AttachmentTimeline timeline = new AttachmentTimeline(2);
|
||||||
|
timeline.setFrame(0, 0, "attachment1");
|
||||||
|
timeline.setFrame(1, 0.5f, "attachment2");
|
||||||
|
|
||||||
|
Animation animation = new Animation("animation", Array.with((Timeline)timeline), 1);
|
||||||
|
animation.setDuration(1);
|
||||||
|
|
||||||
|
state = new AnimationState(new AnimationStateData(skeletonData));
|
||||||
|
state.setAnimation(0, animation, true);
|
||||||
|
|
||||||
|
test(0, attachment1);
|
||||||
|
test(0, attachment1);
|
||||||
|
test(0.25f, attachment1);
|
||||||
|
test(0f, attachment1);
|
||||||
|
test(0.25f, attachment2);
|
||||||
|
test(0.25f, attachment2);
|
||||||
|
|
||||||
|
System.out.println("AttachmentTimeline tests passed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void test (float delta, Attachment attachment) {
|
||||||
|
state.update(delta);
|
||||||
|
state.apply(skeleton);
|
||||||
|
if (slot.getAttachment() != attachment)
|
||||||
|
throw new FailException("Wrong attachment: " + slot.getAttachment() + " != " + attachment);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FailException extends RuntimeException {
|
||||||
|
public FailException (String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public void main (String[] args) throws Exception {
|
||||||
|
new AttachmentTimelineTests();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -72,7 +72,7 @@ public class EventTimelineTests {
|
|||||||
test(0.1f, 0.2f, 0.3f, 0.4f);
|
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);
|
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.");
|
System.out.println("EventTimeline tests passed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void test (float... frames) {
|
private void test (float... frames) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user