evershade/Packages/super-tiled2unity.v2.2.0/Editor/Collision/Geometry/Triangulator.cs

81 lines
2.7 KiB
C#

using System.Collections.Generic;
using System.Linq;
using SuperTiled2Unity.Editor.LibTessDotNet;
using UnityEngine;
namespace SuperTiled2Unity.Editor.Geometry
{
// Input is a ClipperLib solution and output is a collection of triangles
public class Triangulator
{
public List<Vector2[]> TriangulateClipperSolution(ClipperLib.PolyTree solution)
{
var tess = new Tess();
tess.NoEmptyPolygons = true;
// Add a contour for each part of the solution tree
ClipperLib.PolyNode node = solution.GetFirst();
while (node != null)
{
// Only interested in closed paths
if (!node.IsOpen)
{
// Add a new countor. Holes are automatically generated.
var vertices = node.Contour.Select(pt => new ContourVertex { Position = new Vec3 { X = pt.X, Y = pt.Y, Z = 0 } }).ToArray();
tess.AddContour(vertices);
}
node = node.GetNext();
}
return TrianglesFromTessellator(tess);
}
public List<Vector2[]> TriangulatePolygon(Vector2[] points)
{
var tess = new Tess();
tess.NoEmptyPolygons = true;
var vertices = points.Select(pt => new ContourVertex { Position = new Vec3 { X = pt.x, Y = pt.y, Z = 0 } }).ToArray();
tess.AddContour(vertices);
return TrianglesFromTessellator(tess);
}
private List<Vector2[]> TrianglesFromTessellator(Tess tess)
{
var triangles = new List<Vector2[]>();
// Do the tessellation
tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
// Extract the triangles
int numTriangles = tess.ElementCount;
for (int i = 0; i < numTriangles; i++)
{
var v0 = tess.Vertices[tess.Elements[i * 3 + 0]].Position;
var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;
var triangle = new List<Vector2>()
{
new Vector2(v0.X, v0.Y),
new Vector2(v1.X, v1.Y),
new Vector2(v2.X, v2.Y),
};
// Assume each triangle needs to be CCW
float cross = GeoMath.Cross(triangle[0], triangle[1], triangle[2]);
if (cross > 0)
{
triangle.Reverse();
}
triangles.Add(triangle.ToArray());
}
return triangles;
}
}
}