Răsfoiți Sursa

[libgdx] More micro optimizations for clipper.

badlogic 8 ani în urmă
părinte
comite
a10fd95e1b

+ 2 - 1
spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SoftwareClippingTest.java

@@ -186,7 +186,8 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 		clippingPolygon.add(clippingPolygon.get(0));
 		clippingPolygon.add(clippingPolygon.get(1));
 		
-		boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingPolygon, clippedPolygon);
+		boolean isClockwise = SutherlandHodgmanClipper.clockwise(clippingPolygon);
+		boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingPolygon, clippedPolygon, isClockwise);
 		System.out.println("Clipped: " + clipped);
 		if (clipped) {
 			clippedPolygonVertices.clear();

+ 41 - 57
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/SutherlandHodgmanClipper.java

@@ -1,30 +1,18 @@
 
 package com.esotericsoftware.spine.utils;
 
-import com.badlogic.gdx.math.Vector2;
 import com.badlogic.gdx.utils.FloatArray;
 
 public class SutherlandHodgmanClipper {
-	Vector2 tmp = new Vector2();
 	final FloatArray scratch = new FloatArray();
 
-	public boolean clip(float x1, float y1, float x2, float y2, float x3, float y3, FloatArray clippingArea,
-			FloatArray output) {
-		boolean isClockwise = clockwise(clippingArea);
-		return clip(x1, y1, x2, y2, x3, y3, clippingArea, output, isClockwise);
-	}
-
-	/**
-	 * Clips the input triangle against the convex clipping area. 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!
-	 */
-	public boolean clip(float x1, float y1, float x2, float y2, float x3, float y3, FloatArray clippingArea,
-			FloatArray output, boolean isClockwise) {
+	/** Clips the input triangle against the convex clipping area. 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! */
+	public boolean clip (float x1, float y1, float x2, float y2, float x3, float y3, FloatArray clippingArea, FloatArray output,
+		boolean isClockwise) {
 		final FloatArray originalOutput = output;
 		boolean clipped = false;
-		
+
 		FloatArray input = null;
 		// avoid copy at the end
 		if ((clippingArea.size / 2) % 2 != 0) {
@@ -33,7 +21,7 @@ public class SutherlandHodgmanClipper {
 		} else {
 			input = scratch;
 		}
-		 
+
 		input.clear();
 		input.add(x1);
 		input.add(y1);
@@ -75,37 +63,36 @@ public class SutherlandHodgmanClipper {
 				final float inputX2 = inputVertices[j + 2];
 				final float inputY2 = inputVertices[j + 3];
 
-				final int side = pointLineSide(deltaX, deltaY, edgeX2, edgeY2, inputX, inputY);
-				final int side2 = pointLineSide(deltaX, deltaY, edgeX2, edgeY2, inputX2, inputY2);
-
-				// v1 inside, v2 inside
-				if (side >= 0 && side2 >= 0) {
-					output.add(inputX2);
-					output.add(inputY2);
-				}
-				// v1 inside, v2 outside
-				else if (side >= 0 && side2 < 0) {
-					intersectLines(edgeX, edgeY, edgeX2, edgeY2, inputX, inputY, inputX2, inputY2, tmp);
-					output.add(tmp.x);
-					output.add(tmp.y);
-					clipped = true;
-				}
-				// v1 outside, v2 outside
-				else if (side < 0 && side2 < 0) {
-					// no output
-					clipped = true;
-				}
-				// v1 outside, v2 inside
-				else if (side < 0 && side2 >= 0) {
-					intersectLines(edgeX, edgeY, edgeX2, edgeY2, inputX, inputY, inputX2, inputY2, tmp);
-					output.add(tmp.x);
-					output.add(tmp.y);
-					output.add(inputX2);
-					output.add(inputY2);
-					clipped = true;
+				final int side = (int)Math.signum(deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2));
+				final int side2 = (int)Math.signum(deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2));
+
+				if (side >= 0) {
+					// v1 inside, v2 inside
+					if (side2 >= 0) {
+						output.add(inputX2);
+						output.add(inputY2);
+					}
+					// v1 inside, v2 outside
+					else {
+						intersectLines(edgeX, edgeY, edgeX2, edgeY2, inputX, inputY, inputX2, inputY2, output);
+						clipped = true;
+					}
+				} else {
+					// v1 outside, v2 outside
+					if (side2 < 0) {
+						// no output
+						clipped = true;
+					}
+					// v1 outside, v2 inside
+					else {
+						intersectLines(edgeX, edgeY, edgeX2, edgeY2, inputX, inputY, inputX2, inputY2, output);
+						output.add(inputX2);
+						output.add(inputY2);
+						clipped = true;
+					}
 				}
 			}
-			
+
 			output.add(output.items[0]);
 			output.add(output.items[1]);
 
@@ -121,18 +108,14 @@ public class SutherlandHodgmanClipper {
 			originalOutput.clear();
 			originalOutput.addAll(output.items, 0, output.size);
 		}
-		
+
 		originalOutput.setSize(originalOutput.size - 2);
 
 		return clipped;
 	}
 
-	private int pointLineSide(float deltaX, float deltaY, float lineX, float lineY, float pointX, float pointY) {
-		return (int) Math.signum(deltaX * (pointY - lineY) - deltaY * (pointX - lineX));
-	}
-
-	public static void intersectLines(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
-			Vector2 intersection) {
+	public static void intersectLines (float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
+		FloatArray output) {
 		float c0 = y4 - y3;
 		float c1 = x2 - x1;
 		float c2 = x4 - x3;
@@ -140,14 +123,15 @@ public class SutherlandHodgmanClipper {
 		float d = c0 * c1 - c2 * c3;
 
 		float ua = (c2 * (y1 - y3) - c0 * (x1 - x3)) / d;
-		intersection.set(x1 + (x2 - x1) * ua, y1 + (y2 - y1) * ua);
+		output.add(x1 + (x2 - x1) * ua);
+		output.add(y1 + (y2 - y1) * ua);
 	}
 
-	public static boolean clockwise(FloatArray poly) {
+	public static boolean clockwise (FloatArray poly) {
 		return area(poly) < 0;
 	}
 
-	public static float area(FloatArray poly) {
+	public static float area (FloatArray poly) {
 		float area = 0;
 
 		final float[] polyVertices = poly.items;