예제 #1
0
        public void ClearMap()
        {
            VEdge.count   = 0;
            Polygon.count = 0;
            Region.count  = 0;
            debugEdges    = new List <VEdge>();
            debugCorners  = new List <Corner>();
            debugPolygons = new List <Polygon>();
            ClearRegions();

            regions = null;
            dGraph  = null;
            vGraph  = null;
        }
예제 #2
0
        /// <summary>
        /// Some random seeds produce invalid polygon that uses map corners. Ex:
        /// 637427950365396994
        /// 637427958541256155
        /// </summary>
        /// <param name="vGen"></param>
        /// <param name="dGraph"></param>
        public VoronoiGraph(VoronoiGenerator vGen, DelaunayGraph dGraph)
        {
            generator     = vGen;
            delaunayGraph = dGraph;
            cornerCount   = 0;
            uniqueVEdges  = new HashSet <VEdge>();
            uniqueCorners = new HashSet <Corner>();
            removeCorners = new List <Corner>();
            mapCorners    = new Dictionary <byte, Corner>()
            {
                [VoronoiGenerator.TopRightCornerByte]    = new Corner(VoronoiGenerator.topRight, cornerCount++, true),
                [VoronoiGenerator.TopLeftCornerByte]     = new Corner(VoronoiGenerator.topLeft, cornerCount++, true),
                [VoronoiGenerator.BottomRightCornerByte] = new Corner(VoronoiGenerator.bottomRight, cornerCount++, true),
                [VoronoiGenerator.BottomLeftCornerByte]  = new Corner(VoronoiGenerator.bottomLeft, cornerCount++, true),
            };

            invalidatedPolygons = new List <Polygon>();
            invalidatedEdges    = new HashSet <VEdge>();

            polygons = new List <Polygon>();
            for (int i = 0; i < dGraph.centroids.Count; ++i)             // first 4 centroids are map corners
            {
                Polygon poly = new Polygon(dGraph.centroids[i]);
                polygons.Add(poly);
            }

            if (polygons[0].corners == null || polygons[1].corners == null ||
                polygons[2].corners == null || polygons[3].corners == null)
            {
                logMsgs = new List <string>();

                logMsgs.Add("****** Error found on Seed: " + generator.randomSeed + "******");
                logMsgs.Add("Map dimensions: " + generator.mapWidth + ", " + generator.mapHeight);
                logMsgs.Add("Region amt: " + generator.regionAmount);
                logMsgs.Add("MinSqrDistBtwnSites: " + generator.minSqrDistBtwnSites);
                logMsgs.Add("MinDistBtwnSiteAndBorder: " + generator.minDistBtwnSiteAndBorder);
                logMsgs.Add("MinDistBtwnCornerAndBorder: " + generator.minDistBtwnCornerAndBorder);
                logMsgs.Add("MinEdgeLengthToMerge: " + generator.minEdgeLengthToMerge);
                logMsgs.Add("Merge near corners: " + generator.mergeNearCorners);
                logMsgs.Add("******************************************\n");
                logMsgs.Add("Corner polygon did not make it passed initial generation");
                System.IO.File.WriteAllLines(logFilePath + "BorderCornerDeletedIssue_" + generator.randomSeed + ".txt", logMsgs);
                Log("Corner polygon did not make it passed initial generation", LogType.Exception, false);
            }
            VoronoiHelper.Associate(polygons[0], mapCorners[TopLeftCornerByte]);
            VoronoiHelper.Associate(polygons[1], mapCorners[TopRightCornerByte]);
            VoronoiHelper.Associate(polygons[2], mapCorners[BottomRightCornerByte]);
            VoronoiHelper.Associate(polygons[3], mapCorners[BottomLeftCornerByte]);

            if (VoronoiGenerator.MergeNearCorners)
            {
                MergeNearCorners();
            }

            if (generator.clampToMapBounds)
            {
                if (!ClampToMapBounds())
                {
                    return;
                }

                foreach (Corner corner in uniqueCorners)
                {
                    if (corner.isInvalidated)
                    {
                        if (!removeCorners.Contains(corner))
                        {
                            removeCorners.Add(corner);
                        }
                        continue;
                    }

                    if (corner.isOOB)
                    {
                        removeCorners.Add(corner);
                    }
                }
            }


            for (int i = removeCorners.Count - 1; i >= 0; --i)
            {
                Corner removingCorner = removeCorners[i];
                for (int j = removingCorner.connectedEdges.Count - 1; j >= 0; --j)
                {
                    VEdge edge = removingCorner.connectedEdges[j];
                    removingCorner.connectedEdges.Remove(edge);
                    uniqueVEdges.Remove(edge);
                    Corner opposite = edge.GetOppositeSite(removingCorner);
                    opposite.connectedEdges.Remove(edge);
                    foreach (var poly in removingCorner.polygons)
                    {
                        poly.Remove(edge);
                    }
                }

                removingCorner.connectedEdges.Clear();
                RemoveCorner(removingCorner);
            }


            int culled = 0;

            foreach (var polygon in invalidatedPolygons)
            {
                debugPolygons.Add(polygon);
                polygons.Remove(polygon);
                ++culled;
            }


            foreach (Polygon polygon in polygons)
            {
                polygon.CenterCentroid();
                polygon.SortEdges();
            }
        }
