Эх сурвалжийг харах

[libgdx] Fixed up software clipping test

badlogic 8 жил өмнө
parent
commit
b8a603d6af

+ 110 - 100
spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SoftwareClippingTest.java

@@ -6,6 +6,7 @@ import org.lwjgl.opengl.GL11;
 import com.badlogic.gdx.ApplicationAdapter;
 import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.Input.Buttons;
+import com.badlogic.gdx.Input.Keys;
 import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
 import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
 import com.badlogic.gdx.graphics.Color;
@@ -16,9 +17,11 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
 import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
 import com.badlogic.gdx.math.Vector3;
+import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.FloatArray;
 import com.badlogic.gdx.utils.ShortArray;
 import com.esotericsoftware.spine.utils.Clipper;
+import com.esotericsoftware.spine.utils.ConvexDecomposer;
 
 public class SoftwareClippingTest extends ApplicationAdapter {
 	OrthographicCamera sceneCamera;
@@ -26,22 +29,20 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 	PolygonSpriteBatch polyBatcher;
 	Texture image;
 
-	float[] triangleOutline = { 100, 100, 300, 100, 200, 300 };
-	float[] triangle = { 
-		100, 100, Color.WHITE.toFloatBits(), 0, 1, 
-		300, 100, Color.WHITE.toFloatBits(), 1, 1, 
-		200, 300, Color.WHITE.toFloatBits(), 0.5f, 0
-	};
-	short[] triangleIndices = { 0, 1, 2 };	
+	float[] triangleOutline = {100, 100, 300, 100, 200, 300};
+	float[] triangle = {100, 100, Color.WHITE.toFloatBits(), 0, 1, 300, 100, Color.WHITE.toFloatBits(), 1, 1, 200, 300,
+		Color.WHITE.toFloatBits(), 0.5f, 0};
+	short[] triangleIndices = {0, 1, 2};
 	FloatArray clippingPolygon = new FloatArray();
 	FloatArray clippedPolygon = new FloatArray();
-	
+
 	FloatArray clippedPolygonVertices = new FloatArray();
 	ShortArray clippedPolygonIndices = new ShortArray();
 
 	boolean isCreatingClippingArea = false;
 	Vector3 tmp = new Vector3();
 	Clipper clipper;
+	ConvexDecomposer decomposer;
 
 	@Override
 	public void create () {
@@ -49,6 +50,7 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 		shapes = new ShapeRenderer();
 		polyBatcher = new PolygonSpriteBatch();
 		clipper = new Clipper();
+		decomposer = new ConvexDecomposer();
 		image = new Texture("skin/skin.png");
 	}
 
@@ -74,40 +76,46 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 			if (!isCreatingClippingArea) {
 				clippingPolygon.clear();
 				isCreatingClippingArea = true;
-			} 
-			
-			clippingPolygon.add(tmp.x);
-			clippingPolygon.add(tmp.y);
-			
+			}
+
+			clippingPolygon.add((int)tmp.x);
+			clippingPolygon.add((int)tmp.y);
+
 			if (Gdx.input.isButtonPressed(Buttons.RIGHT)) {
-				isCreatingClippingArea = false;					
-				clip();			
+				isCreatingClippingArea = false;
+				clip();
 			}
 		}
