mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-09 16:48:43 +08:00
[libgdx] Added separate keying for translateX/Y, scaleX/Y, shearX/Y, and colorRGB/A.
The first editor version able to export data in this format is 4.0.24-beta. EsotericSoftware/spine-editor#26 EsotericSoftware/spine-editor#27
This commit is contained in:
parent
c223481255
commit
549e9ae67b
@ -187,9 +187,9 @@ public class Animation {
|
||||
in, out
|
||||
}
|
||||
|
||||
static enum Property {
|
||||
static private enum Property {
|
||||
rotate, translateX, translateY, scaleX, scaleY, shearX, shearY, //
|
||||
rgba, rgb2, //
|
||||
rgb, alpha, rgb2, //
|
||||
attachment, deform, //
|
||||
event, drawOrder, //
|
||||
ikConstraint, transformConstraint, //
|
||||
@ -560,6 +560,98 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getX()}. */
|
||||
static public class TranslateXTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
|
||||
public TranslateXTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||
super(frameCount, bezierCount, Property.translateX.ordinal() + "|" + boneIndex);
|
||||
this.boneIndex = boneIndex;
|
||||
}
|
||||
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.x = bone.data.x;
|
||||
return;
|
||||
case first:
|
||||
bone.x += (bone.data.x - bone.x) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float x = getCurveValue(time);
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.x = bone.data.x + x * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bone.x += (bone.data.x + x - bone.x) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.x += x * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getY()}. */
|
||||
static public class TranslateYTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
|
||||
public TranslateYTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||
super(frameCount, bezierCount, Property.translateY.ordinal() + "|" + boneIndex);
|
||||
this.boneIndex = boneIndex;
|
||||
}
|
||||
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.y = bone.data.y;
|
||||
return;
|
||||
case first:
|
||||
bone.y += (bone.data.y - bone.y) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float y = getCurveValue(time);
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.y = bone.data.y + y * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bone.y += (bone.data.y + y - bone.y) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.y += y * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getScaleX()} and {@link Bone#getScaleY()}. */
|
||||
static public class ScaleTimeline extends CurveTimeline2 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
@ -675,6 +767,156 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getScaleX()}. */
|
||||
static public class ScaleXTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
|
||||
public ScaleXTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||
super(frameCount, bezierCount, Property.scaleX.ordinal() + "|" + boneIndex);
|
||||
this.boneIndex = boneIndex;
|
||||
}
|
||||
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.scaleX = bone.data.scaleX;
|
||||
return;
|
||||
case first:
|
||||
bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float x = getCurveValue(time) * bone.data.scaleX;
|
||||
if (alpha == 1) {
|
||||
if (blend == add)
|
||||
bone.scaleX += x - bone.data.scaleX;
|
||||
else
|
||||
bone.scaleX = x;
|
||||
} else {
|
||||
// Mixing out uses sign of setup or current pose, else use sign of key.
|
||||
float bx;
|
||||
if (direction == out) {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bx = bone.data.scaleX;
|
||||
bone.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bx = bone.scaleX;
|
||||
bone.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bx = bone.scaleX;
|
||||
bone.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bone.data.scaleX) * alpha;
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bx = Math.abs(bone.data.scaleX) * Math.signum(x);
|
||||
bone.scaleX = bx + (x - bx) * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bx = Math.abs(bone.scaleX) * Math.signum(x);
|
||||
bone.scaleX = bx + (x - bx) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bx = Math.signum(x);
|
||||
bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getScaleY()}. */
|
||||
static public class ScaleYTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
|
||||
public ScaleYTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||
super(frameCount, bezierCount, Property.scaleY.ordinal() + "|" + boneIndex);
|
||||
this.boneIndex = boneIndex;
|
||||
}
|
||||
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.scaleY = bone.data.scaleY;
|
||||
return;
|
||||
case first:
|
||||
bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float y = getCurveValue(time) * bone.data.scaleY;
|
||||
if (alpha == 1) {
|
||||
if (blend == add)
|
||||
bone.scaleY += y - bone.data.scaleY;
|
||||
else
|
||||
bone.scaleY = y;
|
||||
} else {
|
||||
// Mixing out uses sign of setup or current pose, else use sign of key.
|
||||
float by;
|
||||
if (direction == out) {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
by = bone.data.scaleY;
|
||||
bone.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
by = bone.scaleY;
|
||||
bone.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
|
||||
break;
|
||||
case add:
|
||||
by = bone.scaleY;
|
||||
bone.scaleY = by + (Math.abs(y) * Math.signum(by) - bone.data.scaleY) * alpha;
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
by = Math.abs(bone.data.scaleY) * Math.signum(y);
|
||||
bone.scaleY = by + (y - by) * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
by = Math.abs(bone.scaleY) * Math.signum(y);
|
||||
bone.scaleY = by + (y - by) * alpha;
|
||||
break;
|
||||
case add:
|
||||
by = Math.signum(y);
|
||||
bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getShearX()} and {@link Bone#getShearY()}. */
|
||||
static public class ShearTimeline extends CurveTimeline2 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
@ -747,16 +989,109 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getShearX()}. */
|
||||
static public class ShearXTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
|
||||
public ShearXTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||
super(frameCount, bezierCount, Property.shearX.ordinal() + "|" + boneIndex);
|
||||
this.boneIndex = boneIndex;
|
||||
}
|
||||
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.shearX = bone.data.shearX;
|
||||
return;
|
||||
case first:
|
||||
bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float x = getCurveValue(time);
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.shearX = bone.data.shearX + x * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.shearX += x * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getShearY()}. */
|
||||
static public class ShearYTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
final int boneIndex;
|
||||
|
||||
public ShearYTimeline (int frameCount, int bezierCount, int boneIndex) {
|
||||
super(frameCount, bezierCount, Property.shearY.ordinal() + "|" + boneIndex);
|
||||
this.boneIndex = boneIndex;
|
||||
}
|
||||
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.shearY = bone.data.shearY;
|
||||
return;
|
||||
case first:
|
||||
bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float y = getCurveValue(time);
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.shearY = bone.data.shearY + y * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.shearY += y * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getColor()}. */
|
||||
static public class ColorTimeline extends CurveTimeline implements SlotTimeline {
|
||||
static public class RGBATimeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 5;
|
||||
static private final int R = 1, G = 2, B = 3, A = 4;
|
||||
|
||||
final int slotIndex;
|
||||
|
||||
public ColorTimeline (int frameCount, int bezierCount, int slotIndex) {
|
||||
public RGBATimeline (int frameCount, int bezierCount, int slotIndex) {
|
||||
super(frameCount, bezierCount, //
|
||||
Property.rgba.ordinal() + "|" + slotIndex);
|
||||
Property.rgb.ordinal() + "|" + slotIndex, //
|
||||
Property.alpha.ordinal() + "|" + slotIndex);
|
||||
this.slotIndex = slotIndex;
|
||||
}
|
||||
|
||||
@ -788,12 +1123,12 @@ public class Animation {
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
Color color = slot.color, setup = slot.data.color;
|
||||
switch (blend) {
|
||||
case setup:
|
||||
slot.color.set(slot.data.color);
|
||||
color.set(setup);
|
||||
return;
|
||||
case first:
|
||||
Color color = slot.color, setup = slot.data.color;
|
||||
color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
|
||||
(setup.a - color.a) * alpha);
|
||||
}
|
||||
@ -828,26 +1163,170 @@ public class Animation {
|
||||
a = getBezierValue(time, i, A, curveType + BEZIER_SIZE * 3 - BEZIER);
|
||||
}
|
||||
|
||||
Color color = slot.color;
|
||||
if (alpha == 1)
|
||||
slot.color.set(r, g, b, a);
|
||||
else {
|
||||
Color color = slot.color;
|
||||
if (blend == setup) color.set(slot.data.color);
|
||||
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes the RGB for a slot's {@link Slot#getColor()}. */
|
||||
static public class RGBTimeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 4;
|
||||
static private final int R = 1, G = 2, B = 3;
|
||||
|
||||
final int slotIndex;
|
||||
|
||||
public RGBTimeline (int frameCount, int bezierCount, int slotIndex) {
|
||||
super(frameCount, bezierCount, Property.rgb.ordinal() + "|" + slotIndex);
|
||||
this.slotIndex = slotIndex;
|
||||
}
|
||||
|
||||
public int getFrameEntries () {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time and color for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public void setFrame (int frame, float time, float r, float g, float b) {
|
||||
frame <<= 2;
|
||||
frames[frame] = time;
|
||||
frames[frame + R] = r;
|
||||
frames[frame + G] = g;
|
||||
frames[frame + B] = b;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
Color color = slot.color, setup = slot.data.color;
|
||||
switch (blend) {
|
||||
case setup:
|
||||
color.r = setup.r;
|
||||
color.g = setup.g;
|
||||
color.b = setup.b;
|
||||
return;
|
||||
case first:
|
||||
color.r += (setup.r - color.r) * alpha;
|
||||
color.g += (setup.g - color.g) * alpha;
|
||||
color.b += (setup.b - color.b) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float r, g, b;
|
||||
int i = search(frames, time, ENTRIES), curveType = (int)curves[i >> 2];
|
||||
switch (curveType) {
|
||||
case LINEAR:
|
||||
float before = frames[i];
|
||||
r = frames[i + R];
|
||||
g = frames[i + G];
|
||||
b = frames[i + B];
|
||||
float t = (time - before) / (frames[i + ENTRIES] - before);
|
||||
r += (frames[i + ENTRIES + R] - r) * t;
|
||||
g += (frames[i + ENTRIES + G] - g) * t;
|
||||
b += (frames[i + ENTRIES + B] - b) * t;
|
||||
break;
|
||||
case STEPPED:
|
||||
r = frames[i + R];
|
||||
g = frames[i + G];
|
||||
b = frames[i + B];
|
||||
break;
|
||||
default:
|
||||
r = getBezierValue(time, i, R, curveType - BEZIER);
|
||||
g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
|
||||
b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
|
||||
}
|
||||
|
||||
Color color = slot.color;
|
||||
if (alpha == 1) {
|
||||
color.r = r;
|
||||
color.g = g;
|
||||
color.b = b;
|
||||
} else {
|
||||
if (blend == setup) {
|
||||
Color setup = slot.data.color;
|
||||
color.r = setup.r;
|
||||
color.g = setup.g;
|
||||
color.b = setup.b;
|
||||
}
|
||||
color.r += (r - color.r) * alpha;
|
||||
color.g += (g - color.g) * alpha;
|
||||
color.b += (b - color.b) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes the alpha for a slot's {@link Slot#getColor()}. */
|
||||
static public class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
|
||||
final int slotIndex;
|
||||
|
||||
public AlphaTimeline (int frameCount, int bezierCount, int slotIndex) {
|
||||
super(frameCount, bezierCount, Property.alpha.ordinal() + "|" + slotIndex);
|
||||
this.slotIndex = slotIndex;
|
||||
}
|
||||
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
Color color = slot.color, setup = slot.data.color;
|
||||
switch (blend) {
|
||||
case setup:
|
||||
color.r = setup.r;
|
||||
color.g = setup.g;
|
||||
color.b = setup.b;
|
||||
return;
|
||||
case first:
|
||||
color.r += (setup.r - color.r) * alpha;
|
||||
color.g += (setup.g - color.g) * alpha;
|
||||
color.b += (setup.b - color.b) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float a = getCurveValue(time);
|
||||
if (alpha == 1)
|
||||
slot.color.a = a;
|
||||
else {
|
||||
if (blend == setup) slot.color.a = slot.data.color.a;
|
||||
slot.color.a += (a - slot.color.a) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getColor()} and {@link Slot#getDarkColor()} for two color tinting. */
|
||||
static public class TwoColorTimeline extends CurveTimeline implements SlotTimeline {
|
||||
static public class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 8;
|
||||
static private final int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7;
|
||||
|
||||
final int slotIndex;
|
||||
|
||||
public TwoColorTimeline (int frameCount, int bezierCount, int slotIndex) {
|
||||
public RGBA2Timeline (int frameCount, int bezierCount, int slotIndex) {
|
||||
super(frameCount, bezierCount, //
|
||||
Property.rgba.ordinal() + "|" + slotIndex, //
|
||||
Property.rgb.ordinal() + "|" + slotIndex, //
|
||||
Property.alpha.ordinal() + "|" + slotIndex, //
|
||||
Property.rgb2.ordinal() + "|" + slotIndex);
|
||||
this.slotIndex = slotIndex;
|
||||
}
|
||||
@ -885,16 +1364,20 @@ public class Animation {
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
Color light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
|
||||
switch (blend) {
|
||||
case setup:
|
||||
slot.color.set(slot.data.color);
|
||||
slot.darkColor.set(slot.data.darkColor);
|
||||
light.set(setupLight);
|
||||
dark.r = setupDark.r;
|
||||
dark.g = setupDark.g;
|
||||
dark.b = setupDark.b;
|
||||
return;
|
||||
case first:
|
||||
Color light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
|
||||
light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha,
|
||||
(setupLight.a - light.a) * alpha);
|
||||
dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0);
|
||||
dark.r += (setupDark.r - dark.r) * alpha;
|
||||
dark.g += (setupDark.g - dark.g) * alpha;
|
||||
dark.b += (setupDark.b - dark.b) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -939,17 +1422,152 @@ public class Animation {
|
||||
b2 = getBezierValue(time, i, B2, curveType + BEZIER_SIZE * 6 - BEZIER);
|
||||
}
|
||||
|
||||
Color light = slot.color, dark = slot.darkColor;
|
||||
if (alpha == 1) {
|
||||
slot.color.set(r, g, b, a);
|
||||
slot.darkColor.set(r2, g2, b2, 1);
|
||||
dark.r = r2;
|
||||
dark.g = g2;
|
||||
dark.b = b2;
|
||||
} else {
|
||||
Color light = slot.color, dark = slot.darkColor;
|
||||
if (blend == setup) {
|
||||
light.set(slot.data.color);
|
||||
dark.set(slot.data.darkColor);
|
||||
}
|
||||
light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
|
||||
dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0);
|
||||
dark.r += (r2 - dark.r) * alpha;
|
||||
dark.g += (g2 - dark.g) * alpha;
|
||||
dark.b += (b2 - dark.b) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes the RGB for a slot's {@link Slot#getColor()} and {@link Slot#getDarkColor()} for two color tinting. */
|
||||
static public class RGB2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 7;
|
||||
static private final int R = 1, G = 2, B = 3, R2 = 5, G2 = 6, B2 = 7;
|
||||
|
||||
final int slotIndex;
|
||||
|
||||
public RGB2Timeline (int frameCount, int bezierCount, int slotIndex) {
|
||||
super(frameCount, bezierCount, //
|
||||
Property.rgb.ordinal() + "|" + slotIndex, //
|
||||
Property.rgb2.ordinal() + "|" + slotIndex);
|
||||
this.slotIndex = slotIndex;
|
||||
}
|
||||
|
||||
public int getFrameEntries () {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed when this timeline is applied. The
|
||||
* {@link Slot#getDarkColor()} must not be null. */
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time, light color, and dark color for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public void setFrame (int frame, float time, float r, float g, float b, float r2, float g2, float b2) {
|
||||
frame *= ENTRIES;
|
||||
frames[frame] = time;
|
||||
frames[frame + R] = r;
|
||||
frames[frame + G] = g;
|
||||
frames[frame + B] = b;
|
||||
frames[frame + R2] = r2;
|
||||
frames[frame + G2] = g2;
|
||||
frames[frame + B2] = b2;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
Color light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
|
||||
switch (blend) {
|
||||
case setup:
|
||||
light.r = setupLight.r;
|
||||
light.g = setupLight.g;
|
||||
light.b = setupLight.b;
|
||||
dark.r = setupDark.r;
|
||||
dark.g = setupDark.g;
|
||||
dark.b = setupDark.b;
|
||||
return;
|
||||
case first:
|
||||
light.r += (setupLight.r - light.r) * alpha;
|
||||
light.g += (setupLight.g - light.g) * alpha;
|
||||
light.b += (setupLight.b - light.b) * alpha;
|
||||
dark.r += (setupDark.r - dark.r) * alpha;
|
||||
dark.g += (setupDark.g - dark.g) * alpha;
|
||||
dark.b += (setupDark.b - dark.b) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float r, g, b, r2, g2, b2;
|
||||
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
|
||||
switch (curveType) {
|
||||
case LINEAR:
|
||||
float before = frames[i];
|
||||
r = frames[i + R];
|
||||
g = frames[i + G];
|
||||
b = frames[i + B];
|
||||
r2 = frames[i + R2];
|
||||
g2 = frames[i + G2];
|
||||
b2 = frames[i + B2];
|
||||
float t = (time - before) / (frames[i + ENTRIES] - before);
|
||||
r += (frames[i + ENTRIES + R] - r) * t;
|
||||
g += (frames[i + ENTRIES + G] - g) * t;
|
||||
b += (frames[i + ENTRIES + B] - b) * t;
|
||||
r2 += (frames[i + ENTRIES + R2] - r2) * t;
|
||||
g2 += (frames[i + ENTRIES + G2] - g2) * t;
|
||||
b2 += (frames[i + ENTRIES + B2] - b2) * t;
|
||||
break;
|
||||
case STEPPED:
|
||||
r = frames[i + R];
|
||||
g = frames[i + G];
|
||||
b = frames[i + B];
|
||||
r2 = frames[i + R2];
|
||||
g2 = frames[i + G2];
|
||||
b2 = frames[i + B2];
|
||||
break;
|
||||
default:
|
||||
r = getBezierValue(time, i, R, curveType - BEZIER);
|
||||
g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
|
||||
b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
|
||||
r2 = getBezierValue(time, i, R2, curveType + BEZIER_SIZE * 3 - BEZIER);
|
||||
g2 = getBezierValue(time, i, G2, curveType + BEZIER_SIZE * 4 - BEZIER);
|
||||
b2 = getBezierValue(time, i, B2, curveType + BEZIER_SIZE * 5 - BEZIER);
|
||||
}
|
||||
|
||||
Color light = slot.color, dark = slot.darkColor;
|
||||
if (alpha == 1) {
|
||||
light.r = r;
|
||||
light.g = g;
|
||||
light.b = b;
|
||||
dark.r = r2;
|
||||
dark.g = g2;
|
||||
dark.b = b2;
|
||||
} else {
|
||||
if (blend == setup) {
|
||||
Color setupLight = slot.data.color, setupDark = slot.data.darkColor;
|
||||
light.r = setupLight.r;
|
||||
light.g = setupLight.g;
|
||||
light.b = setupLight.b;
|
||||
dark.r = setupDark.r;
|
||||
dark.g = setupDark.g;
|
||||
dark.b = setupDark.b;
|
||||
}
|
||||
light.r += (r - light.r) * alpha;
|
||||
light.g += (g - light.g) * alpha;
|
||||
light.b += (b - light.b) * alpha;
|
||||
dark.r += (r2 - dark.r) * alpha;
|
||||
dark.g += (g2 - dark.g) * alpha;
|
||||
dark.b += (b2 - dark.b) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,8 +42,8 @@ import com.badlogic.gdx.utils.IntArray;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
import com.badlogic.gdx.utils.SerializationException;
|
||||
|
||||
import com.esotericsoftware.spine.Animation.AlphaTimeline;
|
||||
import com.esotericsoftware.spine.Animation.AttachmentTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ColorTimeline;
|
||||
import com.esotericsoftware.spine.Animation.CurveTimeline;
|
||||
import com.esotericsoftware.spine.Animation.CurveTimeline1;
|
||||
import com.esotericsoftware.spine.Animation.CurveTimeline2;
|
||||
@ -54,13 +54,22 @@ import com.esotericsoftware.spine.Animation.IkConstraintTimeline;
|
||||
import com.esotericsoftware.spine.Animation.PathConstraintMixTimeline;
|
||||
import com.esotericsoftware.spine.Animation.PathConstraintPositionTimeline;
|
||||
import com.esotericsoftware.spine.Animation.PathConstraintSpacingTimeline;
|
||||
import com.esotericsoftware.spine.Animation.RGB2Timeline;
|
||||
import com.esotericsoftware.spine.Animation.RGBA2Timeline;
|
||||
import com.esotericsoftware.spine.Animation.RGBATimeline;
|
||||
import com.esotericsoftware.spine.Animation.RGBTimeline;
|
||||
import com.esotericsoftware.spine.Animation.RotateTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ScaleTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ScaleXTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ScaleYTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ShearTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ShearXTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ShearYTimeline;
|
||||
import com.esotericsoftware.spine.Animation.Timeline;
|
||||
import com.esotericsoftware.spine.Animation.TransformConstraintTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TranslateTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TwoColorTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TranslateXTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TranslateYTimeline;
|
||||
import com.esotericsoftware.spine.BoneData.TransformMode;
|
||||
import com.esotericsoftware.spine.PathConstraintData.PositionMode;
|
||||
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
||||
@ -85,12 +94,21 @@ import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
public class SkeletonBinary extends SkeletonLoader {
|
||||
static public final int BONE_ROTATE = 0;
|
||||
static public final int BONE_TRANSLATE = 1;
|
||||
static public final int BONE_SCALE = 2;
|
||||
static public final int BONE_SHEAR = 3;
|
||||
static public final int BONE_TRANSLATEX = 2;
|
||||
static public final int BONE_TRANSLATEY = 3;
|
||||
static public final int BONE_SCALE = 4;
|
||||
static public final int BONE_SCALEX = 5;
|
||||
static public final int BONE_SCALEY = 6;
|
||||
static public final int BONE_SHEAR = 7;
|
||||
static public final int BONE_SHEARX = 8;
|
||||
static public final int BONE_SHEARY = 9;
|
||||
|
||||
static public final int SLOT_ATTACHMENT = 0;
|
||||
static public final int SLOT_COLOR = 1;
|
||||
static public final int SLOT_TWO_COLOR = 2;
|
||||
static public final int SLOT_RGBA = 1;
|
||||
static public final int SLOT_RGB = 2;
|
||||
static public final int SLOT_ALPHA = 3;
|
||||
static public final int SLOT_RGBA2 = 4;
|
||||
static public final int SLOT_RGB2 = 5;
|
||||
|
||||
static public final int PATH_POSITION = 0;
|
||||
static public final int PATH_SPACING = 1;
|
||||
@ -493,7 +511,7 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
if (nonessential) Color.rgba8888ToColor(point.getColor(), color);
|
||||
return point;
|
||||
}
|
||||
case clipping: {
|
||||
case clipping:
|
||||
int endSlotIndex = input.readInt(true);
|
||||
int vertexCount = input.readInt(true);
|
||||
Vertices vertices = readVertices(input, vertexCount);
|
||||
@ -508,7 +526,6 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
if (nonessential) Color.rgba8888ToColor(clip.getColor(), color);
|
||||
return clip;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -574,8 +591,8 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
timelines.add(timeline);
|
||||
break;
|
||||
}
|
||||
case SLOT_COLOR: {
|
||||
ColorTimeline timeline = new ColorTimeline(frameCount, input.readInt(true), slotIndex);
|
||||
case SLOT_RGBA: {
|
||||
RGBATimeline timeline = new RGBATimeline(frameCount, input.readInt(true), slotIndex);
|
||||
float time = input.readFloat();
|
||||
float r = input.read() / 255f, g = input.read() / 255f;
|
||||
float b = input.read() / 255f, a = input.read() / 255f;
|
||||
@ -604,21 +621,48 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
timelines.add(timeline);
|
||||
break;
|
||||
}
|
||||
case SLOT_TWO_COLOR: {
|
||||
TwoColorTimeline timeline = new TwoColorTimeline(frameCount, input.readInt(true), slotIndex);
|
||||
case SLOT_ALPHA:
|
||||
timelines.add(readTimeline(input, new AlphaTimeline(frameCount, input.readInt(true), input.readInt(true)), 1));
|
||||
break;
|
||||
case SLOT_RGB: {
|
||||
RGBTimeline timeline = new RGBTimeline(frameCount, input.readInt(true), slotIndex);
|
||||
float time = input.readFloat();
|
||||
float r = input.read() / 255f, g = input.read() / 255f, b = input.read() / 255f;
|
||||
for (int frame = 0, bezier = 0;; frame++) {
|
||||
timeline.setFrame(frame, time, r, g, b);
|
||||
if (frame == frameLast) break;
|
||||
float time2 = input.readFloat();
|
||||
float r2 = input.read() / 255f, g2 = input.read() / 255f, b2 = input.read() / 255f;
|
||||
switch (input.readByte()) {
|
||||
case CURVE_STEPPED:
|
||||
timeline.setStepped(frame);
|
||||
break;
|
||||
case CURVE_BEZIER:
|
||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1);
|
||||
}
|
||||
time = time2;
|
||||
r = r2;
|
||||
g = g2;
|
||||
b = b2;
|
||||
}
|
||||
timelines.add(timeline);
|
||||
break;
|
||||
}
|
||||
case SLOT_RGBA2: {
|
||||
RGBA2Timeline timeline = new RGBA2Timeline(frameCount, input.readInt(true), slotIndex);
|
||||
float time = input.readFloat();
|
||||
float r = input.read() / 255f, g = input.read() / 255f;
|
||||
float b = input.read() / 255f, a = input.read() / 255f;
|
||||
float r2 = input.read() / 255f, g2 = input.read() / 255f;
|
||||
float b2 = input.read() / 255f;
|
||||
float r2 = input.read() / 255f, g2 = input.read() / 255f, b2 = input.read() / 255f;
|
||||
for (int frame = 0, bezier = 0;; frame++) {
|
||||
timeline.setFrame(frame, time, r, g, b, a, r2, g2, b2);
|
||||
if (frame == frameLast) break;
|
||||
float time2 = input.readFloat();
|
||||
float nr = input.read() / 255f, ng = input.read() / 255f;
|
||||
float nb = input.read() / 255f, na = input.read() / 255f;
|
||||
float nr2 = input.read() / 255f, ng2 = input.read() / 255f;
|
||||
float nb2 = input.read() / 255f;
|
||||
float nr2 = input.read() / 255f, ng2 = input.read() / 255f, nb2 = input.read() / 255f;
|
||||
switch (input.readByte()) {
|
||||
case CURVE_STEPPED:
|
||||
timeline.setStepped(frame);
|
||||
@ -644,6 +688,39 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
timelines.add(timeline);
|
||||
break;
|
||||
}
|
||||
case SLOT_RGB2:
|
||||
RGB2Timeline timeline = new RGB2Timeline(frameCount, input.readInt(true), slotIndex);
|
||||
float time = input.readFloat();
|
||||
float r = input.read() / 255f, g = input.read() / 255f, b = input.read() / 255f;
|
||||
float r2 = input.read() / 255f, g2 = input.read() / 255f, b2 = input.read() / 255f;
|
||||
for (int frame = 0, bezier = 0;; frame++) {
|
||||
timeline.setFrame(frame, time, r, g, b, r2, g2, b2);
|
||||
if (frame == frameLast) break;
|
||||
float time2 = input.readFloat();
|
||||
float nr = input.read() / 255f, ng = input.read() / 255f, nb = input.read() / 255f;
|
||||
float nr2 = input.read() / 255f, ng2 = input.read() / 255f, nb2 = input.read() / 255f;
|
||||
switch (input.readByte()) {
|
||||
case CURVE_STEPPED:
|
||||
timeline.setStepped(frame);
|
||||
break;
|
||||
case CURVE_BEZIER:
|
||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1);
|
||||
}
|
||||
time = time2;
|
||||
r = nr;
|
||||
g = ng;
|
||||
b = nb;
|
||||
r2 = nr2;
|
||||
g2 = ng2;
|
||||
b2 = nb2;
|
||||
}
|
||||
timelines.add(timeline);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -652,19 +729,37 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
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()) {
|
||||
int type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true);
|
||||
switch (type) {
|
||||
case BONE_ROTATE:
|
||||
timelines.add(readTimeline(input, new RotateTimeline(input.readInt(true), input.readInt(true), boneIndex), 1));
|
||||
timelines.add(readTimeline(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1));
|
||||
break;
|
||||
case BONE_TRANSLATE:
|
||||
timelines
|
||||
.add(readTimeline(input, new TranslateTimeline(input.readInt(true), input.readInt(true), boneIndex), scale));
|
||||
timelines.add(readTimeline(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale));
|
||||
break;
|
||||
case BONE_TRANSLATEX:
|
||||
timelines.add(readTimeline(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale));
|
||||
break;
|
||||
case BONE_TRANSLATEY:
|
||||
timelines.add(readTimeline(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale));
|
||||
break;
|
||||
case BONE_SCALE:
|
||||
timelines.add(readTimeline(input, new ScaleTimeline(input.readInt(true), input.readInt(true), boneIndex), 1));
|
||||
timelines.add(readTimeline(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1));
|
||||
break;
|
||||
case BONE_SCALEX:
|
||||
timelines.add(readTimeline(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1));
|
||||
break;
|
||||
case BONE_SCALEY:
|
||||
timelines.add(readTimeline(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1));
|
||||
break;
|
||||
case BONE_SHEAR:
|
||||
timelines.add(readTimeline(input, new ShearTimeline(input.readInt(true), input.readInt(true), boneIndex), 1));
|
||||
timelines.add(readTimeline(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1));
|
||||
break;
|
||||
case BONE_SHEARX:
|
||||
timelines.add(readTimeline(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1));
|
||||
break;
|
||||
case BONE_SHEARY:
|
||||
timelines.add(readTimeline(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,8 +41,8 @@ import com.badlogic.gdx.utils.JsonReader;
|
||||
import com.badlogic.gdx.utils.JsonValue;
|
||||
import com.badlogic.gdx.utils.SerializationException;
|
||||
|
||||
import com.esotericsoftware.spine.Animation.AlphaTimeline;
|
||||
import com.esotericsoftware.spine.Animation.AttachmentTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ColorTimeline;
|
||||
import com.esotericsoftware.spine.Animation.CurveTimeline;
|
||||
import com.esotericsoftware.spine.Animation.CurveTimeline1;
|
||||
import com.esotericsoftware.spine.Animation.CurveTimeline2;
|
||||
@ -53,13 +53,22 @@ import com.esotericsoftware.spine.Animation.IkConstraintTimeline;
|
||||
import com.esotericsoftware.spine.Animation.PathConstraintMixTimeline;
|
||||
import com.esotericsoftware.spine.Animation.PathConstraintPositionTimeline;
|
||||
import com.esotericsoftware.spine.Animation.PathConstraintSpacingTimeline;
|
||||
import com.esotericsoftware.spine.Animation.RGB2Timeline;
|
||||
import com.esotericsoftware.spine.Animation.RGBA2Timeline;
|
||||
import com.esotericsoftware.spine.Animation.RGBATimeline;
|
||||
import com.esotericsoftware.spine.Animation.RGBTimeline;
|
||||
import com.esotericsoftware.spine.Animation.RotateTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ScaleTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ScaleXTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ScaleYTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ShearTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ShearXTimeline;
|
||||
import com.esotericsoftware.spine.Animation.ShearYTimeline;
|
||||
import com.esotericsoftware.spine.Animation.Timeline;
|
||||
import com.esotericsoftware.spine.Animation.TransformConstraintTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TranslateTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TwoColorTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TranslateXTimeline;
|
||||
import com.esotericsoftware.spine.Animation.TranslateYTimeline;
|
||||
import com.esotericsoftware.spine.BoneData.TransformMode;
|
||||
import com.esotericsoftware.spine.PathConstraintData.PositionMode;
|
||||
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
||||
@ -435,7 +444,7 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
if (color != null) Color.valueOf(color, point.getColor());
|
||||
return point;
|
||||
}
|
||||
case clipping: {
|
||||
case clipping:
|
||||
ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name);
|
||||
if (clip == null) return null;
|
||||
|
||||
@ -452,7 +461,6 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
if (color != null) Color.valueOf(color, clip.getColor());
|
||||
return clip;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -502,10 +510,10 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
timeline.setFrame(frame, keyMap.getFloat("time", 0), keyMap.getString("name"));
|
||||
timelines.add(timeline);
|
||||
|
||||
} else if (timelineName.equals("color")) {
|
||||
ColorTimeline timeline = new ColorTimeline(timelineMap.size, timelineMap.size << 2, slot.index);
|
||||
} else if (timelineName.equals("rgba")) {
|
||||
RGBATimeline timeline = new RGBATimeline(timelineMap.size, timelineMap.size << 2, slot.index);
|
||||
float time = keyMap.getFloat("time", 0);
|
||||
String color = keyMap.getString("color");
|
||||
String color = keyMap.getString("rgba");
|
||||
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float g = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float b = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
@ -518,7 +526,7 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
break;
|
||||
}
|
||||
float time2 = nextMap.getFloat("time", 0);
|
||||
color = nextMap.getString("color");
|
||||
color = nextMap.getString("rgba");
|
||||
float nr = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float ng = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float nb = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
@ -539,8 +547,44 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
}
|
||||
timelines.add(timeline);
|
||||
|
||||
} else if (timelineName.equals("twoColor")) {
|
||||
TwoColorTimeline timeline = new TwoColorTimeline(timelineMap.size, timelineMap.size * 7, slot.index);
|
||||
} else if (timelineName.equals("rgb")) {
|
||||
RGBTimeline timeline = new RGBTimeline(timelineMap.size, timelineMap.size * 3, slot.index);
|
||||
float time = keyMap.getFloat("time", 0);
|
||||
String color = keyMap.getString("rgb");
|
||||
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float g = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float b = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
for (int frame = 0, bezier = 0;; frame++) {
|
||||
timeline.setFrame(frame, time, r, g, b);
|
||||
JsonValue nextMap = keyMap.next;
|
||||
if (nextMap == null) {
|
||||
timeline.shrink(bezier);
|
||||
break;
|
||||
}
|
||||
float time2 = nextMap.getFloat("time", 0);
|
||||
color = nextMap.getString("rgb");
|
||||
float nr = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float ng = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float nb = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
JsonValue curve = keyMap.get("curve");
|
||||
if (curve != null) {
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr, 1);
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng, 1);
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb, 1);
|
||||
}
|
||||
time = time2;
|
||||
r = nr;
|
||||
g = ng;
|
||||
b = nb;
|
||||
keyMap = nextMap;
|
||||
}
|
||||
timelines.add(timeline);
|
||||
|
||||
} else if (timelineName.equals("alpha")) {
|
||||
timelines.add(readTimeline(keyMap, new AlphaTimeline(timelineMap.size, timelineMap.size, slot.index), 0, 1));
|
||||
|
||||
} else if (timelineName.equals("rgba2")) {
|
||||
RGBA2Timeline timeline = new RGBA2Timeline(timelineMap.size, timelineMap.size * 7, slot.index);
|
||||
float time = keyMap.getFloat("time", 0);
|
||||
String color = keyMap.getString("light");
|
||||
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
@ -590,6 +634,53 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
}
|
||||
timelines.add(timeline);
|
||||
|
||||
} else if (timelineName.equals("rgb2")) {
|
||||
RGB2Timeline timeline = new RGB2Timeline(timelineMap.size, timelineMap.size * 6, slot.index);
|
||||
float time = keyMap.getFloat("time", 0);
|
||||
String color = keyMap.getString("light");
|
||||
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float g = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float b = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
color = keyMap.getString("dark");
|
||||
float r2 = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float g2 = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float b2 = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
for (int frame = 0, bezier = 0;; frame++) {
|
||||
timeline.setFrame(frame, time, r, g, b, r2, g2, b2);
|
||||
JsonValue nextMap = keyMap.next;
|
||||
if (nextMap == null) {
|
||||
timeline.shrink(bezier);
|
||||
break;
|
||||
}
|
||||
float time2 = nextMap.getFloat("time", 0);
|
||||
color = nextMap.getString("light");
|
||||
float nr = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float ng = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float nb = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
color = nextMap.getString("dark");
|
||||
float nr2 = Integer.parseInt(color.substring(0, 2), 16) / 255f;
|
||||
float ng2 = Integer.parseInt(color.substring(2, 4), 16) / 255f;
|
||||
float nb2 = Integer.parseInt(color.substring(4, 6), 16) / 255f;
|
||||
JsonValue curve = keyMap.get("curve");
|
||||
if (curve != null) {
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr, 1);
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng, 1);
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb, 1);
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, r2, nr2, 1);
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, g2, ng2, 1);
|
||||
bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, b2, nb2, 1);
|
||||
}
|
||||
time = time2;
|
||||
r = nr;
|
||||
g = ng;
|
||||
b = nb;
|
||||
r2 = nr2;
|
||||
g2 = ng2;
|
||||
b2 = nb2;
|
||||
keyMap = nextMap;
|
||||
}
|
||||
timelines.add(timeline);
|
||||
|
||||
} else
|
||||
throw new RuntimeException("Invalid timeline type for a slot: " + timelineName + " (" + slotMap.name + ")");
|
||||
}
|
||||
@ -609,13 +700,27 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
else if (timelineName.equals("translate")) {
|
||||
TranslateTimeline timeline = new TranslateTimeline(timelineMap.size, timelineMap.size << 1, bone.index);
|
||||
timelines.add(readTimeline(keyMap, timeline, "x", "y", 0, scale));
|
||||
} else if (timelineName.equals("translatex")) {
|
||||
timelines
|
||||
.add(readTimeline(keyMap, new TranslateXTimeline(timelineMap.size, timelineMap.size, bone.index), 0, scale));
|
||||
} else if (timelineName.equals("translatey")) {
|
||||
timelines
|
||||
.add(readTimeline(keyMap, new TranslateYTimeline(timelineMap.size, timelineMap.size, bone.index), 0, scale));
|
||||
} else if (timelineName.equals("scale")) {
|
||||
ScaleTimeline timeline = new ScaleTimeline(timelineMap.size, timelineMap.size << 1, bone.index);
|
||||
timelines.add(readTimeline(keyMap, timeline, "x", "y", 1, 1));
|
||||
} else if (timelineName.equals("shear")) {
|
||||
} else if (timelineName.equals("scalex"))
|
||||
timelines.add(readTimeline(keyMap, new ScaleXTimeline(timelineMap.size, timelineMap.size, bone.index), 1, 1));
|
||||
else if (timelineName.equals("scaley"))
|
||||
timelines.add(readTimeline(keyMap, new ScaleYTimeline(timelineMap.size, timelineMap.size, bone.index), 1, 1));
|
||||
else if (timelineName.equals("shear")) {
|
||||
ShearTimeline timeline = new ShearTimeline(timelineMap.size, timelineMap.size << 1, bone.index);
|
||||
timelines.add(readTimeline(keyMap, timeline, "x", "y", 0, 1));
|
||||
} else
|
||||
} else if (timelineName.equals("shearx"))
|
||||
timelines.add(readTimeline(keyMap, new ShearXTimeline(timelineMap.size, timelineMap.size, bone.index), 0, 1));
|
||||
else if (timelineName.equals("sheary"))
|
||||
timelines.add(readTimeline(keyMap, new ShearYTimeline(timelineMap.size, timelineMap.size, bone.index), 0, 1));
|
||||
else
|
||||
throw new RuntimeException("Invalid timeline type for a bone: " + timelineName + " (" + boneMap.name + ")");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user