class PolygonTriangulationUtil {

    @SuppressWarnings("unchecked")
    public static <T extends TesseraVertex<?>> void triangulatePolygon(SimpleTesseraBlockBuilder<T> triBuilder, Polygon polygon,
            VertexGenerator<T> vertexGenerator)
    {
        org.poly2tri.geometry.polygon.Polygon poly2TriPoly = convertToPoly2TriPolygon(polygon);
        if (poly2TriPoly == null || poly2TriPoly.getPoints().size() < 3)
        {
            return;
        }

        // When the polygon is invalid, Poly2Tri can throw StackOverFlowError or
        // NullPointerException.
        try
        {
            TriangulationContext<?> context = Poly2Tri.createContext(TriangulationAlgorithm.DTSweep);
            context.prepareTriangulation(poly2TriPoly);
            Poly2Tri.triangulate(context);
            context.terminateTriangulation();
            context.clear();
        }
        catch (RuntimeException re)
        {
            if (LOGGER.isDebugEnabled())
            {
                LOGGER.error("Failed to generate triangle fill for polygon " + polygon, re);
            }
        }
        catch (Error e)
        {
            if (LOGGER.isDebugEnabled())
            {
                LOGGER.error("Failed to generate triangle fill for polygon " + polygon, e);
            }
        }

        for (DelaunayTriangle tri : poly2TriPoly.getTriangles())
        {
            T vertexA = vertexGenerator.getVertex(tri.points[0].getX(), tri.points[0].getY(), tri.points[0].getZ());
            T vertexB = vertexGenerator.getVertex(tri.points[1].getX(), tri.points[1].getY(), tri.points[1].getZ());
            T vertexC = vertexGenerator.getVertex(tri.points[2].getX(), tri.points[2].getY(), tri.points[2].getZ());

            if (vertexGenerator.hasCorrectFacing(vertexA, vertexB, vertexC))
            {
                triBuilder.add((T[])new TesseraVertex<?>[] { vertexA, vertexB, vertexC });
            }
            else
            {
                triBuilder.add((T[])new TesseraVertex<?>[] { vertexA, vertexC, vertexB });
            }
        }
    }

    private  PolygonTriangulationUtil();

}