Skip to content

Commit

Permalink
refactor to reuse triangulation of Areas
Browse files Browse the repository at this point in the history
  • Loading branch information
thelsing committed Nov 3, 2023
1 parent a9946dc commit a11e02a
Showing 1 changed file with 81 additions and 58 deletions.
139 changes: 81 additions & 58 deletions src/main/java/net/rptools/maptool/client/ui/zone/gdx/AreaRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.*;
import com.badlogic.gdx.math.Bezier;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Polygon;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.*;
import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.IntArray;
import java.awt.geom.Area;
Expand All @@ -34,6 +31,7 @@
import space.earlygrey.shapedrawer.SideEstimator;

public class AreaRenderer {
public record TriangledPolygon(float[] vertices, short[] indices) {}

public AreaRenderer(TextureRegion whitePixelRegion, ShapeDrawer drawer) {
this.whitePixel = whitePixelRegion;
Expand Down Expand Up @@ -76,8 +74,10 @@ public void setTextureRegion(TextureRegion textureRegion) {
this.textureRegion = textureRegion;
}

public void fillArea(PolygonSpriteBatch batch, Area area) {
if (area == null || area.isEmpty()) return;
public List<TriangledPolygon> triangulate(Area area) {
if (area == null || area.isEmpty()) return new ArrayList<>();

var result = new ArrayList<TriangledPolygon>();

pathToFloatArray(area.getPathIterator(null));

Expand All @@ -88,60 +88,72 @@ public void fillArea(PolygonSpriteBatch batch, Area area) {
tmpFloat.pop();
tmpFloat.pop();
}
paintVertices(batch, tmpFloat.toArray(), null);
} else {
var lastSegmentIndex = 0;
var color = this.color;
var polygons = new ArrayList<Polygon>();
// Polygons in a PathIterator are ordered. If polygon p contains q, q comes first.
// So we draw polygons that contains others, those others are the holes.
var floats = tmpFloat.toArray();
for (int i = 0; i < segmentIndicies.size; i++) {
var idx = segmentIndicies.get(i);
var vertexCount = idx - lastSegmentIndex;
var vertices = new float[2 * vertexCount];
System.arraycopy(floats, 2 * lastSegmentIndex, vertices, 0, 2 * vertexCount);
lastSegmentIndex = idx + 1;

var poly = new Polygon(vertices);
var holes = new ArrayList<Polygon>();
var vertices = tmpFloat.toArray();
var indices = Earcut.earcut(vertices).toArray();
result.add(new TriangledPolygon(vertices, indices));
return result;
}

for (int j = 0; j < polygons.size(); j++) {
var prevPoly = polygons.get(j);
var prevVertices = prevPoly.getVertices();
if (poly.contains(prevVertices[0], prevVertices[1])) {
holes.add(prevPoly);
}
}
if (holes.isEmpty()) {
polygons.add(poly);
continue;
var lastSegmentIndex = 0;
var color = this.color;
var polygons = new ArrayList<Polygon>();
// Polygons in a PathIterator are ordered. If polygon p contains q, q comes first.
// So we draw polygons that contains others, those others are the holes.
var floats = tmpFloat.toArray();
for (int i = 0; i < segmentIndicies.size; i++) {
var idx = segmentIndicies.get(i);
var vertexCount = idx - lastSegmentIndex;
var currentPolyVertices = new float[2 * vertexCount];
System.arraycopy(floats, 2 * lastSegmentIndex, currentPolyVertices, 0, 2 * vertexCount);
lastSegmentIndex = idx + 1;

var poly = new Polygon(currentPolyVertices);
var holes = new ArrayList<Polygon>();

for (int j = 0; j < polygons.size(); j++) {
var prevPoly = polygons.get(j);
var prevVertices = prevPoly.getVertices();
if (poly.contains(prevVertices[0], prevVertices[1])) {
holes.add(prevPoly);
}
tmpFloat.clear();
tmpFloat.addAll(poly.getVertices());

short[] holeIndices = new short[holes.size()];
var lastPoly = poly;
var lastHoleIndex = 0;
for (int j = 0; j < holes.size(); j++) {
lastHoleIndex += lastPoly.getVertices().length;
holeIndices[j] = (short) (lastHoleIndex / 2);
lastPoly = holes.get(j);
polygons.remove(lastPoly);
tmpFloat.addAll(lastPoly.getVertices());
}

paintVertices(batch, tmpFloat.toArray(), holeIndices);
this.color = color;
}

for (var poly : polygons) {
paintVertices(batch, poly.getVertices(), null);
this.color = color;
if (holes.isEmpty()) {
polygons.add(poly);
continue;
}
tmpFloat.clear();
tmpFloat.addAll(poly.getVertices());

short[] holeIndices = new short[holes.size()];
var lastPoly = poly;
var lastHoleIndex = 0;
for (int j = 0; j < holes.size(); j++) {
lastHoleIndex += lastPoly.getVertices().length;
holeIndices[j] = (short) (lastHoleIndex / 2);
lastPoly = holes.get(j);
polygons.remove(lastPoly);
tmpFloat.addAll(lastPoly.getVertices());
}

this.color = null;
var indices = Earcut.earcut(tmpFloat.toArray(), holeIndices, (short) 2);
result.add(new TriangledPolygon(tmpFloat.toArray(), indices.toArray()));
}

for (var poly : polygons) {
var indices = Earcut.earcut(poly.getVertices());
result.add(new TriangledPolygon(poly.getVertices(), indices.toArray()));
}
return result;
}

public void fillArea(PolygonSpriteBatch batch, Area area) {
for (var poly : triangulate(area)) {
var polyRegion = new PolygonRegion(textureRegion, poly.vertices, poly.indices);
var color = this.color;
paintRegion(batch, polyRegion);
this.color = color;
}
this.color = Color.WHITE;
}

private boolean debug = false;
Expand Down Expand Up @@ -214,13 +226,24 @@ private void drawDebug(float[] vertices, short[] indicies) {
}

protected void paintVertices(PolygonSpriteBatch batch, float[] vertices, short[] holeIndices) {

var indices = Earcut.earcut(vertices, holeIndices, (short) 2).toArray();
var polyReg = new PolygonRegion(textureRegion, vertices, indices);
var poly = new PolygonSprite(polyReg);
poly.setColor(color);

if (debug) drawDebug(vertices, indices);
else poly.draw(batch);
else paintRegion(batch, polyReg);
color = Color.WHITE;
}

private PolygonSprite sprite = null;

protected void paintRegion(PolygonSpriteBatch batch, PolygonRegion polygonRegion) {
if (sprite == null) {
sprite = new PolygonSprite(polygonRegion);
} else {
sprite.setRegion(polygonRegion);
}
sprite.setColor(color);
sprite.draw(batch);
color = Color.WHITE;
}

Expand Down

0 comments on commit a11e02a

Please sign in to comment.