diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java
index f4f1987eb..a07c96de0 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java
@@ -79,6 +79,15 @@ public class IkConstraint implements Updatable {
stretch = constraint.stretch;
}
+ public void setToSetupPose () {
+ IkConstraintData data = this.data;
+ mix = data.mix;
+ softness = data.softness;
+ bendDirection = data.bendDirection;
+ compress = data.compress;
+ stretch = data.stretch;
+ }
+
/** Applies the constraint to the constrained bones. */
public void update () {
if (mix == 0) return;
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java
index 0a80cf54b..78b069fcb 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java
@@ -91,6 +91,15 @@ public class PathConstraint implements Updatable {
mixY = constraint.mixY;
}
+ public void setToSetupPose () {
+ PathConstraintData data = this.data;
+ position = data.position;
+ spacing = data.spacing;
+ mixRotate = data.mixRotate;
+ mixX = data.mixX;
+ mixY = data.mixY;
+ }
+
/** Applies the constraint to the constrained bones. */
public void update () {
Attachment attachment = target.attachment;
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java
index b538f403c..baadc420e 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java
@@ -31,15 +31,19 @@ package com.esotericsoftware.spine;
import com.badlogic.gdx.utils.Array;
+import com.esotericsoftware.spine.PhysicsConstraintData.Node;
+import com.esotericsoftware.spine.PhysicsConstraintData.NodeData;
+import com.esotericsoftware.spine.PhysicsConstraintData.Spring;
+import com.esotericsoftware.spine.PhysicsConstraintData.SpringData;
+
/** Stores the current pose for a physics constraint. A physics constraint applies physics to bones.
*
* See Physics constraints in the Spine User Guide. */
public class PhysicsConstraint implements Updatable {
final PhysicsConstraintData data;
- final Array bones;
- // BOZO! - stiffness -> strength. stiffness, damping, rope, stretch -> move to spring.
- float mix, friction, gravity, wind, stiffness, damping;
- boolean rope, stretch;
+ final Array nodes;
+ final Array springs;
+ float mix, length, strength, damping, gravity, wind;
boolean active;
@@ -47,18 +51,21 @@ public class PhysicsConstraint implements Updatable {
if (data == null) throw new IllegalArgumentException("data cannot be null.");
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
this.data = data;
+
+ nodes = new Array(data.nodes.size);
+ for (NodeData nodeData : data.nodes)
+ nodes.add(new Node(nodeData, skeleton));
+
+ springs = new Array(data.springs.size);
+ for (SpringData springData : data.springs)
+ springs.add(new Spring(springData, this, skeleton));
+
mix = data.mix;
- friction = data.friction;
+ length = data.length;
+ strength = data.strength;
+ damping = data.damping;
gravity = data.gravity;
wind = data.wind;
- stiffness = data.stiffness;
- damping = data.damping;
- rope = data.rope;
- stretch = data.stretch;
-
- bones = new Array(data.bones.size);
- for (BoneData boneData : data.bones)
- bones.add(skeleton.bones.get(boneData.index));
}
/** Copy constructor. */
@@ -66,27 +73,52 @@ public class PhysicsConstraint implements Updatable {
if (constraint == null) throw new IllegalArgumentException("constraint cannot be null.");
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
data = constraint.data;
- bones = new Array(constraint.bones.size);
- for (Bone bone : constraint.bones)
- bones.add(skeleton.bones.get(bone.data.index));
+
+ nodes = new Array(constraint.nodes.size);
+ for (Node node : constraint.nodes)
+ nodes.add(new Node(node));
+
+ springs = new Array(constraint.springs.size);
+ for (Spring spring : constraint.springs)
+ springs.add(new Spring(spring, this));
+
mix = constraint.mix;
- friction = constraint.friction;
+ length = constraint.length;
+ strength = constraint.strength;
+ damping = constraint.damping;
gravity = constraint.gravity;
wind = constraint.wind;
- stiffness = constraint.stiffness;
- damping = constraint.damping;
- rope = constraint.rope;
- stretch = constraint.stretch;
+ }
+
+ public void setToSetupPose () {
+ Object[] nodes = this.nodes.items;
+ for (int i = 0, n = this.nodes.size; i < n; i++)
+ ((Node)nodes[i]).setToSetupPose();
+
+ Object[] springs = this.springs.items;
+ for (int i = 0, n = this.springs.size; i < n; i++)
+ ((Spring)springs[i]).setToSetupPose();
+
+ PhysicsConstraintData data = this.data;
+ mix = data.mix;
+ length = data.length;
+ strength = data.strength;
+ damping = data.damping;
+ gravity = data.gravity;
+ wind = data.wind;
}
/** Applies the constraint to the constrained bones. */
public void update () {
-
+ // BOZO! - Physics.
}
- /** The bones that will be modified by this physics constraint. */
- public Array getBones () {
- return bones;
+ public Array getNodes () {
+ return nodes;
+ }
+
+ public Array getSprings () {
+ return springs;
}
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
@@ -98,12 +130,28 @@ public class PhysicsConstraint implements Updatable {
this.mix = mix;
}
- public float getFriction () {
- return friction;
+ public float getLength () {
+ return length;
}
- public void setFriction (float friction) {
- this.friction = friction;
+ public void setLength (float length) {
+ this.length = length;
+ }
+
+ public float getStrength () {
+ return strength;
+ }
+
+ public void setStrength (float strength) {
+ this.strength = strength;
+ }
+
+ public float getDamping () {
+ return damping;
+ }
+
+ public void setDamping (float damping) {
+ this.damping = damping;
}
public float getGravity () {
@@ -122,38 +170,6 @@ public class PhysicsConstraint implements Updatable {
this.wind = wind;
}
- public float getStiffness () {
- return stiffness;
- }
-
- public void setStiffness (float stiffness) {
- this.stiffness = stiffness;
- }
-
- public float getDamping () {
- return damping;
- }
-
- public void setDamping (float damping) {
- this.damping = damping;
- }
-
- public boolean getRope () {
- return rope;
- }
-
- public void setRope (boolean rope) {
- this.rope = rope;
- }
-
- public boolean getStretch () {
- return stretch;
- }
-
- public void setStretch (boolean stretch) {
- this.stretch = stretch;
- }
-
public boolean isActive () {
return active;
}
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 9f9ad330e..cf273fb42 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java
@@ -29,23 +29,29 @@
package com.esotericsoftware.spine;
+import static com.esotericsoftware.spine.utils.SpineUtils.*;
+
import com.badlogic.gdx.utils.Array;
+import com.badlogic.gdx.utils.Null;
/** Stores the setup pose for a {@link PhysicsConstraint}.
*
* See Physics constraints in the Spine User Guide. */
public class PhysicsConstraintData extends ConstraintData {
- final Array bones = new Array();
- float mix, friction, gravity, wind, stiffness, damping;
- boolean rope, stretch;
+ final Array nodes = new Array();
+ final Array springs = new Array();
+ float mix, length, strength, damping, gravity, wind;
public PhysicsConstraintData (String name) {
super(name);
}
- /** The bones that are constrained by this physics constraint. */
- public Array getBones () {
- return bones;
+ public Array getNodes () {
+ return nodes;
+ }
+
+ public Array getSprings () {
+ return springs;
}
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
@@ -57,12 +63,28 @@ public class PhysicsConstraintData extends ConstraintData {
this.mix = mix;
}
- public float getFriction () {
- return friction;
+ public float getLength () {
+ return length;
}
- public void setFriction (float friction) {
- this.friction = friction;
+ public void setLength (float length) {
+ this.length = length;
+ }
+
+ public float getStrength () {
+ return strength;
+ }
+
+ public void setStrength (float strength) {
+ this.strength = strength;
+ }
+
+ public float getDamping () {
+ return damping;
+ }
+
+ public void setDamping (float damping) {
+ this.damping = damping;
}
public float getGravity () {
@@ -81,35 +103,94 @@ public class PhysicsConstraintData extends ConstraintData {
this.wind = wind;
}
- public float getStiffness () {
- return stiffness;
+ static public class NodeData {
+ public int parentBone = -1;
+ public int[] bones;
+ public float x, y;
}
- public void setStiffness (float stiffness) {
- this.stiffness = stiffness;
+ static public class Node {
+ public final NodeData data;
+ public final @Null Bone parentBone;
+ public final Bone[] bones;
+ public float x, y, px, py, ax, ay;
+
+ public Node (NodeData data, Skeleton skeleton) {
+ this.data = data;
+
+ parentBone = data.parentBone == -1 ? null : skeleton.bones.get(data.parentBone);
+
+ bones = new Bone[data.bones.length];
+ for (int i = 0, n = bones.length; i < n; i++)
+ bones[i] = skeleton.bones.get(data.bones[i]);
+
+ setToSetupPose();
+ }
+
+ public Node (Node node) {
+ this.data = node.data;
+ parentBone = node.parentBone;
+ bones = new Bone[node.bones.length];
+ arraycopy(node.bones, 0, bones, 0, bones.length);
+ x = node.x;
+ y = node.y;
+ px = node.px;
+ py = node.py;
+ ax = node.ax;
+ ay = node.ay;
+ }
+
+ public void setToSetupPose () {
+ x = data.x;
+ y = data.y;
+ px = x;
+ py = y;
+ ax = 0;
+ ay = 0;
+ }
}
- public float getDamping () {
- return damping;
+ static public class SpringData {
+ public int node1, node2;
+ public int[] bones;
+ public float length, strength, damping;
+ public boolean rope, stretch;
}
- public void setDamping (float damping) {
- this.damping = damping;
- }
+ static public class Spring {
+ public final SpringData data;
+ public final Node node1, node2;
+ public final Bone[] bones;
+ public float length, strength, damping;
- public boolean getRope () {
- return rope;
- }
+ public Spring (SpringData data, PhysicsConstraint constraint, Skeleton skeleton) {
+ this.data = data;
- public void setRope (boolean rope) {
- this.rope = rope;
- }
+ node1 = constraint.nodes.get(data.node1);
+ node2 = constraint.nodes.get(data.node2);
- public boolean getStretch () {
- return stretch;
- }
+ bones = new Bone[data.bones.length];
+ for (int i = 0, n = bones.length; i < n; i++)
+ bones[i] = skeleton.bones.get(data.bones[i]);
- public void setStretch (boolean stretch) {
- this.stretch = stretch;
+ setToSetupPose();
+ }
+
+ public Spring (Spring spring, PhysicsConstraint constraint) {
+ this.data = spring.data;
+ node1 = constraint.nodes.get(data.node1);
+ node2 = constraint.nodes.get(data.node2);
+ bones = new Bone[spring.bones.length];
+ arraycopy(spring.bones, 0, bones, 0, bones.length);
+ length = spring.length;
+ strength = spring.strength;
+ damping = spring.damping;
+ }
+
+ public void setToSetupPose () {
+ length = data.length;
+ strength = data.strength;
+ damping = data.damping;
+ }
}
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
index f60d8d9e2..b46f98fd1 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
@@ -37,6 +37,7 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.Null;
+import com.esotericsoftware.spine.PhysicsConstraintData.Node;
import com.esotericsoftware.spine.Skin.SkinEntry;
import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.MeshAttachment;
@@ -337,17 +338,29 @@ public class Skeleton {
constraint.active = !constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true));
if (!constraint.active) return;
- Object[] constrained = constraint.bones.items;
- int boneCount = constraint.bones.size;
- for (int i = 0; i < boneCount; i++)
- sortBone((Bone)constrained[i]);
+ Object[] nodes = constraint.nodes.items;
+ int nodeCount = constraint.nodes.size;
+ for (int i = 0; i < nodeCount; i++) {
+ Node node = (Node)nodes[i];
+ if (node.parentBone != null) sortBone(node.parentBone);
+ for (Bone bone : node.bones)
+ sortBone(bone);
+ }
updateCache.add(constraint);
- for (int i = 0; i < boneCount; i++)
- sortReset(((Bone)constrained[i]).children);
- for (int i = 0; i < boneCount; i++)
- ((Bone)constrained[i]).sorted = true;
+ for (int i = 0; i < nodeCount; i++) {
+ Node node = (Node)nodes[i];
+ if (node.parentBone != null) sortReset(node.parentBone.children);
+ for (Bone bone : node.bones)
+ sortReset(bone.children);
+ }
+ for (int i = 0; i < nodeCount; i++) {
+ Node node = (Node)nodes[i];
+ if (node.parentBone != null) node.parentBone.sorted = true;
+ for (Bone bone : node.bones)
+ bone.sorted = true;
+ }
}
private void sortBone (Bone bone) {
@@ -435,51 +448,20 @@ public class Skeleton {
((Bone)bones[i]).setToSetupPose();
Object[] ikConstraints = this.ikConstraints.items;
- for (int i = 0, n = this.ikConstraints.size; i < n; i++) {
- IkConstraint constraint = (IkConstraint)ikConstraints[i];
- constraint.mix = constraint.data.mix;
- constraint.softness = constraint.data.softness;
- constraint.bendDirection = constraint.data.bendDirection;
- constraint.compress = constraint.data.compress;
- constraint.stretch = constraint.data.stretch;
- }
+ for (int i = 0, n = this.ikConstraints.size; i < n; i++)
+ ((IkConstraint)ikConstraints[i]).setToSetupPose();
Object[] transformConstraints = this.transformConstraints.items;
- for (int i = 0, n = this.transformConstraints.size; i < n; i++) {
- TransformConstraint constraint = (TransformConstraint)transformConstraints[i];
- TransformConstraintData data = constraint.data;
- constraint.mixRotate = data.mixRotate;
- constraint.mixX = data.mixX;
- constraint.mixY = data.mixY;
- constraint.mixScaleX = data.mixScaleX;
- constraint.mixScaleY = data.mixScaleY;
- constraint.mixShearY = data.mixShearY;
- }
+ for (int i = 0, n = this.transformConstraints.size; i < n; i++)
+ ((TransformConstraint)transformConstraints[i]).setToSetupPose();
Object[] pathConstraints = this.pathConstraints.items;
- for (int i = 0, n = this.pathConstraints.size; i < n; i++) {
- PathConstraint constraint = (PathConstraint)pathConstraints[i];
- PathConstraintData data = constraint.data;
- constraint.position = data.position;
- constraint.spacing = data.spacing;
- constraint.mixRotate = data.mixRotate;
- constraint.mixX = data.mixX;
- constraint.mixY = data.mixY;
- }
+ for (int i = 0, n = this.pathConstraints.size; i < n; i++)
+ ((PathConstraint)pathConstraints[i]).setToSetupPose();
Object[] physicsConstraints = this.physicsConstraints.items;
- for (int i = 0, n = this.physicsConstraints.size; i < n; i++) {
- PhysicsConstraint constraint = (PhysicsConstraint)physicsConstraints[i];
- PhysicsConstraintData data = constraint.data;
- constraint.mix = data.mix;
- constraint.friction = data.friction;
- constraint.gravity = data.gravity;
- constraint.wind = data.wind;
- constraint.stiffness = data.stiffness;
- constraint.damping = data.damping;
- constraint.rope = data.rope;
- constraint.stretch = data.stretch;
- }
+ for (int i = 0, n = this.physicsConstraints.size; i < n; i++)
+ ((PhysicsConstraint)physicsConstraints[i]).setToSetupPose();
}
/** Sets the slots and draw order to their setup pose values. */
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java
index 8a866e70e..dd3c5dff3 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java
@@ -80,6 +80,16 @@ public class TransformConstraint implements Updatable {
mixShearY = constraint.mixShearY;
}
+ public void setToSetupPose () {
+ TransformConstraintData data = this.data;
+ mixRotate = data.mixRotate;
+ mixX = data.mixX;
+ mixY = data.mixY;
+ mixScaleX = data.mixScaleX;
+ mixScaleY = data.mixScaleY;
+ mixShearY = data.mixShearY;
+ }
+
/** Applies the constraint to the constrained bones. */
public void update () {
if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleX == 0 && mixShearY == 0) return;