SharpNav.PolyMesh.Triangulate C# (CSharp) Method

Triangulate() private static method

Walk the edges of a contour to determine whether a triangle can be formed. Form as many triangles as possible.
private static Triangulate ( int n, PolyVertex verts, int indices, Triangle tris ) : int
n int
verts PolyVertex Vertices array
indices int Indices array
tris Triangle Triangles array
return int
        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;
        }