mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Timeline and JSON/binary improvements.
* Path constraint position and spacing timelines are now value timelines. * Better code reuse in timelines and loaders. * Loader changes for using time for Bezier segments. * Binary knows the number of timelines ahead of time, for allocation.
This commit is contained in:
parent
f165ffeb1c
commit
07bd8451f4
@ -274,7 +274,7 @@ public class Animation {
|
|||||||
* @param propertyIds Unique identifiers for each property the timeline modifies. */
|
* @param propertyIds Unique identifiers for each property the timeline modifies. */
|
||||||
public CurveTimeline (int frameCount, int frameEntries, int bezierCount, String... propertyIds) {
|
public CurveTimeline (int frameCount, int frameEntries, int bezierCount, String... propertyIds) {
|
||||||
super(frameCount, frameEntries, propertyIds);
|
super(frameCount, frameEntries, propertyIds);
|
||||||
curves = new float[frameCount - 1 + (bezierCount == 0 ? frameCount - 1 : bezierCount) * BEZIER_SIZE];
|
curves = new float[frameCount - 1 + bezierCount * BEZIER_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the specified key frame to linear interpolation.
|
/** Sets the specified key frame to linear interpolation.
|
||||||
@ -377,6 +377,31 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The base class for a {@link PercentCurveTimeline} which changes two float properties. */
|
||||||
|
static public abstract class PercentCurveTimeline2 extends PercentCurveTimeline {
|
||||||
|
static public final int ENTRIES = 3;
|
||||||
|
static final int PREV_TIME = -3, PREV_VALUE1 = -2, PREV_VALUE2 = -1;
|
||||||
|
static final int VALUE1 = 1, VALUE2 = 2;
|
||||||
|
|
||||||
|
/** @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}.
|
||||||
|
* @param propertyIds Unique identifiers for each property the timeline modifies. */
|
||||||
|
public PercentCurveTimeline2 (int frameCount, int bezierCount, String... propertyIds) {
|
||||||
|
super(frameCount, ENTRIES, bezierCount, propertyIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFrameCount () {
|
||||||
|
return frames.length / ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the time in seconds and the values for the specified key frame. */
|
||||||
|
public void setFrame (int frameIndex, float time, float value1, float value2) {
|
||||||
|
frameIndex *= ENTRIES;
|
||||||
|
frames[frameIndex] = time;
|
||||||
|
frames[frameIndex + VALUE1] = value1;
|
||||||
|
frames[frameIndex + VALUE2] = value2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** The base class for timelines that use interpolation between key frames for a single property using the key frames' value
|
/** The base class for timelines that use interpolation between key frames for a single property using the key frames' value
|
||||||
* space. */
|
* space. */
|
||||||
static public abstract class ValueCurveTimeline extends CurveTimeline {
|
static public abstract class ValueCurveTimeline extends CurveTimeline {
|
||||||
@ -394,7 +419,6 @@ public class Animation {
|
|||||||
return frames.length >> 1;
|
return frames.length >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time in seconds and the value for the specified key frame. */
|
|
||||||
public void setFrame (int frameIndex, float time, float value) {
|
public void setFrame (int frameIndex, float time, float value) {
|
||||||
frameIndex <<= 1;
|
frameIndex <<= 1;
|
||||||
frames[frameIndex] = time;
|
frames[frameIndex] = time;
|
||||||
@ -453,12 +477,11 @@ public class Animation {
|
|||||||
static public class RotateTimeline extends ValueCurveTimeline implements BoneTimeline {
|
static public class RotateTimeline extends ValueCurveTimeline implements BoneTimeline {
|
||||||
final int boneIndex;
|
final int boneIndex;
|
||||||
|
|
||||||
public RotateTimeline (int frameCount, int bezierIndex, int boneIndex) {
|
public RotateTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||||
super(frameCount, bezierIndex, TimelineType.rotate.ordinal() + "|" + boneIndex);
|
super(frameCount, bezierCount, TimelineType.rotate.ordinal() + "|" + boneIndex);
|
||||||
this.boneIndex = boneIndex;
|
this.boneIndex = boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The index of the bone in {@link Skeleton#getBones()} that will be changed. */
|
|
||||||
public int getBoneIndex () {
|
public int getBoneIndex () {
|
||||||
return boneIndex;
|
return boneIndex;
|
||||||
}
|
}
|
||||||
@ -516,36 +539,20 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Changes a bone's local {@link Bone#getX()} and {@link Bone#getY()}. */
|
/** Changes a bone's local {@link Bone#getX()} and {@link Bone#getY()}. */
|
||||||
static public class TranslateTimeline extends PercentCurveTimeline implements BoneTimeline {
|
static public class TranslateTimeline extends PercentCurveTimeline2 implements BoneTimeline {
|
||||||
static public final int ENTRIES = 3;
|
|
||||||
static final int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1;
|
|
||||||
static final int X = 1, Y = 2;
|
|
||||||
|
|
||||||
final int boneIndex;
|
final int boneIndex;
|
||||||
|
|
||||||
public TranslateTimeline (int frameCount, int bezierIndex, int boneIndex) {
|
public TranslateTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, //
|
super(frameCount, bezierCount, //
|
||||||
TimelineType.translateX.ordinal() + "|" + boneIndex, TimelineType.translateY.ordinal() + "|" + boneIndex);
|
TimelineType.translateX.ordinal() + "|" + boneIndex, //
|
||||||
|
TimelineType.translateY.ordinal() + "|" + boneIndex);
|
||||||
this.boneIndex = boneIndex;
|
this.boneIndex = boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFrameCount () {
|
|
||||||
return frames.length / ENTRIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The index of the bone in {@link Skeleton#getBones()} that will be changed. */
|
|
||||||
public int getBoneIndex () {
|
public int getBoneIndex () {
|
||||||
return boneIndex;
|
return boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time in seconds, x, and y values for the specified key frame. */
|
|
||||||
public void setFrame (int frameIndex, float time, float x, float y) {
|
|
||||||
frameIndex *= ENTRIES;
|
|
||||||
frames[frameIndex] = time;
|
|
||||||
frames[frameIndex + X] = x;
|
|
||||||
frames[frameIndex + Y] = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
||||||
MixDirection direction) {
|
MixDirection direction) {
|
||||||
|
|
||||||
@ -567,16 +574,16 @@ public class Animation {
|
|||||||
|
|
||||||
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_VALUE1];
|
||||||
y = frames[frames.length + PREV_Y];
|
y = frames[frames.length + PREV_VALUE2];
|
||||||
} else {
|
} else {
|
||||||
// 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);
|
||||||
x = frames[frame + PREV_X];
|
x = frames[frame + PREV_VALUE1];
|
||||||
y = frames[frame + PREV_Y];
|
y = frames[frame + PREV_VALUE2];
|
||||||
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
||||||
x += (frames[frame + X] - x) * percent;
|
x += (frames[frame + VALUE1] - x) * percent;
|
||||||
y += (frames[frame + Y] - y) * percent;
|
y += (frames[frame + VALUE2] - y) * percent;
|
||||||
}
|
}
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case setup:
|
case setup:
|
||||||
@ -596,36 +603,20 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Changes a bone's local {@link Bone#getScaleX()} and {@link Bone#getScaleY()}. */
|
/** Changes a bone's local {@link Bone#getScaleX()} and {@link Bone#getScaleY()}. */
|
||||||
static public class ScaleTimeline extends PercentCurveTimeline implements BoneTimeline {
|
static public class ScaleTimeline extends PercentCurveTimeline2 implements BoneTimeline {
|
||||||
static public final int ENTRIES = 3;
|
|
||||||
static final int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1;
|
|
||||||
static final int X = 1, Y = 2;
|
|
||||||
|
|
||||||
final int boneIndex;
|
final int boneIndex;
|
||||||
|
|
||||||
public ScaleTimeline (int frameCount, int bezierIndex, int boneIndex) {
|
public ScaleTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, //
|
super(frameCount, bezierCount, //
|
||||||
TimelineType.scaleX.ordinal() + "|" + boneIndex, TimelineType.scaleY.ordinal() + "|" + boneIndex);
|
TimelineType.scaleX.ordinal() + "|" + boneIndex, //
|
||||||
|
TimelineType.scaleY.ordinal() + "|" + boneIndex);
|
||||||
this.boneIndex = boneIndex;
|
this.boneIndex = boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFrameCount () {
|
|
||||||
return frames.length / ENTRIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The index of the bone in {@link Skeleton#getBones()} that will be changed. */
|
|
||||||
public int getBoneIndex () {
|
public int getBoneIndex () {
|
||||||
return boneIndex;
|
return boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time in seconds, x, and y values for the specified key frame. */
|
|
||||||
public void setFrame (int frameIndex, float time, float x, float y) {
|
|
||||||
frameIndex *= ENTRIES;
|
|
||||||
frames[frameIndex] = time;
|
|
||||||
frames[frameIndex + X] = x;
|
|
||||||
frames[frameIndex + Y] = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
||||||
MixDirection direction) {
|
MixDirection direction) {
|
||||||
|
|
||||||
@ -647,16 +638,16 @@ public class Animation {
|
|||||||
|
|
||||||
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] * bone.data.scaleX;
|
x = frames[frames.length + PREV_VALUE1] * bone.data.scaleX;
|
||||||
y = frames[frames.length + PREV_Y] * bone.data.scaleY;
|
y = frames[frames.length + PREV_VALUE2] * bone.data.scaleY;
|
||||||
} else {
|
} else {
|
||||||
// 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);
|
||||||
x = frames[frame + PREV_X];
|
x = frames[frame + PREV_VALUE1];
|
||||||
y = frames[frame + PREV_Y];
|
y = frames[frame + PREV_VALUE2];
|
||||||
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
||||||
x = (x + (frames[frame + X] - x) * percent) * bone.data.scaleX;
|
x = (x + (frames[frame + VALUE1] - x) * percent) * bone.data.scaleX;
|
||||||
y = (y + (frames[frame + Y] - y) * percent) * bone.data.scaleY;
|
y = (y + (frames[frame + VALUE2] - y) * percent) * bone.data.scaleY;
|
||||||
}
|
}
|
||||||
if (alpha == 1) {
|
if (alpha == 1) {
|
||||||
if (blend == add) {
|
if (blend == add) {
|
||||||
@ -717,36 +708,20 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Changes a bone's local {@link Bone#getShearX()} and {@link Bone#getShearY()}. */
|
/** Changes a bone's local {@link Bone#getShearX()} and {@link Bone#getShearY()}. */
|
||||||
static public class ShearTimeline extends PercentCurveTimeline implements BoneTimeline {
|
static public class ShearTimeline extends PercentCurveTimeline2 implements BoneTimeline {
|
||||||
static public final int ENTRIES = 3;
|
|
||||||
static final int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1;
|
|
||||||
static final int X = 1, Y = 2;
|
|
||||||
|
|
||||||
final int boneIndex;
|
final int boneIndex;
|
||||||
|
|
||||||
public ShearTimeline (int frameCount, int bezierIndex, int boneIndex) {
|
public ShearTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, //
|
super(frameCount, bezierCount, //
|
||||||
TimelineType.shearX.ordinal() + "|" + boneIndex, TimelineType.shearY.ordinal() + "|" + boneIndex);
|
TimelineType.shearX.ordinal() + "|" + boneIndex, //
|
||||||
|
TimelineType.shearY.ordinal() + "|" + boneIndex);
|
||||||
this.boneIndex = boneIndex;
|
this.boneIndex = boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFrameCount () {
|
|
||||||
return frames.length / ENTRIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The index of the bone in {@link Skeleton#getBones()} that will be changed. */
|
|
||||||
public int getBoneIndex () {
|
public int getBoneIndex () {
|
||||||
return boneIndex;
|
return boneIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time in seconds, x, and y values for the specified key frame. */
|
|
||||||
public void setFrame (int frameIndex, float time, float x, float y) {
|
|
||||||
frameIndex *= ENTRIES;
|
|
||||||
frames[frameIndex] = time;
|
|
||||||
frames[frameIndex + X] = x;
|
|
||||||
frames[frameIndex + Y] = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
||||||
MixDirection direction) {
|
MixDirection direction) {
|
||||||
|
|
||||||
@ -768,16 +743,16 @@ public class Animation {
|
|||||||
|
|
||||||
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_VALUE1];
|
||||||
y = frames[frames.length + PREV_Y];
|
y = frames[frames.length + PREV_VALUE2];
|
||||||
} else {
|
} else {
|
||||||
// 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);
|
||||||
x = frames[frame + PREV_X];
|
x = frames[frame + PREV_VALUE1];
|
||||||
y = frames[frame + PREV_Y];
|
y = frames[frame + PREV_VALUE2];
|
||||||
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
||||||
x = x + (frames[frame + X] - x) * percent;
|
x = x + (frames[frame + VALUE1] - x) * percent;
|
||||||
y = y + (frames[frame + Y] - y) * percent;
|
y = y + (frames[frame + VALUE2] - y) * percent;
|
||||||
}
|
}
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case setup:
|
case setup:
|
||||||
@ -804,8 +779,8 @@ public class Animation {
|
|||||||
|
|
||||||
final int slotIndex;
|
final int slotIndex;
|
||||||
|
|
||||||
public ColorTimeline (int frameCount, int bezierIndex, int slotIndex) {
|
public ColorTimeline (int frameCount, int bezierCount, int slotIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, //
|
super(frameCount, ENTRIES, bezierCount, //
|
||||||
TimelineType.rgb.ordinal() + "|" + slotIndex, //
|
TimelineType.rgb.ordinal() + "|" + slotIndex, //
|
||||||
TimelineType.a.ordinal() + "|" + slotIndex);
|
TimelineType.a.ordinal() + "|" + slotIndex);
|
||||||
this.slotIndex = slotIndex;
|
this.slotIndex = slotIndex;
|
||||||
@ -815,7 +790,6 @@ public class Animation {
|
|||||||
return frames.length / ENTRIES;
|
return frames.length / ENTRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
|
|
||||||
public int getSlotIndex () {
|
public int getSlotIndex () {
|
||||||
return slotIndex;
|
return slotIndex;
|
||||||
}
|
}
|
||||||
@ -888,8 +862,8 @@ public class Animation {
|
|||||||
|
|
||||||
final int slotIndex;
|
final int slotIndex;
|
||||||
|
|
||||||
public TwoColorTimeline (int frameCount, int bezierIndex, int slotIndex) {
|
public TwoColorTimeline (int frameCount, int bezierCount, int slotIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, //
|
super(frameCount, ENTRIES, bezierCount, //
|
||||||
TimelineType.rgb.ordinal() + "|" + slotIndex, //
|
TimelineType.rgb.ordinal() + "|" + slotIndex, //
|
||||||
TimelineType.a.ordinal() + "|" + slotIndex, //
|
TimelineType.a.ordinal() + "|" + slotIndex, //
|
||||||
TimelineType.rgb2.ordinal() + "|" + slotIndex);
|
TimelineType.rgb2.ordinal() + "|" + slotIndex);
|
||||||
@ -999,7 +973,6 @@ public class Animation {
|
|||||||
return frames.length;
|
return frames.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
|
|
||||||
public int getSlotIndex () {
|
public int getSlotIndex () {
|
||||||
return slotIndex;
|
return slotIndex;
|
||||||
}
|
}
|
||||||
@ -1052,8 +1025,8 @@ public class Animation {
|
|||||||
final VertexAttachment attachment;
|
final VertexAttachment attachment;
|
||||||
private final float[][] frameVertices;
|
private final float[][] frameVertices;
|
||||||
|
|
||||||
public DeformTimeline (int frameCount, int bezierIndex, int slotIndex, VertexAttachment attachment) {
|
public DeformTimeline (int frameCount, int bezierCount, int slotIndex, VertexAttachment attachment) {
|
||||||
super(frameCount, 1, bezierIndex, TimelineType.deform.ordinal() + "|" + slotIndex + "|" + attachment.getId());
|
super(frameCount, 1, bezierCount, TimelineType.deform.ordinal() + "|" + slotIndex + "|" + attachment.getId());
|
||||||
this.slotIndex = slotIndex;
|
this.slotIndex = slotIndex;
|
||||||
this.attachment = attachment;
|
this.attachment = attachment;
|
||||||
frameVertices = new float[frameCount][];
|
frameVertices = new float[frameCount][];
|
||||||
@ -1063,7 +1036,6 @@ public class Animation {
|
|||||||
return frames.length;
|
return frames.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
|
|
||||||
public int getSlotIndex () {
|
public int getSlotIndex () {
|
||||||
return slotIndex;
|
return slotIndex;
|
||||||
}
|
}
|
||||||
@ -1392,8 +1364,8 @@ public class Animation {
|
|||||||
|
|
||||||
final int ikConstraintIndex;
|
final int ikConstraintIndex;
|
||||||
|
|
||||||
public IkConstraintTimeline (int frameCount, int bezierIndex, int ikConstraintIndex) {
|
public IkConstraintTimeline (int frameCount, int bezierCount, int ikConstraintIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, TimelineType.ikConstraint.ordinal() + "|" + ikConstraintIndex);
|
super(frameCount, ENTRIES, bezierCount, TimelineType.ikConstraint.ordinal() + "|" + ikConstraintIndex);
|
||||||
this.ikConstraintIndex = ikConstraintIndex;
|
this.ikConstraintIndex = ikConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1509,8 +1481,8 @@ public class Animation {
|
|||||||
|
|
||||||
final int transformConstraintIndex;
|
final int transformConstraintIndex;
|
||||||
|
|
||||||
public TransformConstraintTimeline (int frameCount, int bezierIndex, int transformConstraintIndex) {
|
public TransformConstraintTimeline (int frameCount, int bezierCount, int transformConstraintIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, TimelineType.transformConstraint.ordinal() + "|" + transformConstraintIndex);
|
super(frameCount, ENTRIES, bezierCount, TimelineType.transformConstraint.ordinal() + "|" + transformConstraintIndex);
|
||||||
this.transformConstraintIndex = transformConstraintIndex;
|
this.transformConstraintIndex = transformConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1593,34 +1565,19 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Changes a path constraint's {@link PathConstraint#getPosition()}. */
|
/** Changes a path constraint's {@link PathConstraint#getPosition()}. */
|
||||||
static public class PathConstraintPositionTimeline extends PercentCurveTimeline {
|
static public class PathConstraintPositionTimeline extends ValueCurveTimeline {
|
||||||
static public final int ENTRIES = 2;
|
|
||||||
static final int PREV_TIME = -2, PREV_VALUE = -1;
|
|
||||||
static final int VALUE = 1;
|
|
||||||
|
|
||||||
final int pathConstraintIndex;
|
final int pathConstraintIndex;
|
||||||
|
|
||||||
public PathConstraintPositionTimeline (int frameCount, int bezierIndex, int pathConstraintIndex) {
|
public PathConstraintPositionTimeline (int frameCount, int bezierCount, int pathConstraintIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, TimelineType.pathConstraintPosition.ordinal() + "|" + pathConstraintIndex);
|
super(frameCount, bezierCount, TimelineType.pathConstraintPosition.ordinal() + "|" + pathConstraintIndex);
|
||||||
this.pathConstraintIndex = pathConstraintIndex;
|
this.pathConstraintIndex = pathConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFrameCount () {
|
|
||||||
return frames.length >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
||||||
public int getPathConstraintIndex () {
|
public int getPathConstraintIndex () {
|
||||||
return pathConstraintIndex;
|
return pathConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time in seconds and path constraint position for the specified key frame. */
|
|
||||||
public void setFrame (int frameIndex, float time, float position) {
|
|
||||||
frameIndex <<= 1;
|
|
||||||
frames[frameIndex] = time;
|
|
||||||
frames[frameIndex + VALUE] = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
||||||
MixDirection direction) {
|
MixDirection direction) {
|
||||||
|
|
||||||
@ -1644,10 +1601,11 @@ public class Animation {
|
|||||||
else {
|
else {
|
||||||
// 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);
|
||||||
position = frames[frame + PREV_VALUE];
|
position = getCurveValue((frame >> 1) - 1, time, //
|
||||||
float percent = getCurvePercent((frame >> 1) - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
frames[frame + PREV_TIME], frames[frame + PREV_VALUE], //
|
||||||
position += (frames[frame + VALUE] - position) * percent;
|
frames[frame], frames[frame + VALUE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blend == setup)
|
if (blend == setup)
|
||||||
constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
|
constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
|
||||||
else
|
else
|
||||||
@ -1656,34 +1614,19 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Changes a path constraint's {@link PathConstraint#getSpacing()}. */
|
/** Changes a path constraint's {@link PathConstraint#getSpacing()}. */
|
||||||
static public class PathConstraintSpacingTimeline extends PercentCurveTimeline {
|
static public class PathConstraintSpacingTimeline extends ValueCurveTimeline {
|
||||||
static public final int ENTRIES = 2;
|
|
||||||
static final int PREV_TIME = -2, PREV_VALUE = -1;
|
|
||||||
static final int VALUE = 1;
|
|
||||||
|
|
||||||
final int pathConstraintIndex;
|
final int pathConstraintIndex;
|
||||||
|
|
||||||
public PathConstraintSpacingTimeline (int frameCount, int bezierIndex, int pathConstraintIndex) {
|
public PathConstraintSpacingTimeline (int frameCount, int bezierCount, int pathConstraintIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, TimelineType.pathConstraintSpacing.ordinal() + "|" + pathConstraintIndex);
|
super(frameCount, bezierCount, TimelineType.pathConstraintSpacing.ordinal() + "|" + pathConstraintIndex);
|
||||||
this.pathConstraintIndex = pathConstraintIndex;
|
this.pathConstraintIndex = pathConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFrameCount () {
|
|
||||||
return frames.length >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
||||||
public int getPathConstraintIndex () {
|
public int getPathConstraintIndex () {
|
||||||
return pathConstraintIndex;
|
return pathConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time in seconds and path constraint position for the specified key frame. */
|
|
||||||
public void setFrame (int frameIndex, float time, float position) {
|
|
||||||
frameIndex <<= 1;
|
|
||||||
frames[frameIndex] = time;
|
|
||||||
frames[frameIndex + VALUE] = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
||||||
MixDirection direction) {
|
MixDirection direction) {
|
||||||
|
|
||||||
@ -1707,9 +1650,9 @@ public class Animation {
|
|||||||
else {
|
else {
|
||||||
// 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);
|
||||||
spacing = frames[frame + PREV_VALUE];
|
spacing = getCurveValue((frame >> 1) - 1, time, //
|
||||||
float percent = getCurvePercent((frame >> 1) - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
frames[frame + PREV_TIME], frames[frame + PREV_VALUE], //
|
||||||
spacing += (frames[frame + VALUE] - spacing) * percent;
|
frames[frame], frames[frame + VALUE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blend == setup)
|
if (blend == setup)
|
||||||
@ -1721,35 +1664,19 @@ public class Animation {
|
|||||||
|
|
||||||
/** Changes a transform constraint's {@link PathConstraint#getRotateMix()} and
|
/** Changes a transform constraint's {@link PathConstraint#getRotateMix()} and
|
||||||
* {@link TransformConstraint#getTranslateMix()}. */
|
* {@link TransformConstraint#getTranslateMix()}. */
|
||||||
static public class PathConstraintMixTimeline extends PercentCurveTimeline {
|
static public class PathConstraintMixTimeline extends PercentCurveTimeline2 {
|
||||||
static public final int ENTRIES = 3;
|
|
||||||
static private final int PREV_TIME = -3, PREV_ROTATE = -2, PREV_TRANSLATE = -1;
|
|
||||||
static private final int ROTATE = 1, TRANSLATE = 2;
|
|
||||||
|
|
||||||
final int pathConstraintIndex;
|
final int pathConstraintIndex;
|
||||||
|
|
||||||
public PathConstraintMixTimeline (int frameCount, int bezierIndex, int pathConstraintIndex) {
|
public PathConstraintMixTimeline (int frameCount, int bezierCount, int pathConstraintIndex) {
|
||||||
super(frameCount, ENTRIES, bezierIndex, TimelineType.pathConstraintMix.ordinal() + "|" + pathConstraintIndex);
|
super(frameCount, bezierCount, TimelineType.pathConstraintMix.ordinal() + "|" + pathConstraintIndex);
|
||||||
this.pathConstraintIndex = pathConstraintIndex;
|
this.pathConstraintIndex = pathConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFrameCount () {
|
|
||||||
return frames.length / ENTRIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
||||||
public int getPathConstraintIndex () {
|
public int getPathConstraintIndex () {
|
||||||
return pathConstraintIndex;
|
return pathConstraintIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The time in seconds, rotate mix, and translate mix for the specified key frame. */
|
|
||||||
public void setFrame (int frameIndex, float time, float rotateMix, float translateMix) {
|
|
||||||
frameIndex *= ENTRIES;
|
|
||||||
frames[frameIndex] = time;
|
|
||||||
frames[frameIndex + ROTATE] = rotateMix;
|
|
||||||
frames[frameIndex + TRANSLATE] = translateMix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, MixBlend blend,
|
||||||
MixDirection direction) {
|
MixDirection direction) {
|
||||||
|
|
||||||
@ -1771,16 +1698,16 @@ public class Animation {
|
|||||||
|
|
||||||
float rotate, translate;
|
float rotate, translate;
|
||||||
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
||||||
rotate = frames[frames.length + PREV_ROTATE];
|
rotate = frames[frames.length + PREV_VALUE1];
|
||||||
translate = frames[frames.length + PREV_TRANSLATE];
|
translate = frames[frames.length + PREV_VALUE2];
|
||||||
} else {
|
} else {
|
||||||
// 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);
|
||||||
rotate = frames[frame + PREV_ROTATE];
|
rotate = frames[frame + PREV_VALUE1];
|
||||||
translate = frames[frame + PREV_TRANSLATE];
|
translate = frames[frame + PREV_VALUE2];
|
||||||
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
float percent = getCurvePercent(frame / ENTRIES - 1, time, frames[frame + PREV_TIME], frames[frame]);
|
||||||
rotate += (frames[frame + ROTATE] - rotate) * percent;
|
rotate += (frames[frame + VALUE1] - rotate) * percent;
|
||||||
translate += (frames[frame + TRANSLATE] - translate) * percent;
|
translate += (frames[frame + VALUE2] - translate) * percent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blend == setup) {
|
if (blend == setup) {
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import com.esotericsoftware.spine.Animation.PathConstraintMixTimeline;
|
|||||||
import com.esotericsoftware.spine.Animation.PathConstraintPositionTimeline;
|
import com.esotericsoftware.spine.Animation.PathConstraintPositionTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.PathConstraintSpacingTimeline;
|
import com.esotericsoftware.spine.Animation.PathConstraintSpacingTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.PercentCurveTimeline;
|
import com.esotericsoftware.spine.Animation.PercentCurveTimeline;
|
||||||
|
import com.esotericsoftware.spine.Animation.PercentCurveTimeline2;
|
||||||
import com.esotericsoftware.spine.Animation.RotateTimeline;
|
import com.esotericsoftware.spine.Animation.RotateTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.ScaleTimeline;
|
import com.esotericsoftware.spine.Animation.ScaleTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.ShearTimeline;
|
import com.esotericsoftware.spine.Animation.ShearTimeline;
|
||||||
@ -374,8 +375,7 @@ public class SkeletonBinary {
|
|||||||
String name = input.readStringRef();
|
String name = input.readStringRef();
|
||||||
if (name == null) name = attachmentName;
|
if (name == null) name = attachmentName;
|
||||||
|
|
||||||
AttachmentType type = AttachmentType.values[input.readByte()];
|
switch (AttachmentType.values[input.readByte()]) {
|
||||||
switch (type) {
|
|
||||||
case region: {
|
case region: {
|
||||||
String path = input.readStringRef();
|
String path = input.readStringRef();
|
||||||
float rotation = input.readFloat();
|
float rotation = input.readFloat();
|
||||||
@ -529,6 +529,7 @@ public class SkeletonBinary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Vertices readVertices (SkeletonInput input, int vertexCount) throws IOException {
|
private Vertices readVertices (SkeletonInput input, int vertexCount) throws IOException {
|
||||||
|
float scale = this.scale;
|
||||||
int verticesLength = vertexCount << 1;
|
int verticesLength = vertexCount << 1;
|
||||||
Vertices vertices = new Vertices();
|
Vertices vertices = new Vertices();
|
||||||
if (!input.readBoolean()) {
|
if (!input.readBoolean()) {
|
||||||
@ -572,297 +573,257 @@ public class SkeletonBinary {
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Animation readAnimation (SkeletonInput input, String name, SkeletonData skeletonData) {
|
private Animation readAnimation (SkeletonInput input, String name, SkeletonData skeletonData) throws IOException {
|
||||||
Array<Timeline> timelines = new Array(32);
|
Array<Timeline> timelines = new Array(input.readInt(true));
|
||||||
float scale = this.scale;
|
float scale = this.scale;
|
||||||
|
|
||||||
try {
|
// Slot timelines.
|
||||||
// Slot timelines.
|
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
||||||
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
int slotIndex = input.readInt(true);
|
||||||
int slotIndex = input.readInt(true);
|
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
||||||
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
int timelineType = input.readByte(), frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||||
int timelineType = input.readByte();
|
switch (timelineType) {
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
case SLOT_ATTACHMENT: {
|
||||||
switch (timelineType) {
|
AttachmentTimeline timeline = new AttachmentTimeline(frameCount, slotIndex);
|
||||||
case SLOT_ATTACHMENT: {
|
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
|
||||||
AttachmentTimeline timeline = new AttachmentTimeline(frameCount, slotIndex);
|
timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef());
|
||||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
|
timelines.add(timeline);
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef());
|
break;
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLOT_COLOR: {
|
|
||||||
ColorTimeline timeline = new ColorTimeline(frameCount, input.readInt(true), slotIndex);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
Color.rgba8888ToColor(tempColor1, input.readInt());
|
|
||||||
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a);
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SLOT_TWO_COLOR: {
|
|
||||||
TwoColorTimeline timeline = new TwoColorTimeline(frameCount, input.readInt(true), slotIndex);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
Color.rgba8888ToColor(tempColor1, input.readInt());
|
|
||||||
Color.rgb888ToColor(tempColor2, input.readInt());
|
|
||||||
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r,
|
|
||||||
tempColor2.g, tempColor2.b);
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
case SLOT_COLOR: {
|
||||||
|
ColorTimeline timeline = new ColorTimeline(frameCount, input.readInt(true), slotIndex);
|
||||||
// Bone timelines.
|
|
||||||
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
|
||||||
int boneIndex = input.readInt(true);
|
|
||||||
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
||||||
int timelineType = input.readByte();
|
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
|
||||||
switch (timelineType) {
|
|
||||||
case BONE_ROTATE: {
|
|
||||||
RotateTimeline timeline = new RotateTimeline(frameCount, input.readInt(true), boneIndex);
|
|
||||||
float time = input.readFloat(), value = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, value);
|
|
||||||
if (frameIndex < frameLast) readCurve(input, timeline, frameIndex, bezierIndex, time, value,
|
|
||||||
time = input.readFloat(), value = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BONE_TRANSLATE: {
|
|
||||||
TranslateTimeline timeline = new TranslateTimeline(frameCount, input.readInt(true), boneIndex);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat() * scale, input.readFloat() * scale);
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BONE_SCALE: {
|
|
||||||
ScaleTimeline timeline = new ScaleTimeline(frameCount, input.readInt(true), boneIndex);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat());
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BONE_SHEAR: {
|
|
||||||
ShearTimeline timeline = new ShearTimeline(frameCount, input.readInt(true), boneIndex);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat());
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IK constraint timelines.
|
|
||||||
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
|
||||||
int index = input.readInt(true);
|
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
|
||||||
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat() * scale, input.readByte(),
|
|
||||||
input.readBoolean(), input.readBoolean());
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform constraint timelines.
|
|
||||||
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
|
||||||
int index = input.readInt(true);
|
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
|
||||||
TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path constraint timelines.
|
|
||||||
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
|
||||||
int index = input.readInt(true);
|
|
||||||
PathConstraintData data = skeletonData.pathConstraints.get(index);
|
|
||||||
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
||||||
int timelineType = input.readByte();
|
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
|
||||||
switch (timelineType) {
|
|
||||||
case PATH_POSITION: {
|
|
||||||
PathConstraintSpacingTimeline timeline = new PathConstraintSpacingTimeline(frameCount, input.readInt(true),
|
|
||||||
index);
|
|
||||||
float timelineScale = data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale
|
|
||||||
: 1;
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat() * timelineScale);
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PATH_SPACING: {
|
|
||||||
PathConstraintPositionTimeline timeline = new PathConstraintPositionTimeline(frameCount, input.readInt(true),
|
|
||||||
index);
|
|
||||||
float timelineScale = data.positionMode == PositionMode.fixed ? scale : 1;
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat() * timelineScale);
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PATH_MIX: {
|
|
||||||
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount, input.readInt(true), index);
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat());
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deform timelines.
|
|
||||||
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
|
||||||
Skin skin = skeletonData.skins.get(input.readInt(true));
|
|
||||||
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
||||||
int slotIndex = input.readInt(true);
|
|
||||||
for (int iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {
|
|
||||||
VertexAttachment attachment = (VertexAttachment)skin.getAttachment(slotIndex, input.readStringRef());
|
|
||||||
boolean weighted = attachment.getBones() != null;
|
|
||||||
float[] vertices = attachment.getVertices();
|
|
||||||
int deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
|
|
||||||
|
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
|
||||||
DeformTimeline timeline = new DeformTimeline(frameCount, input.readInt(true), slotIndex, attachment);
|
|
||||||
|
|
||||||
float time = input.readFloat();
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
float[] deform;
|
|
||||||
int end = input.readInt(true);
|
|
||||||
if (end == 0)
|
|
||||||
deform = weighted ? new float[deformLength] : vertices;
|
|
||||||
else {
|
|
||||||
deform = new float[deformLength];
|
|
||||||
int start = input.readInt(true);
|
|
||||||
end += start;
|
|
||||||
if (scale == 1) {
|
|
||||||
for (int v = start; v < end; v++)
|
|
||||||
deform[v] = input.readFloat();
|
|
||||||
} else {
|
|
||||||
for (int v = start; v < end; v++)
|
|
||||||
deform[v] = input.readFloat() * scale;
|
|
||||||
}
|
|
||||||
if (!weighted) {
|
|
||||||
for (int v = 0, vn = deform.length; v < vn; v++)
|
|
||||||
deform[v] += vertices[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timeline.setFrame(frameIndex, time, deform);
|
|
||||||
if (frameIndex < frameLast)
|
|
||||||
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw order timeline.
|
|
||||||
int drawOrderCount = input.readInt(true);
|
|
||||||
if (drawOrderCount > 0) {
|
|
||||||
DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount);
|
|
||||||
int slotCount = skeletonData.slots.size;
|
|
||||||
for (int i = 0; i < drawOrderCount; i++) {
|
|
||||||
float time = input.readFloat();
|
float time = input.readFloat();
|
||||||
int offsetCount = input.readInt(true);
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
int[] drawOrder = new int[slotCount];
|
Color.rgba8888ToColor(tempColor1, input.readInt());
|
||||||
for (int ii = slotCount - 1; ii >= 0; ii--)
|
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a);
|
||||||
drawOrder[ii] = -1;
|
if (frameIndex == frameLast) break;
|
||||||
int[] unchanged = new int[slotCount - offsetCount];
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
int originalIndex = 0, unchangedIndex = 0;
|
|
||||||
for (int ii = 0; ii < offsetCount; ii++) {
|
|
||||||
int slotIndex = input.readInt(true);
|
|
||||||
// Collect unchanged items.
|
|
||||||
while (originalIndex != slotIndex)
|
|
||||||
unchanged[unchangedIndex++] = originalIndex++;
|
|
||||||
// Set changed items.
|
|
||||||
drawOrder[originalIndex + input.readInt(true)] = originalIndex++;
|
|
||||||
}
|
}
|
||||||
// Collect remaining unchanged items.
|
timelines.add(timeline);
|
||||||
while (originalIndex < slotCount)
|
break;
|
||||||
unchanged[unchangedIndex++] = originalIndex++;
|
|
||||||
// Fill in unchanged items.
|
|
||||||
for (int ii = slotCount - 1; ii >= 0; ii--)
|
|
||||||
if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
|
|
||||||
timeline.setFrame(i, time, drawOrder);
|
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
case SLOT_TWO_COLOR: {
|
||||||
}
|
TwoColorTimeline timeline = new TwoColorTimeline(frameCount, input.readInt(true), slotIndex);
|
||||||
|
|
||||||
// Event timeline.
|
|
||||||
int eventCount = input.readInt(true);
|
|
||||||
if (eventCount > 0) {
|
|
||||||
EventTimeline timeline = new EventTimeline(eventCount);
|
|
||||||
for (int i = 0; i < eventCount; i++) {
|
|
||||||
float time = input.readFloat();
|
float time = input.readFloat();
|
||||||
EventData eventData = skeletonData.events.get(input.readInt(true));
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
Event event = new Event(time, eventData);
|
Color.rgba8888ToColor(tempColor1, input.readInt());
|
||||||
event.intValue = input.readInt(false);
|
Color.rgb888ToColor(tempColor2, input.readInt());
|
||||||
event.floatValue = input.readFloat();
|
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r,
|
||||||
event.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;
|
tempColor2.g, tempColor2.b);
|
||||||
if (event.getData().audioPath != null) {
|
if (frameIndex == frameLast) break;
|
||||||
event.volume = input.readFloat();
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
event.balance = input.readFloat();
|
|
||||||
}
|
}
|
||||||
timeline.setFrame(i, event);
|
timelines.add(timeline);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new SerializationException("Error reading skeleton file.", ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timelines.shrink();
|
// Bone timelines.
|
||||||
|
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
||||||
|
int boneIndex = input.readInt(true);
|
||||||
|
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
||||||
|
switch (input.readByte()) {
|
||||||
|
case BONE_ROTATE: {
|
||||||
|
timelines.add(readTimeline(input, new RotateTimeline(input.readInt(true), input.readInt(true), boneIndex), 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BONE_TRANSLATE: {
|
||||||
|
timelines
|
||||||
|
.add(readTimeline(input, new TranslateTimeline(input.readInt(true), input.readInt(true), boneIndex), scale));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BONE_SCALE: {
|
||||||
|
timelines.add(readTimeline(input, new ScaleTimeline(input.readInt(true), input.readInt(true), boneIndex), 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BONE_SHEAR: {
|
||||||
|
timelines.add(readTimeline(input, new ShearTimeline(input.readInt(true), input.readInt(true), boneIndex), 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IK constraint timelines.
|
||||||
|
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
||||||
|
int index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||||
|
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index);
|
||||||
|
float time = input.readFloat();
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
|
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat() * scale, input.readByte(),
|
||||||
|
input.readBoolean(), input.readBoolean());
|
||||||
|
if (frameIndex == frameLast) break;
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
|
}
|
||||||
|
timelines.add(timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform constraint timelines.
|
||||||
|
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
||||||
|
int index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||||
|
TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index);
|
||||||
|
float time = input.readFloat();
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
|
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());
|
||||||
|
if (frameIndex == frameLast) break;
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
|
}
|
||||||
|
timelines.add(timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path constraint timelines.
|
||||||
|
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
||||||
|
int index = input.readInt(true);
|
||||||
|
PathConstraintData data = skeletonData.pathConstraints.get(index);
|
||||||
|
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
||||||
|
switch (input.readByte()) {
|
||||||
|
case PATH_POSITION: {
|
||||||
|
timelines
|
||||||
|
.add(readTimeline(input, new PathConstraintSpacingTimeline(input.readInt(true), input.readInt(true), index),
|
||||||
|
data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale : 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PATH_SPACING: {
|
||||||
|
timelines
|
||||||
|
.add(readTimeline(input, new PathConstraintPositionTimeline(input.readInt(true), input.readInt(true), index),
|
||||||
|
data.positionMode == PositionMode.fixed ? scale : 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PATH_MIX: {
|
||||||
|
timelines
|
||||||
|
.add(readTimeline(input, new PathConstraintMixTimeline(input.readInt(true), input.readInt(true), index), 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deform timelines.
|
||||||
|
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
||||||
|
Skin skin = skeletonData.skins.get(input.readInt(true));
|
||||||
|
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
||||||
|
int slotIndex = input.readInt(true);
|
||||||
|
for (int iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {
|
||||||
|
VertexAttachment attachment = (VertexAttachment)skin.getAttachment(slotIndex, input.readStringRef());
|
||||||
|
boolean weighted = attachment.getBones() != null;
|
||||||
|
float[] vertices = attachment.getVertices();
|
||||||
|
int deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
|
||||||
|
|
||||||
|
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||||
|
DeformTimeline timeline = new DeformTimeline(frameCount, input.readInt(true), slotIndex, attachment);
|
||||||
|
|
||||||
|
float time = input.readFloat();
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
|
float[] deform;
|
||||||
|
int end = input.readInt(true);
|
||||||
|
if (end == 0)
|
||||||
|
deform = weighted ? new float[deformLength] : vertices;
|
||||||
|
else {
|
||||||
|
deform = new float[deformLength];
|
||||||
|
int start = input.readInt(true);
|
||||||
|
end += start;
|
||||||
|
if (scale == 1) {
|
||||||
|
for (int v = start; v < end; v++)
|
||||||
|
deform[v] = input.readFloat();
|
||||||
|
} else {
|
||||||
|
for (int v = start; v < end; v++)
|
||||||
|
deform[v] = input.readFloat() * scale;
|
||||||
|
}
|
||||||
|
if (!weighted) {
|
||||||
|
for (int v = 0, vn = deform.length; v < vn; v++)
|
||||||
|
deform[v] += vertices[v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeline.setFrame(frameIndex, time, deform);
|
||||||
|
if (frameIndex == frameLast) break;
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
|
}
|
||||||
|
timelines.add(timeline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw order timeline.
|
||||||
|
int drawOrderCount = input.readInt(true);
|
||||||
|
if (drawOrderCount > 0) {
|
||||||
|
DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount);
|
||||||
|
int slotCount = skeletonData.slots.size;
|
||||||
|
for (int i = 0; i < drawOrderCount; i++) {
|
||||||
|
float time = input.readFloat();
|
||||||
|
int offsetCount = input.readInt(true);
|
||||||
|
int[] drawOrder = new int[slotCount];
|
||||||
|
for (int ii = slotCount - 1; ii >= 0; ii--)
|
||||||
|
drawOrder[ii] = -1;
|
||||||
|
int[] unchanged = new int[slotCount - offsetCount];
|
||||||
|
int originalIndex = 0, unchangedIndex = 0;
|
||||||
|
for (int ii = 0; ii < offsetCount; ii++) {
|
||||||
|
int slotIndex = input.readInt(true);
|
||||||
|
// Collect unchanged items.
|
||||||
|
while (originalIndex != slotIndex)
|
||||||
|
unchanged[unchangedIndex++] = originalIndex++;
|
||||||
|
// Set changed items.
|
||||||
|
drawOrder[originalIndex + input.readInt(true)] = originalIndex++;
|
||||||
|
}
|
||||||
|
// Collect remaining unchanged items.
|
||||||
|
while (originalIndex < slotCount)
|
||||||
|
unchanged[unchangedIndex++] = originalIndex++;
|
||||||
|
// Fill in unchanged items.
|
||||||
|
for (int ii = slotCount - 1; ii >= 0; ii--)
|
||||||
|
if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
|
||||||
|
timeline.setFrame(i, time, drawOrder);
|
||||||
|
}
|
||||||
|
timelines.add(timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event timeline.
|
||||||
|
int eventCount = input.readInt(true);
|
||||||
|
if (eventCount > 0) {
|
||||||
|
EventTimeline timeline = new EventTimeline(eventCount);
|
||||||
|
for (int i = 0; i < eventCount; i++) {
|
||||||
|
float time = input.readFloat();
|
||||||
|
EventData eventData = skeletonData.events.get(input.readInt(true));
|
||||||
|
Event event = new Event(time, eventData);
|
||||||
|
event.intValue = input.readInt(false);
|
||||||
|
event.floatValue = input.readFloat();
|
||||||
|
event.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;
|
||||||
|
if (event.getData().audioPath != null) {
|
||||||
|
event.volume = input.readFloat();
|
||||||
|
event.balance = input.readFloat();
|
||||||
|
}
|
||||||
|
timeline.setFrame(i, event);
|
||||||
|
}
|
||||||
|
timelines.add(timeline);
|
||||||
|
}
|
||||||
|
|
||||||
float duration = 0;
|
float duration = 0;
|
||||||
for (int i = 0, n = timelines.size; i < n; i++)
|
for (int i = 0, n = timelines.size; i < n; i++)
|
||||||
duration = Math.max(duration, timelines.get(i).getDuration());
|
duration = Math.max(duration, timelines.get(i).getDuration());
|
||||||
return new Animation(name, timelines, duration);
|
return new Animation(name, timelines, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Timeline readTimeline (SkeletonInput input, ValueCurveTimeline timeline, float scale) throws IOException {
|
||||||
|
float time = input.readFloat(), value = input.readFloat() * scale;
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0, frameLast = timeline.getFrameCount() - 1;; frameIndex++) {
|
||||||
|
timeline.setFrame(frameIndex, time, value);
|
||||||
|
if (frameIndex == frameLast) break;
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, value, time = input.readFloat(),
|
||||||
|
value = input.readFloat() * scale);
|
||||||
|
}
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Timeline readTimeline (SkeletonInput input, PercentCurveTimeline2 timeline, float scale) throws IOException {
|
||||||
|
float time = input.readFloat();
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0, frameLast = timeline.getFrameCount() - 1;; frameIndex++) {
|
||||||
|
timeline.setFrame(frameIndex, time, input.readFloat() * scale, input.readFloat() * scale);
|
||||||
|
if (frameIndex == frameLast) break;
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
|
}
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
int readCurve (SkeletonInput input, PercentCurveTimeline timeline, int frameIndex, int bezierIndex, float time1, float time2)
|
int readCurve (SkeletonInput input, PercentCurveTimeline timeline, int frameIndex, int bezierIndex, float time1, float time2)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
switch (input.readByte()) {
|
switch (input.readByte()) {
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import com.esotericsoftware.spine.Animation.PathConstraintMixTimeline;
|
|||||||
import com.esotericsoftware.spine.Animation.PathConstraintPositionTimeline;
|
import com.esotericsoftware.spine.Animation.PathConstraintPositionTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.PathConstraintSpacingTimeline;
|
import com.esotericsoftware.spine.Animation.PathConstraintSpacingTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.PercentCurveTimeline;
|
import com.esotericsoftware.spine.Animation.PercentCurveTimeline;
|
||||||
|
import com.esotericsoftware.spine.Animation.PercentCurveTimeline2;
|
||||||
import com.esotericsoftware.spine.Animation.RotateTimeline;
|
import com.esotericsoftware.spine.Animation.RotateTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.ScaleTimeline;
|
import com.esotericsoftware.spine.Animation.ScaleTimeline;
|
||||||
import com.esotericsoftware.spine.Animation.ShearTimeline;
|
import com.esotericsoftware.spine.Animation.ShearTimeline;
|
||||||
@ -359,9 +360,7 @@ public class SkeletonJson {
|
|||||||
float scale = this.scale;
|
float scale = this.scale;
|
||||||
name = map.getString("name", name);
|
name = map.getString("name", name);
|
||||||
|
|
||||||
String type = map.getString("type", AttachmentType.region.name());
|
switch (AttachmentType.valueOf(map.getString("type", AttachmentType.region.name()))) {
|
||||||
|
|
||||||
switch (AttachmentType.valueOf(type)) {
|
|
||||||
case region: {
|
case region: {
|
||||||
String path = map.getString("path", name);
|
String path = map.getString("path", name);
|
||||||
RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path);
|
RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path);
|
||||||
@ -507,44 +506,46 @@ public class SkeletonJson {
|
|||||||
SlotData slot = skeletonData.findSlot(slotMap.name);
|
SlotData slot = skeletonData.findSlot(slotMap.name);
|
||||||
if (slot == null) throw new SerializationException("Slot not found: " + slotMap.name);
|
if (slot == null) throw new SerializationException("Slot not found: " + slotMap.name);
|
||||||
for (JsonValue timelineMap = slotMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
for (JsonValue timelineMap = slotMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
JsonValue valueMap = timelineMap.child;
|
JsonValue keyMap = timelineMap.child;
|
||||||
if (valueMap == null) continue;
|
if (keyMap == null) continue;
|
||||||
String timelineName = timelineMap.name;
|
String timelineName = timelineMap.name;
|
||||||
|
|
||||||
if (timelineName.equals("attachment")) {
|
if (timelineName.equals("attachment")) {
|
||||||
AttachmentTimeline timeline = new AttachmentTimeline(timelineMap.size, slot.index);
|
AttachmentTimeline timeline = new AttachmentTimeline(timelineMap.size, slot.index);
|
||||||
for (int frameIndex = 0; valueMap != null; valueMap = valueMap.next, frameIndex++)
|
for (int frameIndex = 0; keyMap != null; keyMap = keyMap.next, frameIndex++)
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.getString("name"));
|
timeline.setFrame(frameIndex, keyMap.getFloat("time", 0), keyMap.getString("name"));
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else if (timelineName.equals("color")) {
|
} else if (timelineName.equals("color")) {
|
||||||
ColorTimeline timeline = new ColorTimeline(timelineMap.size, 0, slot.index);
|
ColorTimeline timeline = new ColorTimeline(timelineMap.size, timelineMap.size, slot.index);
|
||||||
float time = timelineMap.child.getFloat("time", 0);
|
float time = timelineMap.child.getFloat("time", 0);
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
Color color = Color.valueOf(valueMap.getString("color"));
|
Color color = Color.valueOf(keyMap.getString("color"));
|
||||||
timeline.setFrame(frameIndex, time, color.r, color.g, color.b, color.a);
|
timeline.setFrame(frameIndex, time, color.r, color.g, color.b, color.a);
|
||||||
valueMap = valueMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (valueMap == null) {
|
if (nextMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
bezierIndex = readCurve(keyMap, timeline, frameIndex, bezierIndex, time, time = nextMap.getFloat("time", 0));
|
||||||
|
keyMap = nextMap;
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else if (timelineName.equals("twoColor")) {
|
} else if (timelineName.equals("twoColor")) {
|
||||||
TwoColorTimeline timeline = new TwoColorTimeline(timelineMap.size, 0, slot.index);
|
TwoColorTimeline timeline = new TwoColorTimeline(timelineMap.size, timelineMap.size, slot.index);
|
||||||
float time = timelineMap.child.getFloat("time", 0);
|
float time = timelineMap.child.getFloat("time", 0);
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
Color light = Color.valueOf(valueMap.getString("light")), dark = Color.valueOf(valueMap.getString("dark"));
|
Color light = Color.valueOf(keyMap.getString("light")), dark = Color.valueOf(keyMap.getString("dark"));
|
||||||
timeline.setFrame(frameIndex, time, light.r, light.g, light.b, light.a, //
|
timeline.setFrame(frameIndex, time, light.r, light.g, light.b, light.a, //
|
||||||
dark.r, dark.g, dark.b);
|
dark.r, dark.g, dark.b);
|
||||||
valueMap = valueMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (valueMap == null) {
|
if (nextMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
bezierIndex = readCurve(keyMap, timeline, frameIndex, bezierIndex, time, time = nextMap.getFloat("time", 0));
|
||||||
|
keyMap = nextMap;
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
@ -558,102 +559,65 @@ public class SkeletonJson {
|
|||||||
BoneData bone = skeletonData.findBone(boneMap.name);
|
BoneData bone = skeletonData.findBone(boneMap.name);
|
||||||
if (bone == null) throw new SerializationException("Bone not found: " + boneMap.name);
|
if (bone == null) throw new SerializationException("Bone not found: " + boneMap.name);
|
||||||
for (JsonValue timelineMap = boneMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
for (JsonValue timelineMap = boneMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
JsonValue valueMap = timelineMap.child;
|
JsonValue keyMap = timelineMap.child;
|
||||||
if (valueMap == null) continue;
|
if (keyMap == null) continue;
|
||||||
|
|
||||||
String timelineName = timelineMap.name;
|
String timelineName = timelineMap.name;
|
||||||
|
if (timelineName.equals("rotate"))
|
||||||
if (timelineName.equals("rotate")) {
|
timelines.add(readTimeline(keyMap, new RotateTimeline(timelineMap.size, timelineMap.size, bone.index), 0, 1));
|
||||||
timelines.add(readTimeline(valueMap, new RotateTimeline(timelineMap.size, 0, bone.index)));
|
else if (timelineName.equals("translate")) {
|
||||||
|
timelines
|
||||||
} else if (timelineName.equals("translate")) {
|
.add(readTimeline(keyMap, new TranslateTimeline(timelineMap.size, timelineMap.size, bone.index), 0, scale));
|
||||||
TranslateTimeline timeline = new TranslateTimeline(timelineMap.size, 0, bone.index);
|
} else if (timelineName.equals("scale"))
|
||||||
float time = valueMap.getFloat("time", 0);
|
timelines.add(readTimeline(keyMap, new ScaleTimeline(timelineMap.size, timelineMap.size, bone.index), 1, 1));
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
else if (timelineName.equals("shear"))
|
||||||
float x = valueMap.getFloat("x", 0), y = valueMap.getFloat("y", 0);
|
timelines.add(readTimeline(keyMap, new ShearTimeline(timelineMap.size, timelineMap.size, bone.index), 0, 1));
|
||||||
timeline.setFrame(frameIndex, time, x * scale, y * scale);
|
else
|
||||||
valueMap = valueMap.next;
|
|
||||||
if (valueMap == null) {
|
|
||||||
timeline.shrink(bezierIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
|
|
||||||
} else if (timelineName.equals("scale")) {
|
|
||||||
ScaleTimeline timeline = new ScaleTimeline(timelineMap.size, 0, bone.index);
|
|
||||||
float time = valueMap.getFloat("time", 0);
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
|
||||||
float x = valueMap.getFloat("x", 1), y = valueMap.getFloat("y", 1);
|
|
||||||
timeline.setFrame(frameIndex, time, x, y);
|
|
||||||
valueMap = valueMap.next;
|
|
||||||
if (valueMap == null) {
|
|
||||||
timeline.shrink(bezierIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
|
|
||||||
} else if (timelineName.equals("shear")) {
|
|
||||||
ShearTimeline timeline = new ShearTimeline(timelineMap.size, 0, bone.index);
|
|
||||||
float time = valueMap.getFloat("time", 0);
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
|
||||||
float x = valueMap.getFloat("x", 0), y = valueMap.getFloat("y", 0);
|
|
||||||
timeline.setFrame(frameIndex, time, x, y);
|
|
||||||
valueMap = valueMap.next;
|
|
||||||
if (valueMap == null) {
|
|
||||||
timeline.shrink(bezierIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
|
|
||||||
} else
|
|
||||||
throw new RuntimeException("Invalid timeline type for a bone: " + timelineName + " (" + boneMap.name + ")");
|
throw new RuntimeException("Invalid timeline type for a bone: " + timelineName + " (" + boneMap.name + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IK constraint timelines.
|
// IK constraint timelines.
|
||||||
for (JsonValue timelineMap = map.getChild("ik"); timelineMap != null; timelineMap = timelineMap.next) {
|
for (JsonValue timelineMap = map.getChild("ik"); timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
JsonValue valueMap = timelineMap.child;
|
JsonValue keyMap = timelineMap.child;
|
||||||
if (valueMap == null) continue;
|
if (keyMap == null) continue;
|
||||||
IkConstraintData constraint = skeletonData.findIkConstraint(timelineMap.name);
|
IkConstraintData constraint = skeletonData.findIkConstraint(timelineMap.name);
|
||||||
IkConstraintTimeline timeline = new IkConstraintTimeline(timelineMap.size, 0,
|
IkConstraintTimeline timeline = new IkConstraintTimeline(timelineMap.size, timelineMap.size,
|
||||||
skeletonData.getIkConstraints().indexOf(constraint, true));
|
skeletonData.getIkConstraints().indexOf(constraint, true));
|
||||||
float time = valueMap.getFloat("time", 0);
|
float time = keyMap.getFloat("time", 0);
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, time, valueMap.getFloat("mix", 1), valueMap.getFloat("softness", 0) * scale,
|
timeline.setFrame(frameIndex, time, keyMap.getFloat("mix", 1), keyMap.getFloat("softness", 0) * scale,
|
||||||
valueMap.getBoolean("bendPositive", true) ? 1 : -1, valueMap.getBoolean("compress", false),
|
keyMap.getBoolean("bendPositive", true) ? 1 : -1, keyMap.getBoolean("compress", false),
|
||||||
valueMap.getBoolean("stretch", false));
|
keyMap.getBoolean("stretch", false));
|
||||||
valueMap = valueMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (valueMap == null) {
|
if (nextMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
bezierIndex = readCurve(keyMap, timeline, frameIndex, bezierIndex, time, time = nextMap.getFloat("time", 0));
|
||||||
|
keyMap = nextMap;
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform constraint timelines.
|
// Transform constraint timelines.
|
||||||
for (JsonValue timelineMap = map.getChild("transform"); timelineMap != null; timelineMap = timelineMap.next) {
|
for (JsonValue timelineMap = map.getChild("transform"); timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
JsonValue valueMap = timelineMap.child;
|
JsonValue keyMap = timelineMap.child;
|
||||||
if (valueMap == null) continue;
|
if (keyMap == null) continue;
|
||||||
TransformConstraintData constraint = skeletonData.findTransformConstraint(timelineMap.name);
|
TransformConstraintData constraint = skeletonData.findTransformConstraint(timelineMap.name);
|
||||||
TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMap.size, 0,
|
TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMap.size, timelineMap.size,
|
||||||
skeletonData.getTransformConstraints().indexOf(constraint, true));
|
skeletonData.getTransformConstraints().indexOf(constraint, true));
|
||||||
float time = valueMap.getFloat("time", 0);
|
float time = keyMap.getFloat("time", 0);
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, time, valueMap.getFloat("rotateMix", 1), valueMap.getFloat("translateMix", 1),
|
timeline.setFrame(frameIndex, time, keyMap.getFloat("rotateMix", 1), keyMap.getFloat("translateMix", 1),
|
||||||
valueMap.getFloat("scaleMix", 1), valueMap.getFloat("shearMix", 1));
|
keyMap.getFloat("scaleMix", 1), keyMap.getFloat("shearMix", 1));
|
||||||
valueMap = valueMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (valueMap == null) {
|
if (nextMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
bezierIndex = readCurve(keyMap, timeline, frameIndex, bezierIndex, time, time = nextMap.getFloat("time", 0));
|
||||||
|
keyMap = nextMap;
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
@ -664,53 +628,19 @@ public class SkeletonJson {
|
|||||||
if (data == null) throw new SerializationException("Path constraint not found: " + constraintMap.name);
|
if (data == null) throw new SerializationException("Path constraint not found: " + constraintMap.name);
|
||||||
int index = skeletonData.pathConstraints.indexOf(data, true);
|
int index = skeletonData.pathConstraints.indexOf(data, true);
|
||||||
for (JsonValue timelineMap = constraintMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
for (JsonValue timelineMap = constraintMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
JsonValue valueMap = timelineMap.child;
|
JsonValue keyMap = timelineMap.child;
|
||||||
if (valueMap == null) continue;
|
if (keyMap == null) continue;
|
||||||
String timelineName = timelineMap.name;
|
String timelineName = timelineMap.name;
|
||||||
|
|
||||||
if (timelineName.equals("position")) {
|
if (timelineName.equals("position")) {
|
||||||
PathConstraintPositionTimeline timeline = new PathConstraintPositionTimeline(timelineMap.size, 0, index);
|
timelines.add(readTimeline(keyMap, new PathConstraintPositionTimeline(timelineMap.size, timelineMap.size, index),
|
||||||
float timelineScale = data.positionMode == PositionMode.fixed ? scale : 1;
|
0, data.positionMode == PositionMode.fixed ? scale : 1));
|
||||||
float time = valueMap.getFloat("time", 0);
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, valueMap.getFloat(timelineName, 0) * timelineScale);
|
|
||||||
valueMap = valueMap.next;
|
|
||||||
if (valueMap == null) {
|
|
||||||
timeline.shrink(bezierIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
|
|
||||||
} else if (timelineName.equals("spacing")) {
|
} else if (timelineName.equals("spacing")) {
|
||||||
PathConstraintSpacingTimeline timeline = new PathConstraintSpacingTimeline(timelineMap.size, 0, index);
|
timelines.add(readTimeline(keyMap, new PathConstraintSpacingTimeline(timelineMap.size, timelineMap.size, index), 0,
|
||||||
float timelineScale = data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale : 1;
|
data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale : 1));
|
||||||
float time = valueMap.getFloat("time", 0);
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, valueMap.getFloat(timelineName, 0) * timelineScale);
|
|
||||||
valueMap = valueMap.next;
|
|
||||||
if (valueMap == null) {
|
|
||||||
timeline.shrink(bezierIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
|
|
||||||
} else if (timelineName.equals("mix")) {
|
} else if (timelineName.equals("mix")) {
|
||||||
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(timelineMap.size, 0, index);
|
timelines
|
||||||
float time = valueMap.getFloat("time", 0);
|
.add(readTimeline(keyMap, new PathConstraintMixTimeline(timelineMap.size, timelineMap.size, index), 1, 1));
|
||||||
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, time, valueMap.getFloat("rotateMix", 1), valueMap.getFloat("translateMix", 1));
|
|
||||||
valueMap = valueMap.next;
|
|
||||||
if (valueMap == null) {
|
|
||||||
timeline.shrink(bezierIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
|
||||||
}
|
|
||||||
timelines.add(timeline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -723,8 +653,8 @@ public class SkeletonJson {
|
|||||||
SlotData slot = skeletonData.findSlot(slotMap.name);
|
SlotData slot = skeletonData.findSlot(slotMap.name);
|
||||||
if (slot == null) throw new SerializationException("Slot not found: " + slotMap.name);
|
if (slot == null) throw new SerializationException("Slot not found: " + slotMap.name);
|
||||||
for (JsonValue timelineMap = slotMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
for (JsonValue timelineMap = slotMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
JsonValue valueMap = timelineMap.child;
|
JsonValue keyMap = timelineMap.child;
|
||||||
if (valueMap == null) continue;
|
if (keyMap == null) continue;
|
||||||
|
|
||||||
VertexAttachment attachment = (VertexAttachment)skin.getAttachment(slot.index, timelineMap.name);
|
VertexAttachment attachment = (VertexAttachment)skin.getAttachment(slot.index, timelineMap.name);
|
||||||
if (attachment == null) throw new SerializationException("Deform attachment not found: " + timelineMap.name);
|
if (attachment == null) throw new SerializationException("Deform attachment not found: " + timelineMap.name);
|
||||||
@ -732,17 +662,16 @@ public class SkeletonJson {
|
|||||||
float[] vertices = attachment.getVertices();
|
float[] vertices = attachment.getVertices();
|
||||||
int deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
|
int deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
|
||||||
|
|
||||||
DeformTimeline timeline = new DeformTimeline(timelineMap.size, 0, slot.index, attachment);
|
DeformTimeline timeline = new DeformTimeline(timelineMap.size, timelineMap.size, slot.index, attachment);
|
||||||
int bezierIndex = 0;
|
float time = keyMap.getFloat("time", 0);
|
||||||
float time = valueMap.getFloat("time", 0);
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
for (int frameIndex = 0;; frameIndex++) {
|
|
||||||
float[] deform;
|
float[] deform;
|
||||||
JsonValue verticesValue = valueMap.get("vertices");
|
JsonValue verticesValue = keyMap.get("vertices");
|
||||||
if (verticesValue == null)
|
if (verticesValue == null)
|
||||||
deform = weighted ? new float[deformLength] : vertices;
|
deform = weighted ? new float[deformLength] : vertices;
|
||||||
else {
|
else {
|
||||||
deform = new float[deformLength];
|
deform = new float[deformLength];
|
||||||
int start = valueMap.getInt("offset", 0);
|
int start = keyMap.getInt("offset", 0);
|
||||||
arraycopy(verticesValue.asFloatArray(), 0, deform, start, verticesValue.size);
|
arraycopy(verticesValue.asFloatArray(), 0, deform, start, verticesValue.size);
|
||||||
if (scale != 1) {
|
if (scale != 1) {
|
||||||
for (int i = start, n = i + verticesValue.size; i < n; i++)
|
for (int i = start, n = i + verticesValue.size; i < n; i++)
|
||||||
@ -755,12 +684,15 @@ public class SkeletonJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
timeline.setFrame(frameIndex, time, deform);
|
timeline.setFrame(frameIndex, time, deform);
|
||||||
valueMap = valueMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (valueMap == null) break;
|
if (nextMap == null) {
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(keyMap, timeline, frameIndex, bezierIndex, time, time = nextMap.getFloat("time", 0));
|
||||||
|
keyMap = nextMap;
|
||||||
}
|
}
|
||||||
timeline.shrink(bezierIndex);
|
//timelines.add(timeline);
|
||||||
timelines.add(timeline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -830,15 +762,32 @@ public class SkeletonJson {
|
|||||||
skeletonData.animations.add(new Animation(name, timelines, duration));
|
skeletonData.animations.add(new Animation(name, timelines, duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueCurveTimeline readTimeline (JsonValue valueMap, ValueCurveTimeline timeline) {
|
private ValueCurveTimeline readTimeline (JsonValue keyMap, ValueCurveTimeline timeline, float defaultValue, float scale) {
|
||||||
float time = valueMap.getFloat("time", 0), value = valueMap.getFloat("value", 0);
|
float time = keyMap.getFloat("time", 0), value = keyMap.getFloat("value", defaultValue);
|
||||||
int bezierIndex = 0;
|
int bezierIndex = 0;
|
||||||
for (int frameIndex = 0;; frameIndex++) {
|
for (int frameIndex = 0;; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, time, value);
|
timeline.setFrame(frameIndex, time, value);
|
||||||
valueMap = valueMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (valueMap == null) break;
|
if (nextMap == null) break;
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, //
|
bezierIndex = readCurve(keyMap, timeline, frameIndex, bezierIndex, //
|
||||||
time, value, time = valueMap.getFloat("time", 0), value = valueMap.getFloat("value", 0));
|
time, value, time = nextMap.getFloat("time", 0), value = nextMap.getFloat("value", defaultValue));
|
||||||
|
keyMap = nextMap;
|
||||||
|
}
|
||||||
|
timeline.shrink(bezierIndex);
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PercentCurveTimeline2 readTimeline (JsonValue keyMap, PercentCurveTimeline2 timeline, float defaultValue,
|
||||||
|
float scale) {
|
||||||
|
float time = keyMap.getFloat("time", 0);
|
||||||
|
int bezierIndex = 0;
|
||||||
|
for (int frameIndex = 0;; frameIndex++) {
|
||||||
|
float x = keyMap.getFloat("x", defaultValue), y = keyMap.getFloat("y", defaultValue);
|
||||||
|
timeline.setFrame(frameIndex, time, x * scale, y * scale);
|
||||||
|
JsonValue nextMap = keyMap.next;
|
||||||
|
if (nextMap == null) break;
|
||||||
|
bezierIndex = readCurve(keyMap, timeline, frameIndex, bezierIndex, time, time = nextMap.getFloat("time", 0));
|
||||||
|
keyMap = nextMap;
|
||||||
}
|
}
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
return timeline;
|
return timeline;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user