[libgdx] Physics reset timelines data loading. Fixed physics rotate/shear.

This commit is contained in:
Nathan Sweet 2023-11-10 21:17:41 -04:00
parent 7fae9e54ae
commit f7c8c6deb1
3 changed files with 80 additions and 36 deletions

View File

@ -217,28 +217,34 @@ public class PhysicsConstraint implements Updatable {
} }
if (rotateOrShearX) { if (rotateOrShearX) {
float r = rotateOffset * mix, a = bone.a, s, c; float o = rotateOffset * mix, s, c, a;
if (data.rotate > 0) { if (data.shearX > 0) {
if (data.shearX > 0) { float r = 0;
r *= 0.5f; if (data.rotate > 0) {
s = sin(r * data.shearX); r = o * data.rotate;
c = cos(r * data.shearX); s = sin(r);
bone.a = c * a - s * bone.c; c = cos(r);
bone.c = s * a + c * bone.c; a = bone.b;
a = bone.a; bone.b = c * a - s * bone.d;
} else { bone.d = s * a + c * bone.d;
s = sin(r * data.rotate);
c = cos(r * data.rotate);
} }
float b = bone.b; r += o * data.shearX;
bone.b = c * b - s * bone.d; s = sin(r);
bone.d = s * b + c * bone.d; c = cos(r);
a = bone.a;
bone.a = c * a - s * bone.c;
bone.c = s * a + c * bone.c;
} else { } else {
s = sin(r * data.shearX); o *= data.rotate;
c = cos(r * data.shearX); s = sin(o);
c = cos(o);
a = bone.a;
bone.a = c * a - s * bone.c;
bone.c = s * a + c * bone.c;
a = bone.b;
bone.b = c * a - s * bone.d;
bone.d = s * a + c * bone.d;
} }
bone.a = c * a - s * bone.c;
bone.c = s * a + c * bone.c;
} }
if (scaleX) { if (scaleX) {
float s = 1 + scaleOffset * mix * data.scaleX; float s = 1 + scaleOffset * mix * data.scaleX;

View File

@ -60,6 +60,7 @@ import com.esotericsoftware.spine.Animation.PhysicsConstraintGravityTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintInertiaTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintInertiaTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintMassTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintMassTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintMixTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintMixTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintResetTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintStrengthTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintStrengthTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintWindTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintWindTimeline;
import com.esotericsoftware.spine.Animation.RGB2Timeline; import com.esotericsoftware.spine.Animation.RGB2Timeline;
@ -134,6 +135,7 @@ public class SkeletonBinary extends SkeletonLoader {
static public final int PHYSICS_WIND = 5; static public final int PHYSICS_WIND = 5;
static public final int PHYSICS_GRAVITY = 6; static public final int PHYSICS_GRAVITY = 6;
static public final int PHYSICS_MIX = 7; static public final int PHYSICS_MIX = 7;
static public final int PHYSICS_RESET = 8;
static public final int CURVE_LINEAR = 0; static public final int CURVE_LINEAR = 0;
static public final int CURVE_STEPPED = 1; static public final int CURVE_STEPPED = 1;
@ -959,7 +961,15 @@ public class SkeletonBinary extends SkeletonLoader {
for (int i = 0, n = input.readInt(true); i < n; i++) { for (int i = 0, n = input.readInt(true); i < n; i++) {
int index = input.readInt(true); int index = input.readInt(true);
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) { for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
int type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true); int type = input.readByte(), frameCount = input.readInt(true);
if (type == PHYSICS_RESET) {
PhysicsConstraintResetTimeline timeline = new PhysicsConstraintResetTimeline(frameCount, index);
for (int frame = 0; frame < frameCount; frame++)
timeline.setFrame(frame, input.readFloat());
timelines.add(timeline);
continue;
}
int bezierCount = input.readInt(true);
switch (type) { switch (type) {
case PHYSICS_INERTIA: case PHYSICS_INERTIA:
readTimeline(input, timelines, new PhysicsConstraintInertiaTimeline(frameCount, bezierCount, index), 1); readTimeline(input, timelines, new PhysicsConstraintInertiaTimeline(frameCount, bezierCount, index), 1);
@ -1056,6 +1066,15 @@ public class SkeletonBinary extends SkeletonLoader {
} }
} }
// Physics constraint reset all timeline.
int resetCount = input.readInt(true);
if (resetCount > 0) {
PhysicsConstraintResetTimeline timeline = new PhysicsConstraintResetTimeline(resetCount, -1);
for (int i = 0; i < resetCount; i++)
timeline.setFrame(i, input.readFloat());
timelines.add(timeline);
}
// Draw order timeline. // Draw order timeline.
int drawOrderCount = input.readInt(true); int drawOrderCount = input.readInt(true);
if (drawOrderCount > 0) { if (drawOrderCount > 0) {

View File

@ -61,6 +61,7 @@ import com.esotericsoftware.spine.Animation.PhysicsConstraintGravityTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintInertiaTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintInertiaTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintMassTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintMassTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintMixTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintMixTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintResetTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintStrengthTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintStrengthTimeline;
import com.esotericsoftware.spine.Animation.PhysicsConstraintWindTimeline; import com.esotericsoftware.spine.Animation.PhysicsConstraintWindTimeline;
import com.esotericsoftware.spine.Animation.RGB2Timeline; import com.esotericsoftware.spine.Animation.RGB2Timeline;
@ -310,7 +311,7 @@ public class SkeletonJson extends SkeletonLoader {
data.damping = constraintMap.getFloat("damping", 1); data.damping = constraintMap.getFloat("damping", 1);
data.massInverse = 1f / constraintMap.getFloat("mass", 1); data.massInverse = 1f / constraintMap.getFloat("mass", 1);
data.wind = constraintMap.getFloat("wind", 0); data.wind = constraintMap.getFloat("wind", 0);
data.gravity = constraintMap.getFloat("getFloat", 0); data.gravity = constraintMap.getFloat("gravity", 0);
data.mix = constraintMap.getFloat("mix", 1); data.mix = constraintMap.getFloat("mix", 1);
skeletonData.physicsConstraints.add(data); skeletonData.physicsConstraints.add(data);
@ -932,6 +933,14 @@ public class SkeletonJson extends SkeletonLoader {
int frames = timelineMap.size; int frames = timelineMap.size;
String timelineName = timelineMap.name; String timelineName = timelineMap.name;
if (timelineName.equals("reset")) {
PhysicsConstraintResetTimeline timeline = new PhysicsConstraintResetTimeline(timelineMap.size, index);
for (int frame = 0; keyMap != null; keyMap = keyMap.next, frame++)
timeline.setFrame(frame, keyMap.getFloat("time", 0));
timelines.add(timeline);
continue;
}
CurveTimeline1 timeline; CurveTimeline1 timeline;
if (timelineName.equals("inertia")) if (timelineName.equals("inertia"))
timeline = new PhysicsConstraintInertiaTimeline(frames, frames, index); timeline = new PhysicsConstraintInertiaTimeline(frames, frames, index);
@ -1023,15 +1032,25 @@ public class SkeletonJson extends SkeletonLoader {
} }
} }
// Physics constraint reset all timeline.
JsonValue resetMap = map.get("physicsReset");
if (resetMap != null) {
PhysicsConstraintResetTimeline timeline = new PhysicsConstraintResetTimeline(resetMap.size, -1);
int frame = 0;
for (JsonValue keyMap = resetMap.child; keyMap != null; keyMap = keyMap.next, frame++)
timeline.setFrame(frame, keyMap.getFloat("time", 0));
timelines.add(timeline);
}
// Draw order timeline. // Draw order timeline.
JsonValue drawOrdersMap = map.get("drawOrder"); JsonValue drawOrderMap = map.get("drawOrder");
if (drawOrdersMap != null) { if (drawOrderMap != null) {
DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrdersMap.size); DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderMap.size);
int slotCount = skeletonData.slots.size; int slotCount = skeletonData.slots.size;
int frame = 0; int frame = 0;
for (JsonValue drawOrderMap = drawOrdersMap.child; drawOrderMap != null; drawOrderMap = drawOrderMap.next, frame++) { for (JsonValue keyMap = drawOrderMap.child; keyMap != null; keyMap = keyMap.next, frame++) {
int[] drawOrder = null; int[] drawOrder = null;
JsonValue offsets = drawOrderMap.get("offsets"); JsonValue offsets = keyMap.get("offsets");
if (offsets != null) { if (offsets != null) {
drawOrder = new int[slotCount]; drawOrder = new int[slotCount];
for (int i = slotCount - 1; i >= 0; i--) for (int i = slotCount - 1; i >= 0; i--)
@ -1054,7 +1073,7 @@ public class SkeletonJson extends SkeletonLoader {
for (int i = slotCount - 1; i >= 0; i--) for (int i = slotCount - 1; i >= 0; i--)
if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
} }
timeline.setFrame(frame, drawOrderMap.getFloat("time", 0), drawOrder); timeline.setFrame(frame, keyMap.getFloat("time", 0), drawOrder);
} }
timelines.add(timeline); timelines.add(timeline);
} }
@ -1064,16 +1083,16 @@ public class SkeletonJson extends SkeletonLoader {
if (eventsMap != null) { if (eventsMap != null) {
EventTimeline timeline = new EventTimeline(eventsMap.size); EventTimeline timeline = new EventTimeline(eventsMap.size);
int frame = 0; int frame = 0;
for (JsonValue eventMap = eventsMap.child; eventMap != null; eventMap = eventMap.next, frame++) { for (JsonValue keyMap = eventsMap.child; keyMap != null; keyMap = keyMap.next, frame++) {
EventData eventData = skeletonData.findEvent(eventMap.getString("name")); EventData eventData = skeletonData.findEvent(keyMap.getString("name"));
if (eventData == null) throw new SerializationException("Event not found: " + eventMap.getString("name")); if (eventData == null) throw new SerializationException("Event not found: " + keyMap.getString("name"));
Event event = new Event(eventMap.getFloat("time", 0), eventData); Event event = new Event(keyMap.getFloat("time", 0), eventData);
event.intValue = eventMap.getInt("int", eventData.intValue); event.intValue = keyMap.getInt("int", eventData.intValue);
event.floatValue = eventMap.getFloat("float", eventData.floatValue); event.floatValue = keyMap.getFloat("float", eventData.floatValue);
event.stringValue = eventMap.getString("string", eventData.stringValue); event.stringValue = keyMap.getString("string", eventData.stringValue);
if (event.getData().audioPath != null) { if (event.getData().audioPath != null) {
event.volume = eventMap.getFloat("volume", eventData.volume); event.volume = keyMap.getFloat("volume", eventData.volume);
event.balance = eventMap.getFloat("balance", eventData.balance); event.balance = keyMap.getFloat("balance", eventData.balance);
} }
timeline.setFrame(frame, event); timeline.setFrame(frame, event);
} }