소스 검색

[libgdx] SutherlandHodgman assumes clip area is given clockwise

badlogic 8 년 전
부모
커밋
687a3ade7b

+ 3 - 0
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java

@@ -394,6 +394,9 @@ public class SkeletonRenderer {
 			float[] vertices = this.clippingArea.setSize(n);
 			float[] vertices = this.clippingArea.setSize(n);
 			clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
 			clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
 			clippingAreaClockwise = SutherlandHodgmanClipper.clockwise(this.clippingArea);
 			clippingAreaClockwise = SutherlandHodgmanClipper.clockwise(this.clippingArea);
+			if (!clippingAreaClockwise) {
+				SutherlandHodgmanClipper.makeClockwise(clippingArea);
+			}
 			clippingArea.add(clippingArea.items[0]);
 			clippingArea.add(clippingArea.items[0]);
 			clippingArea.add(clippingArea.items[1]);
 			clippingArea.add(clippingArea.items[1]);
 		}
 		}

+ 17 - 11
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/SutherlandHodgmanClipper.java

@@ -6,7 +6,7 @@ import com.badlogic.gdx.utils.FloatArray;
 public class SutherlandHodgmanClipper {
 public class SutherlandHodgmanClipper {
 	final FloatArray scratch = new FloatArray();
 	final FloatArray scratch = new FloatArray();
 
 
-	/** Clips the input triangle against the convex clipping area. If the triangle lies entirely within the clipping area, false is
+	/** Clips the input triangle against the convex clipping area, which needs to be clockwise. If the triangle lies entirely within the clipping area, false is
 	 * returned. The clipping area must duplicate the first vertex at the end of the vertices list! */
 	 * returned. The clipping area must duplicate the first vertex at the end of the vertices list! */
 	public boolean clip (float x1, float y1, float x2, float y2, float x3, float y3, FloatArray clippingArea, FloatArray output,
 	public boolean clip (float x1, float y1, float x2, float y2, float x3, float y3, FloatArray clippingArea, FloatArray output,
 		boolean isClockwise) {
 		boolean isClockwise) {
@@ -41,16 +41,6 @@ public class SutherlandHodgmanClipper {
 			float edgeX2 = clippingVertices[i + 2];
 			float edgeX2 = clippingVertices[i + 2];
 			float edgeY2 = clippingVertices[i + 3];
 			float edgeY2 = clippingVertices[i + 3];
 
 
-			if (!isClockwise) {
-				float tmp = edgeX;
-				edgeX = edgeX2;
-				edgeX2 = tmp;
-
-				tmp = edgeY;
-				edgeY = edgeY2;
-				edgeY2 = tmp;
-			}
-
 			final float deltaX = edgeX - edgeX2;
 			final float deltaX = edgeX - edgeX2;
 			final float deltaY = edgeY - edgeY2;
 			final float deltaY = edgeY - edgeY2;
 
 
@@ -126,6 +116,22 @@ public class SutherlandHodgmanClipper {
 		output.add(x1 + (x2 - x1) * ua);
 		output.add(x1 + (x2 - x1) * ua);
 		output.add(y1 + (y2 - y1) * ua);
 		output.add(y1 + (y2 - y1) * ua);
 	}
 	}
+	
+	public static void makeClockwise (FloatArray poly) {
+		if (clockwise(poly)) return;
+		
+		int lastX = poly.size - 2;
+		final float[] polygon = poly.items;
+		for (int i = 0, n = poly.size / 2; i < n; i += 2) {
+			int other = lastX - i;
+			float x = polygon[i];
+			float y = polygon[i + 1];
+			polygon[i] = polygon[other];
+			polygon[i + 1] = polygon[other + 1];
+			polygon[other] = x;
+			polygon[other + 1] = y;
+		}
+	}
 
 
 	public static boolean clockwise (FloatArray poly) {
 	public static boolean clockwise (FloatArray poly) {
 		return area(poly) < 0;
 		return area(poly) < 0;