internal void Spawn() { Debug.Log("spawning"); Polygon start = FindObjectOfType <SetPlayerSpawnPos>().SpawningPoly; var path = new List <Node <Polygon> >(); var exit = Instantiate(_exitPrefab); start: VoronoiGenerator.DrawNodeGraphLine(start.Node, _angle, ref path); var exitSite = path.Last(); //var exitSite = path[(int)(path.Count * 0.8f)]; if (!exitSite.Data.IsWall && exitSite.ConnectionAngles.Any((i) => i.Value.Data.IsWall)) { exitSite = exitSite.ConnectionAngles.First((i) => i.Value.Data.IsWall).Value; } if (!exitSite.Data.IsWall && _angle < 180f) { //_angle += 10f; //goto start; } ; var pos = exitSite.Data.Centre; exit.transform.position = new Vector3(pos.x, pos.y, -7); _spawned = false; _path = path; }
void Start() { _voronoiGen = _levelGenerator.GetComponent <VoronoiGenerator>(); _voronoiGen.Generate(); _voronoiGen.ScaleAllPolies(Scale); OnGenerationComplete?.Invoke(); }
/// <summary> /// Generate a Voronoi Diagram from the generated points /// </summary> private void GenerateVoronoi() { //check if there are enough points if (_points == null || _points.Count <= 2 || _voronoiDiagram.Triangulation == null) { Console.WriteLine("No points available!"); GeneratePoints(PointsToGenerate); //return; } _baseColor = Extensions.Extensions.RandomColor(); _voronoiSettings.VoronoiAlgorithm = VoronoiAlgorithm; //create voronoi using specified algorithm var timer = Stopwatch.StartNew(); _voronoiDiagram = VoronoiGenerator.CreateVoronoi(_points, _voronoiSettings); timer.Stop(); if (_voronoiDiagram == null) { return; } //update info var time = timer.ElapsedMilliseconds / 1000.0; GenerationTimeText = $"For {_points.Count} points using {VoronoiAlgorithm.ToString()}: {time} seconds."; //Update canvas RefreshCanvas(); }
public SimpleVoronoi(IValueGenerator <float> random, VoronoiGenerator parameters, List <ShapeRelaxManipulator> manipulatorses) { _prng = random; _prng.Init(); _manipulators = manipulatorses; _parameters = parameters; }
public void Generate() { if (!_generatedVertexOrder) { GenerateVertexOrder(); } _generator = GetComponent <VoronoiGenerator>(); if (_generator == null || _generator.Polygons.Count == 0) { return; } // 3 is the least amount of sides for a polygon var polies = _generator.Polygons.Where((p) => p.Vertices.Count >= 3).ToList(); var corner0 = (polies.First().Centre); var corner1 = (polies.Last().Centre); List <Bound> bounds = new List <Bound>() { // new Bound(corner0 - new Vector2(2f, 2f), corner1 + new Vector2(2, 2)) new Bound(corner0 - new Vector2(0.2f, 0.2f), corner1 + new Vector2(0.2f, 0.2f)) }; int power = Mathf.CeilToInt(Mathf.Log(polies.Count / _chunkSize, 4f)); if (polies.Count < _chunkSize) { power = 0; } for (int i = 0; i < power; i++) { // this is the snapshot the count int boundCount = bounds.Count; var newBounds = new List <Bound>(); //for (int bound = 0; bound < boundCount; bound++) for (int bound = boundCount - 1; bound >= 0; bound--) { newBounds.AddRange(bounds[bound].Subdivide()); bounds.RemoveAt(bound); } bounds.AddRange(newBounds); } foreach (var bound in bounds) { List <Polygon> poliesInChunk = new List <Polygon>(); for (int poly = polies.Count - 1; poly >= 0; poly--) { if (bound.Contains(polies[poly].Centre)) { poliesInChunk.Add(polies[poly]); polies.RemoveAt(poly); } } var go = GenerateMesh(poliesInChunk); go.transform.SetParent(transform); } }
public override ISubGenerator Build(int seed) { var np = _noiseBuilder.Random(new Rand(seed)).Build(); var lp = _layerBuilder.Build(); // TODO change rand approach var rnd2 = new RandomSeeded(seed); var sd = new SegmentDivider(rnd2, 30, 1); var c = new VoronoiConverter(sd); var g = new VoronoiGenerator(c); var gg = new VoronoiAreaGenerator(g, new Rand(seed)); // todo Use parameters return(new MountainGenerator(new VisualLogger(), gg, np, lp) { Influence = _influence }); }
private void Spawn() { _voronoi = FindObjectOfType <VoronoiGenerator>(); // get a random poly as a starting point int randIndex; Polygon poly; do { //randIndex = Random.Range(0, _voronoi.Polygons.Count); randIndex = _levelSeeds[Random.Range(0, _levelSeeds.Length)]; poly = _voronoi.Polygons[randIndex]; // keep picking random polies till we find a valid spawn position } while (!IsValidSpawn(poly)); Debug.Log(randIndex); SpawningPoly = poly; transform.position = new Vector3(poly.Centre.x, poly.Centre.y, transform.position.z); _spawned = false; }
private List <Vector2> GetPoints() { List <Vector2> points = null; if (pointGeneration == PointGeneration.Random) { points = VoronoiGenerator.GetVector2Points(seed, (meshSize / pointSpacing) * (meshSize / pointSpacing), meshSize); } else if (pointGeneration == PointGeneration.PoissonDisc) { var poisson = new PoissonDiscSampler(meshSize, meshSize, pointSpacing, seed); points = poisson.Samples().ToList(); } else if (pointGeneration == PointGeneration.Grid) { points = new List <Vector2>(); for (int x = pointSpacing; x < meshSize; x += pointSpacing) { for (int y = pointSpacing; y < meshSize; y += pointSpacing) { points.Add(new Vector2(x, y)); } } } else if (pointGeneration == PointGeneration.OffsetGrid) { points = new List <Vector2>(); for (int x = pointSpacing; x < meshSize; x += pointSpacing) { bool even = false; for (int y = pointSpacing; y < meshSize; y += pointSpacing) { var newX = even ? x : x - (pointSpacing / 2f); points.Add(new Vector2(newX, y)); even = !even; } } } return(points); }
private static ILayer printMountainProfile(int countOfCells, ISegmendDivider sd) { var l = new Layer2DObject(res); // TODO change rand approach var rnd = new Rand(seed); var c = new VoronoiConverter(sd); var g = new VoronoiGenerator(c); var gg = new VoronoiAreaGenerator(g, rnd); var vd = new VoronoiAreaDrawer(); var areas = gg.GenerateAreas(res, res, countOfCells); vd.PrintToLayer(l, areas, Vector2.Zero); return(l); }
private void GenerateCity() { //seed random if (!GenerationSettings.UseSeed) { GenerationSettings.Seed = DateTime.Now.GetHashCode(); } //Store Settings var width = GenerationSettings.Width; var length = GenerationSettings.Length; //Parent.transform.position = citypos; GenerationSettings.StartX = Parent.transform.position.x - width / 2.0; GenerationSettings.StartY = Parent.transform.position.z - length / 2.0; //Generate Points and diagram var points = PointGenerator.Generate(GenerationSettings); VoronoiDiagram = VoronoiGenerator.CreateVoronoi(points, GenerationSettings); //generate city districts and roads _cityData = CityBuilder.GenerateCity(CitySettings, VoronoiDiagram); }
public List <GameObject> Explode(Vector3 impact, Vector3 direction, GameObject original) { List <VoronoiGenerator.VoronoiCell> cells = VoronoiGenerator.GenerateVoronoiSet(VoronoiGenerator.RandomPointSet(original.GetComponent <MeshFilter>().sharedMesh.bounds, 200)); List <GameObject> parts = new List <GameObject>(); foreach (VoronoiGenerator.VoronoiCell voronoiCell in cells) { GameObject cell; if (cell = MeshSlicerUtility.CellSlice(original, voronoiCell.faces, false)) { MeshCollider meshCollider = cell.AddComponent <MeshCollider>(); meshCollider.convex = true; meshCollider.sharedMesh = cell.GetComponent <MeshFilter>().sharedMesh; Rigidbody rigidbody = cell.AddComponent <Rigidbody>(); rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous; parts.Add(cell); } } return(parts); }
private static void printVoronoi(int countOfCells, ISegmendDivider sd) { var l = new Layer2DObject(res); // TODO change rand approach var rnd = new Rand(seed); var c = new VoronoiConverter(sd); var g = new VoronoiGenerator(c); var gg = new VoronoiAreaGenerator(g, rnd); var vd = new VoronoiAreaDrawer(); var areas = gg.GenerateAreas(res, res * .5f, countOfCells); vd.PrintToLayer(l, areas, new Vector2()); var vl = new VisualLogger(); vl.Log(l, "profile"); }
public void GeneratePoints() { _points = VoronoiGenerator.RandomPointSet(_meshFilter.sharedMesh.bounds, 10); }
private void _generateTerrain() { try { IGenerator generator = null; switch (_configurationManager.Algorithm) { case GeneratorAlgorithm.PerlinNoise: generator = new PerlinNoiseGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.Hill: generator = new HillAlgorithmGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.Random: generator = new RandomGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.Rectangle: generator = new RectangleGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.Voronoi: generator = new VoronoiGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.SimplexNoise: generator = new SimplexNoise(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.DiamondSquare: generator = new DiamondSquareGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.RandomWalk: generator = new RandomWalkGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters); break; case GeneratorAlgorithm.DrunkardWalk: generator = new DrunkardWalk(GraphicsDevice, Graphics, _configurationManager.Parameters); break; default: throw new NotImplementedException("Unknown algorithm"); } if (generator == null) { throw new NullReferenceException("Generator cannot be null"); } var timeStart = System.DateTime.Now; Scene.AddObjectToRender(generator.Generate()); Logger.Log.Info("Generated time = " + (DateTime.Now - timeStart).TotalMilliseconds + " ms for " + _configurationManager.Algorithm.ToString()); } catch (Exception e) { Logger.Log.Error(e); throw; } }
void OnSceneGUI() { VoronoiGenerator gen = (VoronoiGenerator)target; if (gen.lr != null) { if (quad == null || gen.wasReset) { if (VoronoiGenerator.instance == null) { gen.GenerateNoisyLineDebug(); } var lr = gen.lr; VoronoiGenerator.TryGetLineIntersections( gen.startControl, gen.endControl, gen.startNoisy, gen.endNoisy, out Vector2 intersectPoint, out float t1, out float t2); Debug.Log("t1: " + t1 + " t2: " + t2); quad = new Quad(gen.startControl, gen.endControl, gen.startNoisy, gen.endNoisy, gen.debugSubdivisions, -t1, gen.debugAmplitude, new System.Random()); List <Vector3> positions = new List <Vector3>(); positions.Add(gen.startNoisy); positions.AddRange(quad.points); positions.Add(gen.endNoisy); lr.SetPositions(positions.ToArray()); gen.wasReset = false; } else { quad.Draw(); } } if (gen.dGraph != null && gen.viewDelaunayTriangles) { Handles.color = Color.red; foreach (var edge in gen.dGraph.edges) { Handles.DrawDottedLine(edge.start.position, edge.end.position, 2); } } if (gen.vGraph != null && gen.viewVoronoiPolygons) { if (gen.viewIntersectionDirections) { if (VoronoiGraph.boundCrossingEdges != null) { foreach (MapSide mapSide in (MapSide[])Enum.GetValues(typeof(MapSide))) { if (mapSide == MapSide.Inside) { continue; } Handles.color = new Color(1, .62f, .016f, 1); for (int i = 0; i < VoronoiGraph.boundCrossingEdges[mapSide].Count; ++i) { var edge = VoronoiGraph.boundCrossingEdges[mapSide][i]; Vector2 nextPos; if (i == VoronoiGraph.boundCrossingEdges[mapSide].Count - 1) { //nextPos = borderEndPoints[mapSide].Item2; continue; } else { nextPos = VoronoiGraph.boundCrossingEdges[mapSide][i + 1].intersectPosition; } Handles.ArrowHandleCap(i, edge.intersectPosition, Quaternion.LookRotation(Vector3.right + new Vector3(0, .5f, 0)), Vector2.Distance(edge.intersectPosition, nextPos), EventType.Repaint); Handles.Label((edge.intersectPosition + nextPos) / 2, "" + i); } } } } style.normal.textColor = Color.black; if (gen.viewCorners) { foreach (var corner in VoronoiGraph.uniqueCorners) { if (corner.isInvalidated) { Handles.color = new Color(.5f, .5f, .5f, .5f); } else if (corner.isOOB) { Handles.color = Color.red; } else if (corner.isOnBorder) { Handles.color = cornerGreen; } else { Handles.color = Color.white; } Handles.SphereHandleCap(0, corner.position, Quaternion.identity, .25f, EventType.Repaint); if (gen.viewCornerIDs) { Handles.Label(corner.position + textOffset, "" + corner.num, style); } } } int intersectCount = 0; style.normal.textColor = Color.yellow; foreach (var edge in VoronoiGraph.uniqueVEdges) { if (edge.start.isOnBorder && edge.end.isOnBorder) { Handles.color = Color.green; } else if (!edge.start.isOOB && !edge.end.isOOB) { Handles.color = Color.blue; } else if ((edge.start.isOOB ^ edge.end.isOOB) && !edge.start.isOnBorder && !edge.end.isOnBorder) { Handles.color = Color.yellow; style.normal.textColor = Color.yellow; if (gen.viewIntersections) { foreach (var intersection in VoronoiGenerator.FindMapBoundsIntersection(edge.start.position, edge.end.position)) { Handles.CylinderHandleCap(0, intersection, Quaternion.identity, .4f, EventType.Repaint); if (gen.viewIntersectionIDs) { Handles.Label(intersection + textOffset, "" + (intersectCount++), style); } } } } else { Handles.color = Color.red; if (gen.viewIntersections) { foreach (var intersection in VoronoiGenerator.FindMapBoundsIntersection(edge.start.position, edge.end.position)) { // this is a very rare occurence of an edge that starts on a border and intersects with a different map edge. Handles.CylinderHandleCap(0, intersection, Quaternion.identity, .4f, EventType.Repaint); if (gen.viewIntersectionIDs) { Handles.Label(intersection + textOffset, "" + (intersectCount++), style); } Handles.color = Color.yellow; } } } Handles.DrawDottedLine(edge.start.position, edge.end.position, 2); if (gen.viewEdgeIDs) { style.normal.textColor = Color.cyan; Handles.Label((edge.start.position + edge.end.position) * .5f + textOffset, "" + edge.id, style); } } Handles.color = Color.cyan; foreach (var polygon in VoronoiGenerator.debugPolygons) { foreach (var edge in polygon.GetVoronoiEdges()) { Handles.DrawDottedLine(edge.start.position, edge.end.position, 1); } foreach (var corner in polygon.corners) { Handles.SphereHandleCap(0, corner.position, Quaternion.identity, .175f, EventType.Repaint); } int i = 0; style.normal.textColor = Color.cyan; foreach (var edge in polygon.GetVoronoiEdges()) { Handles.Label((edge.start.position + edge.end.position) / 2, "" + i, style); ++i; } style.normal.textColor = Color.white; i = 0; foreach (var corner in polygon.corners) { Handles.Label(corner.position + textOffset, "" + i, style); ++i; } } Handles.color = Color.magenta; foreach (var edge in VoronoiGenerator.debugEdges) { Handles.DrawDottedLine(edge.start.position, edge.end.position, 1); } foreach (var corner in VoronoiGenerator.debugCorners) { Handles.SphereHandleCap(0, corner.position, Quaternion.identity, .175f, EventType.Repaint); } } if (gen.regions != null && gen.viewRegionIDs) { foreach (var region in gen.regions) { if (region == null || region.polygon == null) { break; } Handles.Label(region.polygon.centroid.position, "" + region.id, style); } } if (VoronoiGraph.uniqueCorners != null && gen.debugSlopeDirections) { foreach (Corner corner in VoronoiGraph.uniqueCorners) { if (corner.downSlope != null) { Vector3 cornerPos = Quaternion.AngleAxis(90, Vector3.right) * corner.position; Vector3 targetPos = Quaternion.AngleAxis(90, Vector3.right) * corner.downSlope.position; Handles.ArrowHandleCap(0, cornerPos, Quaternion.LookRotation(targetPos - cornerPos, Vector3.up), 1, EventType.Repaint); } } } }
public override void OnInspectorGUI() { VoronoiGenerator gen = (VoronoiGenerator)target; using (var check = new EditorGUI.ChangeCheckScope()) { mapGenerationSettingsFoldout = EditorGUILayout.Foldout(mapGenerationSettingsFoldout, new GUIContent("Map Generation Settings")); if (mapGenerationSettingsFoldout) { EditorGUI.indentLevel = 1; gen.newRandomSeed = EditorGUILayout.Toggle(new GUIContent("New RandomSeed"), gen.newRandomSeed); gen.randomSeed = EditorGUILayout.DelayedTextField(new GUIContent("RandomSeed"), gen.randomSeed); EditorGUILayout.PropertyField(serializedObject.FindProperty("mapWidth")); EditorGUILayout.PropertyField(serializedObject.FindProperty("mapHeight")); EditorGUILayout.PropertyField(serializedObject.FindProperty("regionAmount")); EditorGUILayout.PropertyField(serializedObject.FindProperty("minSqrDistBtwnSites")); EditorGUILayout.PropertyField(serializedObject.FindProperty("minDistBtwnSiteAndBorder")); EditorGUILayout.PropertyField(serializedObject.FindProperty("minDistBtwnCornerAndBorder")); EditorGUILayout.PropertyField(serializedObject.FindProperty("minEdgeLengthToMerge")); GUI.enabled = false; EditorGUILayout.PropertyField(serializedObject.FindProperty("mergeNearCorners")); EditorGUILayout.PropertyField(serializedObject.FindProperty("clampToMapBounds")); GUI.enabled = true; EditorGUI.indentLevel = 0; } gen.borderSettingsFoldout = EditorGUILayout.Foldout(gen.borderSettingsFoldout, new GUIContent("Border Settings")); if (gen.borderSettingsFoldout) { EditorGUI.indentLevel = 1; bool borders = EditorGUILayout.Toggle(new GUIContent("Show Borders"), gen.bordersEnabled); if (borders != gen.bordersEnabled) { gen.ToggleBorders(borders); } EditorGUILayout.PropertyField(serializedObject.FindProperty("subdivisions")); EditorGUILayout.PropertyField(serializedObject.FindProperty("amplitude")); EditorGUI.indentLevel = 0; } EditorGUILayout.PropertyField(serializedObject.FindProperty("regionMaterial")); EditorGUILayout.PropertyField(serializedObject.FindProperty("sideMaterial")); EditorGUILayout.PropertyField(serializedObject.FindProperty("regionPrefab")); EditorGUILayout.PropertyField(serializedObject.FindProperty("regionHolder")); EditorGUILayout.PropertyField(serializedObject.FindProperty("noisePreviewMeshRenderer")); if (check.changed || GUILayout.Button("Generate Voronoi")) { AtomosZ.EditorTools.EditorUtils.ClearLogConsole(); gen.GenerateMap(); EditorUtility.SetDirty(target); } if (GUILayout.Button("Clear Map")) { gen.ClearMap(); } } using (var check = new EditorGUI.ChangeCheckScope()) { EditorGUILayout.PropertyField(serializedObject.FindProperty("noiseSettings")); EditorGUILayout.PropertyField(serializedObject.FindProperty("heightMapSettings")); if (check.changed) { gen.GenerateTexture(); } } gen.mapDebugFoldout = EditorGUILayout.Foldout(gen.mapDebugFoldout, new GUIContent("Map Debug Settings")); if (gen.mapDebugFoldout) { EditorGUI.indentLevel = 1; EditorGUILayout.PropertyField(serializedObject.FindProperty("viewDelaunayCircles")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewDelaunayTriangles")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewCenteroids")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewVoronoiPolygons")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewCorners")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewCornerIDs")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewEdgeIDs")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewIntersections")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewIntersectionIDs")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewIntersectionDirections")); EditorGUILayout.PropertyField(serializedObject.FindProperty("viewRegionIDs")); EditorGUILayout.PropertyField(serializedObject.FindProperty("debugSlopeDirections")); gen.debugBorders = EditorGUILayout.Toggle(new GUIContent("Debug Borders"), gen.debugBorders); if (gen.debugBorders) { EditorGUI.indentLevel = 2; EditorGUILayout.PropertyField(serializedObject.FindProperty("topBorder")); EditorGUILayout.PropertyField(serializedObject.FindProperty("rightBorder")); EditorGUILayout.PropertyField(serializedObject.FindProperty("bottomBorder")); EditorGUILayout.PropertyField(serializedObject.FindProperty("leftBorder")); EditorGUI.indentLevel = 1; } gen.debugNoisyLine = EditorGUILayout.Foldout(gen.debugNoisyLine, new GUIContent("Noisy Line Debug")); if (gen.debugNoisyLine) { EditorGUI.indentLevel = 2; EditorGUILayout.PropertyField(serializedObject.FindProperty("debugSubdivisions")); EditorGUILayout.PropertyField(serializedObject.FindProperty("debugAmplitude")); EditorGUILayout.PropertyField(serializedObject.FindProperty("startNoisy")); EditorGUILayout.PropertyField(serializedObject.FindProperty("endNoisy")); EditorGUILayout.PropertyField(serializedObject.FindProperty("startControl")); EditorGUILayout.PropertyField(serializedObject.FindProperty("endControl")); if (GUILayout.Button("Generate Noisy Line")) { AtomosZ.EditorTools.EditorUtils.ClearLogConsole(); gen.GenerateNoisyLineDebug(); EditorUtility.SetDirty(target); } EditorGUI.indentLevel = 1; } EditorGUI.indentLevel = 0; } serializedObject.ApplyModifiedProperties(); }