[libgdx] Refactor to prefer switch with arrows.

This commit is contained in:
Nathan Sweet 2025-05-14 12:52:45 -04:00
parent 4895329215
commit ab46181a0d
5 changed files with 241 additions and 246 deletions

View File

@ -411,25 +411,23 @@ public class Animation {
} }
int curveType = (int)curves[i >> 1]; int curveType = (int)curves[i >> 1];
switch (curveType) { return switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i], value = frames[i + VALUE]; float before = frames[i], value = frames[i + VALUE];
return value + (time - before) / (frames[i + ENTRIES] - before) * (frames[i + ENTRIES + VALUE] - value); yield value + (time - before) / (frames[i + ENTRIES] - before) * (frames[i + ENTRIES + VALUE] - value);
case STEPPED:
return frames[i + VALUE];
} }
return getBezierValue(time, i, VALUE, curveType - BEZIER); case STEPPED -> frames[i + VALUE];
default -> getBezierValue(time, i, VALUE, curveType - BEZIER);
};
} }
public float getRelativeValue (float time, float alpha, MixBlend blend, float current, float setup) { public float getRelativeValue (float time, float alpha, MixBlend blend, float current, float setup) {
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { return switch (blend) {
case setup: case setup -> setup;
return setup; case first -> current + (setup - current) * alpha;
case first: default -> current;
return current + (setup - current) * alpha; };
}
return current;
} }
float value = getCurveValue(time); float value = getCurveValue(time);
switch (blend) { switch (blend) {
@ -444,13 +442,11 @@ public class Animation {
public float getAbsoluteValue (float time, float alpha, MixBlend blend, float current, float setup) { public float getAbsoluteValue (float time, float alpha, MixBlend blend, float current, float setup) {
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { return switch (blend) {
case setup: case setup -> setup;
return setup; case first -> current + (setup - current) * alpha;
case first: default -> current;
return current + (setup - current) * alpha; };
}
return current;
} }
float value = getCurveValue(time); float value = getCurveValue(time);
if (blend == MixBlend.setup) return setup + (value - setup) * alpha; if (blend == MixBlend.setup) return setup + (value - setup) * alpha;
@ -459,13 +455,11 @@ public class Animation {
public float getAbsoluteValue (float time, float alpha, MixBlend blend, float current, float setup, float value) { public float getAbsoluteValue (float time, float alpha, MixBlend blend, float current, float setup, float value) {
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { return switch (blend) {
case setup: case setup -> setup;
return setup; case first -> current + (setup - current) * alpha;
case first: default -> current;
return current + (setup - current) * alpha; };
}
return current;
} }
if (blend == MixBlend.setup) return setup + (value - setup) * alpha; if (blend == MixBlend.setup) return setup + (value - setup) * alpha;
return current + (value - current) * alpha; return current + (value - current) * alpha;
@ -474,19 +468,14 @@ public class Animation {
public float getScaleValue (float time, float alpha, MixBlend blend, MixDirection direction, float current, float setup) { public float getScaleValue (float time, float alpha, MixBlend blend, MixDirection direction, float current, float setup) {
float[] frames = this.frames; float[] frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { return switch (blend) {
case setup: case setup -> setup;
return setup; case first -> current + (setup - current) * alpha;
case first: default -> current;
return current + (setup - current) * alpha; };
}
return current;
} }
float value = getCurveValue(time) * setup; float value = getCurveValue(time) * setup;
if (alpha == 1) { if (alpha == 1) return blend == add ? current + value - setup : value;
if (blend == add) return current + value - setup;
return value;
}
// Mixing out uses sign of setup or current pose, else use sign of key. // Mixing out uses sign of setup or current pose, else use sign of key.
if (direction == out) { if (direction == out) {
switch (blend) { switch (blend) {
@ -604,53 +593,55 @@ public class Animation {
float[] frames = this.frames; float[] frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.x = setup.x; pose.x = setup.x;
pose.y = setup.y; pose.y = setup.y;
return; }
case first: case first -> {
pose.x += (setup.x - pose.x) * alpha; pose.x += (setup.x - pose.x) * alpha;
pose.y += (setup.y - pose.y) * alpha; pose.y += (setup.y - pose.y) * alpha;
} }
}
return; return;
} }
float x, y; float x, y;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
x = frames[i + VALUE1]; x = frames[i + VALUE1];
y = frames[i + VALUE2]; y = frames[i + VALUE2];
float t = (time - before) / (frames[i + ENTRIES] - before); float t = (time - before) / (frames[i + ENTRIES] - before);
x += (frames[i + ENTRIES + VALUE1] - x) * t; x += (frames[i + ENTRIES + VALUE1] - x) * t;
y += (frames[i + ENTRIES + VALUE2] - y) * t; y += (frames[i + ENTRIES + VALUE2] - y) * t;
break; }
case STEPPED: case STEPPED -> {
x = frames[i + VALUE1]; x = frames[i + VALUE1];
y = frames[i + VALUE2]; y = frames[i + VALUE2];
break; }
default: default -> {
x = getBezierValue(time, i, VALUE1, curveType - BEZIER); x = getBezierValue(time, i, VALUE1, curveType - BEZIER);
y = getBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER); y = getBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER);
} }
}
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.x = setup.x + x * alpha; pose.x = setup.x + x * alpha;
pose.y = setup.y + y * alpha; pose.y = setup.y + y * alpha;
break; }
case first: case first, replace -> {
case replace:
pose.x += (setup.x + x - pose.x) * alpha; pose.x += (setup.x + x - pose.x) * alpha;
pose.y += (setup.y + y - pose.y) * alpha; pose.y += (setup.y + y - pose.y) * alpha;
break; }
case add: case add -> {
pose.x += x * alpha; pose.x += x * alpha;
pose.y += y * alpha; pose.y += y * alpha;
} }
} }
} }
}
/** Changes a bone's local {@link BoneLocal#getX()}. */ /** Changes a bone's local {@link BoneLocal#getX()}. */
static public class TranslateXTimeline extends BoneTimeline1 { static public class TranslateXTimeline extends BoneTimeline1 {
@ -684,36 +675,38 @@ public class Animation {
float[] frames = this.frames; float[] frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.scaleX = setup.scaleX; pose.scaleX = setup.scaleX;
pose.scaleY = setup.scaleY; pose.scaleY = setup.scaleY;
return; }
case first: case first -> {
pose.scaleX += (setup.scaleX - pose.scaleX) * alpha; pose.scaleX += (setup.scaleX - pose.scaleX) * alpha;
pose.scaleY += (setup.scaleY - pose.scaleY) * alpha; pose.scaleY += (setup.scaleY - pose.scaleY) * alpha;
} }
}
return; return;
} }
float x, y; float x, y;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
x = frames[i + VALUE1]; x = frames[i + VALUE1];
y = frames[i + VALUE2]; y = frames[i + VALUE2];
float t = (time - before) / (frames[i + ENTRIES] - before); float t = (time - before) / (frames[i + ENTRIES] - before);
x += (frames[i + ENTRIES + VALUE1] - x) * t; x += (frames[i + ENTRIES + VALUE1] - x) * t;
y += (frames[i + ENTRIES + VALUE2] - y) * t; y += (frames[i + ENTRIES + VALUE2] - y) * t;
break; }
case STEPPED: case STEPPED -> {
x = frames[i + VALUE1]; x = frames[i + VALUE1];
y = frames[i + VALUE2]; y = frames[i + VALUE2];
break; }
default: default -> {
x = getBezierValue(time, i, VALUE1, curveType - BEZIER); x = getBezierValue(time, i, VALUE1, curveType - BEZIER);
y = getBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER); y = getBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER);
} }
}
x *= setup.scaleX; x *= setup.scaleX;
y *= setup.scaleY; y *= setup.scaleY;
@ -730,39 +723,38 @@ public class Animation {
float bx, by; float bx, by;
if (direction == out) { if (direction == out) {
switch (blend) { switch (blend) {
case setup: case setup -> {
bx = setup.scaleX; bx = setup.scaleX;
by = setup.scaleY; by = setup.scaleY;
pose.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha; pose.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
pose.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha; pose.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
break; }
case first: case first, replace -> {
case replace:
bx = pose.scaleX; bx = pose.scaleX;
by = pose.scaleY; by = pose.scaleY;
pose.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha; pose.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
pose.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha; pose.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
break; }
case add: case add -> {
pose.scaleX += (x - setup.scaleX) * alpha; pose.scaleX += (x - setup.scaleX) * alpha;
pose.scaleY += (y - setup.scaleY) * alpha; pose.scaleY += (y - setup.scaleY) * alpha;
} }
}
} else { } else {
switch (blend) { switch (blend) {
case setup: case setup -> {
bx = Math.abs(setup.scaleX) * Math.signum(x); bx = Math.abs(setup.scaleX) * Math.signum(x);
by = Math.abs(setup.scaleY) * Math.signum(y); by = Math.abs(setup.scaleY) * Math.signum(y);
pose.scaleX = bx + (x - bx) * alpha; pose.scaleX = bx + (x - bx) * alpha;
pose.scaleY = by + (y - by) * alpha; pose.scaleY = by + (y - by) * alpha;
break; }
case first: case first, replace -> {
case replace:
bx = Math.abs(pose.scaleX) * Math.signum(x); bx = Math.abs(pose.scaleX) * Math.signum(x);
by = Math.abs(pose.scaleY) * Math.signum(y); by = Math.abs(pose.scaleY) * Math.signum(y);
pose.scaleX = bx + (x - bx) * alpha; pose.scaleX = bx + (x - bx) * alpha;
pose.scaleY = by + (y - by) * alpha; pose.scaleY = by + (y - by) * alpha;
break; }
case add: case add -> {
pose.scaleX += (x - setup.scaleX) * alpha; pose.scaleX += (x - setup.scaleX) * alpha;
pose.scaleY += (y - setup.scaleY) * alpha; pose.scaleY += (y - setup.scaleY) * alpha;
} }
@ -770,6 +762,7 @@ public class Animation {
} }
} }
} }
}
/** Changes a bone's local {@link BoneLocal#getScaleX()}. */ /** Changes a bone's local {@link BoneLocal#getScaleX()}. */
static public class ScaleXTimeline extends BoneTimeline1 { static public class ScaleXTimeline extends BoneTimeline1 {
@ -803,53 +796,55 @@ public class Animation {
float[] frames = this.frames; float[] frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.shearX = setup.shearX; pose.shearX = setup.shearX;
pose.shearY = setup.shearY; pose.shearY = setup.shearY;
return; }
case first: case first -> {
pose.shearX += (setup.shearX - pose.shearX) * alpha; pose.shearX += (setup.shearX - pose.shearX) * alpha;
pose.shearY += (setup.shearY - pose.shearY) * alpha; pose.shearY += (setup.shearY - pose.shearY) * alpha;
} }
}
return; return;
} }
float x, y; float x, y;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
x = frames[i + VALUE1]; x = frames[i + VALUE1];
y = frames[i + VALUE2]; y = frames[i + VALUE2];
float t = (time - before) / (frames[i + ENTRIES] - before); float t = (time - before) / (frames[i + ENTRIES] - before);
x += (frames[i + ENTRIES + VALUE1] - x) * t; x += (frames[i + ENTRIES + VALUE1] - x) * t;
y += (frames[i + ENTRIES + VALUE2] - y) * t; y += (frames[i + ENTRIES + VALUE2] - y) * t;
break; }
case STEPPED: case STEPPED -> {
x = frames[i + VALUE1]; x = frames[i + VALUE1];
y = frames[i + VALUE2]; y = frames[i + VALUE2];
break; }
default: default -> {
x = getBezierValue(time, i, VALUE1, curveType - BEZIER); x = getBezierValue(time, i, VALUE1, curveType - BEZIER);
y = getBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER); y = getBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER);
} }
}
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.shearX = setup.shearX + x * alpha; pose.shearX = setup.shearX + x * alpha;
pose.shearY = setup.shearY + y * alpha; pose.shearY = setup.shearY + y * alpha;
break; }
case first: case first, replace -> {
case replace:
pose.shearX += (setup.shearX + x - pose.shearX) * alpha; pose.shearX += (setup.shearX + x - pose.shearX) * alpha;
pose.shearY += (setup.shearY + y - pose.shearY) * alpha; pose.shearY += (setup.shearY + y - pose.shearY) * alpha;
break; }
case add: case add -> {
pose.shearX += x * alpha; pose.shearX += x * alpha;
pose.shearY += y * alpha; pose.shearY += y * alpha;
} }
} }
} }
}
/** Changes a bone's local {@link BoneLocal#getShearX()}. */ /** Changes a bone's local {@link BoneLocal#getShearX()}. */
static public class ShearXTimeline extends BoneTimeline1 { static public class ShearXTimeline extends BoneTimeline1 {
@ -977,11 +972,8 @@ public class Animation {
if (time < frames[0]) { if (time < frames[0]) {
Color setup = slot.data.setup.color; Color setup = slot.data.setup.color;
switch (blend) { switch (blend) {
case setup: case setup -> color.set(setup);
color.set(setup); case first -> color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
return;
case first:
color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
(setup.a - color.a) * alpha); (setup.a - color.a) * alpha);
} }
return; return;
@ -990,7 +982,7 @@ public class Animation {
float r, g, b, a; float r, g, b, a;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
@ -1001,19 +993,20 @@ public class Animation {
g += (frames[i + ENTRIES + G] - g) * t; g += (frames[i + ENTRIES + G] - g) * t;
b += (frames[i + ENTRIES + B] - b) * t; b += (frames[i + ENTRIES + B] - b) * t;
a += (frames[i + ENTRIES + A] - a) * t; a += (frames[i + ENTRIES + A] - a) * t;
break; }
case STEPPED: case STEPPED -> {
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
b = frames[i + B]; b = frames[i + B];
a = frames[i + A]; a = frames[i + A];
break; }
default: default -> {
r = getBezierValue(time, i, R, curveType - BEZIER); r = getBezierValue(time, i, R, curveType - BEZIER);
g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER); g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER); b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
a = getBezierValue(time, i, A, curveType + BEZIER_SIZE * 3 - BEZIER); a = getBezierValue(time, i, A, curveType + BEZIER_SIZE * 3 - BEZIER);
} }
}
if (alpha == 1) if (alpha == 1)
color.set(r, g, b, a); color.set(r, g, b, a);
@ -1054,23 +1047,24 @@ public class Animation {
if (time < frames[0]) { if (time < frames[0]) {
Color setup = slot.data.setup.color; Color setup = slot.data.setup.color;
switch (blend) { switch (blend) {
case setup: case setup -> {
color.r = setup.r; color.r = setup.r;
color.g = setup.g; color.g = setup.g;
color.b = setup.b; color.b = setup.b;
return; }
case first: case first -> {
color.r += (setup.r - color.r) * alpha; color.r += (setup.r - color.r) * alpha;
color.g += (setup.g - color.g) * alpha; color.g += (setup.g - color.g) * alpha;
color.b += (setup.b - color.b) * alpha; color.b += (setup.b - color.b) * alpha;
} }
}
return; return;
} }
float r, g, b; float r, g, b;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i >> 2]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i >> 2];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
@ -1079,17 +1073,18 @@ public class Animation {
r += (frames[i + ENTRIES + R] - r) * t; r += (frames[i + ENTRIES + R] - r) * t;
g += (frames[i + ENTRIES + G] - g) * t; g += (frames[i + ENTRIES + G] - g) * t;
b += (frames[i + ENTRIES + B] - b) * t; b += (frames[i + ENTRIES + B] - b) * t;
break; }
case STEPPED: case STEPPED -> {
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
b = frames[i + B]; b = frames[i + B];
break; }
default: default -> {
r = getBezierValue(time, i, R, curveType - BEZIER); r = getBezierValue(time, i, R, curveType - BEZIER);
g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER); g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER); b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
} }
}
if (alpha == 1) { if (alpha == 1) {
color.r = r; color.r = r;
@ -1133,11 +1128,8 @@ public class Animation {
if (time < frames[0]) { if (time < frames[0]) {
Color setup = slot.data.setup.color; Color setup = slot.data.setup.color;
switch (blend) { switch (blend) {
case setup: case setup -> color.a = setup.a;
color.a = setup.a; case first -> color.a += (setup.a - color.a) * alpha;
return;
case first:
color.a += (setup.a - color.a) * alpha;
} }
return; return;
} }
@ -1190,26 +1182,27 @@ public class Animation {
SlotPose setup = slot.data.setup; SlotPose setup = slot.data.setup;
Color setupLight = setup.color, setupDark = setup.darkColor; Color setupLight = setup.color, setupDark = setup.darkColor;
switch (blend) { switch (blend) {
case setup: case setup -> {
light.set(setupLight); light.set(setupLight);
dark.r = setupDark.r; dark.r = setupDark.r;
dark.g = setupDark.g; dark.g = setupDark.g;
dark.b = setupDark.b; dark.b = setupDark.b;
return; }
case first: case first -> {
light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha,
(setupLight.a - light.a) * alpha); (setupLight.a - light.a) * alpha);
dark.r += (setupDark.r - dark.r) * alpha; dark.r += (setupDark.r - dark.r) * alpha;
dark.g += (setupDark.g - dark.g) * alpha; dark.g += (setupDark.g - dark.g) * alpha;
dark.b += (setupDark.b - dark.b) * alpha; dark.b += (setupDark.b - dark.b) * alpha;
} }
}
return; return;
} }
float r, g, b, a, r2, g2, b2; float r, g, b, a, r2, g2, b2;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i >> 3]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i >> 3];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
@ -1226,8 +1219,8 @@ public class Animation {
r2 += (frames[i + ENTRIES + R2] - r2) * t; r2 += (frames[i + ENTRIES + R2] - r2) * t;
g2 += (frames[i + ENTRIES + G2] - g2) * t; g2 += (frames[i + ENTRIES + G2] - g2) * t;
b2 += (frames[i + ENTRIES + B2] - b2) * t; b2 += (frames[i + ENTRIES + B2] - b2) * t;
break; }
case STEPPED: case STEPPED -> {
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
b = frames[i + B]; b = frames[i + B];
@ -1235,8 +1228,8 @@ public class Animation {
r2 = frames[i + R2]; r2 = frames[i + R2];
g2 = frames[i + G2]; g2 = frames[i + G2];
b2 = frames[i + B2]; b2 = frames[i + B2];
break; }
default: default -> {
r = getBezierValue(time, i, R, curveType - BEZIER); r = getBezierValue(time, i, R, curveType - BEZIER);
g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER); g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER); b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
@ -1245,6 +1238,7 @@ public class Animation {
g2 = getBezierValue(time, i, G2, curveType + BEZIER_SIZE * 5 - BEZIER); g2 = getBezierValue(time, i, G2, curveType + BEZIER_SIZE * 5 - BEZIER);
b2 = getBezierValue(time, i, B2, curveType + BEZIER_SIZE * 6 - BEZIER); b2 = getBezierValue(time, i, B2, curveType + BEZIER_SIZE * 6 - BEZIER);
} }
}
if (alpha == 1) { if (alpha == 1) {
light.set(r, g, b, a); light.set(r, g, b, a);
@ -1304,15 +1298,15 @@ public class Animation {
SlotPose setup = slot.data.setup; SlotPose setup = slot.data.setup;
Color setupLight = setup.color, setupDark = setup.darkColor; Color setupLight = setup.color, setupDark = setup.darkColor;
switch (blend) { switch (blend) {
case setup: case setup -> {
light.r = setupLight.r; light.r = setupLight.r;
light.g = setupLight.g; light.g = setupLight.g;
light.b = setupLight.b; light.b = setupLight.b;
dark.r = setupDark.r; dark.r = setupDark.r;
dark.g = setupDark.g; dark.g = setupDark.g;
dark.b = setupDark.b; dark.b = setupDark.b;
return; }
case first: case first -> {
light.r += (setupLight.r - light.r) * alpha; light.r += (setupLight.r - light.r) * alpha;
light.g += (setupLight.g - light.g) * alpha; light.g += (setupLight.g - light.g) * alpha;
light.b += (setupLight.b - light.b) * alpha; light.b += (setupLight.b - light.b) * alpha;
@ -1320,13 +1314,14 @@ public class Animation {
dark.g += (setupDark.g - dark.g) * alpha; dark.g += (setupDark.g - dark.g) * alpha;
dark.b += (setupDark.b - dark.b) * alpha; dark.b += (setupDark.b - dark.b) * alpha;
} }
}
return; return;
} }
float r, g, b, r2, g2, b2; float r, g, b, r2, g2, b2;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
@ -1341,16 +1336,16 @@ public class Animation {
r2 += (frames[i + ENTRIES + R2] - r2) * t; r2 += (frames[i + ENTRIES + R2] - r2) * t;
g2 += (frames[i + ENTRIES + G2] - g2) * t; g2 += (frames[i + ENTRIES + G2] - g2) * t;
b2 += (frames[i + ENTRIES + B2] - b2) * t; b2 += (frames[i + ENTRIES + B2] - b2) * t;
break; }
case STEPPED: case STEPPED -> {
r = frames[i + R]; r = frames[i + R];
g = frames[i + G]; g = frames[i + G];
b = frames[i + B]; b = frames[i + B];
r2 = frames[i + R2]; r2 = frames[i + R2];
g2 = frames[i + G2]; g2 = frames[i + G2];
b2 = frames[i + B2]; b2 = frames[i + B2];
break; }
default: default -> {
r = getBezierValue(time, i, R, curveType - BEZIER); r = getBezierValue(time, i, R, curveType - BEZIER);
g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER); g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER); b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
@ -1358,6 +1353,7 @@ public class Animation {
g2 = getBezierValue(time, i, G2, curveType + BEZIER_SIZE * 4 - BEZIER); g2 = getBezierValue(time, i, G2, curveType + BEZIER_SIZE * 4 - BEZIER);
b2 = getBezierValue(time, i, B2, curveType + BEZIER_SIZE * 5 - BEZIER); b2 = getBezierValue(time, i, B2, curveType + BEZIER_SIZE * 5 - BEZIER);
} }
}
if (alpha == 1) { if (alpha == 1) {
light.r = r; light.r = r;
@ -1545,10 +1541,8 @@ public class Animation {
float[] frames = this.frames; float[] frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { switch (blend) {
case setup: case setup -> deformArray.clear();
deformArray.clear(); case first -> {
return;
case first:
if (alpha == 1) { if (alpha == 1) {
deformArray.clear(); deformArray.clear();
return; return;
@ -1564,6 +1558,7 @@ public class Animation {
deform[i] *= alpha; deform[i] *= alpha;
} }
} }
}
return; return;
} }
@ -1585,7 +1580,7 @@ public class Animation {
arraycopy(lastVertices, 0, deform, 0, vertexCount); arraycopy(lastVertices, 0, deform, 0, vertexCount);
} else { } else {
switch (blend) { switch (blend) {
case setup: { case setup -> {
if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, with alpha. if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, with alpha.
float[] setupVertices = vertexAttachment.getVertices(); float[] setupVertices = vertexAttachment.getVertices();
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
@ -1596,14 +1591,12 @@ public class Animation {
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
deform[i] = lastVertices[i] * alpha; deform[i] = lastVertices[i] * alpha;
} }
break;
} }
case first: case first, replace -> { // Vertex positions or deform offsets, with alpha.
case replace: // Vertex positions or deform offsets, with alpha.
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
deform[i] += (lastVertices[i] - deform[i]) * alpha; deform[i] += (lastVertices[i] - deform[i]) * alpha;
break; }
case add: case add -> {
if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, no alpha. if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, no alpha.
float[] setupVertices = vertexAttachment.getVertices(); float[] setupVertices = vertexAttachment.getVertices();
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
@ -1614,6 +1607,7 @@ public class Animation {
} }
} }
} }
}
return; return;
} }
@ -1646,7 +1640,7 @@ public class Animation {
} }
} else { } else {
switch (blend) { switch (blend) {
case setup: { case setup -> {
if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, with alpha. if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, with alpha.
float[] setupVertices = vertexAttachment.getVertices(); float[] setupVertices = vertexAttachment.getVertices();
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
@ -1659,16 +1653,14 @@ public class Animation {
deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
} }
} }
break;
} }
case first: case first, replace -> {// Vertex positions or deform offsets, with alpha.
case replace: // Vertex positions or deform offsets, with alpha.
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha;
} }
break; }
case add: case add -> {
if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, with alpha. if (vertexAttachment.getBones() == null) { // Unweighted vertex positions, with alpha.
float[] setupVertices = vertexAttachment.getVertices(); float[] setupVertices = vertexAttachment.getVertices();
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
@ -1685,6 +1677,7 @@ public class Animation {
} }
} }
} }
}
/** Changes a slot's {@link SlotPose#getSequenceIndex()} for an attachment's {@link Sequence}. */ /** Changes a slot's {@link SlotPose#getSequenceIndex()} for an attachment's {@link Sequence}. */
static public class SequenceTimeline extends Timeline implements SlotTimeline { static public class SequenceTimeline extends Timeline implements SlotTimeline {
@ -1759,30 +1752,22 @@ public class Animation {
if (mode != SequenceMode.hold) { if (mode != SequenceMode.hold) {
index += (time - before) / delay + 0.0001f; index += (time - before) / delay + 0.0001f;
switch (mode) { switch (mode) {
case once: case once -> index = Math.min(count - 1, index);
index = Math.min(count - 1, index); case loop -> index %= count;
break; case pingpong -> {
case loop:
index %= count;
break;
case pingpong: {
int n = (count << 1) - 2; int n = (count << 1) - 2;
index = n == 0 ? 0 : index % n; index = n == 0 ? 0 : index % n;
if (index >= count) index = n - index; if (index >= count) index = n - index;
break;
} }
case onceReverse: case onceReverse -> index = Math.max(count - 1 - index, 0);
index = Math.max(count - 1 - index, 0); case loopReverse -> index = count - 1 - (index % count);
break; case pingpongReverse -> {
case loopReverse:
index = count - 1 - (index % count);
break;
case pingpongReverse:
int n = (count << 1) - 2; int n = (count << 1) - 2;
index = n == 0 ? 0 : (index + count - 1) % n; index = n == 0 ? 0 : (index + count - 1) % n;
if (index >= count) index = n - index; if (index >= count) index = n - index;
} }
} }
}
pose.setSequenceIndex(index); pose.setSequenceIndex(index);
} }
} }
@ -1955,42 +1940,44 @@ public class Animation {
if (time < frames[0]) { if (time < frames[0]) {
IkConstraintPose setup = constraint.data.setup; IkConstraintPose setup = constraint.data.setup;
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.mix = setup.mix; pose.mix = setup.mix;
pose.softness = setup.softness; pose.softness = setup.softness;
pose.bendDirection = setup.bendDirection; pose.bendDirection = setup.bendDirection;
pose.compress = setup.compress; pose.compress = setup.compress;
pose.stretch = setup.stretch; pose.stretch = setup.stretch;
return; }
case first: case first -> {
pose.mix += (setup.mix - pose.mix) * alpha; pose.mix += (setup.mix - pose.mix) * alpha;
pose.softness += (setup.softness - pose.softness) * alpha; pose.softness += (setup.softness - pose.softness) * alpha;
pose.bendDirection = setup.bendDirection; pose.bendDirection = setup.bendDirection;
pose.compress = setup.compress; pose.compress = setup.compress;
pose.stretch = setup.stretch; pose.stretch = setup.stretch;
} }
}
return; return;
} }
float mix, softness; float mix, softness;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
mix = frames[i + MIX]; mix = frames[i + MIX];
softness = frames[i + SOFTNESS]; softness = frames[i + SOFTNESS];
float t = (time - before) / (frames[i + ENTRIES] - before); float t = (time - before) / (frames[i + ENTRIES] - before);
mix += (frames[i + ENTRIES + MIX] - mix) * t; mix += (frames[i + ENTRIES + MIX] - mix) * t;
softness += (frames[i + ENTRIES + SOFTNESS] - softness) * t; softness += (frames[i + ENTRIES + SOFTNESS] - softness) * t;
break; }
case STEPPED: case STEPPED -> {
mix = frames[i + MIX]; mix = frames[i + MIX];
softness = frames[i + SOFTNESS]; softness = frames[i + SOFTNESS];
break; }
default: default -> {
mix = getBezierValue(time, i, MIX, curveType - BEZIER); mix = getBezierValue(time, i, MIX, curveType - BEZIER);
softness = getBezierValue(time, i, SOFTNESS, curveType + BEZIER_SIZE - BEZIER); softness = getBezierValue(time, i, SOFTNESS, curveType + BEZIER_SIZE - BEZIER);
} }
}
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
IkConstraintPose setup = constraint.data.setup; IkConstraintPose setup = constraint.data.setup;
@ -2065,15 +2052,15 @@ public class Animation {
if (time < frames[0]) { if (time < frames[0]) {
TransformConstraintPose setup = constraint.data.setup; TransformConstraintPose setup = constraint.data.setup;
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.mixRotate = setup.mixRotate; pose.mixRotate = setup.mixRotate;
pose.mixX = setup.mixX; pose.mixX = setup.mixX;
pose.mixY = setup.mixY; pose.mixY = setup.mixY;
pose.mixScaleX = setup.mixScaleX; pose.mixScaleX = setup.mixScaleX;
pose.mixScaleY = setup.mixScaleY; pose.mixScaleY = setup.mixScaleY;
pose.mixShearY = setup.mixShearY; pose.mixShearY = setup.mixShearY;
return; }
case first: case first -> {
pose.mixRotate += (setup.mixRotate - pose.mixRotate) * alpha; pose.mixRotate += (setup.mixRotate - pose.mixRotate) * alpha;
pose.mixX += (setup.mixX - pose.mixX) * alpha; pose.mixX += (setup.mixX - pose.mixX) * alpha;
pose.mixY += (setup.mixY - pose.mixY) * alpha; pose.mixY += (setup.mixY - pose.mixY) * alpha;
@ -2081,13 +2068,14 @@ public class Animation {
pose.mixScaleY += (setup.mixScaleY - pose.mixScaleY) * alpha; pose.mixScaleY += (setup.mixScaleY - pose.mixScaleY) * alpha;
pose.mixShearY += (setup.mixShearY - pose.mixShearY) * alpha; pose.mixShearY += (setup.mixShearY - pose.mixShearY) * alpha;
} }
}
return; return;
} }
float rotate, x, y, scaleX, scaleY, shearY; float rotate, x, y, scaleX, scaleY, shearY;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
rotate = frames[i + ROTATE]; rotate = frames[i + ROTATE];
x = frames[i + X]; x = frames[i + X];
@ -2102,16 +2090,16 @@ public class Animation {
scaleX += (frames[i + ENTRIES + SCALEX] - scaleX) * t; scaleX += (frames[i + ENTRIES + SCALEX] - scaleX) * t;
scaleY += (frames[i + ENTRIES + SCALEY] - scaleY) * t; scaleY += (frames[i + ENTRIES + SCALEY] - scaleY) * t;
shearY += (frames[i + ENTRIES + SHEARY] - shearY) * t; shearY += (frames[i + ENTRIES + SHEARY] - shearY) * t;
break; }
case STEPPED: case STEPPED -> {
rotate = frames[i + ROTATE]; rotate = frames[i + ROTATE];
x = frames[i + X]; x = frames[i + X];
y = frames[i + Y]; y = frames[i + Y];
scaleX = frames[i + SCALEX]; scaleX = frames[i + SCALEX];
scaleY = frames[i + SCALEY]; scaleY = frames[i + SCALEY];
shearY = frames[i + SHEARY]; shearY = frames[i + SHEARY];
break; }
default: default -> {
rotate = getBezierValue(time, i, ROTATE, curveType - BEZIER); rotate = getBezierValue(time, i, ROTATE, curveType - BEZIER);
x = getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER); x = getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER);
y = getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER); y = getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER);
@ -2119,6 +2107,7 @@ public class Animation {
scaleY = getBezierValue(time, i, SCALEY, curveType + BEZIER_SIZE * 4 - BEZIER); scaleY = getBezierValue(time, i, SCALEY, curveType + BEZIER_SIZE * 4 - BEZIER);
shearY = getBezierValue(time, i, SHEARY, curveType + BEZIER_SIZE * 5 - BEZIER); shearY = getBezierValue(time, i, SHEARY, curveType + BEZIER_SIZE * 5 - BEZIER);
} }
}
if (blend == setup) { if (blend == setup) {
TransformConstraintPose setup = constraint.data.setup; TransformConstraintPose setup = constraint.data.setup;
@ -2229,23 +2218,24 @@ public class Animation {
if (time < frames[0]) { if (time < frames[0]) {
PathConstraintPose setup = constraint.data.setup; PathConstraintPose setup = constraint.data.setup;
switch (blend) { switch (blend) {
case setup: case setup -> {
pose.mixRotate = setup.mixRotate; pose.mixRotate = setup.mixRotate;
pose.mixX = setup.mixX; pose.mixX = setup.mixX;
pose.mixY = setup.mixY; pose.mixY = setup.mixY;
return; }
case first: case first -> {
pose.mixRotate += (setup.mixRotate - pose.mixRotate) * alpha; pose.mixRotate += (setup.mixRotate - pose.mixRotate) * alpha;
pose.mixX += (setup.mixX - pose.mixX) * alpha; pose.mixX += (setup.mixX - pose.mixX) * alpha;
pose.mixY += (setup.mixY - pose.mixY) * alpha; pose.mixY += (setup.mixY - pose.mixY) * alpha;
} }
}
return; return;
} }
float rotate, x, y; float rotate, x, y;
int i = search(frames, time, ENTRIES), curveType = (int)curves[i >> 2]; int i = search(frames, time, ENTRIES), curveType = (int)curves[i >> 2];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR -> {
float before = frames[i]; float before = frames[i];
rotate = frames[i + ROTATE]; rotate = frames[i + ROTATE];
x = frames[i + X]; x = frames[i + X];
@ -2254,17 +2244,18 @@ public class Animation {
rotate += (frames[i + ENTRIES + ROTATE] - rotate) * t; rotate += (frames[i + ENTRIES + ROTATE] - rotate) * t;
x += (frames[i + ENTRIES + X] - x) * t; x += (frames[i + ENTRIES + X] - x) * t;
y += (frames[i + ENTRIES + Y] - y) * t; y += (frames[i + ENTRIES + Y] - y) * t;
break; }
case STEPPED: case STEPPED -> {
rotate = frames[i + ROTATE]; rotate = frames[i + ROTATE];
x = frames[i + X]; x = frames[i + X];
y = frames[i + Y]; y = frames[i + Y];
break; }
default: default -> {
rotate = getBezierValue(time, i, ROTATE, curveType - BEZIER); rotate = getBezierValue(time, i, ROTATE, curveType - BEZIER);
x = getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER); x = getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER);
y = getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER); y = getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER);
} }
}
if (blend == setup) { if (blend == setup) {
PathConstraintPose setup = constraint.data.setup; PathConstraintPose setup = constraint.data.setup;

View File

@ -330,28 +330,28 @@ public class AnimationState {
MixBlend timelineBlend; MixBlend timelineBlend;
float alpha; float alpha;
switch (timelineMode[i]) { switch (timelineMode[i]) {
case SUBSEQUENT: case SUBSEQUENT -> {
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue; if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
timelineBlend = blend; timelineBlend = blend;
alpha = alphaMix; alpha = alphaMix;
break; }
case FIRST: case FIRST -> {
timelineBlend = MixBlend.setup; timelineBlend = MixBlend.setup;
alpha = alphaMix; alpha = alphaMix;
break; }
case HOLD_SUBSEQUENT: case HOLD_SUBSEQUENT -> {
timelineBlend = blend; timelineBlend = blend;
alpha = alphaHold; alpha = alphaHold;
break; }
case HOLD_FIRST: case HOLD_FIRST -> {
timelineBlend = MixBlend.setup; timelineBlend = MixBlend.setup;
alpha = alphaHold; alpha = alphaHold;
break; }
default: // HOLD_MIX default -> { // HOLD_MIX
timelineBlend = MixBlend.setup; timelineBlend = MixBlend.setup;
TrackEntry holdMix = timelineHoldMix[i]; TrackEntry holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break; }
} }
from.totalAlpha += alpha; from.totalAlpha += alpha;
if (!shortestRotation && timeline instanceof RotateTimeline rotateTimeline) { if (!shortestRotation && timeline instanceof RotateTimeline rotateTimeline) {

View File

@ -553,8 +553,8 @@ public class SkeletonBinary extends SkeletonLoader {
int flags = input.readByte(); int flags = input.readByte();
String name = (flags & 8) != 0 ? input.readStringRef() : attachmentName; String name = (flags & 8) != 0 ? input.readStringRef() : attachmentName;
switch (AttachmentType.values[flags & 0b111]) { return switch (AttachmentType.values[flags & 0b111]) {
case region: { case region -> {
String path = (flags & 16) != 0 ? input.readStringRef() : null; String path = (flags & 16) != 0 ? input.readStringRef() : null;
int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff; int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff;
Sequence sequence = (flags & 64) != 0 ? readSequence(input) : null; Sequence sequence = (flags & 64) != 0 ? readSequence(input) : null;
@ -568,7 +568,7 @@ public class SkeletonBinary extends SkeletonLoader {
if (path == null) path = name; if (path == null) path = name;
RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path, sequence); RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path, sequence);
if (region == null) return null; if (region == null) yield null;
region.setPath(path); region.setPath(path);
region.setX(x * scale); region.setX(x * scale);
region.setY(y * scale); region.setY(y * scale);
@ -580,21 +580,21 @@ public class SkeletonBinary extends SkeletonLoader {
Color.rgba8888ToColor(region.getColor(), color); Color.rgba8888ToColor(region.getColor(), color);
region.setSequence(sequence); region.setSequence(sequence);
if (sequence == null) region.updateRegion(); if (sequence == null) region.updateRegion();
return region; yield region;
} }
case boundingbox: { case boundingbox -> {
Vertices vertices = readVertices(input, (flags & 16) != 0); Vertices vertices = readVertices(input, (flags & 16) != 0);
int color = nonessential ? input.readInt() : 0; int color = nonessential ? input.readInt() : 0;
BoundingBoxAttachment box = attachmentLoader.newBoundingBoxAttachment(skin, name); BoundingBoxAttachment box = attachmentLoader.newBoundingBoxAttachment(skin, name);
if (box == null) return null; if (box == null) yield null;
box.setWorldVerticesLength(vertices.length); box.setWorldVerticesLength(vertices.length);
box.setVertices(vertices.vertices); box.setVertices(vertices.vertices);
box.setBones(vertices.bones); box.setBones(vertices.bones);
if (nonessential) Color.rgba8888ToColor(box.getColor(), color); if (nonessential) Color.rgba8888ToColor(box.getColor(), color);
return box; yield box;
} }
case mesh: { case mesh -> {
String path = (flags & 16) != 0 ? input.readStringRef() : name; String path = (flags & 16) != 0 ? input.readStringRef() : name;
int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff; int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff;
Sequence sequence = (flags & 64) != 0 ? readSequence(input) : null; Sequence sequence = (flags & 64) != 0 ? readSequence(input) : null;
@ -612,7 +612,7 @@ public class SkeletonBinary extends SkeletonLoader {
} }
MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, sequence); MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, sequence);
if (mesh == null) return null; if (mesh == null) yield null;
mesh.setPath(path); mesh.setPath(path);
Color.rgba8888ToColor(mesh.getColor(), color); Color.rgba8888ToColor(mesh.getColor(), color);
mesh.setBones(vertices.bones); mesh.setBones(vertices.bones);
@ -628,9 +628,9 @@ public class SkeletonBinary extends SkeletonLoader {
mesh.setWidth(width * scale); mesh.setWidth(width * scale);
mesh.setHeight(height * scale); mesh.setHeight(height * scale);
} }
return mesh; yield mesh;
} }
case linkedmesh: { case linkedmesh -> {
String path = (flags & 16) != 0 ? input.readStringRef() : name; String path = (flags & 16) != 0 ? input.readStringRef() : name;
int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff; int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff;
Sequence sequence = (flags & 64) != 0 ? readSequence(input) : null; Sequence sequence = (flags & 64) != 0 ? readSequence(input) : null;
@ -644,7 +644,7 @@ public class SkeletonBinary extends SkeletonLoader {
} }
MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, sequence); MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, sequence);
if (mesh == null) return null; if (mesh == null) yield null;
mesh.setPath(path); mesh.setPath(path);
Color.rgba8888ToColor(mesh.getColor(), color); Color.rgba8888ToColor(mesh.getColor(), color);
mesh.setSequence(sequence); mesh.setSequence(sequence);
@ -653,9 +653,9 @@ public class SkeletonBinary extends SkeletonLoader {
mesh.setHeight(height * scale); mesh.setHeight(height * scale);
} }
linkedMeshes.add(new LinkedMesh(mesh, skinIndex, slotIndex, parent, inheritTimelines)); linkedMeshes.add(new LinkedMesh(mesh, skinIndex, slotIndex, parent, inheritTimelines));
return mesh; yield mesh;
} }
case path: { case path -> {
boolean closed = (flags & 16) != 0; boolean closed = (flags & 16) != 0;
boolean constantSpeed = (flags & 32) != 0; boolean constantSpeed = (flags & 32) != 0;
Vertices vertices = readVertices(input, (flags & 64) != 0); Vertices vertices = readVertices(input, (flags & 64) != 0);
@ -665,7 +665,7 @@ public class SkeletonBinary extends SkeletonLoader {
int color = nonessential ? input.readInt() : 0; int color = nonessential ? input.readInt() : 0;
PathAttachment path = attachmentLoader.newPathAttachment(skin, name); PathAttachment path = attachmentLoader.newPathAttachment(skin, name);
if (path == null) return null; if (path == null) yield null;
path.setClosed(closed); path.setClosed(closed);
path.setConstantSpeed(constantSpeed); path.setConstantSpeed(constantSpeed);
path.setWorldVerticesLength(vertices.length); path.setWorldVerticesLength(vertices.length);
@ -673,37 +673,38 @@ public class SkeletonBinary extends SkeletonLoader {
path.setBones(vertices.bones); path.setBones(vertices.bones);
path.setLengths(lengths); path.setLengths(lengths);
if (nonessential) Color.rgba8888ToColor(path.getColor(), color); if (nonessential) Color.rgba8888ToColor(path.getColor(), color);
return path; yield path;
} }
case point: { case point -> {
float rotation = input.readFloat(); float rotation = input.readFloat();
float x = input.readFloat(); float x = input.readFloat();
float y = input.readFloat(); float y = input.readFloat();
int color = nonessential ? input.readInt() : 0; int color = nonessential ? input.readInt() : 0;
PointAttachment point = attachmentLoader.newPointAttachment(skin, name); PointAttachment point = attachmentLoader.newPointAttachment(skin, name);
if (point == null) return null; if (point == null) yield null;
point.setX(x * scale); point.setX(x * scale);
point.setY(y * scale); point.setY(y * scale);
point.setRotation(rotation); point.setRotation(rotation);
if (nonessential) Color.rgba8888ToColor(point.getColor(), color); if (nonessential) Color.rgba8888ToColor(point.getColor(), color);
return point; yield point;
} }
case clipping: case clipping -> {
int endSlotIndex = input.readInt(true); int endSlotIndex = input.readInt(true);
Vertices vertices = readVertices(input, (flags & 16) != 0); Vertices vertices = readVertices(input, (flags & 16) != 0);
int color = nonessential ? input.readInt() : 0; int color = nonessential ? input.readInt() : 0;
ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name); ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name);
if (clip == null) return null; if (clip == null) yield null;
clip.setEndSlot(skeletonData.slots.items[endSlotIndex]); clip.setEndSlot(skeletonData.slots.items[endSlotIndex]);
clip.setWorldVerticesLength(vertices.length); clip.setWorldVerticesLength(vertices.length);
clip.setVertices(vertices.vertices); clip.setVertices(vertices.vertices);
clip.setBones(vertices.bones); clip.setBones(vertices.bones);
if (nonessential) Color.rgba8888ToColor(clip.getColor(), color); if (nonessential) Color.rgba8888ToColor(clip.getColor(), color);
return clip; yield clip;
} }
return null; default -> null;
};
} }
private Sequence readSequence (SkeletonInput input) throws IOException { private Sequence readSequence (SkeletonInput input) throws IOException {

View File

@ -543,12 +543,12 @@ public class SkeletonJson extends SkeletonLoader {
float scale = this.scale; float scale = this.scale;
name = map.getString("name", name); name = map.getString("name", name);
switch (AttachmentType.valueOf(map.getString("type", AttachmentType.region.name()))) { return switch (AttachmentType.valueOf(map.getString("type", AttachmentType.region.name()))) {
case region: { case region -> {
String path = map.getString("path", name); String path = map.getString("path", name);
Sequence sequence = readSequence(map.get("sequence")); Sequence sequence = readSequence(map.get("sequence"));
RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path, sequence); RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path, sequence);
if (region == null) return null; if (region == null) yield null;
region.setPath(path); region.setPath(path);
region.setX(map.getFloat("x", 0) * scale); region.setX(map.getFloat("x", 0) * scale);
region.setY(map.getFloat("y", 0) * scale); region.setY(map.getFloat("y", 0) * scale);
@ -563,23 +563,22 @@ public class SkeletonJson extends SkeletonLoader {
if (color != null) Color.valueOf(color, region.getColor()); if (color != null) Color.valueOf(color, region.getColor());
if (region.getRegion() != null) region.updateRegion(); if (region.getRegion() != null) region.updateRegion();
return region; yield region;
} }
case boundingbox: { case boundingbox -> {
BoundingBoxAttachment box = attachmentLoader.newBoundingBoxAttachment(skin, name); BoundingBoxAttachment box = attachmentLoader.newBoundingBoxAttachment(skin, name);
if (box == null) return null; if (box == null) yield null;
readVertices(map, box, map.getInt("vertexCount") << 1); readVertices(map, box, map.getInt("vertexCount") << 1);
String color = map.getString("color", null); String color = map.getString("color", null);
if (color != null) Color.valueOf(color, box.getColor()); if (color != null) Color.valueOf(color, box.getColor());
return box; yield box;
} }
case mesh: case mesh, linkedmesh -> {
case linkedmesh: {
String path = map.getString("path", name); String path = map.getString("path", name);
Sequence sequence = readSequence(map.get("sequence")); Sequence sequence = readSequence(map.get("sequence"));
MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, sequence); MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, sequence);
if (mesh == null) return null; if (mesh == null) yield null;
mesh.setPath(path); mesh.setPath(path);
String color = map.getString("color", null); String color = map.getString("color", null);
@ -593,7 +592,7 @@ public class SkeletonJson extends SkeletonLoader {
if (parent != null) { if (parent != null) {
linkedMeshes linkedMeshes
.add(new LinkedMesh(mesh, map.getString("skin", null), slotIndex, parent, map.getBoolean("timelines", true))); .add(new LinkedMesh(mesh, map.getString("skin", null), slotIndex, parent, map.getBoolean("timelines", true)));
return mesh; yield mesh;
} }
float[] uvs = map.require("uvs").asFloatArray(); float[] uvs = map.require("uvs").asFloatArray();
@ -604,11 +603,11 @@ public class SkeletonJson extends SkeletonLoader {
if (map.has("hull")) mesh.setHullLength(map.require("hull").asInt() << 1); if (map.has("hull")) mesh.setHullLength(map.require("hull").asInt() << 1);
if (map.has("edges")) mesh.setEdges(map.require("edges").asShortArray()); if (map.has("edges")) mesh.setEdges(map.require("edges").asShortArray());
return mesh; yield mesh;
} }
case path: { case path -> {
PathAttachment path = attachmentLoader.newPathAttachment(skin, name); PathAttachment path = attachmentLoader.newPathAttachment(skin, name);
if (path == null) return null; if (path == null) yield null;
path.setClosed(map.getBoolean("closed", false)); path.setClosed(map.getBoolean("closed", false));
path.setConstantSpeed(map.getBoolean("constantSpeed", true)); path.setConstantSpeed(map.getBoolean("constantSpeed", true));
@ -623,22 +622,22 @@ public class SkeletonJson extends SkeletonLoader {
String color = map.getString("color", null); String color = map.getString("color", null);
if (color != null) Color.valueOf(color, path.getColor()); if (color != null) Color.valueOf(color, path.getColor());
return path; yield path;
} }
case point: { case point -> {
PointAttachment point = attachmentLoader.newPointAttachment(skin, name); PointAttachment point = attachmentLoader.newPointAttachment(skin, name);
if (point == null) return null; if (point == null) yield null;
point.setX(map.getFloat("x", 0) * scale); point.setX(map.getFloat("x", 0) * scale);
point.setY(map.getFloat("y", 0) * scale); point.setY(map.getFloat("y", 0) * scale);
point.setRotation(map.getFloat("rotation", 0)); point.setRotation(map.getFloat("rotation", 0));
String color = map.getString("color", null); String color = map.getString("color", null);
if (color != null) Color.valueOf(color, point.getColor()); if (color != null) Color.valueOf(color, point.getColor());
return point; yield point;
} }
case clipping: case clipping -> {
ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name); ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name);
if (clip == null) return null; if (clip == null) yield null;
String end = map.getString("end", null); String end = map.getString("end", null);
if (end != null) { if (end != null) {
@ -651,9 +650,10 @@ public class SkeletonJson extends SkeletonLoader {
String color = map.getString("color", null); String color = map.getString("color", null);
if (color != null) Color.valueOf(color, clip.getColor()); if (color != null) Color.valueOf(color, clip.getColor());
return clip; yield clip;
} }
return null; default -> null;
};
} }
private Sequence readSequence (@Null JsonValue map) { private Sequence readSequence (@Null JsonValue map) {

View File

@ -114,7 +114,7 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
v = region.getV(); v = region.getV();
float textureWidth = region.getTexture().getWidth(), textureHeight = region.getTexture().getHeight(); float textureWidth = region.getTexture().getWidth(), textureHeight = region.getTexture().getHeight();
switch (region.degrees) { switch (region.degrees) {
case 90: case 90 -> {
u -= (region.originalHeight - region.offsetY - region.packedWidth) / textureWidth; u -= (region.originalHeight - region.offsetY - region.packedWidth) / textureWidth;
v -= (region.originalWidth - region.offsetX - region.packedHeight) / textureHeight; v -= (region.originalWidth - region.offsetX - region.packedHeight) / textureHeight;
width = region.originalHeight / textureWidth; width = region.originalHeight / textureWidth;
@ -123,8 +123,8 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
uvs[i] = u + regionUVs[i + 1] * width; uvs[i] = u + regionUVs[i + 1] * width;
uvs[i + 1] = v + (1 - regionUVs[i]) * height; uvs[i + 1] = v + (1 - regionUVs[i]) * height;
} }
return; }
case 180: case 180 -> {
u -= (region.originalWidth - region.offsetX - region.packedWidth) / textureWidth; u -= (region.originalWidth - region.offsetX - region.packedWidth) / textureWidth;
v -= region.offsetY / textureHeight; v -= region.offsetY / textureHeight;
width = region.originalWidth / textureWidth; width = region.originalWidth / textureWidth;
@ -133,8 +133,8 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
uvs[i] = u + (1 - regionUVs[i]) * width; uvs[i] = u + (1 - regionUVs[i]) * width;
uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;
} }
return; }
case 270: case 270 -> {
u -= region.offsetY / textureWidth; u -= region.offsetY / textureWidth;
v -= region.offsetX / textureHeight; v -= region.offsetX / textureHeight;
width = region.originalHeight / textureWidth; width = region.originalHeight / textureWidth;
@ -143,12 +143,15 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
uvs[i] = u + (1 - regionUVs[i + 1]) * width; uvs[i] = u + (1 - regionUVs[i + 1]) * width;
uvs[i + 1] = v + regionUVs[i] * height; uvs[i + 1] = v + regionUVs[i] * height;
} }
return;
} }
default -> {
u -= region.offsetX / textureWidth; u -= region.offsetX / textureWidth;
v -= (region.originalHeight - region.offsetY - region.packedHeight) / textureHeight; v -= (region.originalHeight - region.offsetY - region.packedHeight) / textureHeight;
width = region.originalWidth / textureWidth; width = region.originalWidth / textureWidth;
height = region.originalHeight / textureHeight; height = region.originalHeight / textureHeight;
}
}
return;
} else if (region == null) { } else if (region == null) {
u = v = 0; u = v = 0;
width = height = 1; width = height = 1;