-
-
Notifications
You must be signed in to change notification settings - Fork 227
/
Tessellator.cs
157 lines (147 loc) · 6.32 KB
/
Tessellator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using ProceduralToolkit.LibTessDotNet;
using System.Collections.Generic;
using UnityEngine;
using Mesh = UnityEngine.Mesh;
namespace ProceduralToolkit
{
/// <summary>
/// LibTessDotNet wrapper
/// </summary>
public class Tessellator
{
/// <summary>
/// If true, will remove empty (zero area) polygons.
/// </summary>
public bool removeEmptyPolygons
{
get => tess.NoEmptyPolygons;
set => tess.NoEmptyPolygons = value;
}
/// <summary>
/// Vertices of the tessellated mesh.
/// </summary>
public ContourVertex[] vertices => tess.Vertices;
/// <summary>
/// Number of vertices in the tessellated mesh.
/// </summary>
public int vertexCount => tess.VertexCount;
/// <summary>
/// Indices of the tessellated mesh. See <see cref="ElementType"/> for details on data layout.
/// </summary>
public int[] indices => tess.Elements;
/// <summary>
/// Number of elements in the tessellated mesh.
/// </summary>
public int indexCount => tess.ElementCount;
private readonly Tess tess = new Tess {NoEmptyPolygons = true};
/// <summary>
/// Adds a closed contour to be tessellated.
/// </summary>
/// <param name="vertices"> Vertices of the contour. </param>
/// <param name="forceOrientation">
/// Orientation of the contour.
/// <see cref="ContourOrientation.Original"/> keeps the orientation of the input vertices.
/// <see cref="ContourOrientation.Clockwise"/> and <see cref="ContourOrientation.CounterClockwise"/>
/// force the vertices to have a specified orientation.
/// </param>
public void AddContour(IReadOnlyList<Vector2> vertices, ContourOrientation forceOrientation = ContourOrientation.Original)
{
var contour = new ContourVertex[vertices.Count];
for (int i = 0; i < vertices.Count; i++)
{
Vector2 vertex = vertices[i];
contour[i].Position = new Vec3(vertex.x, vertex.y, 0);
}
tess.AddContour(contour, forceOrientation);
}
/// <summary>
/// Adds a closed contour to be tessellated.
/// </summary>
/// <param name="vertices"> Vertices of the contour. </param>
/// <param name="forceOrientation">
/// Orientation of the contour.
/// <see cref="ContourOrientation.Original"/> keeps the orientation of the input vertices.
/// <see cref="ContourOrientation.Clockwise"/> and <see cref="ContourOrientation.CounterClockwise"/>
/// force the vertices to have a specified orientation.
/// </param>
public void AddContour(IReadOnlyList<Vector3> vertices, ContourOrientation forceOrientation = ContourOrientation.Original)
{
var contour = new ContourVertex[vertices.Count];
for (int i = 0; i < vertices.Count; i++)
{
Vector3 vertex = vertices[i];
contour[i].Position = new Vec3(vertex.x, vertex.y, vertex.z);
}
tess.AddContour(contour, forceOrientation);
}
/// <summary>
/// Adds a closed contour to be tessellated.
/// </summary>
/// <param name="vertices"> Vertices of the contour. </param>
/// <param name="forceOrientation">
/// Orientation of the contour.
/// <see cref="ContourOrientation.Original"/> keeps the orientation of the input vertices.
/// <see cref="ContourOrientation.Clockwise"/> and <see cref="ContourOrientation.CounterClockwise"/>
/// force the vertices to have a specified orientation.
/// </param>
public void AddContour(IReadOnlyList<ContourVertex> vertices, ContourOrientation forceOrientation = ContourOrientation.Original)
{
tess.AddContour(vertices, forceOrientation);
}
/// <summary>
/// Tessellates the input contours.
/// </summary>
/// <param name="windingRule"> Winding rule used for tessellation. See <see cref="WindingRule"/> for details. </param>
/// <param name="elementType"> Tessellation output type. See <see cref="ElementType"/> for details. </param>
/// <param name="polySize"> Number of vertices per polygon if output is polygons. </param>
/// <param name="combineCallback"> Interpolator used to determine the data payload of generated vertices. </param>
/// <param name="normal"> Normal of the input contours. If set to zero, the normal will be calculated during tessellation. </param>
public void Tessellate(WindingRule windingRule = WindingRule.EvenOdd, ElementType elementType = ElementType.Polygons, int polySize = 3,
CombineCallback combineCallback = null, Vector3 normal = new Vector3())
{
tess.Tessellate(windingRule, elementType, polySize, combineCallback, new Vec3(normal.x, normal.y, normal.z));
}
/// <summary>
/// Converts the tessellated mesh to MeshDraft.
/// </summary>
public MeshDraft ToMeshDraft()
{
var draft = new MeshDraft();
for (int i = 0; i < vertexCount; i++)
{
Vec3 vertex = vertices[i].Position;
draft.vertices.Add(new Vector3(vertex.X, vertex.Y, vertex.Z));
}
draft.triangles.AddRange(indices);
return draft;
}
/// <summary>
/// Converts the tessellated mesh to MeshDraft.
/// </summary>
public void ToMeshDraft(MeshDraft draft)
{
draft.vertices.Clear();
draft.triangles.Clear();
for (int i = 0; i < vertexCount; i++)
{
Vec3 vertex = vertices[i].Position;
draft.vertices.Add(new Vector3(vertex.X, vertex.Y, vertex.Z));
}
draft.triangles.AddRange(indices);
}
/// <summary>
/// Converts the tessellated mesh to Mesh.
/// </summary>
public Mesh ToMesh()
{
return ToMeshDraft().ToMesh();
}
/// <summary>
/// Converts the tessellated mesh to Mesh.
/// </summary>
public void ToMesh(Mesh mesh)
{
ToMeshDraft().ToMesh(mesh);
}
}
}