mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
Use time for Bezier segments rather than percent.
Saves calculating the percent between frames for the Bezier path.
This commit is contained in:
parent
927b9cf866
commit
f165ffeb1c
@ -270,8 +270,7 @@ public class Animation {
|
|||||||
float[] curves;
|
float[] curves;
|
||||||
|
|
||||||
/** @param frameEntries The number of entries stored per frame.
|
/** @param frameEntries The number of entries stored per frame.
|
||||||
* @param bezierCount The number of frames that will use Bezier curves, used to reduce allocations. Pass 0 if unknown, which
|
* @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}.
|
||||||
* will allocate for <code>frameCount</code> Bezier curves (see {@link #shrink(int)}).
|
|
||||||
* @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);
|
||||||
@ -290,9 +289,7 @@ public class Animation {
|
|||||||
curves[frameIndex] = STEPPED;
|
curves[frameIndex] = STEPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the specified key frame to Bezier interpolation.
|
int setBezier (int frameIndex, int bezierIndex) {
|
||||||
* @param frameIndex Between 0 and <code>frameCount - 1</code>. */
|
|
||||||
protected int setBezier (int frameIndex, int bezierIndex) {
|
|
||||||
int index = getFrameCount() - 1 + bezierIndex * BEZIER_SIZE;
|
int index = getFrameCount() - 1 + bezierIndex * BEZIER_SIZE;
|
||||||
curves[frameIndex] = BEZIER + index;
|
curves[frameIndex] = BEZIER + index;
|
||||||
return index;
|
return index;
|
||||||
@ -311,7 +308,8 @@ public class Animation {
|
|||||||
return BEZIER;
|
return BEZIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Shrinks the storage for Bezier curves, for use when <code>bezierCount</code> specified in the constructor was 0. */
|
/** Shrinks the storage for Bezier curves, for use when <code>bezierCount</code> specified in the constructor was larger
|
||||||
|
* than the actual number of Bezier curves. */
|
||||||
public void shrink (int bezierCount) {
|
public void shrink (int bezierCount) {
|
||||||
int size = getFrameCount() - 1 + bezierCount * BEZIER_SIZE;
|
int size = getFrameCount() - 1 + bezierCount * BEZIER_SIZE;
|
||||||
if (curves.length > size) {
|
if (curves.length > size) {
|
||||||
@ -325,24 +323,27 @@ public class Animation {
|
|||||||
/** The base class for timelines that use interpolation between key frames for one or more properties using a percentage of the
|
/** The base class for timelines that use interpolation between key frames for one or more properties using a percentage of the
|
||||||
* difference between values. */
|
* difference between values. */
|
||||||
static public abstract class PercentCurveTimeline extends CurveTimeline {
|
static public abstract class PercentCurveTimeline extends CurveTimeline {
|
||||||
public PercentCurveTimeline (int frameCount, int frameEntries, int bezierIndex, String... propertyIds) {
|
/** @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}.
|
||||||
super(frameCount, frameEntries, bezierIndex, propertyIds);
|
* @param propertyIds Unique identifiers for each property the timeline modifies. */
|
||||||
|
public PercentCurveTimeline (int frameCount, int frameEntries, int bezierCount, String... propertyIds) {
|
||||||
|
super(frameCount, frameEntries, bezierCount, propertyIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the specified key frame to Bezier interpolation.
|
/** Sets the specified key frame to Bezier interpolation.
|
||||||
* <p>
|
* @param frameIndex Between 0 and <code>frameCount - 1</code>.
|
||||||
* <code>cx1</code> and <code>cx2</code> are from 0 to 1, representing the percent of time between the two key frames.
|
* @param cx1 The time for the first Bezier handle.
|
||||||
* <p>
|
* @param cy1 The percentage of the difference between the key frame's values for the first Bezier handle.
|
||||||
* <code>cy1</code> and <code>cy2</code> are the percent of the difference between the key frame's values.
|
* @param cx2 The time of the second Bezier handle.
|
||||||
* @param frameIndex Between 0 and <code>frameCount - 1</code>. */
|
* @param cy2 The percentage of the difference between the key frame's values for the second Bezier handle. */
|
||||||
public void setBezier (int frameIndex, int bezierIndex, float cx1, float cy1, float cx2, float cy2) {
|
public void setBezier (int frameIndex, int bezierIndex, float time1, float cx1, float cy1, float cx2, float cy2,
|
||||||
|
float time2) {
|
||||||
int i = setBezier(frameIndex, bezierIndex);
|
int i = setBezier(frameIndex, bezierIndex);
|
||||||
float[] curves = this.curves;
|
float[] curves = this.curves;
|
||||||
float tmpx = cx2 * 0.03f - cx1 * 0.06f, tmpy = cy2 * 0.03f - cy1 * 0.06f;
|
float tmpx = (time1 - cx1 * 2 + cx2) * 0.03f, tmpy = cy2 * 0.03f - cy1 * 0.06f;
|
||||||
float dddx = (cx1 - cx2 + 0.33333333f) * 0.018f, dddy = (cy1 - cy2 + 0.33333333f) * 0.018f;
|
float dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006f, dddy = (cy1 - cy2 + 0.33333333f) * 0.018f;
|
||||||
float ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;
|
float ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;
|
||||||
float dx = cx1 * 0.3f + tmpx + dddx * 0.16666667f, dy = cy1 * 0.3f + tmpy + dddy * 0.16666667f;
|
float dx = (cx1 - time1) * 0.3f + tmpx + dddx * 0.16666667f, dy = cy1 * 0.3f + tmpy + dddy * 0.16666667f;
|
||||||
float x = dx, y = dy;
|
float x = time1 + dx, y = dy;
|
||||||
for (int n = i + BEZIER_SIZE; i < n; i += 2) {
|
for (int n = i + BEZIER_SIZE; i < n; i += 2) {
|
||||||
curves[i] = x;
|
curves[i] = x;
|
||||||
curves[i + 1] = y;
|
curves[i + 1] = y;
|
||||||
@ -360,21 +361,19 @@ public class Animation {
|
|||||||
public float getCurvePercent (int frameIndex, float time, float time1, float time2) {
|
public float getCurvePercent (int frameIndex, float time, float time1, float time2) {
|
||||||
float[] curves = this.curves;
|
float[] curves = this.curves;
|
||||||
int i = (int)curves[frameIndex];
|
int i = (int)curves[frameIndex];
|
||||||
|
if (i == LINEAR) return MathUtils.clamp((time - time1) / (time2 - time1), 0, 1);
|
||||||
if (i == STEPPED) return 0;
|
if (i == STEPPED) return 0;
|
||||||
float percent = MathUtils.clamp((time - time1) / (time2 - time1), 0, 1);
|
|
||||||
if (i == LINEAR) return percent;
|
|
||||||
i -= BEZIER;
|
i -= BEZIER;
|
||||||
float x = 0;
|
if (curves[i] > time) return curves[i + 1] * (time - time1) / (curves[i] - time1);
|
||||||
for (int start = i, n = i + BEZIER_SIZE; i < n; i += 2) {
|
i += 2;
|
||||||
x = curves[i];
|
for (int n = i + BEZIER_SIZE - 2; i < n; i += 2) {
|
||||||
if (x >= percent) {
|
if (curves[i] >= time) {
|
||||||
if (i == start) return curves[i + 1] * percent / x; // First point is 0,0.
|
float x = curves[i - 2], y = curves[i - 1];
|
||||||
float prevX = curves[i - 2], prevY = curves[i - 1];
|
return y + (curves[i + 1] - y) * (time - x) / (curves[i] - x);
|
||||||
return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float y = curves[i - 1];
|
float x = curves[i - 2], y = curves[i - 1];
|
||||||
return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
|
return y + (1 - y) * (time - x) / (time2 - x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,8 +384,10 @@ public class Animation {
|
|||||||
static final int PREV_TIME = -2, PREV_VALUE = -1;
|
static final int PREV_TIME = -2, PREV_VALUE = -1;
|
||||||
static final int VALUE = 1;
|
static final int VALUE = 1;
|
||||||
|
|
||||||
public ValueCurveTimeline (int frameCount, int bezierIndex, String... propertyIds) {
|
/** @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}.
|
||||||
super(frameCount, 2, bezierIndex, propertyIds);
|
* @param propertyIds Unique identifiers for each property the timeline modifies. */
|
||||||
|
public ValueCurveTimeline (int frameCount, int bezierCount, String... propertyIds) {
|
||||||
|
super(frameCount, 2, bezierCount, propertyIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFrameCount () {
|
public int getFrameCount () {
|
||||||
@ -401,53 +402,50 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the specified key frame to Bezier interpolation.
|
/** Sets the specified key frame to Bezier interpolation.
|
||||||
* <p>
|
* @param frameIndex Between 0 and <code>frameCount - 1</code>.
|
||||||
* <code>y1</code> and <code>y2</code> are the key frame values for this and the next frame.
|
* @param cx1 The time for the first Bezier handle.
|
||||||
* <p>
|
* @param cy1 The value for the first Bezier handle.
|
||||||
* <code>cx1</code> and <code>cx2</code> are from 0 to 1, representing the percent of time between the two key frames.
|
* @param cx2 The time of the second Bezier handle.
|
||||||
* <p>
|
* @param cy2 The value for the second Bezier handle. */
|
||||||
* <code>cy1</code> and <code>cy2</code> are in the key frames' value space.
|
public void setBezier (int frameIndex, int bezierIndex, float time1, float value1, float cx1, float cy1, float cx2,
|
||||||
* @param frameIndex Between 0 and <code>frameCount - 1</code>. */
|
float cy2, float time2, float value2) {
|
||||||
public void setBezier (int frameIndex, int bezierIndex, float y1, float cx1, float cy1, float cx2, float cy2, float y2) {
|
|
||||||
int i = setBezier(frameIndex, bezierIndex);
|
int i = setBezier(frameIndex, bezierIndex);
|
||||||
float[] curves = this.curves;
|
float[] curves = this.curves;
|
||||||
float tmpx = cx2 * 0.03f - cx1 * 0.06f, tmpy = (y1 - cy1 * 2 + cy2) * 0.03f;
|
float tmpx = (time1 - cx1 * 2 + cx2) * 0.03f, tmpy = (value1 - cy1 * 2 + cy2) * 0.03f;
|
||||||
float dddfx = (cx1 - cx2 + 0.33333333f) * 0.018f, dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006f;
|
float dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006f, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 0.006f;
|
||||||
float ddx = tmpx * 2 + dddfx, ddy = tmpy * 2 + dddfy;
|
float ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;
|
||||||
float dx = cx1 * 0.3f + tmpx + dddfx * 0.16666667f, dy = (cy1 - y1) * 0.3f + tmpy + dddfy * 0.16666667f;
|
float dx = (cx1 - time1) * 0.3f + tmpx + dddx * 0.16666667f, dy = (cy1 - value1) * 0.3f + tmpy + dddy * 0.16666667f;
|
||||||
float x = dx, y = y1 + dy;
|
float x = time1 + dx, y = value1 + dy;
|
||||||
for (int n = i + BEZIER_SIZE; i < n; i += 2) {
|
for (int n = i + BEZIER_SIZE; i < n; i += 2) {
|
||||||
curves[i] = x;
|
curves[i] = x;
|
||||||
curves[i + 1] = y;
|
curves[i + 1] = y;
|
||||||
dx += ddx;
|
dx += ddx;
|
||||||
dy += ddy;
|
dy += ddy;
|
||||||
ddx += dddfx;
|
ddx += dddx;
|
||||||
ddy += dddfy;
|
ddy += dddy;
|
||||||
x += dx;
|
x += dx;
|
||||||
y += dy;
|
y += dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the interpolated value for the specified key frame and times.
|
/** Returns the interpolated value for the specified key frame, times, and values.
|
||||||
* @param frameIndex Between 0 and <code>frameCount - 1</code>. */
|
* @param frameIndex Between 0 and <code>frameCount - 1</code>. */
|
||||||
public float getCurveValue (int frameIndex, float time, float time1, float value1, float time2, float value2) {
|
public float getCurveValue (int frameIndex, float time, float time1, float value1, float time2, float value2) {
|
||||||
float[] curves = this.curves;
|
float[] curves = this.curves;
|
||||||
int i = (int)curves[frameIndex];
|
int i = (int)curves[frameIndex];
|
||||||
|
if (i == LINEAR) return value1 + (value2 - value1) * MathUtils.clamp((time - time1) / (time2 - time1), 0, 1);
|
||||||
if (i == STEPPED) return value1;
|
if (i == STEPPED) return value1;
|
||||||
float percent = MathUtils.clamp((time - time1) / (time2 - time1), 0, 1);
|
|
||||||
if (i == LINEAR) return value1 + (value2 - value1) * percent;
|
|
||||||
i -= BEZIER;
|
i -= BEZIER;
|
||||||
float x = 0;
|
if (curves[i] > time) return value1 + (curves[i + 1] - value1) * (time - value1) / (curves[i] - value1);
|
||||||
for (int start = i, n = i + BEZIER_SIZE; i < n; i += 2) {
|
i += 2;
|
||||||
x = curves[i];
|
for (int n = i + BEZIER_SIZE - 2; i < n; i += 2) {
|
||||||
if (x >= percent) {
|
if (curves[i] >= time) {
|
||||||
if (i == start) return value1 + (curves[i + 1] - value1) * percent / x; // First point is 0,value1.
|
float x = curves[i - 2], y = curves[i - 1];
|
||||||
float prevY = curves[i - 1], prevX = curves[i - 2];
|
return y + (curves[i + 1] - y) * (time - x) / (curves[i] - x);
|
||||||
return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float y = curves[i - 1];
|
float x = curves[i - 2], y = curves[i - 1];
|
||||||
return y + (value2 - y) * (percent - x) / (1 - x); // Last point is 1,value2.
|
return y + (value2 - y) * (time - x) / (time2 - x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -593,24 +593,26 @@ public class SkeletonBinary {
|
|||||||
}
|
}
|
||||||
case SLOT_COLOR: {
|
case SLOT_COLOR: {
|
||||||
ColorTimeline timeline = new ColorTimeline(frameCount, input.readInt(true), slotIndex);
|
ColorTimeline timeline = new ColorTimeline(frameCount, input.readInt(true), slotIndex);
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
float time = input.readFloat();
|
float time = input.readFloat();
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
Color.rgba8888ToColor(tempColor1, input.readInt());
|
Color.rgba8888ToColor(tempColor1, input.readInt());
|
||||||
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a);
|
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a);
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SLOT_TWO_COLOR: {
|
case SLOT_TWO_COLOR: {
|
||||||
TwoColorTimeline timeline = new TwoColorTimeline(frameCount, input.readInt(true), slotIndex);
|
TwoColorTimeline timeline = new TwoColorTimeline(frameCount, input.readInt(true), slotIndex);
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
float time = input.readFloat();
|
float time = input.readFloat();
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
Color.rgba8888ToColor(tempColor1, input.readInt());
|
Color.rgba8888ToColor(tempColor1, input.readInt());
|
||||||
Color.rgb888ToColor(tempColor2, input.readInt());
|
Color.rgb888ToColor(tempColor2, input.readInt());
|
||||||
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r,
|
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r,
|
||||||
tempColor2.g, tempColor2.b);
|
tempColor2.g, tempColor2.b);
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
@ -628,38 +630,44 @@ public class SkeletonBinary {
|
|||||||
switch (timelineType) {
|
switch (timelineType) {
|
||||||
case BONE_ROTATE: {
|
case BONE_ROTATE: {
|
||||||
RotateTimeline timeline = new RotateTimeline(frameCount, input.readInt(true), boneIndex);
|
RotateTimeline timeline = new RotateTimeline(frameCount, input.readInt(true), boneIndex);
|
||||||
float value = input.readFloat();
|
float time = input.readFloat(), value = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), value);
|
timeline.setFrame(frameIndex, time, value);
|
||||||
if (frameIndex < frameLast)
|
if (frameIndex < frameLast) readCurve(input, timeline, frameIndex, bezierIndex, time, value,
|
||||||
readCurve(input, timeline, frameIndex, bezierIndex, value, value = input.readFloat());
|
time = input.readFloat(), value = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BONE_TRANSLATE: {
|
case BONE_TRANSLATE: {
|
||||||
TranslateTimeline timeline = new TranslateTimeline(frameCount, input.readInt(true), boneIndex);
|
TranslateTimeline timeline = new TranslateTimeline(frameCount, input.readInt(true), boneIndex);
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * scale, input.readFloat() * scale);
|
timeline.setFrame(frameIndex, time, input.readFloat() * scale, input.readFloat() * scale);
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BONE_SCALE: {
|
case BONE_SCALE: {
|
||||||
ScaleTimeline timeline = new ScaleTimeline(frameCount, input.readInt(true), boneIndex);
|
ScaleTimeline timeline = new ScaleTimeline(frameCount, input.readInt(true), boneIndex);
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat());
|
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat());
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BONE_SHEAR: {
|
case BONE_SHEAR: {
|
||||||
ShearTimeline timeline = new ShearTimeline(frameCount, input.readInt(true), boneIndex);
|
ShearTimeline timeline = new ShearTimeline(frameCount, input.readInt(true), boneIndex);
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat());
|
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat());
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
@ -673,10 +681,12 @@ public class SkeletonBinary {
|
|||||||
int index = input.readInt(true);
|
int index = input.readInt(true);
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||||
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index);
|
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index);
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat() * scale, input.readByte(),
|
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat() * scale, input.readByte(),
|
||||||
input.readBoolean(), input.readBoolean());
|
input.readBoolean(), input.readBoolean());
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
@ -686,10 +696,11 @@ public class SkeletonBinary {
|
|||||||
int index = input.readInt(true);
|
int index = input.readInt(true);
|
||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||||
TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index);
|
TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index);
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(),
|
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());
|
||||||
input.readFloat());
|
if (frameIndex < frameLast)
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
@ -707,9 +718,11 @@ public class SkeletonBinary {
|
|||||||
index);
|
index);
|
||||||
float timelineScale = data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale
|
float timelineScale = data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale
|
||||||
: 1;
|
: 1;
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale);
|
timeline.setFrame(frameIndex, time, input.readFloat() * timelineScale);
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
@ -718,18 +731,22 @@ public class SkeletonBinary {
|
|||||||
PathConstraintPositionTimeline timeline = new PathConstraintPositionTimeline(frameCount, input.readInt(true),
|
PathConstraintPositionTimeline timeline = new PathConstraintPositionTimeline(frameCount, input.readInt(true),
|
||||||
index);
|
index);
|
||||||
float timelineScale = data.positionMode == PositionMode.fixed ? scale : 1;
|
float timelineScale = data.positionMode == PositionMode.fixed ? scale : 1;
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale);
|
timeline.setFrame(frameIndex, time, input.readFloat() * timelineScale);
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PATH_MIX: {
|
case PATH_MIX: {
|
||||||
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount, input.readInt(true), index);
|
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount, input.readInt(true), index);
|
||||||
|
float time = input.readFloat();
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat());
|
timeline.setFrame(frameIndex, time, input.readFloat(), input.readFloat());
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
break;
|
break;
|
||||||
@ -752,8 +769,8 @@ public class SkeletonBinary {
|
|||||||
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
int frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||||
DeformTimeline timeline = new DeformTimeline(frameCount, input.readInt(true), slotIndex, attachment);
|
DeformTimeline timeline = new DeformTimeline(frameCount, input.readInt(true), slotIndex, attachment);
|
||||||
|
|
||||||
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
||||||
float time = input.readFloat();
|
float time = input.readFloat();
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
float[] deform;
|
float[] deform;
|
||||||
int end = input.readInt(true);
|
int end = input.readInt(true);
|
||||||
if (end == 0)
|
if (end == 0)
|
||||||
@ -776,7 +793,8 @@ public class SkeletonBinary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
timeline.setFrame(frameIndex, time, deform);
|
timeline.setFrame(frameIndex, time, deform);
|
||||||
if (frameIndex < frameLast) bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex);
|
if (frameIndex < frameLast)
|
||||||
|
bezierIndex = readCurve(input, timeline, frameIndex, bezierIndex, time, time = input.readFloat());
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
@ -845,28 +863,29 @@ public class SkeletonBinary {
|
|||||||
return new Animation(name, timelines, duration);
|
return new Animation(name, timelines, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
int readCurve (SkeletonInput input, PercentCurveTimeline timeline, int frameIndex, int bezierIndex) throws IOException {
|
int readCurve (SkeletonInput input, PercentCurveTimeline timeline, int frameIndex, int bezierIndex, float time1, float time2)
|
||||||
switch (input.readByte()) {
|
|
||||||
case CURVE_STEPPED:
|
|
||||||
timeline.setStepped(frameIndex);
|
|
||||||
break;
|
|
||||||
case CURVE_BEZIER:
|
|
||||||
timeline.setBezier(frameIndex, bezierIndex++, input.readFloat(), input.readFloat(), input.readFloat(),
|
|
||||||
input.readFloat());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return bezierIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int readCurve (SkeletonInput input, ValueCurveTimeline timeline, int frameIndex, int bezierIndex, float value1, float value2)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
switch (input.readByte()) {
|
switch (input.readByte()) {
|
||||||
case CURVE_STEPPED:
|
case CURVE_STEPPED:
|
||||||
timeline.setStepped(frameIndex);
|
timeline.setStepped(frameIndex);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
timeline.setBezier(frameIndex, bezierIndex++, value1, input.readFloat(), input.readFloat(), input.readFloat(),
|
timeline.setBezier(frameIndex, bezierIndex++, time1, input.readFloat(), input.readFloat(), input.readFloat(),
|
||||||
input.readFloat(), value2);
|
input.readFloat(), time2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return bezierIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readCurve (SkeletonInput input, ValueCurveTimeline timeline, int frameIndex, int bezierIndex, float time1, float value1,
|
||||||
|
float time2, float value2) throws IOException {
|
||||||
|
switch (input.readByte()) {
|
||||||
|
case CURVE_STEPPED:
|
||||||
|
timeline.setStepped(frameIndex);
|
||||||
|
break;
|
||||||
|
case CURVE_BEZIER:
|
||||||
|
timeline.setBezier(frameIndex, bezierIndex++, time1, value1, input.readFloat(), input.readFloat(), input.readFloat(),
|
||||||
|
input.readFloat(), time2, value2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return bezierIndex;
|
return bezierIndex;
|
||||||
|
|||||||
@ -507,34 +507,45 @@ 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;
|
||||||
|
if (valueMap == null) continue;
|
||||||
String timelineName = timelineMap.name;
|
String timelineName = timelineMap.name;
|
||||||
int frameIndex = 0, bezierIndex = 0;
|
|
||||||
|
|
||||||
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 (JsonValue valueMap = timelineMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++)
|
for (int frameIndex = 0; valueMap != null; valueMap = valueMap.next, frameIndex++)
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.getString("name"));
|
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.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, 0, slot.index);
|
||||||
for (JsonValue valueMap = timelineMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = timelineMap.child.getFloat("time", 0);
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
Color color = Color.valueOf(valueMap.getString("color"));
|
Color color = Color.valueOf(valueMap.getString("color"));
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), color.r, color.g, color.b, color.a);
|
timeline.setFrame(frameIndex, time, color.r, color.g, color.b, color.a);
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
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, 0, slot.index);
|
||||||
for (JsonValue valueMap = timelineMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = timelineMap.child.getFloat("time", 0);
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
Color light = Color.valueOf(valueMap.getString("light")), dark = Color.valueOf(valueMap.getString("dark"));
|
Color light = Color.valueOf(valueMap.getString("light")), dark = Color.valueOf(valueMap.getString("dark"));
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), 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);
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
@ -550,49 +561,53 @@ public class SkeletonJson {
|
|||||||
JsonValue valueMap = timelineMap.child;
|
JsonValue valueMap = timelineMap.child;
|
||||||
if (valueMap == null) continue;
|
if (valueMap == null) continue;
|
||||||
String timelineName = timelineMap.name;
|
String timelineName = timelineMap.name;
|
||||||
int frameIndex = 0, bezierIndex = 0;
|
|
||||||
|
|
||||||
if (timelineName.equals("rotate")) {
|
if (timelineName.equals("rotate")) {
|
||||||
RotateTimeline timeline = new RotateTimeline(timelineMap.size, 0, bone.index);
|
timelines.add(readTimeline(valueMap, new RotateTimeline(timelineMap.size, 0, bone.index)));
|
||||||
float rotation = valueMap.getFloat("angle", 0);
|
|
||||||
for (;; frameIndex++) {
|
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), rotation);
|
|
||||||
valueMap = valueMap.next;
|
|
||||||
if (valueMap == null) break;
|
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, rotation,
|
|
||||||
rotation = valueMap.getFloat("angle", 0));
|
|
||||||
}
|
|
||||||
timeline.shrink(bezierIndex);
|
|
||||||
timelines.add(timeline);
|
|
||||||
|
|
||||||
} else if (timelineName.equals("translate")) {
|
} else if (timelineName.equals("translate")) {
|
||||||
TranslateTimeline timeline = new TranslateTimeline(timelineMap.size, 0, bone.index);
|
TranslateTimeline timeline = new TranslateTimeline(timelineMap.size, 0, bone.index);
|
||||||
for (; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = valueMap.getFloat("time", 0);
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
float x = valueMap.getFloat("x", 0), y = valueMap.getFloat("y", 0);
|
float x = valueMap.getFloat("x", 0), y = valueMap.getFloat("y", 0);
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), x * scale, y * scale);
|
timeline.setFrame(frameIndex, time, x * scale, y * scale);
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else if (timelineName.equals("scale")) {
|
} else if (timelineName.equals("scale")) {
|
||||||
ScaleTimeline timeline = new ScaleTimeline(timelineMap.size, 0, bone.index);
|
ScaleTimeline timeline = new ScaleTimeline(timelineMap.size, 0, bone.index);
|
||||||
for (; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = valueMap.getFloat("time", 0);
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
float x = valueMap.getFloat("x", 1), y = valueMap.getFloat("y", 1);
|
float x = valueMap.getFloat("x", 1), y = valueMap.getFloat("y", 1);
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), x, y);
|
timeline.setFrame(frameIndex, time, x, y);
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else if (timelineName.equals("shear")) {
|
} else if (timelineName.equals("shear")) {
|
||||||
ShearTimeline timeline = new ShearTimeline(timelineMap.size, 0, bone.index);
|
ShearTimeline timeline = new ShearTimeline(timelineMap.size, 0, bone.index);
|
||||||
for (; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = valueMap.getFloat("time", 0);
|
||||||
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
float x = valueMap.getFloat("x", 0), y = valueMap.getFloat("y", 0);
|
float x = valueMap.getFloat("x", 0), y = valueMap.getFloat("y", 0);
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), x, y);
|
timeline.setFrame(frameIndex, time, x, y);
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
@ -601,33 +616,45 @@ public class SkeletonJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IK constraint timelines.
|
// IK constraint timelines.
|
||||||
for (JsonValue constraintMap = map.getChild("ik"); constraintMap != null; constraintMap = constraintMap.next) {
|
for (JsonValue timelineMap = map.getChild("ik"); timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
IkConstraintData constraint = skeletonData.findIkConstraint(constraintMap.name);
|
JsonValue valueMap = timelineMap.child;
|
||||||
IkConstraintTimeline timeline = new IkConstraintTimeline(constraintMap.size, 0,
|
if (valueMap == null) continue;
|
||||||
|
IkConstraintData constraint = skeletonData.findIkConstraint(timelineMap.name);
|
||||||
|
IkConstraintTimeline timeline = new IkConstraintTimeline(timelineMap.size, 0,
|
||||||
skeletonData.getIkConstraints().indexOf(constraint, true));
|
skeletonData.getIkConstraints().indexOf(constraint, true));
|
||||||
int frameIndex = 0, bezierIndex = 0;
|
float time = valueMap.getFloat("time", 0);
|
||||||
for (JsonValue valueMap = constraintMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.getFloat("mix", 1),
|
timeline.setFrame(frameIndex, time, valueMap.getFloat("mix", 1), valueMap.getFloat("softness", 0) * scale,
|
||||||
valueMap.getFloat("softness", 0) * scale, valueMap.getBoolean("bendPositive", true) ? 1 : -1,
|
valueMap.getBoolean("bendPositive", true) ? 1 : -1, valueMap.getBoolean("compress", false),
|
||||||
valueMap.getBoolean("compress", false), valueMap.getBoolean("stretch", false));
|
valueMap.getBoolean("stretch", false));
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform constraint timelines.
|
// Transform constraint timelines.
|
||||||
for (JsonValue constraintMap = map.getChild("transform"); constraintMap != null; constraintMap = constraintMap.next) {
|
for (JsonValue timelineMap = map.getChild("transform"); timelineMap != null; timelineMap = timelineMap.next) {
|
||||||
TransformConstraintData constraint = skeletonData.findTransformConstraint(constraintMap.name);
|
JsonValue valueMap = timelineMap.child;
|
||||||
TransformConstraintTimeline timeline = new TransformConstraintTimeline(constraintMap.size, 0,
|
if (valueMap == null) continue;
|
||||||
|
TransformConstraintData constraint = skeletonData.findTransformConstraint(timelineMap.name);
|
||||||
|
TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMap.size, 0,
|
||||||
skeletonData.getTransformConstraints().indexOf(constraint, true));
|
skeletonData.getTransformConstraints().indexOf(constraint, true));
|
||||||
int frameIndex = 0, bezierIndex = 0;
|
float time = valueMap.getFloat("time", 0);
|
||||||
for (JsonValue valueMap = constraintMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.getFloat("rotateMix", 1),
|
timeline.setFrame(frameIndex, time, valueMap.getFloat("rotateMix", 1), valueMap.getFloat("translateMix", 1),
|
||||||
valueMap.getFloat("translateMix", 1), valueMap.getFloat("scaleMix", 1), valueMap.getFloat("shearMix", 1));
|
valueMap.getFloat("scaleMix", 1), valueMap.getFloat("shearMix", 1));
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,37 +664,52 @@ 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;
|
||||||
|
if (valueMap == null) continue;
|
||||||
String timelineName = timelineMap.name;
|
String timelineName = timelineMap.name;
|
||||||
int frameIndex = 0, bezierIndex = 0;
|
|
||||||
|
|
||||||
if (timelineName.equals("position")) {
|
if (timelineName.equals("position")) {
|
||||||
PathConstraintPositionTimeline timeline = new PathConstraintPositionTimeline(timelineMap.size, 0, index);
|
PathConstraintPositionTimeline timeline = new PathConstraintPositionTimeline(timelineMap.size, 0, index);
|
||||||
float timelineScale = data.positionMode == PositionMode.fixed ? scale : 1;
|
float timelineScale = data.positionMode == PositionMode.fixed ? scale : 1;
|
||||||
for (JsonValue valueMap = timelineMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = valueMap.getFloat("time", 0);
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.getFloat(timelineName, 0) * timelineScale);
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
timeline.setFrame(frameIndex, time, valueMap.getFloat(timelineName, 0) * timelineScale);
|
||||||
}
|
valueMap = valueMap.next;
|
||||||
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else if (timelineName.equals("spacing")) {
|
} else if (timelineName.equals("spacing")) {
|
||||||
PathConstraintSpacingTimeline timeline = new PathConstraintSpacingTimeline(timelineMap.size, 0, index);
|
PathConstraintSpacingTimeline timeline = new PathConstraintSpacingTimeline(timelineMap.size, 0, index);
|
||||||
float timelineScale = data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale : 1;
|
float timelineScale = data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale : 1;
|
||||||
for (JsonValue valueMap = timelineMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = valueMap.getFloat("time", 0);
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.getFloat(timelineName, 0) * timelineScale);
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
timeline.setFrame(frameIndex, time, valueMap.getFloat(timelineName, 0) * timelineScale);
|
||||||
}
|
valueMap = valueMap.next;
|
||||||
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
|
|
||||||
} else if (timelineName.equals("mix")) {
|
} else if (timelineName.equals("mix")) {
|
||||||
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(timelineMap.size, 0, index);
|
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(timelineMap.size, 0, index);
|
||||||
for (JsonValue valueMap = timelineMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = valueMap.getFloat("time", 0);
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), valueMap.getFloat("rotateMix", 1),
|
for (int frameIndex = 0, bezierIndex = 0;; frameIndex++) {
|
||||||
valueMap.getFloat("translateMix", 1));
|
timeline.setFrame(frameIndex, time, valueMap.getFloat("rotateMix", 1), valueMap.getFloat("translateMix", 1));
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
}
|
if (valueMap == null) {
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
|
}
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,6 +723,9 @@ 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;
|
||||||
|
if (valueMap == 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);
|
||||||
boolean weighted = attachment.getBones() != null;
|
boolean weighted = attachment.getBones() != null;
|
||||||
@ -688,8 +733,9 @@ public class SkeletonJson {
|
|||||||
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, 0, slot.index, attachment);
|
||||||
int frameIndex = 0, bezierIndex = 0;
|
int bezierIndex = 0;
|
||||||
for (JsonValue valueMap = timelineMap.child; valueMap != null; valueMap = valueMap.next, frameIndex++) {
|
float time = valueMap.getFloat("time", 0);
|
||||||
|
for (int frameIndex = 0;; frameIndex++) {
|
||||||
float[] deform;
|
float[] deform;
|
||||||
JsonValue verticesValue = valueMap.get("vertices");
|
JsonValue verticesValue = valueMap.get("vertices");
|
||||||
if (verticesValue == null)
|
if (verticesValue == null)
|
||||||
@ -708,8 +754,10 @@ public class SkeletonJson {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeline.setFrame(frameIndex, valueMap.getFloat("time", 0), deform);
|
timeline.setFrame(frameIndex, time, deform);
|
||||||
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex);
|
valueMap = valueMap.next;
|
||||||
|
if (valueMap == null) break;
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, time, time = valueMap.getFloat("time", 0));
|
||||||
}
|
}
|
||||||
timeline.shrink(bezierIndex);
|
timeline.shrink(bezierIndex);
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
@ -782,27 +830,42 @@ public class SkeletonJson {
|
|||||||
skeletonData.animations.add(new Animation(name, timelines, duration));
|
skeletonData.animations.add(new Animation(name, timelines, duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
int readCurve (JsonValue map, PercentCurveTimeline timeline, int frameIndex, int bezierIndex) {
|
private ValueCurveTimeline readTimeline (JsonValue valueMap, ValueCurveTimeline timeline) {
|
||||||
|
float time = valueMap.getFloat("time", 0), value = valueMap.getFloat("value", 0);
|
||||||
|
int bezierIndex = 0;
|
||||||
|
for (int frameIndex = 0;; frameIndex++) {
|
||||||
|
timeline.setFrame(frameIndex, time, value);
|
||||||
|
valueMap = valueMap.next;
|
||||||
|
if (valueMap == null) break;
|
||||||
|
bezierIndex = readCurve(valueMap, timeline, frameIndex, bezierIndex, //
|
||||||
|
time, value, time = valueMap.getFloat("time", 0), value = valueMap.getFloat("value", 0));
|
||||||
|
}
|
||||||
|
timeline.shrink(bezierIndex);
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readCurve (JsonValue map, PercentCurveTimeline timeline, int frameIndex, int bezierIndex, float time1, float time2) {
|
||||||
JsonValue curve = map.get("curve");
|
JsonValue curve = map.get("curve");
|
||||||
if (curve != null) {
|
if (curve != null) {
|
||||||
if (curve.isString())
|
if (curve.isString())
|
||||||
timeline.setStepped(frameIndex);
|
timeline.setStepped(frameIndex);
|
||||||
else {
|
else {
|
||||||
timeline.setBezier(frameIndex, bezierIndex++, curve.asFloat(), map.getFloat("c2", 0), map.getFloat("c3", 1),
|
timeline.setBezier(frameIndex, bezierIndex++, time1, curve.asFloat(), map.getFloat("c2", 0), map.getFloat("c3", 1),
|
||||||
map.getFloat("c4", 1));
|
map.getFloat("c4", 1), time2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bezierIndex;
|
return bezierIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
int readCurve (JsonValue map, ValueCurveTimeline timeline, int frameIndex, int bezierIndex, float value1, float value2) {
|
int readCurve (JsonValue map, ValueCurveTimeline timeline, int frameIndex, int bezierIndex, float time1, float value1,
|
||||||
|
float time2, float value2) {
|
||||||
JsonValue curve = map.get("curve");
|
JsonValue curve = map.get("curve");
|
||||||
if (curve != null) {
|
if (curve != null) {
|
||||||
if (curve.isString())
|
if (curve.isString())
|
||||||
timeline.setStepped(frameIndex);
|
timeline.setStepped(frameIndex);
|
||||||
else {
|
else {
|
||||||
timeline.setBezier(frameIndex, bezierIndex++, value1, curve.asFloat(), map.getFloat("c2", 0), map.getFloat("c3", 1),
|
timeline.setBezier(frameIndex, bezierIndex++, time1, value1, curve.asFloat(), map.getFloat("c2", 0),
|
||||||
map.getFloat("c4", 1), value2);
|
map.getFloat("c3", 1), map.getFloat("c4", 1), time2, value2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bezierIndex;
|
return bezierIndex;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user