private static int Triangulate(int n, PolyVertex[] verts, int[] indices, Triangle[] tris)
{
int ntris = 0;
//last bit of index determines whether vertex can be removed
for (int i = 0; i < n; i++)
{
int i1 = Next(i, n);
int i2 = Next(i1, n);
if (Diagonal(i, i2, verts, indices))
{
SetDiagonalFlag(ref indices[i1]);
}
}
//need 3 verts minimum for a polygon
while (n > 3)
{
//find the minimum distance betwee two vertices.
//also, save their index
int minLen = -1;
int minIndex = -1;
for (int i = 0; i < n; i++)
{
int i1 = Next(i, n);
if (HasDiagonalFlag(indices[i1]))
{
int p0 = RemoveDiagonalFlag(indices[i]);
int p2 = RemoveDiagonalFlag(indices[Next(i1, n)]);
int dx = verts[p2].X - verts[p0].X;
int dy = verts[p2].Z - verts[p0].Z;
int len = dx * dx + dy * dy;
if (minLen < 0 || len < minLen)
{
minLen = len;
minIndex = i;
}
}
}
if (minIndex == -1)
{
minLen = -1;
minIndex = -1;
for (int i = 0; i < n; i++)
{
int i1 = Next(i, n);
int i2 = Next(i1, n);
if (DiagonalLoose(i, i2, verts, indices))
{
int p0 = RemoveDiagonalFlag(indices[i]);
int p2 = RemoveDiagonalFlag(indices[Next(i2, n)]);
int dx = verts[p2].X - verts[p0].X;
int dy = verts[p2].Z - verts[p0].Z;
int len = dx * dx + dy * dy;
if (minLen < 0 || len < minLen)
{
minLen = len;
minIndex = i;
}
}
}
//really messed up
if (minIndex == -1)
return -ntris;
}
int mi = minIndex;
int mi1 = Next(mi, n);
int mi2 = Next(mi1, n);
tris[ntris] = new Triangle();
tris[ntris].Index0 = RemoveDiagonalFlag(indices[mi]);
tris[ntris].Index1 = RemoveDiagonalFlag(indices[mi1]);
tris[ntris].Index2 = RemoveDiagonalFlag(indices[mi2]);
ntris++;
//remove P[i1]
n--;
for (int k = mi1; k < n; k++)
indices[k] = indices[k + 1];
if (mi1 >= n) mi1 = 0;
mi = Prev(mi1, n);
//update diagonal flags
if (Diagonal(Prev(mi, n), mi1, verts, indices))
{
SetDiagonalFlag(ref indices[mi]);
}
else
{
RemoveDiagonalFlag(ref indices[mi]);
}
if (Diagonal(mi, Next(mi1, n), verts, indices))
{
SetDiagonalFlag(ref indices[mi1]);
}
else
{
RemoveDiagonalFlag(ref indices[mi1]);
}
}
//append remaining triangle
tris[ntris] = new Triangle();
tris[ntris].Index0 = RemoveDiagonalFlag(indices[0]);
tris[ntris].Index1 = RemoveDiagonalFlag(indices[1]);
tris[ntris].Index2 = RemoveDiagonalFlag(indices[2]);
ntris++;
return ntris;
}