+
+		if (Gdx.input.isKeyJustPressed(Keys.T)) {
+			clip();
+		}
 	}
 
 	private void renderScene () {
 		sceneCamera.update();
 		shapes.setProjectionMatrix(sceneCamera.combined);
 		polyBatcher.setProjectionMatrix(sceneCamera.combined);
-		
+
 		polyBatcher.begin();
 		polyBatcher.disableBlending();
-		
-		if (clippedPolygon.size == 0) {
+
+		// clipped polygon
+		if (clippedPolygonVertices.size == 0) {
 			polyBatcher.draw(image, triangle, 0, 15, triangleIndices, 0, 3);
 		} else {
-			polyBatcher.draw(image, clippedPolygonVertices.items, 0, clippedPolygonVertices.size, clippedPolygonIndices.items, 0, clippedPolygonIndices.size);
+			polyBatcher.draw(image, clippedPolygonVertices.items, 0, clippedPolygonVertices.size, clippedPolygonIndices.items, 0,
+				clippedPolygonIndices.size);
 		}
 		polyBatcher.end();
-		
+
 		shapes.begin(ShapeType.Line);
 
 		// triangle
 		shapes.setColor(Color.GREEN);
 		shapes.polygon(triangleOutline);
 
-		// clipped polygons
+		// clipping area
 		shapes.setColor(Color.RED);
 		if (isCreatingClippingArea) {
 			tmp.set(Gdx.input.getX(), Gdx.input.getY(), 0);
@@ -115,7 +123,7 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 			clippingPolygon.add(tmp.x);
 			clippingPolygon.add(tmp.y);
 		}
-		
+
 		switch (clippingPolygon.size) {
 		case 0:
 			break;
@@ -134,41 +142,41 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 			shapes.polygon(clippingPolygon.items, 0, clippingPolygon.size);
 		}
 
-		// edge normals
-		shapes.setColor(Color.YELLOW);		
-		if (clippingPolygon.size > 2) {
-			boolean clockwise = Clipper.isClockwise(clippingPolygon);
-			for (int i = 0; i < clippingPolygon.size; i += 2) {
-				float x = clippingPolygon.get(i);
-				float y = clippingPolygon.get(i + 1);
-				float x2 = clippingPolygon.get((i + 2) % clippingPolygon.size);
-				float y2 = clippingPolygon.get((i + 3) % clippingPolygon.size);
-
-				float mx = x + (x2 - x) / 2;
-				float my = y + (y2 - y) / 2;
-				float nx = (y2 - y);
-				float ny = -(x2 - x);
-				if (!clockwise) {
-					nx = -nx;
-					ny = -ny;
-				}
-				float l = 1 / (float)Math.sqrt(nx * nx + ny * ny);
-				nx *= l * 20;
-				ny *= l * 20;
+// // edge normals
+// shapes.setColor(Color.YELLOW);
+// if (clippingPolygon.size > 2) {
+// boolean clockwise = Clipper.isClockwise(clippingPolygon);
+// for (int i = 0; i < clippingPolygon.size; i += 2) {
+// float x = clippingPolygon.get(i);
+// float y = clippingPolygon.get(i + 1);
+// float x2 = clippingPolygon.get((i + 2) % clippingPolygon.size);
+// float y2 = clippingPolygon.get((i + 3) % clippingPolygon.size);
+//
+// float mx = x + (x2 - x) / 2;
+// float my = y + (y2 - y) / 2;
+// float nx = (y2 - y);
+// float ny = -(x2 - x);
+// if (!clockwise) {
+// nx = -nx;
+// ny = -ny;
+// }
+// float l = 1 / (float)Math.sqrt(nx * nx + ny * ny);
+// nx *= l * 20;
+// ny *= l * 20;
+//
+// shapes.line(mx, my, mx + nx, my + ny);
+// }
+// }
 
-				shapes.line(mx, my, mx + nx, my + ny);
-			}
-		}
-		
 		if (isCreatingClippingArea) {
 			clippingPolygon.setSize(clippingPolygon.size - 2);
 		}
 
-		// clipped polygon
-		shapes.setColor(Color.PINK);
-		if (clippedPolygon.size > 0) {
-			shapes.polygon(clippedPolygon.items, 0, clippedPolygon.size);
-		}
+// // clipped polygon
+// shapes.setColor(Color.PINK);
+// if (clippedPolygon.size > 0) {
+// shapes.polygon(clippedPolygon.items, 0, clippedPolygon.size);
+// }
 
 		shapes.end();
 	}
@@ -180,56 +188,58 @@ public class SoftwareClippingTest extends ApplicationAdapter {
 		float y2 = triangle[6];
 		float x3 = triangle[10];
 		float y3 = triangle[11];
-		
-		// must duplicate first vertex at end of polygon
-		// so we can avoid module/branch in clipping code
-		Clipper.makeClockwise(clippingPolygon);
-		clippingPolygon.add(clippingPolygon.get(0));
-		clippingPolygon.add(clippingPolygon.get(1));
-		
-		boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingPolygon, clippedPolygon);
-		System.out.println("Clipped: " + clipped);
-		if (clipped) {
-			clippedPolygonVertices.clear();
-			clippedPolygonIndices.clear();
-			
-			float d0 = y2 - y3;
-			float d1 = x3 - x2;
-			float d2 = x1 - x3;
-			float d3 = y1 - y3;
-			float d4 = y3 - y1;
-			
-			float denom = 1 / (d0 * d2 + d1 * d3);
-			
-			// triangulate by creating a triangle fan, duplicate vertices
-			float color = Color.WHITE.toFloatBits();
-			for (int i = 0; i < clippedPolygon.size; i+=2) {				
-				float x = clippedPolygon.get(i);
-				float y = clippedPolygon.get(i + 1);
-					
-				float a = (d0 * (x - x3) + d1 * (y - y3)) * denom;
-				float b = (d4 * (x - x3) + d2 * (y - y3)) * denom;
-				float c = 1.0f - a - b;
-				
-				float u = triangle[3] * a + triangle[8] * b + triangle[13] * c;
-				float v = triangle[4] * a + triangle[9] * b + triangle[14] * c;
-				clippedPolygonVertices.add(x);
-				clippedPolygonVertices.add(y);
-				clippedPolygonVertices.add(color);
-				clippedPolygonVertices.add(u);
-				clippedPolygonVertices.add(v);
-			}
-			
-			for (int i = 1; i < (clippedPolygon.size >> 1) - 1; i++) {
-				clippedPolygonIndices.add(0);
-				clippedPolygonIndices.add(i);
-				clippedPolygonIndices.add(i + 1);
+
+		Array<FloatArray> clippingPolygons = decomposer.decompose(clippingPolygon);
+		clippedPolygonVertices.clear();
+		clippedPolygonIndices.clear();
+
+		for (FloatArray poly : clippingPolygons) {
+			Clipper.makeClockwise(poly);
+			poly.add(poly.get(0));
+			poly.add(poly.get(1));
+
+			boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, poly, clippedPolygon);
+			System.out.println("Clipped: " + clipped);
+			if (clipped) {
+				float d0 = y2 - y3;
+				float d1 = x3 - x2;
+				float d2 = x1 - x3;
+				float d3 = y1 - y3;
+				float d4 = y3 - y1;
+
+				float denom = 1 / (d0 * d2 + d1 * d3);
+
+				// triangulate by creating a triangle fan, duplicate vertices
+				int o = clippedPolygonVertices.size / 5;
+				float color = Color.WHITE.toFloatBits();
+				for (int i = 0; i < clippedPolygon.size; i += 2) {
+					float x = clippedPolygon.get(i);
+					float y = clippedPolygon.get(i + 1);
+
+					float a = (d0 * (x - x3) + d1 * (y - y3)) * denom;
+					float b = (d4 * (x - x3) + d2 * (y - y3)) * denom;
+					float c = 1.0f - a - b;
+
+					float u = triangle[3] * a + triangle[8] * b + triangle[13] * c;
+					float v = triangle[4] * a + triangle[9] * b + triangle[14] * c;
+					clippedPolygonVertices.add(x);
+					clippedPolygonVertices.add(y);
+					clippedPolygonVertices.add(color);
+					clippedPolygonVertices.add(u);
+					clippedPolygonVertices.add(v);
+				}
+
+				for (int i = 1; i < (clippedPolygon.size >> 1) - 1; i++) {
+					clippedPolygonIndices.add(o);
+					clippedPolygonIndices.add(o + i);
+					clippedPolygonIndices.add(o + i + 1);
+				}
+			} else {
+				clippedPolygon.clear();
 			}
-		} else {
-			clippedPolygon.clear();
+
+			poly.setSize(poly.size - 2);
 		}
-		
-		clippingPolygon.setSize(clippingPolygon.size - 2);
 	}
 
 	public static void main (String[] args) {