mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-12 18:18:43 +08:00
[libgdx] Added global physics timelines.
This commit is contained in:
parent
c2906998ad
commit
7f89281d57
@ -460,6 +460,20 @@ public class Animation {
|
||||
return current + (value - current) * alpha;
|
||||
}
|
||||
|
||||
public float getAbsoluteValue (float time, float alpha, MixBlend blend, float current, float setup, float value) {
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
return setup;
|
||||
case first:
|
||||
return current + (setup - current) * alpha;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
if (blend == MixBlend.setup) return setup + (value - setup) * alpha;
|
||||
return current + (value - current) * alpha;
|
||||
}
|
||||
|
||||
public float getScaleValue (float time, float alpha, MixBlend blend, MixDirection direction, float current, float setup) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
@ -2242,20 +2256,48 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** The base class for {@link PhysicsConstraint} timelines. */
|
||||
/** The base class for most {@link PhysicsConstraint} timelines. */
|
||||
static public abstract class PhysicsConstraintTimeline extends CurveTimeline1 {
|
||||
final int constraintIndex;
|
||||
|
||||
/** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */
|
||||
public PhysicsConstraintTimeline (int frameCount, int bezierCount, int physicsConstraintIndex, Property property) {
|
||||
super(frameCount, bezierCount, property.ordinal() + "|" + physicsConstraintIndex);
|
||||
constraintIndex = physicsConstraintIndex;
|
||||
}
|
||||
|
||||
/** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be changed when this timeline
|
||||
* is applied. */
|
||||
* is applied, or -1 if all physics constraints in the skeleton will be changed. */
|
||||
public int getPhysicsConstraintIndex () {
|
||||
return constraintIndex;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
|
||||
PhysicsConstraint constraint;
|
||||
if (constraintIndex == -1) {
|
||||
float value = time >= frames[0] ? getCurveValue(time) : 0;
|
||||
|
||||
Object[] constraints = skeleton.physicsConstraints.items;
|
||||
for (int i = 0, n = skeleton.physicsConstraints.size; i < n; i++) {
|
||||
constraint = (PhysicsConstraint)constraints[i];
|
||||
if (constraint.active && global(constraint.data))
|
||||
set(constraint, getAbsoluteValue(time, alpha, blend, get(constraint), setup(constraint), value));
|
||||
}
|
||||
} else {
|
||||
constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active) set(constraint, getAbsoluteValue(time, alpha, blend, get(constraint), setup(constraint)));
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected float setup (PhysicsConstraint constraint);
|
||||
|
||||
abstract protected float get (PhysicsConstraint constraint);
|
||||
|
||||
abstract protected void set (PhysicsConstraint constraint, float value);
|
||||
|
||||
abstract protected boolean global (PhysicsConstraintData constraint);
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getInertia()}. */
|
||||
@ -2264,12 +2306,20 @@ public class Animation {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintInertia);
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.inertia;
|
||||
}
|
||||
|
||||
PhysicsConstraint constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active)
|
||||
constraint.inertia = getAbsoluteValue(time, alpha, blend, constraint.inertia, constraint.data.inertia);
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.inertia;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.inertia = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
return constraint.inertiaGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2279,12 +2329,20 @@ public class Animation {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintStrength);
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.strength;
|
||||
}
|
||||
|
||||
PhysicsConstraint constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active)
|
||||
constraint.strength = getAbsoluteValue(time, alpha, blend, constraint.strength, constraint.data.strength);
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.strength;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.strength = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
return constraint.strengthGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2294,12 +2352,20 @@ public class Animation {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintDamping);
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.damping;
|
||||
}
|
||||
|
||||
PhysicsConstraint constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active)
|
||||
constraint.damping = getAbsoluteValue(time, alpha, blend, constraint.damping, constraint.data.damping);
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.damping;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.damping = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
return constraint.dampingGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2309,14 +2375,20 @@ public class Animation {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMass);
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return 1 / constraint.data.massInverse;
|
||||
}
|
||||
|
||||
PhysicsConstraint constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active) {
|
||||
constraint.massInverse = 1
|
||||
/ getAbsoluteValue(time, alpha, blend, 1 / constraint.massInverse, 1 / constraint.data.massInverse);
|
||||
}
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return 1 / constraint.massInverse;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.massInverse = 1 / value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
return constraint.massGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2326,11 +2398,20 @@ public class Animation {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintWind);
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.wind;
|
||||
}
|
||||
|
||||
PhysicsConstraint constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active) constraint.wind = getAbsoluteValue(time, alpha, blend, constraint.wind, constraint.data.wind);
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.wind;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.wind = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
return constraint.windGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2340,12 +2421,20 @@ public class Animation {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity);
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.gravity;
|
||||
}
|
||||
|
||||
PhysicsConstraint constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active)
|
||||
constraint.gravity = getAbsoluteValue(time, alpha, blend, constraint.gravity, constraint.data.gravity);
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.gravity;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.gravity = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
return constraint.gravityGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2355,11 +2444,20 @@ public class Animation {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix);
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction) {
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.mix;
|
||||
}
|
||||
|
||||
PhysicsConstraint constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active) constraint.mix = getAbsoluteValue(time, alpha, blend, constraint.mix, constraint.data.mix);
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.mix;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.mix = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
return constraint.mixGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2375,8 +2473,8 @@ public class Animation {
|
||||
constraintIndex = physicsConstraintIndex;
|
||||
}
|
||||
|
||||
/** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be reset by this timeline, or
|
||||
* -1 if all physics constraints in the skeleton will be reset. */
|
||||
/** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be reset when this timeline is
|
||||
* applied, or -1 if all physics constraints in the skeleton will be reset. */
|
||||
public int getPhysicsConstraintIndex () {
|
||||
return constraintIndex;
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ public class PhysicsConstraintData extends ConstraintData {
|
||||
BoneData bone;
|
||||
float x, y, rotate, scaleX, shearX;
|
||||
float step, inertia, strength, damping, massInverse, wind, gravity, mix;
|
||||
boolean inertiaGlobal, strengthGlobal, dampingGlobal, massGlobal, windGlobal, gravityGlobal, mixGlobal;
|
||||
|
||||
public PhysicsConstraintData (String name) {
|
||||
super(name);
|
||||
@ -154,4 +155,60 @@ public class PhysicsConstraintData extends ConstraintData {
|
||||
public void setMix (float mix) {
|
||||
this.mix = mix;
|
||||
}
|
||||
|
||||
public boolean getInertiaGlobal () {
|
||||
return inertiaGlobal;
|
||||
}
|
||||
|
||||
public void setInertiaGlobal (boolean inertiaGlobal) {
|
||||
this.inertiaGlobal = inertiaGlobal;
|
||||
}
|
||||
|
||||
public boolean getStrengthGlobal () {
|
||||
return strengthGlobal;
|
||||
}
|
||||
|
||||
public void setStrengthGlobal (boolean strengthGlobal) {
|
||||
this.strengthGlobal = strengthGlobal;
|
||||
}
|
||||
|
||||
public boolean getDampingGlobal () {
|
||||
return dampingGlobal;
|
||||
}
|
||||
|
||||
public void setDampingGlobal (boolean dampingGlobal) {
|
||||
this.dampingGlobal = dampingGlobal;
|
||||
}
|
||||
|
||||
public boolean getMassGlobal () {
|
||||
return massGlobal;
|
||||
}
|
||||
|
||||
public void setMassGlobal (boolean massGlobal) {
|
||||
this.massGlobal = massGlobal;
|
||||
}
|
||||
|
||||
public boolean getWindGlobal () {
|
||||
return windGlobal;
|
||||
}
|
||||
|
||||
public void setWindGlobal (boolean windGlobal) {
|
||||
this.windGlobal = windGlobal;
|
||||
}
|
||||
|
||||
public boolean getGravityGlobal () {
|
||||
return gravityGlobal;
|
||||
}
|
||||
|
||||
public void setGravityGlobal (boolean gravityGlobal) {
|
||||
this.gravityGlobal = gravityGlobal;
|
||||
}
|
||||
|
||||
public boolean getMixGlobal () {
|
||||
return mixGlobal;
|
||||
}
|
||||
|
||||
public void setMixGlobal (boolean mixGlobal) {
|
||||
this.mixGlobal = mixGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,6 +328,14 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
data.wind = input.readFloat();
|
||||
data.gravity = input.readFloat();
|
||||
data.mix = input.readFloat();
|
||||
flags = input.read();
|
||||
if ((flags & 1) != 0) data.inertiaGlobal = true;
|
||||
if ((flags & 2) != 0) data.strengthGlobal = true;
|
||||
if ((flags & 4) != 0) data.dampingGlobal = true;
|
||||
if ((flags & 8) != 0) data.massGlobal = true;
|
||||
if ((flags & 16) != 0) data.windGlobal = true;
|
||||
if ((flags & 32) != 0) data.gravityGlobal = true;
|
||||
if ((flags & 64) != 0) data.mixGlobal = true;
|
||||
o[i] = data;
|
||||
}
|
||||
|
||||
@ -959,7 +967,7 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
|
||||
// Physics timelines.
|
||||
for (int i = 0, n = input.readInt(true); i < n; i++) {
|
||||
int index = input.readInt(true);
|
||||
int index = input.readInt(true) - 1;
|
||||
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
||||
int type = input.readByte(), frameCount = input.readInt(true);
|
||||
if (type == PHYSICS_RESET) {
|
||||
@ -1066,15 +1074,6 @@ 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.
|
||||
int drawOrderCount = input.readInt(true);
|
||||
if (drawOrderCount > 0) {
|
||||
|
||||
@ -313,6 +313,13 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
data.wind = constraintMap.getFloat("wind", 0);
|
||||
data.gravity = constraintMap.getFloat("gravity", 0);
|
||||
data.mix = constraintMap.getFloat("mix", 1);
|
||||
data.inertiaGlobal = constraintMap.getBoolean("inertiaGlobal", false);
|
||||
data.strengthGlobal = constraintMap.getBoolean("strengthGlobal", false);
|
||||
data.dampingGlobal = constraintMap.getBoolean("dampingGlobal", false);
|
||||
data.massGlobal = constraintMap.getBoolean("massGlobal", false);
|
||||
data.windGlobal = constraintMap.getBoolean("windGlobal", false);
|
||||
data.gravityGlobal = constraintMap.getBoolean("gravityGlobal", false);
|
||||
data.mixGlobal = constraintMap.getBoolean("mixGlobal", false);
|
||||
|
||||
skeletonData.physicsConstraints.add(data);
|
||||
}
|
||||
@ -924,9 +931,12 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
|
||||
// Physics constraint timelines.
|
||||
for (JsonValue constraintMap = map.getChild("physics"); constraintMap != null; constraintMap = constraintMap.next) {
|
||||
PhysicsConstraintData constraint = skeletonData.findPhysicsConstraint(constraintMap.name);
|
||||
if (constraint == null) throw new SerializationException("Physics constraint not found: " + constraintMap.name);
|
||||
int index = skeletonData.physicsConstraints.indexOf(constraint, true);
|
||||
int index = -1;
|
||||
if (!constraintMap.name.isEmpty()) {
|
||||
PhysicsConstraintData constraint = skeletonData.findPhysicsConstraint(constraintMap.name);
|
||||
if (constraint == null) throw new SerializationException("Physics constraint not found: " + constraintMap.name);
|
||||
index = skeletonData.physicsConstraints.indexOf(constraint, true);
|
||||
}
|
||||
for (JsonValue timelineMap = constraintMap.child; timelineMap != null; timelineMap = timelineMap.next) {
|
||||
JsonValue keyMap = timelineMap.child;
|
||||
if (keyMap == null) continue;
|
||||
@ -1032,16 +1042,6 @@ 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.
|
||||
JsonValue drawOrderMap = map.get("drawOrder");
|
||||
if (drawOrderMap != null) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user