mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-22 02:06:03 +08:00
Added mixingOut parameter to Timeline#apply so timelines know which direction mixing is happening.
See ScaleTimeline which uses this to know which scale sign to use.
This commit is contained in:
parent
b4924b0a49
commit
280024a685
@ -65,7 +65,7 @@ public class BonePlotting {
|
|||||||
for (Animation animation : skeletonData.getAnimations()) {
|
for (Animation animation : skeletonData.getAnimations()) {
|
||||||
float time = 0;
|
float time = 0;
|
||||||
while (time < animation.getDuration()) {
|
while (time < animation.getDuration()) {
|
||||||
animation.apply(skeleton, time, time, false, null, 1, false);
|
animation.apply(skeleton, time, time, false, null, 1, false, false);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform();
|
||||||
System.out
|
System.out
|
||||||
.println(animation.getName() + "," + bone.getWorldX() + "," + bone.getWorldY() + "," + bone.getWorldRotationX());
|
.println(animation.getName() + "," + bone.getWorldX() + "," + bone.getWorldY() + "," + bone.getWorldRotationX());
|
||||||
|
|||||||
@ -145,7 +145,7 @@ public class Box2DExample extends ApplicationAdapter {
|
|||||||
batch.setTransformMatrix(camera.view);
|
batch.setTransformMatrix(camera.view);
|
||||||
batch.begin();
|
batch.begin();
|
||||||
|
|
||||||
animation.apply(skeleton, time, time, true, events, 1, false);
|
animation.apply(skeleton, time, time, true, events, 1, false, false);
|
||||||
skeleton.x += 8 * delta;
|
skeleton.x += 8 * delta;
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform();
|
||||||
skeletonRenderer.draw(batch, skeleton);
|
skeletonRenderer.draw(batch, skeleton);
|
||||||
|
|||||||
@ -177,7 +177,7 @@ public class EventTimelineTests {
|
|||||||
|
|
||||||
int beforeCount = firedEvents.size;
|
int beforeCount = firedEvents.size;
|
||||||
Array<Event> original = new Array(firedEvents);
|
Array<Event> original = new Array(firedEvents);
|
||||||
timeline.apply(skeleton, lastTimeLooped, timeLooped, firedEvents, 1, false);
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, firedEvents, 1, false, false);
|
||||||
|
|
||||||
while (beforeCount < firedEvents.size) {
|
while (beforeCount < firedEvents.size) {
|
||||||
char fired = firedEvents.get(beforeCount).getData().getName().charAt(0);
|
char fired = firedEvents.get(beforeCount).getData().getName().charAt(0);
|
||||||
@ -186,7 +186,7 @@ public class EventTimelineTests {
|
|||||||
} else {
|
} else {
|
||||||
if (firedEvents.size > eventsCount) {
|
if (firedEvents.size > eventsCount) {
|
||||||
if (print) System.out.println(lastTimeLooped + "->" + timeLooped + ": " + fired + " == ?");
|
if (print) System.out.println(lastTimeLooped + "->" + timeLooped + ": " + fired + " == ?");
|
||||||
timeline.apply(skeleton, lastTimeLooped, timeLooped, original, 1, false);
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, original, 1, false, false);
|
||||||
fail("Too many events fired.");
|
fail("Too many events fired.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ public class EventTimelineTests {
|
|||||||
System.out.println(lastTimeLooped + "->" + timeLooped + ": " + fired + " == " + events[eventIndex]);
|
System.out.println(lastTimeLooped + "->" + timeLooped + ": " + fired + " == " + events[eventIndex]);
|
||||||
}
|
}
|
||||||
if (fired != events[eventIndex]) {
|
if (fired != events[eventIndex]) {
|
||||||
timeline.apply(skeleton, lastTimeLooped, timeLooped, original, 1, false);
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, original, 1, false, false);
|
||||||
fail("Wrong event fired.");
|
fail("Wrong event fired.");
|
||||||
}
|
}
|
||||||
eventIndex++;
|
eventIndex++;
|
||||||
@ -206,7 +206,7 @@ public class EventTimelineTests {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (firedEvents.size < eventsCount) {
|
if (firedEvents.size < eventsCount) {
|
||||||
timeline.apply(skeleton, lastTimeLooped, timeLooped, firedEvents, 1, false);
|
timeline.apply(skeleton, lastTimeLooped, timeLooped, firedEvents, 1, false, false);
|
||||||
if (print) System.out.println(firedEvents);
|
if (print) System.out.println(firedEvents);
|
||||||
fail("Event not fired: " + events[eventIndex] + ", " + frames[eventIndex]);
|
fail("Event not fired: " + events[eventIndex] + ", " + frames[eventIndex]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,22 +104,21 @@ public class MixTest extends ApplicationAdapter {
|
|||||||
skeleton.setX(-50);
|
skeleton.setX(-50);
|
||||||
} else if (time > beforeJump + jump) {
|
} else if (time > beforeJump + jump) {
|
||||||
// just walk after jump
|
// just walk after jump
|
||||||
walkAnimation.apply(skeleton, time, time, true, events, 1, false);
|
walkAnimation.apply(skeleton, time, time, true, events, 1, false, false);
|
||||||
} else if (time > blendOutStart) {
|
} else if (time > blendOutStart) {
|
||||||
// blend out jump
|
// blend out jump
|
||||||
walkAnimation.apply(skeleton, time, time, true, events, 1, false);
|
walkAnimation.apply(skeleton, time, time, true, events, 1, false, false);
|
||||||
jumpAnimation.apply(skeleton, time - beforeJump, time - beforeJump, false, events, 1 - (time - blendOutStart) / blendOut,
|
jumpAnimation.apply(skeleton, time - beforeJump, time - beforeJump, false, events, 1 - (time - blendOutStart) / blendOut, false, false);
|
||||||
false);
|
|
||||||
} else if (time > beforeJump + blendIn) {
|
} else if (time > beforeJump + blendIn) {
|
||||||
// just jump
|
// just jump
|
||||||
jumpAnimation.apply(skeleton, time - beforeJump, time - beforeJump, false, events, 1, false);
|
jumpAnimation.apply(skeleton, time - beforeJump, time - beforeJump, false, events, 1, false, false);
|
||||||
} else if (time > beforeJump) {
|
} else if (time > beforeJump) {
|
||||||
// blend in jump
|
// blend in jump
|
||||||
walkAnimation.apply(skeleton, time, time, true, events, 1, false);
|
walkAnimation.apply(skeleton, time, time, true, events, 1, false, false);
|
||||||
jumpAnimation.apply(skeleton, time - beforeJump, time - beforeJump, false, events, (time - beforeJump) / blendIn, false);
|
jumpAnimation.apply(skeleton, time - beforeJump, time - beforeJump, false, events, (time - beforeJump) / blendIn, false, false);
|
||||||
} else {
|
} else {
|
||||||
// just walk before jump
|
// just walk before jump
|
||||||
walkAnimation.apply(skeleton, time, time, true, events, 1, false);
|
walkAnimation.apply(skeleton, time, time, true, events, 1, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform();
|
||||||
|
|||||||
@ -131,7 +131,7 @@ public class NormalMapTest extends ApplicationAdapter {
|
|||||||
public void render () {
|
public void render () {
|
||||||
float lastTime = time;
|
float lastTime = time;
|
||||||
time += Gdx.graphics.getDeltaTime();
|
time += Gdx.graphics.getDeltaTime();
|
||||||
if (animation != null) animation.apply(skeleton, lastTime, time, true, null, 1, false);
|
if (animation != null) animation.apply(skeleton, lastTime, time, true, null, 1, false, false);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform();
|
||||||
skeleton.update(Gdx.graphics.getDeltaTime());
|
skeleton.update(Gdx.graphics.getDeltaTime());
|
||||||
|
|
||||||
|
|||||||
@ -67,11 +67,13 @@ public class Animation {
|
|||||||
/** Poses the skeleton at the specified time for this animation mixed with the current or setup pose.
|
/** Poses the skeleton at the specified time for this animation mixed with the current or setup pose.
|
||||||
* @param lastTime The last time the animation was applied.
|
* @param lastTime The last time the animation was applied.
|
||||||
* @param events Any triggered events are added. May be null.
|
* @param events Any triggered events are added. May be null.
|
||||||
* @param alpha The amount of this animation that affects the current pose.
|
* @param alpha The percentage between this animation's pose and the current pose.
|
||||||
* @param setupPose If true, the animation is mixed with the setup pose, else it is mixed with the current pose. Pass true when
|
* @param setupPose If true, the animation is mixed with the setup pose, else it is mixed with the current pose. Passing true
|
||||||
* alpha is 1. */
|
* when alpha is 1 is slightly more efficient.
|
||||||
|
* @param mixingOut True when mixing over time toward the setup or current pose, false when mixing toward the keyed pose.
|
||||||
|
* Irrelevant when alpha is 1. */
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, boolean loop, Array<Event> events, float alpha,
|
public void apply (Skeleton skeleton, float lastTime, float time, boolean loop, Array<Event> events, float alpha,
|
||||||
boolean setupPose) {
|
boolean setupPose, boolean mixingOut) {
|
||||||
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) {
|
||||||
@ -81,7 +83,7 @@ public class Animation {
|
|||||||
|
|
||||||
Array<Timeline> timelines = this.timelines;
|
Array<Timeline> timelines = this.timelines;
|
||||||
for (int i = 0, n = timelines.size; i < n; i++)
|
for (int i = 0, n = timelines.size; i < n; i++)
|
||||||
timelines.get(i).apply(skeleton, lastTime, time, events, alpha, setupPose);
|
timelines.get(i).apply(skeleton, lastTime, time, events, alpha, setupPose, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName () {
|
public String getName () {
|
||||||
@ -135,9 +137,12 @@ public class Animation {
|
|||||||
static public interface Timeline {
|
static public interface Timeline {
|
||||||
/** Sets the value(s) for the specified time.
|
/** Sets the value(s) for the specified time.
|
||||||
* @param events May be null to not collect fired events.
|
* @param events May be null to not collect fired events.
|
||||||
* @param setupPose If true, the timeline is mixed with the setup pose, else it is mixed with the current pose. Pass true
|
* @param setupPose If true, the timeline is mixed with the setup pose, else it is mixed with the current pose. Passing true
|
||||||
* when alpha is 1. */
|
* when alpha is 1 is slightly more efficient.
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose);
|
* @param mixingOut True when mixing over time toward the setup or current pose, false when mixing toward the keyed pose.
|
||||||
|
* Irrelevant when alpha is 1. */
|
||||||
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut);
|
||||||
|
|
||||||
public int getId ();
|
public int getId ();
|
||||||
}
|
}
|
||||||
@ -274,9 +279,11 @@ public class Animation {
|
|||||||
frames[frameIndex + ROTATION] = degrees;
|
frames[frameIndex + ROTATION] = degrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
Bone bone = skeleton.bones.get(boneIndex);
|
Bone bone = skeleton.bones.get(boneIndex);
|
||||||
|
|
||||||
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
||||||
@ -297,13 +304,13 @@ public class Animation {
|
|||||||
float percent = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
float percent = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||||
|
|
||||||
float amount = frames[frame + ROTATION] - prevRotation;
|
float amount = frames[frame + ROTATION] - prevRotation;
|
||||||
amount = amount - (16384 - (int)(16384.499999999996 - amount / 360)) * 360;
|
amount -= (16384 - (int)(16384.499999999996 - amount / 360)) * 360;
|
||||||
if (setupPose) {
|
|
||||||
amount = prevRotation + amount * percent;
|
amount = prevRotation + amount * percent;
|
||||||
amount = amount - (16384 - (int)(16384.499999999996 - amount / 360)) * 360;
|
if (setupPose) {
|
||||||
|
amount -= (16384 - (int)(16384.499999999996 - amount / 360)) * 360;
|
||||||
bone.rotation = bone.data.rotation + amount * alpha;
|
bone.rotation = bone.data.rotation + amount * alpha;
|
||||||
} else {
|
} else {
|
||||||
amount = bone.data.rotation + (prevRotation + amount * percent) - bone.rotation;
|
amount = bone.data.rotation + amount - bone.rotation;
|
||||||
amount -= (16384 - (int)(16384.499999999996 - amount / 360)) * 360;
|
amount -= (16384 - (int)(16384.499999999996 - amount / 360)) * 360;
|
||||||
bone.rotation += amount * alpha;
|
bone.rotation += amount * alpha;
|
||||||
}
|
}
|
||||||
@ -348,36 +355,35 @@ public class Animation {
|
|||||||
frames[frameIndex + Y] = y;
|
frames[frameIndex + Y] = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
Bone bone = skeleton.bones.get(boneIndex);
|
Bone bone = skeleton.bones.get(boneIndex);
|
||||||
|
|
||||||
|
float x, y;
|
||||||
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
||||||
if (setupPose) {
|
x = frames[frames.length + PREV_X];
|
||||||
bone.x = bone.data.x + frames[frames.length + PREV_X] * alpha;
|
y = frames[frames.length + PREV_Y];
|
||||||
bone.y = bone.data.y + frames[frames.length + PREV_Y] * alpha;
|
|
||||||
} else {
|
} else {
|
||||||
bone.x += (bone.data.x + frames[frames.length + PREV_X] - bone.x) * alpha;
|
|
||||||
bone.y += (bone.data.y + frames[frames.length + PREV_Y] - bone.y) * alpha;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interpolate between the previous frame and the current frame.
|
// Interpolate between the previous frame and the current frame.
|
||||||
int frame = binarySearch(frames, time, ENTRIES);
|
int frame = binarySearch(frames, time, ENTRIES);
|
||||||
float prevX = frames[frame + PREV_X];
|
float prevX = frames[frame + PREV_X];
|
||||||
float prevY = frames[frame + PREV_Y];
|
float prevY = frames[frame + PREV_Y];
|
||||||
float frameTime = frames[frame];
|
float frameTime = frames[frame];
|
||||||
float percent = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||||
|
1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||||
|
|
||||||
|
x = prevX + (frames[frame + X] - prevX) * percent;
|
||||||
|
y = prevY + (frames[frame + Y] - prevY) * percent;
|
||||||
|
}
|
||||||
if (setupPose) {
|
if (setupPose) {
|
||||||
bone.x = bone.data.x + (prevX + (frames[frame + X] - prevX) * percent) * alpha;
|
bone.x = bone.data.x + x * alpha;
|
||||||
bone.y = bone.data.y + (prevY + (frames[frame + Y] - prevY) * percent) * alpha;
|
bone.y = bone.data.y + y * alpha;
|
||||||
} else {
|
} else {
|
||||||
bone.x += (bone.data.x + prevX + (frames[frame + X] - prevX) * percent - bone.x) * alpha;
|
bone.x += (bone.data.x + x - bone.x) * alpha;
|
||||||
bone.y += (bone.data.y + prevY + (frames[frame + Y] - prevY) * percent - bone.y) * alpha;
|
bone.y += (bone.data.y + y - bone.y) * alpha;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,11 +397,13 @@ public class Animation {
|
|||||||
return (TimelineType.scale.ordinal() << 24) + boneIndex;
|
return (TimelineType.scale.ordinal() << 24) + boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
Bone bone = skeleton.bones.get(boneIndex);
|
Bone bone = skeleton.bones.get(boneIndex);
|
||||||
|
|
||||||
float x, y;
|
float x, y;
|
||||||
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
||||||
x = frames[frames.length + PREV_X];
|
x = frames[frames.length + PREV_X];
|
||||||
@ -418,7 +426,22 @@ public class Animation {
|
|||||||
bone.scaleX = x;
|
bone.scaleX = x;
|
||||||
bone.scaleY = y;
|
bone.scaleY = y;
|
||||||
} else {
|
} else {
|
||||||
float bx = Math.abs(bone.scaleX) * Math.signum(x), by = Math.abs(bone.scaleY) * Math.signum(y);
|
float bx, by;
|
||||||
|
if (setupPose) {
|
||||||
|
bx = bone.data.scaleX;
|
||||||
|
by = bone.data.scaleY;
|
||||||
|
} else {
|
||||||
|
bx = bone.scaleX;
|
||||||
|
by = bone.scaleY;
|
||||||
|
}
|
||||||
|
// Mixing out uses sign of setup or current pose, else use sign of key.
|
||||||
|
if (mixingOut) {
|
||||||
|
x = Math.abs(x) * Math.signum(bx);
|
||||||
|
y = Math.abs(y) * Math.signum(by);
|
||||||
|
} else {
|
||||||
|
bx = Math.abs(bx) * Math.signum(x);
|
||||||
|
by = Math.abs(by) * Math.signum(y);
|
||||||
|
}
|
||||||
bone.scaleX = bx + (x - bx) * alpha;
|
bone.scaleX = bx + (x - bx) * alpha;
|
||||||
bone.scaleY = by + (y - by) * alpha;
|
bone.scaleY = by + (y - by) * alpha;
|
||||||
}
|
}
|
||||||
@ -434,7 +457,8 @@ public class Animation {
|
|||||||
return (TimelineType.shear.ordinal() << 24) + boneIndex;
|
return (TimelineType.shear.ordinal() << 24) + boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -497,7 +521,8 @@ public class Animation {
|
|||||||
frames[frameIndex + A] = a;
|
frames[frameIndex + A] = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -573,7 +598,8 @@ public class Animation {
|
|||||||
attachmentNames[frameIndex] = attachmentName;
|
attachmentNames[frameIndex] = attachmentName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -636,8 +662,8 @@ public class Animation {
|
|||||||
frameVertices[frameIndex] = vertices;
|
frameVertices[frameIndex] = vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, boolean setupPose,
|
||||||
boolean setupPose) {
|
boolean mixingOut) {
|
||||||
Slot slot = skeleton.slots.get(slotIndex);
|
Slot slot = skeleton.slots.get(slotIndex);
|
||||||
Attachment slotAttachment = slot.attachment;
|
Attachment slotAttachment = slot.attachment;
|
||||||
if (!(slotAttachment instanceof VertexAttachment) || !((VertexAttachment)slotAttachment).applyDeform(attachment)) return;
|
if (!(slotAttachment instanceof VertexAttachment) || !((VertexAttachment)slotAttachment).applyDeform(attachment)) return;
|
||||||
@ -715,14 +741,14 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Fires events for frames > lastTime and <= time. */
|
/** 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, boolean setupPose,
|
||||||
boolean setupPose) {
|
boolean mixingOut) {
|
||||||
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 > 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, setupPose);
|
apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha, setupPose, mixingOut);
|
||||||
lastTime = -1f;
|
lastTime = -1f;
|
||||||
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
||||||
return;
|
return;
|
||||||
@ -776,8 +802,8 @@ public class Animation {
|
|||||||
drawOrders[frameIndex] = drawOrder;
|
drawOrders[frameIndex] = drawOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, boolean setupPose,
|
||||||
boolean setupPose) {
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -837,7 +863,8 @@ public class Animation {
|
|||||||
frames[frameIndex + BEND_DIRECTION] = bendDirection;
|
frames[frameIndex + BEND_DIRECTION] = bendDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -900,7 +927,8 @@ public class Animation {
|
|||||||
frames[frameIndex + SHEAR] = shearMix;
|
frames[frameIndex + SHEAR] = shearMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -970,7 +998,8 @@ public class Animation {
|
|||||||
frames[frameIndex + VALUE] = value;
|
frames[frameIndex + VALUE] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -1001,7 +1030,8 @@ public class Animation {
|
|||||||
return (TimelineType.pathConstraintSpacing.ordinal() << 24) + pathConstraintIndex;
|
return (TimelineType.pathConstraintSpacing.ordinal() << 24) + pathConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
@ -1062,7 +1092,8 @@ public class Animation {
|
|||||||
frames[frameIndex + TRANSLATE] = translateMix;
|
frames[frameIndex + TRANSLATE] = translateMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose) {
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||||
|
boolean mixingOut) {
|
||||||
float[] frames = this.frames;
|
float[] frames = this.frames;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
|
|||||||
@ -122,11 +122,12 @@ public class AnimationState {
|
|||||||
float mix = current.alpha;
|
float mix = current.alpha;
|
||||||
if (current.mixingFrom != null) {
|
if (current.mixingFrom != null) {
|
||||||
mix *= current.mixTime / current.mixDuration;
|
mix *= current.mixTime / current.mixDuration;
|
||||||
|
if (mix > 1) mix = 1;
|
||||||
applyMixingFrom(current.mixingFrom, skeleton, mix);
|
applyMixingFrom(current.mixingFrom, skeleton, mix);
|
||||||
if (mix >= 1) {
|
if (mix == 1) {
|
||||||
mix = 1;
|
|
||||||
queue.end(current.mixingFrom);
|
queue.end(current.mixingFrom);
|
||||||
current.mixingFrom = null;
|
current.mixingFrom = null;
|
||||||
|
updateSetupPose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ public class AnimationState {
|
|||||||
Array<Timeline> timelines = current.animation.timelines;
|
Array<Timeline> timelines = current.animation.timelines;
|
||||||
BooleanArray setupPose = current.setupPose;
|
BooleanArray setupPose = current.setupPose;
|
||||||
for (int ii = 0, n = timelines.size; ii < n; ii++)
|
for (int ii = 0, n = timelines.size; ii < n; ii++)
|
||||||
timelines.get(ii).apply(skeleton, animationLast, animationTime, events, mix, setupPose.get(ii));
|
timelines.get(ii).apply(skeleton, animationLast, animationTime, events, mix, setupPose.get(ii), false);
|
||||||
queueEvents(current, animationTime);
|
queueEvents(current, animationTime);
|
||||||
current.animationLast = animationTime;
|
current.animationLast = animationTime;
|
||||||
current.trackLast = current.trackTime;
|
current.trackLast = current.trackTime;
|
||||||
@ -155,9 +156,9 @@ public class AnimationState {
|
|||||||
for (int i = 0, n = timelines.size; i < n; i++) {
|
for (int i = 0, n = timelines.size; i < n; i++) {
|
||||||
Timeline timeline = timelines.get(i);
|
Timeline timeline = timelines.get(i);
|
||||||
if (setupPose.get(i))
|
if (setupPose.get(i))
|
||||||
timeline.apply(skeleton, animationLast, animationTime, events, alphaMix, true);
|
timeline.apply(skeleton, animationLast, animationTime, events, alphaMix, true, true);
|
||||||
else
|
else
|
||||||
timeline.apply(skeleton, animationLast, animationTime, events, alphaFull, false);
|
timeline.apply(skeleton, animationLast, animationTime, events, alphaFull, false, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0, n = timelines.size; i < n; i++) {
|
for (int i = 0, n = timelines.size; i < n; i++) {
|
||||||
@ -165,9 +166,9 @@ public class AnimationState {
|
|||||||
if (!attachments && timeline instanceof AttachmentTimeline) continue;
|
if (!attachments && timeline instanceof AttachmentTimeline) continue;
|
||||||
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
|
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
|
||||||
if (setupPose.get(i))
|
if (setupPose.get(i))
|
||||||
timeline.apply(skeleton, animationLast, animationTime, events, alphaMix, true);
|
timeline.apply(skeleton, animationLast, animationTime, events, alphaMix, true, true);
|
||||||
else
|
else
|
||||||
timeline.apply(skeleton, animationLast, animationTime, events, alphaFull, false);
|
timeline.apply(skeleton, animationLast, animationTime, events, alphaFull, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,9 +283,10 @@ public class AnimationState {
|
|||||||
updateSetupPose(entry);
|
updateSetupPose(entry);
|
||||||
} else
|
} else
|
||||||
updateFirstSetupPose(entry);
|
updateFirstSetupPose(entry);
|
||||||
|
i++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (i++; i < n; i++) {
|
for (; i < n; i++) {
|
||||||
TrackEntry entry = tracks.get(i);
|
TrackEntry entry = tracks.get(i);
|
||||||
if (entry == null) continue;
|
if (entry == null) continue;
|
||||||
if (entry.mixingFrom != null) updateSetupPose(entry.mixingFrom);
|
if (entry.mixingFrom != null) updateSetupPose(entry.mixingFrom);
|
||||||
@ -678,7 +680,8 @@ public class AnimationState {
|
|||||||
return trackTime >= animationEnd - animationStart;
|
return trackTime >= animationEnd - animationStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Seconds from 0 to the mix duration when mixing from the previous animation to this animation. */
|
/** Seconds from 0 to the mix duration when mixing from the previous animation to this animation. May be slightly more than
|
||||||
|
* {@link #getMixDuration()}. */
|
||||||
public float getMixTime () {
|
public float getMixTime () {
|
||||||
return mixTime;
|
return mixTime;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -205,12 +205,16 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
// Configure skeleton from UI.
|
// Configure skeleton from UI.
|
||||||
|
|
||||||
if (ui.skinList.getSelected() != null) skeleton.setSkin(ui.skinList.getSelected());
|
if (ui.skinList.getSelected() != null) skeleton.setSkin(ui.skinList.getSelected());
|
||||||
if (ui.animationList.getSelected() != null)
|
if (ui.animationList.getSelected() != null) setAnimation();
|
||||||
state.setAnimation(0, ui.animationList.getSelected(), ui.loopCheckbox.isChecked());
|
|
||||||
|
|
||||||
if (reload) ui.toast("Reloaded.");
|
if (reload) ui.toast("Reloaded.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAnimation () {
|
||||||
|
TrackEntry entry = state.setAnimation(0, ui.animationList.getSelected(), ui.loopCheckbox.isChecked());
|
||||||
|
entry.setTrackEnd(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
public void render () {
|
public void render () {
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
@ -486,11 +490,17 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
if (name == null)
|
if (name == null)
|
||||||
state.clearTrack(0);
|
state.clearTrack(0);
|
||||||
else
|
else
|
||||||
state.setAnimation(0, name, loopCheckbox.isChecked());
|
setAnimation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
loopCheckbox.addListener(new ChangeListener() {
|
||||||
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
|
setAnimation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
skinList.addListener(new ChangeListener() {
|
skinList.addListener(new ChangeListener() {
|
||||||
public void changed (ChangeEvent event, Actor actor) {
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
if (skeleton != null) {
|
if (skeleton != null) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user