public static float4 Tessellate(Allocator allocator, NativeArray <float2> points, NativeArray <int2> edges, ref NativeArray <float2> outVertices, ref int outVertexCount, ref NativeArray <int> outIndices, ref int outIndexCount, ref NativeArray <int2> outEdges, ref int outEdgeCount)
        {
            // Inputs are garbage, just early out.
            outEdgeCount = 0; outIndexCount = 0; outVertexCount = 0;
            if (points.Length == 0 || points.Length >= kMaxVertexCount)
            {
                return(float4.zero);
            }

            // Ensure inputs form a proper PlanarGraph.
            bool                 validGraph = false;
            int                  pgEdgeCount = 0, pgPointCount = 0;
            float4               ret      = float4.zero;
            NativeArray <int2>   pgEdges  = new NativeArray <int2>(kMaxEdgeCount, allocator);
            NativeArray <float2> pgPoints = new NativeArray <float2>(kMaxVertexCount, allocator);

            // Valid Edges and Paths, correct the Planar Graph. If invalid create a simple convex hull rect.
            validGraph = PlanarGraph.Validate(allocator, points, points.Length, edges, edges.Length, ref pgPoints, ref pgPointCount, ref pgEdges, ref pgEdgeCount);
            if (!validGraph)
            {
                GraphConditioner(points, ref pgPoints, ref pgPointCount, ref pgEdges, ref pgEdgeCount);
            }

            // Do a proper Delaunay Triangulation.
            int tsIndexCount = 0, tsVertexCount = 0;
            NativeArray <int>    tsIndices = new NativeArray <int>(kMaxIndexCount, allocator);
            NativeArray <float2> tsVertices = new NativeArray <float2>(kMaxVertexCount, allocator);

            validGraph = Tessellator.Tessellate(allocator, pgPoints, pgPointCount, pgEdges, pgEdgeCount, ref tsVertices, ref tsVertexCount, ref tsIndices, ref tsIndexCount);
            if (!validGraph)
            {
                // Create a simplex convex hull rect.
                GraphConditioner(points, ref pgPoints, ref pgPointCount, ref pgEdges, ref pgEdgeCount);
                tsIndexCount = 0; tsVertexCount = 0;
                Tessellator.Tessellate(allocator, pgPoints, pgPointCount, pgEdges, pgEdgeCount, ref tsVertices, ref tsVertexCount, ref tsIndices, ref tsIndexCount);
            }

            // Copy Out
            TransferOutput(pgEdges, pgEdgeCount, ref outEdges, ref outEdgeCount, tsIndices, tsIndexCount, ref outIndices, ref outIndexCount, tsVertices, tsVertexCount, ref outVertices, ref outVertexCount);

            // Dispose Temp Memory.
            tsVertices.Dispose();
            tsIndices.Dispose();
            pgPoints.Dispose();
            pgEdges.Dispose();
            return(ret);
        }
Example #2
0
        public static float4 Tessellate(Allocator allocator, NativeArray <float2> points, NativeArray <int2> edges, ref NativeArray <float2> outVertices, ref int outVertexCount, ref NativeArray <int> outIndices, ref int outIndexCount, ref NativeArray <int2> outEdges, ref int outEdgeCount)
        {
            // Inputs are garbage, just early out.
            float4 ret = float4.zero;

            outEdgeCount = 0; outIndexCount = 0; outVertexCount = 0;
            if (points.Length < 3 || points.Length >= kMaxVertexCount)
            {
                return(ret);
            }

            // Ensure inputs form a proper PlanarGraph.
            bool validGraph = false, handleEdgeCase = false;
            int  pgEdgeCount = 0, pgPointCount = 0;
            NativeArray <int2>   pgEdges  = new NativeArray <int2>(kMaxEdgeCount, allocator);
            NativeArray <float2> pgPoints = new NativeArray <float2>(kMaxVertexCount, allocator);

            // Valid Edges and Paths, correct the Planar Graph. If invalid create a simple convex hull rect.
            if (0 != edges.Length)
            {
                validGraph = PlanarGraph.Validate(allocator, points, points.Length, edges, edges.Length, ref pgPoints, ref pgPointCount, ref pgEdges, ref pgEdgeCount);
            }


// Fallbacks are now handled by the Higher level packages. Enable if UTess needs to handle it.
// #if UTESS_QUAD_FALLBACK
//             if (!validGraph)
//             {
//                 pgPointCount = 0;
//                 handleEdgeCase = true;
//                 ModuleHandle.Copy(points, pgPoints, points.Length);
//                 GraphConditioner(points, ref pgPoints, ref pgPointCount, ref pgEdges, ref pgEdgeCount, false);
//             }
// #else

// If its not a valid Graph simply return back input Data without triangulation instead of going through UTess (pointless wasted cpu cycles).
            if (!validGraph)
            {
                outEdgeCount   = edges.Length;
                outVertexCount = points.Length;
                ModuleHandle.Copy(edges, outEdges, edges.Length);
                ModuleHandle.Copy(points, outVertices, points.Length);
            }

            // Do a proper Delaunay Triangulation if Inputs are valid.
            if (pgPointCount > 2 && pgEdgeCount > 2)
            {
                int tsIndexCount = 0, tsVertexCount = 0;
                NativeArray <int>    tsIndices = new NativeArray <int>(kMaxIndexCount, allocator);
                NativeArray <float2> tsVertices = new NativeArray <float2>(kMaxVertexCount, allocator);
                validGraph = Tessellator.Tessellate(allocator, pgPoints, pgPointCount, pgEdges, pgEdgeCount, ref tsVertices, ref tsVertexCount, ref tsIndices, ref tsIndexCount);
                if (validGraph)
                {
                    // Copy Out
                    TransferOutput(pgEdges, pgEdgeCount, ref outEdges, ref outEdgeCount, tsIndices, tsIndexCount, ref outIndices, ref outIndexCount, tsVertices, tsVertexCount, ref outVertices, ref outVertexCount);
                    if (handleEdgeCase == true)
                    {
                        outEdgeCount = 0;
                    }
                }
                tsVertices.Dispose();
                tsIndices.Dispose();
            }

            // Dispose Temp Memory.
            pgPoints.Dispose();
            pgEdges.Dispose();
            return(ret);
        }