Regions() публичный Метод

public Regions ( ) : List>
Результат List>
Пример #1
0
    public static List <GameObject> GenerateVoronoiPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null)
    {
        List <GameObject> pieces = new List <GameObject>();

        if (mat == null)
        {
            mat = createFragmentMaterial(source);
        }

        //get transform information
        Vector3 origScale = source.transform.localScale;

        source.transform.localScale = Vector3.one;
        Quaternion origRotation = source.transform.localRotation;

        source.transform.localRotation = Quaternion.identity;

        //get rigidbody information
        Rigidbody2D rigbody      = source.GetComponent <Rigidbody2D>(); //Я добавил
        Vector2     origVelocity = rigbody.velocity;

        //get collider information
        PolygonCollider2D sourcePolyCollider = source.GetComponent <PolygonCollider2D>();
        BoxCollider2D     sourceBoxCollider  = source.GetComponent <BoxCollider2D>();
        List <Vector2>    points             = new List <Vector2>();
        List <Vector2>    borderPoints       = new List <Vector2>();

        if (sourcePolyCollider != null)
        {
            points       = getPoints(sourcePolyCollider);
            borderPoints = getPoints(sourcePolyCollider);
        }
        else if (sourceBoxCollider != null)
        {
            points       = getPoints(sourceBoxCollider);
            borderPoints = getPoints(sourceBoxCollider);
        }

        Rect rect = getRect(source);

        for (int i = 0; i < extraPoints; i++)
        {
            points.Add(new Vector2(Random.Range(rect.width / -2, rect.width / 2), Random.Range(rect.height / -2, rect.height / 2)));
        }


        Voronoi voronoi = new Delaunay.Voronoi(points, null, rect);
        List <List <Vector2> > clippedRegions = new List <List <Vector2> >();

        foreach (List <Vector2> region in voronoi.Regions())
        {
            clippedRegions = ClipperHelper.clip(borderPoints, region);
            foreach (List <Vector2> clippedRegion in clippedRegions)
            {
                pieces.Add(generateVoronoiPiece(source, clippedRegion, origVelocity, origScale, origRotation, mat, rigbody));
            }
        }

        List <GameObject> morePieces = new List <GameObject>();

        if (subshatterSteps > 0)
        {
            subshatterSteps--;
            foreach (GameObject piece in pieces)
            {
                morePieces.AddRange(SpriteExploder.GenerateVoronoiPieces(piece, extraPoints, subshatterSteps));
                GameObject.DestroyImmediate(piece);
            }
        }
        else
        {
            morePieces = pieces;
        }

        //reset transform information
        source.transform.localScale    = origScale;
        source.transform.localRotation = origRotation;

        Resources.UnloadUnusedAssets();

        return(morePieces);
    }