예제 #3
0
        public void GenerateMap()
        {
            instance = this;
            DestroyImmediate(lr);
            ClearMap();

            CreateRNG();

            MergeNearCorners = mergeNearCorners;

            minSqrDistBetweenCorners = minSqrDistBtwnSites;
            minDistCornerAndBorder   = minDistBtwnCornerAndBorder;



            mapBounds = new Rect(0, 0, mapWidth, mapHeight);

            topLeft     = new Vector2(mapBounds.xMin, mapBounds.yMax);
            topRight    = new Vector2(mapBounds.xMax, mapBounds.yMax);
            bottomRight = new Vector2(mapBounds.xMax, mapBounds.yMin);
            bottomLeft  = new Vector2(mapBounds.xMin, mapBounds.yMin);

            borderEndPoints = new Dictionary <MapSide, Tuple <Vector2, Vector2> >();
            borderEndPoints.Add(MapSide.Top, new Tuple <Vector2, Vector2>(topLeft, topRight));
            borderEndPoints.Add(MapSide.Right, new Tuple <Vector2, Vector2>(topRight, bottomRight));
            borderEndPoints.Add(MapSide.Bottom, new Tuple <Vector2, Vector2>(bottomRight, bottomLeft));
            borderEndPoints.Add(MapSide.Left, new Tuple <Vector2, Vector2>(bottomLeft, topLeft));

            List <Vector2> sites = new List <Vector2>();

            // create corner sites

            sites.Add(topLeft);
            sites.Add(topRight);
            sites.Add(bottomRight);
            sites.Add(bottomLeft);

            int retryAttempts = 0;

            for (int i = 0; i < regionAmount; i++)
            {
                Vector2 site = new Vector2(
                    (float)(minDistBtwnSiteAndBorder + rng.NextDouble() * (mapHeight - minDistBtwnSiteAndBorder * 2)),
                    (float)(minDistBtwnSiteAndBorder + rng.NextDouble() * (mapWidth - minDistBtwnSiteAndBorder * 2)));
                if (IsTooNear(sites, site))
                {                   // try again
                    ++retryAttempts;
                    if (retryAttempts > 25)
                    {
                        Debug.Log("Unable to place new site within exceptable distance parameters."
                                  + "\nAborting creating new sites. Created " + i + " out of " + regionAmount);
                        break;
                    }

                    --i;
                }
                else
                {
                    sites.Add(site);
                }
            }

            try
            {
                dGraph = new DelaunayGraph(sites);
                vGraph = new VoronoiGraph(this, dGraph);
                CreateRegions();
            }
            catch (System.Exception ex)
            {
                newRandomSeed = false;                 // make sure we stay on this seed until the problem has been rectified
                Debug.LogException(ex);
            }
        }