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; }
/// <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(); } }
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); } }