下载:传送门 ,提取码:4z74
这个是我编译好的dll库,下载后直接放到新建立的Unity项目Assets下即可;
建立Triangulation脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TriangleNet.Geometry;
public class Triangulation : MonoBehaviour
{
/// <summary>
/// 三角剖分是否成功
/// </summary>
/// <returns></returns>
public static bool triangulate(List<Vector2> points, List<List<Vector2>> holes, out List<int> outIndices, out List<Vector3> outVertices )
{
// 三角化后输出的信息
outIndices = new List<int>();
outVertices = new List<Vector3>();
Polygon poly = new Polygon();
// points and segments
for (int i = 0; i < points.Count; i++)
{
poly.Add(new Vertex(points[i].x,points[i].y));
if (i == points.Count - 1)
{
poly.Add(new Segment(new Vertex(points[i].x, points[i].y), new Vertex(points[0].x, points[0].y)));
}
else
{
poly.Add(new Segment(new Vertex(points[i].x,points[i].y),new Vertex(points[i+1].x,points[i+1].y)));
}
}
// holes
for(int i = 0; i < holes.Count; i++)
{
List<Vertex> vertices = new List<Vertex>();
for(int j = 0; j< holes[i].Count;j++)
{
vertices.Add(new Vertex(holes[i][j].x,holes[i][j].y));
}
poly.Add(new Contour(vertices), true);
}
var mesh = poly.Triangulate();
foreach(ITriangle t in mesh.Triangles)
{
// 三个点
for(int j = 2; j >= 0; j--)
{
bool found = false;
// 去重
for (int k = 0; k < outVertices.Count; k++)
{
if((outVertices[k].x == t.GetVertex(j).X) && (outVertices[k].z == t.GetVertex(j).Y))
{
outIndices.Add(k);
found = true;
break;
}
}
if (!found)
{
outVertices.Add(new Vector3((float)t.GetVertex(j).X, 0, (float)t.GetVertex(j).Y));
outIndices.Add(outVertices.Count-1);
}
}
}
return true;
}
}
TriangulatorTest脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TriangulatorTest : MonoBehaviour
{
void Start()
{
GameObject go = new GameObject();
go.name = "Cross";
MeshFilter mf = go.AddComponent<MeshFilter>();
MeshCollider mc = go.AddComponent<MeshCollider>();
go.AddComponent<MeshRenderer>();
Mesh mesh = mf.mesh;
List<Vector2> points = new List<Vector2>();
List<List<Vector2>> holes = new List<List<Vector2>>();
List<int> indices = null;
List<Vector3> vertices = null;
// construct
points.Add(new Vector2(10,0));
points.Add(new Vector2(20, 0));
points.Add(new Vector2(20, 10));
points.Add(new Vector2(30, 10));
points.Add(new Vector2(30, 20));
points.Add(new Vector2(20, 20));
points.Add(new Vector2(20, 30));
points.Add(new Vector2(10, 30));
points.Add(new Vector2(10, 20));
points.Add(new Vector2(0, 20));
points.Add(new Vector2(0, 10));
points.Add(new Vector2(10, 10));
List<Vector2> hole = new List<Vector2>();
hole.Add(new Vector2(12,12));
hole.Add(new Vector2(18, 12));
hole.Add(new Vector2(18, 18));
hole.Add(new Vector2(12, 18));
holes.Add(hole);
// 剖分
Triangulation.triangulate(points, holes, out indices, out vertices);
foreach(var v in vertices)
{
Debug.Log(v);
}
// 重新计算法线等信息
mesh.Clear();
mesh.vertices = vertices.ToArray();
mesh.triangles = indices.ToArray();
// 网格几何体和顶点在内部重新排序,提高渲染性能
mesh.Optimize();
mesh.RecalculateNormals();
go.GetComponent<MeshCollider>().sharedMesh = mesh;
Vector2[] uvs = new Vector2[mesh.vertices.Length];
for(int i = 0; i < uvs.Length; i++)
{
uvs[i] = new Vector2(mesh.vertices[i].x,mesh.vertices[i].y);
}
mesh.uv = uvs;
}
void Update()
{
}
}
在场景下建立空物体,命名为Triangulator,挂载TriangulatorTest脚本:
直接运行即可,运行结果:
代码里面有我的简单注解,有问题的地方随时联系我讨论哈!