[libgdx] Working version of convex decomposer, can improve result by merging left over triangles at end of decomposition

This commit is contained in:
badlogic 2017-03-30 10:55:11 +02:00
parent afd2a95594
commit 61d5a3de5a
2 changed files with 50 additions and 41 deletions

View File

@ -43,6 +43,11 @@ public class ConvexDecomposerTest extends ApplicationAdapter {
polyBatcher = new PolygonSpriteBatch();
image = new Texture("skin/skin.png");
font = new BitmapFont();
// float[] v = { 87, 288, 217, 371, 456, 361, 539, 175, 304, 194, 392, 290, 193, 214, 123, 15, 14, 137 };
float[] v = { 336, 153, 207, 184, 364, 333, 529, 326, 584, 130, 438, 224 };
polygon.addAll(v);
triangulate();
}
@Override
@ -70,11 +75,17 @@ public class ConvexDecomposerTest extends ApplicationAdapter {
isCreatingPolygon = true;
}
polygon.add(tmp.x);
polygon.add(tmp.y);
polygon.add((int)tmp.x);
polygon.add((int)tmp.y);
if (Gdx.input.isButtonPressed(Buttons.RIGHT)) {
isCreatingPolygon = false;
System.out.print("float[] v = { ");
for (int i = 0; i < polygon.size; i++) {
System.out.print(polygon.get(i));
if (i != polygon.size - 1) System.out.print(", ");
}
System.out.println("};");
triangulate();
}
}
@ -133,7 +144,7 @@ public class ConvexDecomposerTest extends ApplicationAdapter {
float my = y + (y2 - y) / 2;
float nx = (y2 - y);
float ny = -(x2 - x);
if (clockwise) {
if (!clockwise) {
nx = -nx;
ny = -ny;
}
@ -167,8 +178,9 @@ public class ConvexDecomposerTest extends ApplicationAdapter {
for (int i = 0; i < polygon.size; i+=2) {
float x = polygon.get(i);
float y = polygon.get(i + 1);
font.draw(polyBatcher, "" + (i >> 1), x, y);
font.draw(polyBatcher, "" + (i >> 1), x, y); // + ", " + x + ", " + y, x, y);
}
font.draw(polyBatcher, Gdx.input.getX() + ", " + (Gdx.graphics.getHeight() - Gdx.input.getY()), 0, 20);
polyBatcher.end();
}

View File

@ -74,14 +74,22 @@ public class ConvexDecomposer {
polyIndices.add(idx3);
idx3 <<= 1;
System.out.println("Triangle: " + idx1 / 2 + ", " + idx2 / 2 + ", " + idx3 / 2);
poly.add(polygon.get(idx1));
poly.add(polygon.get(idx1 + 1));
poly.add(polygon.get(idx2));
poly.add(polygon.get(idx2 + 1));
poly.add(polygon.get(idx3));
poly.add(polygon.get(idx3 + 1));
int lastWinding = lastWinding(poly);
int fanBaseIndex = idx1 >> 1;
float x1 = polygon.get(idx1);
float y1 = polygon.get(idx1 + 1);
float x2 = polygon.get(idx2);
float y2 = polygon.get(idx2 + 1);
float x3 = polygon.get(idx3);
float y3 = polygon.get(idx3 + 1);
poly.add(x1);
poly.add(y1);
poly.add(x2);
poly.add(y2);
poly.add(x3);
poly.add(y3);
int lastWinding = winding(x1, y1, x2, y2, x3, y3);
int fanBaseIndex = idx1 >> 1;
for (int i = 3, n = triangles.size; i < n; i += 3) {
idx1 = triangles.get(i);
@ -89,31 +97,26 @@ public class ConvexDecomposer {
idx3 = triangles.get(i + 2);
System.out.println("Triangle: " + idx1 + ", " + idx2 + ", " + idx3);
float x1 = polygon.get(idx1 * 2);
float y1 = polygon.get(idx1 * 2 + 1);
float x2 = polygon.get(idx2 * 2);
float y2 = polygon.get(idx2 * 2 + 1);
float x3 = polygon.get(idx3 * 2);
float y3 = polygon.get(idx3 * 2 + 1);
x1 = polygon.get(idx1 * 2);
y1 = polygon.get(idx1 * 2 + 1);
x2 = polygon.get(idx2 * 2);
y2 = polygon.get(idx2 * 2 + 1);
x3 = polygon.get(idx3 * 2);
y3 = polygon.get(idx3 * 2 + 1);
// if the base of the last triangle
// is the same as this triangle's base
// check if they form a convex polygon (triangle fan)
boolean merged = false;
if (fanBaseIndex == idx1) {
poly.add(x3);
poly.add(y3);
poly.add(poly.get(0));
poly.add(poly.get(1));
poly.add(poly.get(2));
poly.add(poly.get(3));
float winding = lastWinding(poly);
if (winding == lastWinding) {
poly.size -= 4;
if (fanBaseIndex == idx1) {
int o = poly.size - 4;
int winding1 = winding(poly.get(o), poly.get(o + 1), poly.get(o + 2), poly.get(o + 3), x3, y3);
int winding2 = winding(x3, y3, poly.get(0), poly.get(1), poly.get(2), poly.get(3));
if (winding1 == lastWinding && winding2 == lastWinding) {
poly.add(x3);
poly.add(y3);
polyIndices.add(idx3);
merged = true;
} else {
poly.size -= 6;
}
}
@ -133,7 +136,7 @@ public class ConvexDecomposer {
polyIndices.add(idx1);
polyIndices.add(idx2);
polyIndices.add(idx3);
lastWinding = lastWinding(poly);
lastWinding = winding(x1, y1, x2, y2, x3, y3);
fanBaseIndex = idx1;
}
}
@ -150,16 +153,10 @@ public class ConvexDecomposer {
return polyResult;
}
private int lastWinding (FloatArray poly) {
float px = poly.get(poly.size - 5);
float py = poly.get(poly.size - 6);
float tx = poly.get(poly.size - 3);
float ty = poly.get(poly.size - 4);
float ux = poly.get(poly.size - 1);
float uy = poly.get(poly.size - 2);
float vx = tx - px;
float vy = ty - py;
return ux * vy - uy * vx + vx * py - px * vy >= 0 ? 1 : -1;
public static int winding (float v1x, float v1y, float v2x, float v2y, float v3x, float v3y) {
float vx = v2x - v1x;
float vy = v2y - v1y;
return v3x * vy - v3y * vx + vx * v1y - v1x * vy >= 0 ? 1 : -1;
}
/** @return {@link #CONCAVE}, {@link #TANGENTIAL} or {@link #CONVEX} */