Пример #2
0
    void OnDrawGizmos()
    {
        if (v == null)
        {
            return;
        }

        Gizmos.color = Color.red;
        if (m_points != null)
        {
            for (int i = 0; i < m_points.Count; i++)
            {
                Gizmos.DrawSphere(m_points [i], 0.2f);
            }
        }

        if (DrawAllEdges)
        {
            if (m_edges != null)
            {
                Gizmos.color = Color.gray;
                for (int i = 0; i < m_edges.Count; i++)
                {
                    Vector2 left  = (Vector2)m_edges [i].p0;
                    Vector2 right = (Vector2)m_edges [i].p1;
                    Gizmos.DrawLine((Vector3)left, (Vector3)right);
                }
            }
        }

        if (DrawDelaunayTriangulation)
        {
            Gizmos.color = Color.magenta;
            if (m_delaunayTriangulation != null)
            {
                for (int i = 0; i < m_delaunayTriangulation.Count; i++)
                {
                    Vector2 left  = (Vector2)m_delaunayTriangulation [i].p0;
                    Vector2 right = (Vector2)m_delaunayTriangulation [i].p1;
                    Gizmos.DrawLine((Vector3)left, (Vector3)right);
                }
            }
        }

        if (DrawSpanningTree)
        {
            if (m_spanningTree != null)
            {
                Gizmos.color = Color.green;
                for (int i = 0; i < m_spanningTree.Count; i++)
                {
                    LineSegment seg   = m_spanningTree [i];
                    Vector2     left  = (Vector2)seg.p0;
                    Vector2     right = (Vector2)seg.p1;
                    Gizmos.DrawLine((Vector3)left, (Vector3)right);
                }
            }
        }

        /** This is the correct source of Voronoi polygons: the "Regions" data from the Voronoi object.
         *      Note that the list is points, not lines, and you usually have to manually CLOSE the final point to the first */
        if (DrawVoronoiRegions)
        {
            Debug.Log("Found " + v.Regions().Count + " regions to draw");
            foreach (List <Vector2> region in v.Regions())
            {
                if (randomizeVoronoiColours)                                                 /** Note: the Edges display above (in Gray) shows unconnected edges,
                                                                                              * but this section re-uses the actual semi-polygons created automatically by the Voronoi algorithm. To prove
                                                                                              * this you can optionally turn on colourization of the edges, so that that shared edges will show with same colours
                                                                                              */
                {
                    Gizmos.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f));
                }
                else
                {
                    Gizmos.color = Color.white;
                }

                for (int i = 0; i + 1 < region.Count; i++)
                {
                    Vector2 s = (Vector2)region [i];
                    Vector2 e = (Vector2)region [i + 1];

                    if (randomizeVoronoiColours)
                    {
                        /** To make them easier to see, shift the vectors SLIGHTLY towards the center point.
                         *
                         * REMoVED: WE CANT DO THAT WHEN USING THE REGIONS SHORTCUT, REGIONS DELETE THEIR POINTS, sadly :(
                         *
                         * This lets you see EXACTLY what poly / partial poly the algorithm is giving us "for free",
                         * so that triangulating it will be easy in your own projects */
                        //	s += (siteCoord - s) * 0.05f;
                        //		e += (siteCoord - e) * 0.05f;
                    }
                    Gizmos.DrawLine(s, e);
                }

                if (CloseExternalVoronoPolys)
                {
                    Gizmos.DrawLine((Vector2)region [region.Count - 1], (Vector2)region [0]);
                }
            }
        }

        /** This is the INcorrect way of getting polygons out; but it has an advantage: the Voronoi class deletes
         *      the Site at center of a Region when giving us Regions (bug: I'd like to fix that and have it return a data
         *      structure that includes the Site!).
         *
         *      In the meantime, here's how to manually generate the polys by re-using the Boundaries code from Voronoi,
         *      much easier than trying to manually generate from raw edges.
         *
         *      But ideally: use DrawVoronoiRegions instead
         */
        if (DrawManualVoronoiPolygons)
        {
            /** Note, the SiteCoords are identical to the raw Points array you passed-in when creating the Voronoi object,
             *  I think. So ... you could safely re-use that here instead of fetching it from the Voronoi object (maybe; could be
             *  some filteing happening? Dupes removed, etc?) */
            List <Vector2> ses = m_points;                                   // v.SiteCoords ();
            foreach (Vector2 siteCoord in ses)
            {
                if (randomizeVoronoiColours)                                                 /** Note: the Edges display above (in Gray) shows unconnected edges,
                                                                                              * but this section re-uses the actual semi-polygons created automatically by the Voronoi algorithm. To prove
                                                                                              * this you can optionally turn on colourization of the edges, so that that shared edges will show with same colours
                                                                                              */
                {
                    Gizmos.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f));
                }
                else
                {
                    Gizmos.color = Color.white;
                }

                /** NB: this is the reason we had to change VoronoiDemo class and save the Voronoi object: the boundaries
                 *      are the Voronoi polygons, the most precious thing from the algorithm. They are saved as Regions data structure
                 *      when you run the algorithm - but that data structure throws-away the Site/Point that generates each Region.
                 */
                List <LineSegment> outlineOfSite          = v.VoronoiBoundaryForSite(siteCoord);
                List <Vector2>     pointsOnPolygonOutline = null;
                if (CloseExternalVoronoPolys)
                {
                    pointsOnPolygonOutline = new List <Vector2> ();
                }
                foreach (LineSegment seg in outlineOfSite)
                {
                    Vector2 s = (Vector2)seg.p0;
                    Vector2 e = (Vector2)seg.p1;

                    if (randomizeVoronoiColours)
                    {
                        /** To make them easier to see, shift the vectors SLIGHTLY towards the center point.
                         *
                         * This lets you see EXACTLY what poly / partial poly the algorithm is giving us "for free",
                         * so that triangulating it will be easy in your own projects */
                        s += (siteCoord - s) * 0.05f;
                        e += (siteCoord - e) * 0.05f;
                    }
                    Gizmos.DrawLine(s, e);

                    if (CloseExternalVoronoPolys)
                    {
                        pointsOnPolygonOutline.Add(s);
                        pointsOnPolygonOutline.Add(e);
                    }
                }

                if (CloseExternalVoronoPolys)
                {
                    List <Vector2> unduplicatedPoints = new List <Vector2> ();

                    //Debug.Log( "Closing outline; "+pointsOnPolygonOutline.Count+" points on outline, with "+outlineOfSite.Count+" lines between them");
                    foreach (Vector2 point in pointsOnPolygonOutline)
                    {
                        Vector2 dupe;
                        if ((dupe = ListContainsVectorCloseToVector(unduplicatedPoints, point)) != Vector2.zero)
                        {
                            //Debug.Log( " - point: "+point);
                            unduplicatedPoints.Remove(dupe);
                        }
                        else
                        {
                            //Debug.Log( " + point: "+point);
                            unduplicatedPoints.Add(point);
                        }
                    }

                    if (unduplicatedPoints.Count == 2)
                    {
                        // two points that need connecting
                        Gizmos.DrawLine(unduplicatedPoints [0], unduplicatedPoints [1]);
                    }
                    else if (unduplicatedPoints.Count > 1)
                    {
                        Debug.LogError("Should only have 0 or 2 unconnected points in a single polygon; had: " + unduplicatedPoints.Count);
                    }
                }

                if (DrawManualVoronoiLinesToCenter)
                {
                    foreach (LineSegment seg in outlineOfSite)
                    {
                        Gizmos.color = Color.gray;
                        Gizmos.DrawLine((Vector2)seg.p0, siteCoord);
                    }
                }
            }
        }

        if (DrawBounds)
        {
            Gizmos.color = Color.yellow;
            Gizmos.DrawLine(new Vector2(0, 0), new Vector2(0, m_mapHeight));
            Gizmos.DrawLine(new Vector2(0, 0), new Vector2(m_mapWidth, 0));
            Gizmos.DrawLine(new Vector2(m_mapWidth, 0), new Vector2(m_mapWidth, m_mapHeight));
            Gizmos.DrawLine(new Vector2(0, m_mapHeight), new Vector2(m_mapWidth, m_mapHeight));
        }
    }
    public static List<GameObject> GenerateVoronoiPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null)
    {
        List<GameObject> pieces = new List<GameObject>();

        if (mat == null)
        {
            mat = createFragmentMaterial(source);
        }

        //get transform information
        Vector3 origScale = source.transform.localScale;
        source.transform.localScale = Vector3.one;
        Quaternion origRotation = source.transform.localRotation;
        source.transform.localRotation = Quaternion.identity;

        //get rigidbody information
        Vector2 origVelocity = source.GetComponent<Rigidbody2D>().velocity;

        //get collider information
        PolygonCollider2D sourcePolyCollider = source.GetComponent<PolygonCollider2D>();
        BoxCollider2D sourceBoxCollider = source.GetComponent<BoxCollider2D>();
        List<Vector2> points = new List<Vector2>();
        List<Vector2> borderPoints = new List<Vector2>();
        if (sourcePolyCollider != null)
        {
            points = getPoints(sourcePolyCollider);
            borderPoints = getPoints(sourcePolyCollider);
        }
        else if (sourceBoxCollider != null)
        {
            points = getPoints(sourceBoxCollider);
            borderPoints = getPoints(sourceBoxCollider);
        }

        Rect rect = getRect(source);

        for (int i = 0; i < extraPoints; i++)
        {
            points.Add(new Vector2(Random.Range(
				rect.width / -2 + rect.center.x, rect.width / 2 + rect.center.x), 
				Random.Range(rect.height / -2 + rect.center.y, rect.height / 2 + rect.center.y)
				));
		}


		Voronoi voronoi = new Delaunay.Voronoi(points, null, rect);
        List<List<Vector2>> clippedRegions = new List<List<Vector2>>();
        foreach (List<Vector2> region in voronoi.Regions())
        {
            clippedRegions = ClipperHelper.clip(borderPoints, region);
            foreach (List<Vector2> clippedRegion in clippedRegions)
            {
                pieces.Add(generateVoronoiPiece(source, clippedRegion, origVelocity, origScale, origRotation, mat));
            }
        }

        List<GameObject> morePieces = new List<GameObject>();
        if (subshatterSteps > 0)
        {
            subshatterSteps--;
            foreach (GameObject piece in pieces)
            {
                morePieces.AddRange(SpriteExploder.GenerateVoronoiPieces(piece, extraPoints, subshatterSteps));
                GameObject.DestroyImmediate(piece);
            }
        }
        else
        {
            morePieces = pieces;
        }

        //reset transform information
        source.transform.localScale = origScale;
        source.transform.localRotation = origRotation;

        Resources.UnloadUnusedAssets();

        return morePieces;
    }
    private static List <List <Vector2> > GenerateCylindricalVoronoi(List <Vector2> centroids, float width, float height)
    {
        var nullColors = new List <uint>(); //needed to call Voronoi(), but redundant in this use case

        int noOfCentroids = centroids.Count;

        for (int i = 0; i < noOfCentroids; i++)
        {
            //We copy all of the centroids to create 2 "ghost" versions of the voronoi which we we stitch onto either side of the real one. This will help us to cylindricalise the map.
            Vector2 ghostCentroidRight      = new Vector2(centroids[i].x + width, centroids[i].y);
            Vector2 ghostCentroidRightRight = new Vector2(centroids[i].x + (2f * width), centroids[i].y);
            centroids.Add(ghostCentroidRight);
            centroids.Add(ghostCentroidRightRight);

            //the colors list has to be the same size as the centroids list
            nullColors.Add(0);
            nullColors.Add(0);
            nullColors.Add(0);
        }

        Delaunay.Voronoi       voronoi    = new Delaunay.Voronoi(centroids, nullColors, new Rect(0, 0, 3f * width, height));
        List <List <Vector2> > vorRegions = voronoi.Regions();
        var centralVorRegions             = new List <List <Vector2> >();

        //Now run the cylindricalisation step by removing all regions that are solely in the 2 ghost diagrams
        for (int i = 0; i < vorRegions.Count; i++)
        {
            bool hasPointInMiddle = false;
            for (int j = 0; j < vorRegions[i].Count; j++)
            {
                if ((vorRegions[i][j].x >= width) && (vorRegions[i][j].x < (2f * width)))
                {
                    hasPointInMiddle = true;
                    break;
                }
            }

            if (hasPointInMiddle)
            {
                centralVorRegions.Add(vorRegions[i]); // this region has points within our final diagram, so keep it
            }
        }

        var cylindricalVorRegions = new List <List <Vector2> >();

        //Also remove any overlap regions on the left hand side so that we only have one copy of each wrap-around polygon (on the right hand side)
        for (int i = 0; i < centralVorRegions.Count; i++)
        {
            bool hasPointOutsideLeftBoundary = false;
            for (int j = 0; j < centralVorRegions[i].Count; j++)
            {
                if (centralVorRegions[i][j].x < width)
                {
                    hasPointOutsideLeftBoundary = true;
                    break;
                }
            }

            if (!hasPointOutsideLeftBoundary)
            {
                // this region does not spill over the left side, so keep it, and shift all its points to the left by a mesh width
                for (int p = 0; p < centralVorRegions[i].Count; p++)
                {
                    centralVorRegions[i][p] = new Vector2(centralVorRegions[i][p].x - width, centralVorRegions[i][p].y);
                }
                cylindricalVorRegions.Add(centralVorRegions[i]);
            }
        }

        return(cylindricalVorRegions);
    }