Procházet zdrojové kódy

[libgdx] Added a proportional spacing mode to path constraints.

EsotericSoftware/spine-editor#414
Nathan Sweet před 4 roky
rodič
revize
10d5a918ca

+ 70 - 28
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java

@@ -98,47 +98,71 @@ public class PathConstraint implements Updatable {
 		if (mixRotate == 0 && mixX == 0 && mixY == 0) return;
 		if (mixRotate == 0 && mixX == 0 && mixY == 0) return;
 
 
 		PathConstraintData data = this.data;
 		PathConstraintData data = this.data;
-		boolean percentSpacing = data.spacingMode == SpacingMode.percent;
-		RotateMode rotateMode = data.rotateMode;
-		boolean tangents = rotateMode == RotateMode.tangent, scale = rotateMode == RotateMode.chainScale;
+		boolean tangents = data.rotateMode == RotateMode.tangent, scale = data.rotateMode == RotateMode.chainScale;
 		int boneCount = this.bones.size, spacesCount = tangents ? boneCount : boneCount + 1;
 		int boneCount = this.bones.size, spacesCount = tangents ? boneCount : boneCount + 1;
 		Object[] bones = this.bones.items;
 		Object[] bones = this.bones.items;
-		float[] spaces = this.spaces.setSize(spacesCount), lengths = null;
+		float[] spaces = this.spaces.setSize(spacesCount), lengths = scale ? this.lengths.setSize(boneCount) : null;
 		float spacing = this.spacing;
 		float spacing = this.spacing;
-		if (scale || !percentSpacing) {
-			if (scale) lengths = this.lengths.setSize(boneCount);
-			boolean lengthSpacing = data.spacingMode == SpacingMode.length;
+
+		switch (data.spacingMode) {
+		case percent:
 			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 < epsilon) {
 				if (setupLength < epsilon) {
 					if (scale) lengths[i] = 0;
 					if (scale) lengths[i] = 0;
 					spaces[++i] = 0;
 					spaces[++i] = 0;
-				} else if (percentSpacing) {
+				} else {
 					if (scale) {
 					if (scale) {
 						float x = setupLength * bone.a, y = setupLength * bone.c;
 						float x = setupLength * bone.a, y = setupLength * bone.c;
-						float length = (float)Math.sqrt(x * x + y * y);
-						lengths[i] = length;
+						lengths[i] = (float)Math.sqrt(x * x + y * y);
 					}
 					}
 					spaces[++i] = spacing;
 					spaces[++i] = spacing;
+				}
+			}
+			break;
+		case proportional:
+			float sum = 0;
+			for (int i = 0; i < boneCount;) {
+				Bone bone = (Bone)bones[i];
+				float setupLength = bone.data.length;
+				if (setupLength < epsilon) {
+					if (scale) lengths[i] = 0;
+					spaces[++i] = 0;
 				} else {
 				} else {
 					float x = setupLength * bone.a, y = setupLength * bone.c;
 					float x = setupLength * bone.a, y = setupLength * bone.c;
 					float length = (float)Math.sqrt(x * x + y * y);
 					float length = (float)Math.sqrt(x * x + y * y);
 					if (scale) lengths[i] = length;
 					if (scale) lengths[i] = length;
-					spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
+					spaces[++i] = length;
+					sum += length;
 				}
 				}
 			}
 			}
-		} else {
+			sum = spacesCount / sum * spacing;
 			for (int i = 1; i < spacesCount; i++)
 			for (int i = 1; i < spacesCount; i++)
-				spaces[i] = spacing;
+				spaces[i] *= sum;
+			break;
+		default:
+			boolean lengthSpacing = data.spacingMode == SpacingMode.length;
+			for (int i = 0, n = spacesCount - 1; i < n;) {
+				Bone bone = (Bone)bones[i];
+				float setupLength = bone.data.length;
+				if (setupLength < epsilon) {
+					if (scale) lengths[i] = 0;
+					spaces[++i] = 0;
+				} else {
+					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;
+				}
+			}
 		}
 		}
 
 
-		float[] positions = computeWorldPositions((PathAttachment)attachment, spacesCount, tangents,
-			data.positionMode == PositionMode.percent, percentSpacing);
+		float[] positions = computeWorldPositions((PathAttachment)attachment, spacesCount, tangents);
 		float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
 		float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
 		boolean tip;
 		boolean tip;
 		if (offsetRotation == 0)
 		if (offsetRotation == 0)
