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 cddd40793..9e675a540 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java
@@ -42,6 +42,8 @@ import com.esotericsoftware.spine.PhysicsConstraintData.SpringData;
*
* See Physics constraints in the Spine User Guide. */
public class PhysicsConstraint implements Updatable {
+ static final Vector2 temp = new Vector2();
+
final PhysicsConstraintData data;
final Array nodes;
final Array springs;
@@ -51,7 +53,6 @@ public class PhysicsConstraint implements Updatable {
final Skeleton skeleton;
float remaining, lastTime;
- final Vector2 temp = new Vector2();
public PhysicsConstraint (PhysicsConstraintData data, Skeleton skeleton) {
if (data == null) throw new IllegalArgumentException("data cannot be null.");
@@ -123,9 +124,11 @@ public class PhysicsConstraint implements Updatable {
/** Applies the constraint to the constrained bones. */
public void update () {
+ if (mix == 0) return;
+
Object[] nodes = this.nodes.items;
int nodeCount = this.nodes.size;
- Vector2 temp = this.temp;
+ Vector2 temp = PhysicsConstraint.temp;
for (int i = 0; i < nodeCount; i++) {
Node node = (Node)nodes[i];
if (node.parentBone == null) continue;
@@ -142,26 +145,29 @@ public class PhysicsConstraint implements Updatable {
while (remaining >= 0.016f) {
remaining -= 0.016f;
for (int i = 0; i < springCount; i++)
- ((Spring)springs[i]).update();
+ ((Spring)springs[i]).step();
for (int i = 0; i < nodeCount; i++)
- ((Node)nodes[i]).update(this);
+ ((Node)nodes[i]).step(this);
}
- for (int i = 0; i < nodeCount; i++) {
- Node node = (Node)nodes[i];
- Object[] bones = node.bones;
- int ii = 0, nn = bones.length;
- if (mix == 1) {
- for (; ii < nn; ii++) {
+ if (mix == 1) {
+ for (int i = 0; i < nodeCount; i++) {
+ Node node = (Node)nodes[i];
+ Object[] bones = node.bones;
+ for (int ii = 0, nn = bones.length; ii < nn; ii++) {
Bone bone = (Bone)bones[ii];
bone.worldX = node.x;
bone.worldY = node.y;
- bone.worldToLocal(temp.set(bone.worldX, bone.worldY));
+ bone.parent.worldToLocal(temp.set(node.x, node.y));
bone.ax = temp.x;
bone.ay = temp.y;
}
- } else {
- for (; ii < nn; ii++) {
+ }
+ } else {
+ for (int i = 0; i < nodeCount; i++) {
+ Node node = (Node)nodes[i];
+ Object[] bones = node.bones;
+ for (int ii = 0, nn = bones.length; ii < nn; ii++) {
Bone bone = (Bone)bones[ii];
bone.worldX = bone.worldX + (node.x - bone.worldX) * mix;
bone.worldY = bone.worldY + (node.y - bone.worldY) * mix;
@@ -295,12 +301,8 @@ public class PhysicsConstraint implements Updatable {
vy = 0;
}
- public void update (PhysicsConstraint constraint) {
- if (parentBone != null) {
- vx = 0;
- vy = 0;
- return;
- }
+ public void step (PhysicsConstraint constraint) {
+ if (parentBone != null) return;
x += vx;
y += vy;
vx = vx * constraint.friction + constraint.wind;
@@ -308,35 +310,36 @@ public class PhysicsConstraint implements Updatable {
}
}
- static public class Spring {
+ static public class Spring implements Updatable {
public final SpringData data;
+ public final PhysicsConstraint constraint;
public Node node1, node2;
- public Bone[] bones;
+ public Bone bone;
public float length, stiffness, damping;
- Spring (SpringData data) { // Editor.
+ Spring (SpringData data, PhysicsConstraint constraint) { // Editor.
this.data = data;
+ this.constraint = constraint;
}
public Spring (SpringData data, PhysicsConstraint constraint, Skeleton skeleton) {
this.data = data;
+ this.constraint = constraint;
node1 = constraint.nodes.get(data.node1);
node2 = constraint.nodes.get(data.node2);
- bones = new Bone[data.bones.length];
- for (int i = 0, n = bones.length; i < n; i++)
- bones[i] = skeleton.bones.get(data.bones[i]);
+ bone = skeleton.bones.get(data.bone);
setToSetupPose();
}
public Spring (Spring spring, PhysicsConstraint constraint) {
this.data = spring.data;
+ this.constraint = constraint;
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);
+ bone = spring.bone;
length = spring.length;
stiffness = spring.stiffness;
damping = spring.damping;
@@ -348,9 +351,10 @@ public class PhysicsConstraint implements Updatable {
damping = data.damping;
}
- public void update () {
- float x = node2.x - node1.x, y = node2.y - node1.y, d = (float)Math.sqrt(Math.max(x * x + y * y, 0.00001f));
+ public void step () {
+ float x = node2.x - node1.x, y = node2.y - node1.y, d = x * x + y * y;
if (data.rope && d <= length) return;
+ d = (float)Math.sqrt(Math.max(d, 0.00001f));
x /= d;
y /= d;
float m1 = node1.massInverse, m2 = node2.massInverse;
@@ -362,5 +366,21 @@ public class PhysicsConstraint implements Updatable {
node2.vx -= x * m2;
node2.vy -= y * m2;
}
+
+ public void update () {
+ float dx = node2.x - node1.x, dy = node2.y - node1.y;
+ float s = (float)Math.sqrt(dx * dx + dy * dy) / length, r = atan2(dy, dx), sin = sin(r), cos = cos(r);
+ if (constraint.mix == 1) {
+ bone.updateWorldTransform(bone.ax, bone.ay,
+ atan2(bone.a * sin - bone.c * cos, bone.d * cos - bone.b * sin) * radDeg + bone.arotation - bone.ashearX,
+ bone.ascaleX * s, bone.ascaleY, bone.ashearX, bone.ashearY);
+ } else {
+ // BOZO
+ }
+ }
+
+ public boolean isActive () {
+ return constraint.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 f2e55eb12..cd7b5ff76 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java
@@ -115,8 +115,7 @@ public class PhysicsConstraintData extends ConstraintData {
}
static public class SpringData {
- public int node1, node2;
- public int[] bones;
+ public int node1, node2, bone;
public float length, stiffness, damping;
public boolean rope;
}
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 6a16d416a..150b2d7ee 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
@@ -38,6 +38,7 @@ import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.Null;
import com.esotericsoftware.spine.PhysicsConstraint.Node;
+import com.esotericsoftware.spine.PhysicsConstraint.Spring;
import com.esotericsoftware.spine.Skin.SkinEntry;
import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.MeshAttachment;
@@ -355,16 +356,26 @@ public class Skeleton {
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;
}
+
+ Object[] springs = constraint.springs.items;
+ for (int i = 0, n = constraint.springs.size; i < n; i++) {
+ Spring spring = (Spring)springs[i];
+ if (spring.bone == null) continue;
+ sortBone(spring.bone);
+ updateCache.add(spring);
+ sortReset(spring.bone.children);
+ spring.bone.sorted = true;
+ for (Bone child : spring.bone.children)
+ sortBone(child);
+ }
}
private void sortBone (Bone bone) {