diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index d62217e38..719a24674 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -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 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 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 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 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 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 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 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 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; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java index 8d494b4ce..fa5c928b4 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java @@ -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; + } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java index 60857a185..035196c88 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java @@ -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) { diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java index 855f811f8..1392bc2a3 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java @@ -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) {