-			tip = rotateMode == RotateMode.chain;
+			tip = data.rotateMode == RotateMode.chain;
 		else {
 		else {
 			tip = false;
 			tip = false;
 			Bone p = target.bone;
 			Bone p = target.bone;
@@ -192,8 +216,7 @@ public class PathConstraint implements Updatable {
 		}
 		}
 	}
 	}
 
 
-	float[] computeWorldPositions (PathAttachment path, int spacesCount, boolean tangents, boolean percentPosition,
-		boolean percentSpacing) {
+	float[] computeWorldPositions (PathAttachment path, int spacesCount, boolean tangents) {
 		Slot target = this.target;
 		Slot target = this.target;
 		float position = this.position;
 		float position = this.position;
 		float[] spaces = this.spaces.items, out = this.positions.setSize(spacesCount * 3 + 2), world;
 		float[] spaces = this.spaces.items, out = this.positions.setSize(spacesCount * 3 + 2), world;
@@ -204,14 +227,24 @@ public class PathConstraint implements Updatable {
 			float[] lengths = path.getLengths();
 			float[] lengths = path.getLengths();
 			curveCount -= closed ? 1 : 2;
 			curveCount -= closed ? 1 : 2;
 			float pathLength = lengths[curveCount];
 			float pathLength = lengths[curveCount];
-			if (percentPosition) position *= pathLength;
-			if (percentSpacing) {
-				for (int i = 1; i < spacesCount; i++)
-					spaces[i] *= pathLength;
+
+			if (data.positionMode == PositionMode.percent) position *= pathLength;
+
+			float multiplier;
+			switch (data.spacingMode) {
+			case percent:
+				multiplier = pathLength;
+				break;
+			case proportional:
+				multiplier = pathLength / spacesCount;
+				break;
+			default:
+				multiplier = 1;
 			}
 			}
+
 			world = this.world.setSize(8);
 			world = this.world.setSize(8);
 			for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
 			for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
-				float space = spaces[i];
+				float space = spaces[i] * multiplier;
 				position += space;
 				position += space;
 				float p = position;
 				float p = position;
 
 
@@ -312,19 +345,28 @@ public class PathConstraint implements Updatable {
 			x1 = x2;
 			x1 = x2;
 			y1 = y2;
 			y1 = y2;
 		}
 		}
-		if (percentPosition)
+
+		if (data.positionMode == PositionMode.percent)
 			position *= pathLength;
 			position *= pathLength;
 		else
 		else
 			position *= pathLength / path.getLengths()[curveCount - 1];
 			position *= pathLength / path.getLengths()[curveCount - 1];
-		if (percentSpacing) {
-			for (int i = 1; i < spacesCount; i++)
-				spaces[i] *= pathLength;
+
+		float multiplier;
+		switch (data.spacingMode) {
+		case percent:
+			multiplier = pathLength;
+			break;
+		case proportional:
+			multiplier = pathLength / spacesCount;
+			break;
+		default:
+			multiplier = 1;
 		}
 		}
 
 
 		float[] segments = this.segments;
 		float[] segments = this.segments;
 		float curveLength = 0;
 		float curveLength = 0;
 		for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
 		for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
-			float space = spaces[i];
+			float space = spaces[i] * multiplier;
 			position += space;
 			position += space;
 			float p = position;
 			float p = position;
 
 

+ 1 - 1
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraintData.java

@@ -159,7 +159,7 @@ public class PathConstraintData extends ConstraintData {
 	 * <p>
 	 * <p>
 	 * See <a href="http://esotericsoftware.com/spine-path-constraints#Spacing-mode">Spacing mode</a> in the Spine User Guide. */
 	 * See <a href="http://esotericsoftware.com/spine-path-constraints#Spacing-mode">Spacing mode</a> in the Spine User Guide. */
 	static public enum SpacingMode {
 	static public enum SpacingMode {
-		length, fixed, percent;
+		length, fixed, percent, proportional;
 
 
 		static public final SpacingMode[] values = SpacingMode.values();
 		static public final SpacingMode[] values = SpacingMode.values();
 	}
 	}