Clean up, optimization.

This commit is contained in:
NathanSweet 2016-06-05 00:58:07 +02:00
parent 3d8b674444
commit 633432647b
2 changed files with 61 additions and 50 deletions

View File

@ -9,6 +9,10 @@ import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.PathAttachment; import com.esotericsoftware.spine.attachments.PathAttachment;
public class PathConstraint implements Updatable { public class PathConstraint implements Updatable {
static private final int NONE = -1;
static private final int BEFORE = -2;
static private final int AFTER = -3;
final PathConstraintData data; final PathConstraintData data;
final Array<Bone> bones; final Array<Bone> bones;
Slot target; Slot target;
@ -98,9 +102,12 @@ public class PathConstraint implements Updatable {
bone.worldY += (boneY - bone.worldY) * translateMix; bone.worldY += (boneY - bone.worldY) * translateMix;
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 s = ((float)Math.sqrt(dx * dx + dy * dy) / lengths.get(i + 1) - 1) * scaleMix + 1; float length = lengths.get(i + 1);
bone.a *= s; if (length != 0) {
bone.c *= s; float s = ((float)Math.sqrt(dx * dx + dy * dy) / length - 1) * scaleMix + 1;
bone.a *= s;
bone.c *= s;
}
} }
if (!rotate) { if (!rotate) {
boneX = x; boneX = x;
@ -143,11 +150,11 @@ public class PathConstraint implements Updatable {
boolean closed = path.getClosed(); boolean closed = path.getClosed();
int verticesLength = path.getWorldVerticesLength(), curves = verticesLength / 6; int verticesLength = path.getWorldVerticesLength(), curves = verticesLength / 6;
float[] temp; float[] temp;
int lastCurve = -1; int lastCurve = NONE;
if (!path.getConstantSpeed()) { if (!path.getConstantSpeed()) {
if (!closed) curves--; if (!closed) curves--;
float pathLength = path.getLength(); float pathLength = path.getTotalLength();
temp = this.temp.setSize(8); temp = this.temp.setSize(8);
for (int i = 0; i < lengthCount; i++) { for (int i = 0; i < lengthCount; i++) {
position += lengths[i] / pathLength; position += lengths[i] / pathLength;
@ -155,15 +162,15 @@ public class PathConstraint implements Updatable {
position %= 1; position %= 1;
if (position < 0) position += 1; if (position < 0) position += 1;
} else if (position < 0) { } else if (position < 0) {
if (lastCurve != -2) { if (lastCurve != BEFORE) {
lastCurve = -2; lastCurve = BEFORE;
path.computeWorldVertices(target, 2, 4, temp, 0); path.computeWorldVertices(target, 2, 4, temp, 0);
} }
addBeforePosition(position * pathLength, temp, 0, positions, tangents); addBeforePosition(position * pathLength, temp, 0, positions, tangents);
continue; continue;
} else if (position > 1) { } else if (position > 1) {
if (lastCurve != -3) { if (lastCurve != AFTER) {
lastCurve = -3; lastCurve = AFTER;
path.computeWorldVertices(target, verticesLength - 6, 4, temp, 0); path.computeWorldVertices(target, verticesLength - 6, 4, temp, 0);
} }
addAfterPosition((position - 1) * pathLength, temp, 0, positions, tangents); addAfterPosition((position - 1) * pathLength, temp, 0, positions, tangents);
@ -184,7 +191,7 @@ public class PathConstraint implements Updatable {
return positions.items; return positions.items;
} }
// World vertices, verticesStart to verticesStart + verticesLength. // World vertices, verticesStart to verticesStart + verticesLength - 1.
int verticesStart = 10 + curves; int verticesStart = 10 + curves;
temp = this.temp.setSize(verticesStart + verticesLength + 2); temp = this.temp.setSize(verticesStart + verticesLength + 2);
if (closed) { if (closed) {
@ -200,7 +207,7 @@ public class PathConstraint implements Updatable {
path.computeWorldVertices(target, 2, verticesLength, temp, verticesStart); path.computeWorldVertices(target, 2, verticesLength, temp, verticesStart);
} }
// Curve lengths, 10 to verticesStart. // Curve lengths, 10 to verticesStart - 1.
float pathLength = 0; float pathLength = 0;
float x1 = temp[verticesStart], y1 = temp[verticesStart + 1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; float x1 = temp[verticesStart], y1 = temp[verticesStart + 1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
float tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy; float tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy;
@ -238,6 +245,7 @@ public class PathConstraint implements Updatable {
position *= pathLength; position *= pathLength;
float curveLength = 0; float curveLength = 0;
int curve = 10, segment = 0;
for (int i = 0; i < lengthCount; i++) { for (int i = 0; i < lengthCount; i++) {
position += lengths[i]; position += lengths[i];
float p = position; float p = position;
@ -254,34 +262,30 @@ public class PathConstraint implements Updatable {
} }
// Determine curve containing position. // Determine curve containing position.
int curve; for (;; curve++) {
float length = temp[10]; float length = temp[curve];
if (p <= length) { if (p > length) continue;
curve = verticesStart; if (curve == 10)
p /= length; p /= length;
} else { else {
for (curve = 11;; curve++) { float prev = temp[curve - 1];
length = temp[curve]; p = (p - prev) / (length - prev);
if (p <= length) {
float prev = temp[curve - 1];
p = (p - prev) / (length - prev);
break;
}
} }
curve = verticesStart + (curve - 10) * 6; break;
} }
// Curve segment lengths, 0 to 10. // Curve segment lengths, 0 to 9.
if (curve != lastCurve) { if (curve != lastCurve) {
lastCurve = curve; lastCurve = curve;
x1 = temp[curve]; int index = verticesStart + (curve - 10) * 6;
y1 = temp[curve + 1]; x1 = temp[index];
cx1 = temp[curve + 2]; y1 = temp[index + 1];
cy1 = temp[curve + 3]; cx1 = temp[index + 2];
cx2 = temp[curve + 4]; cy1 = temp[index + 3];
cy2 = temp[curve + 5]; cx2 = temp[index + 4];
x2 = temp[curve + 6]; cy2 = temp[index + 5];
y2 = temp[curve + 7]; x2 = temp[index + 6];
y2 = temp[index + 7];
tmpx = (x1 - cx1 * 2 + cx2) * 0.03f; tmpx = (x1 - cx1 * 2 + cx2) * 0.03f;
tmpy = (y1 - cy1 * 2 + cy2) * 0.03f; tmpy = (y1 - cy1 * 2 + cy2) * 0.03f;
dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006f; dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006f;
@ -308,22 +312,21 @@ public class PathConstraint implements Updatable {
dfy += ddfy + dddfy; dfy += ddfy + dddfy;
curveLength += (float)Math.sqrt(dfx * dfx + dfy * dfy); curveLength += (float)Math.sqrt(dfx * dfx + dfy * dfy);
temp[9] = curveLength; temp[9] = curveLength;
segment = 0;
} }
// Weight by segment length. // Weight by segment length.
p *= curveLength; p *= curveLength;
length = temp[0]; for (;; segment++) {
if (p <= length) float length = temp[segment];
p = 0.1f * p / length; if (p > length) continue;
else { if (segment == 0)
for (int ii = 1;; ii++) { p = 0.1f * p / length;
length = temp[ii]; else {
if (p <= length) { float prev = temp[segment - 1];
float prev = temp[ii - 1]; p = 0.1f * (segment + (p - prev) / (length - prev));
p = 0.1f * (ii + (p - prev) / (length - prev));
break;
}
} }
break;
} }
addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, positions, tangents); addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, positions, tangents);

View File

@ -32,10 +32,12 @@
package com.esotericsoftware.spine.attachments; package com.esotericsoftware.spine.attachments;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.FloatArray;
import com.esotericsoftware.spine.Slot; import com.esotericsoftware.spine.Slot;
public class PathAttachment extends VertexAttachment { public class PathAttachment extends VertexAttachment {
float length; float totalLength;
final FloatArray lengths = new FloatArray();
boolean closed, constantSpeed; boolean closed, constantSpeed;
// Nonessential. // Nonessential.
@ -69,12 +71,18 @@ public class PathAttachment extends VertexAttachment {
this.constantSpeed = constantSpeed; this.constantSpeed = constantSpeed;
} }
public float getLength () { /** Returns the length of the path in the setup pose. */
return length; public float getTotalLength () {
return totalLength;
} }
public void setLength (float length) { public void setTotalLength (float totalLength) {
this.length = length; this.totalLength = totalLength;
}
/** Returns the length of each curve in the setup pose. */
public FloatArray getLengths () {
return lengths;
} }
public Color getColor () { public Color getColor () {