コード例 #1
0
        // Perform Voronoi based Smoothing. Does not add/remove points but merely relocates internal vertices so they are uniform distributed.
        public static bool Condition(Allocator allocator, ref NativeArray <float2> pgPoints, int pgPointCount, NativeArray <int2> pgEdges, int pgEdgeCount, ref NativeArray <float2> vertices, ref int vertexCount, ref NativeArray <int> indices, ref int indexCount)
        {
            // Build Triangles and Edges.
            float maxArea = 0, cmpArea = 0;
            bool  polygonCentroid = true, validGraph = true;
            int   triangleCount = 0, delaEdgeCount = 0, affectingEdgeCount = 0;
            var   triangles    = new NativeArray <UTriangle>(indexCount / 3, allocator);
            var   delaEdges    = new NativeArray <int4>(indexCount, allocator);
            var   voronoiEdges = new NativeArray <int4>(indexCount, allocator);
            var   connectedTri = new NativeArray <int4>(vertexCount, allocator);
            var   voronoiCheck = new NativeArray <int>(indexCount, allocator);
            var   affectsEdges = new NativeArray <int>(indexCount, allocator);
            var   triCentroids = new NativeArray <int>(vertexCount, allocator);

            UTess.BuildTrianglesAndEdges(vertices, vertexCount, indices, indexCount, ref triangles, ref triangleCount, ref delaEdges, ref delaEdgeCount, ref maxArea);
            var refinedEdges = new NativeArray <int4>(delaEdgeCount, allocator);

            // Sort the Delaunay Edges.
            unsafe
            {
                UTess.InsertionSort <int4, DelaEdgeCompare>(
                    NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(delaEdges), 0, delaEdgeCount - 1,
                    new DelaEdgeCompare());
            }

            // TrimEdges. Update Triangle Info for Shared Edges and remove Duplicates.
            RefineEdges(ref refinedEdges, ref delaEdges, ref delaEdgeCount, ref voronoiEdges);

            // Now for each point, generate Voronoi diagram.
            for (int i = 0; i < vertexCount; ++i)
            {
                // Try moving this to Centroid of the Voronoi Polygon.
                GetAffectingEdges(i, delaEdges, delaEdgeCount, ref affectsEdges, ref voronoiCheck, ref affectingEdgeCount);
                var bounded = affectingEdgeCount != 0;

                // Check for Boundedness
                for (int j = 0; j < affectingEdgeCount; ++j)
                {
                    // Edge Index.
                    var ei = affectsEdges[j];
                    if (delaEdges[ei].z == -1 || delaEdges[ei].w == -1)
                    {
                        bounded = false;
                        break;
                    }
                }

                // If this is bounded point, relocate to Voronoi Diagram's Centroid
                if (bounded)
                {
                    polygonCentroid = ConnectTriangles(ref connectedTri, ref affectsEdges, ref voronoiCheck, voronoiEdges, affectingEdgeCount);
                    if (!polygonCentroid)
                    {
                        break;
                    }

                    float2 point = float2.zero;
                    float  area = 0, distance = 0;
                    for (int k = 0; k < affectingEdgeCount; ++k)
                    {
                        CentroidByPolygon(connectedTri[k], triangles, ref point, ref area, ref distance);
                    }
                    point      /= (3 * area);
                    pgPoints[i] = point;
                }
            }

            // Do Delaunay Again.
            int srcIndexCount = indexCount, srcVertexCount = vertexCount;

            indexCount = 0; vertexCount = 0; triangleCount = 0;
            if (polygonCentroid)
            {
                validGraph = Tessellator.Tessellate(allocator, pgPoints, pgPointCount, pgEdges, pgEdgeCount, ref vertices, ref vertexCount, ref indices, ref indexCount);
                if (validGraph)
                {
                    UTess.BuildTriangles(vertices, vertexCount, indices, indexCount, ref triangles, ref triangleCount, ref cmpArea);
                }
            }

            // Cleanup.
            triangles.Dispose();
            delaEdges.Dispose();
            refinedEdges.Dispose();
            voronoiCheck.Dispose();
            voronoiEdges.Dispose();
            affectsEdges.Dispose();
            triCentroids.Dispose();
            connectedTri.Dispose();
            return(validGraph && srcIndexCount == indexCount && srcVertexCount == vertexCount && (cmpArea < maxArea * kAreaTolerance));
        }