[libgdx] Fixed using path constraint length spacing with zero length bones. Safer float zero checks.

This commit is contained in:
NathanSweet 2017-10-19 12:44:00 +02:00
parent e6aebf2754
commit bcf90240db

View File

@ -30,7 +30,6 @@
package com.esotericsoftware.spine; package com.esotericsoftware.spine;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
import com.esotericsoftware.spine.PathConstraintData.PositionMode; import com.esotericsoftware.spine.PathConstraintData.PositionMode;
@ -46,6 +45,7 @@ import com.esotericsoftware.spine.utils.SpineUtils;
* See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */ * See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
public class PathConstraint implements Constraint { public class PathConstraint implements Constraint {
static private final int NONE = -1, BEFORE = -2, AFTER = -3; static private final int NONE = -1, BEFORE = -2, AFTER = -3;
static private final float epsilon = 0.00001f;
final PathConstraintData data; final PathConstraintData data;
final Array<Bone> bones; final Array<Bone> bones;
@ -113,11 +113,15 @@ public class PathConstraint implements Constraint {
for (int i = 0, n = spacesCount - 1; i < n;) { for (int i = 0, n = spacesCount - 1; i < n;) {
Bone bone = (Bone)bones[i]; Bone bone = (Bone)bones[i];
float setupLength = bone.data.length; float setupLength = bone.data.length;
if (setupLength == 0) setupLength = 0.000000001f; if (setupLength < epsilon) {
float x = setupLength * bone.a, y = setupLength * bone.c; if (scale) lengths[i] = 0;
float length = (float)Math.sqrt(x * x + y * y); spaces[++i] = 0;
if (scale) lengths[i] = length; } else {
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; float x = setupLength * bone.a, y = setupLength * bone.c;
float length = (float)Math.sqrt(x * x + y * y);
if (scale) lengths[i] = length;
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
}
} }
} else { } else {
for (int i = 1; i < spacesCount; i++) for (int i = 1; i < spacesCount; i++)
@ -142,7 +146,7 @@ public class PathConstraint implements Constraint {
float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
if (scale) { if (scale) {
float length = lengths[i]; float length = lengths[i];
if (length != 0) { if (length >= epsilon) {
float s = ((float)Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1; float s = ((float)Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
bone.a *= s; bone.a *= s;
bone.c *= s; bone.c *= s;
@ -154,7 +158,7 @@ public class PathConstraint implements Constraint {
float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin; float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin;
if (tangents) if (tangents)
r = positions[p - 1]; r = positions[p - 1];
else if (spaces[i + 1] == 0) else if (spaces[i + 1] < epsilon)
r = positions[p + 2]; r = positions[p + 2];
else else
r = (float)Math.atan2(dy, dx); r = (float)Math.atan2(dy, dx);
@ -247,7 +251,7 @@ public class PathConstraint implements Constraint {
path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2);
} }
addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
tangents || (i > 0 && space == 0)); tangents || (i > 0 && space < epsilon));
} }
return out; return out;
} }
@ -395,7 +399,7 @@ public class PathConstraint implements Constraint {
} }
break; break;
} }
addCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); addCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space < epsilon));
} }
return out; return out;
} }
@ -416,13 +420,14 @@ public class PathConstraint implements Constraint {
private void addCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, private void addCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2,
float[] out, int o, boolean tangents) { float[] out, int o, boolean tangents) {
if (p == 0 || Float.isNaN(p)) p = 0.0001f; if (p < epsilon || Float.isNaN(p)) p = epsilon;
float tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; float tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;
float ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; float ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p;
float x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; float x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
out[o] = x; out[o] = x;
out[o + 1] = y; out[o + 1] = y;
if (tangents) out[o + 2] = (float)Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); if (tangents)
out[o + 2] = (float)Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
} }
public int getOrder () { public int getOrder () {