Make location generator use Location structure instead of color

This commit is contained in:
Kacper Donat 2019-08-16 14:37:48 +02:00
parent fdd3fb35c5
commit fb1be67f90
9 changed files with 97 additions and 65 deletions

View File

@ -2,6 +2,7 @@ using System;
using Assets; using Assets;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using Random = UnityEngine.Random;
namespace Editor namespace Editor
{ {
@ -21,6 +22,13 @@ namespace Editor
if (GUILayout.Button("Reset")) { if (GUILayout.Button("Reset")) {
generator.Reset(); generator.Reset();
} }
if (GUILayout.Button("Generate Random"))
{
generator.seed = (int)(Random.value * int.MaxValue);
generator.Reset();
generator.Generate();
}
if (GUILayout.Button("Generate")) { if (GUILayout.Button("Generate")) {
generator.Generate(); generator.Generate();

View File

@ -1,17 +0,0 @@
using Assets.Common;
using Assets.Voronoi;
using UnityEngine;
namespace Assets.Map
{
public class Location
{
public readonly Point Center;
public Color Type;
public Location(Point center)
{
Center = center;
}
}
}

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Random = System.Random; using Random = System.Random;
@ -8,26 +7,26 @@ namespace Assets.Map
{ {
public class LocationGenerator public class LocationGenerator
{ {
private Graph<Location> _graph; private Graph<LocationSite> _graph;
private readonly List<(int, Color)> _queue = new List<(int, Color)>(); private readonly List<(int, Location)> _queue = new List<(int, Location)>();
private Random _random; private Random _random;
public bool Done => _queue.Count == 0; public bool Done => _queue.Count == 0;
public Graph<Location> Result => _graph; public Graph<LocationSite> Result => _graph;
public LocationGenerator(Graph<Location> graph, Random random = null) public LocationGenerator(Graph<LocationSite> graph, Random random = null)
{ {
_graph = graph; _graph = graph;
_random = random ?? new Random(); _random = random ?? new Random();
} }
public void Init(params (int, Color)[] start) public void Init(params (int, Location)[] start)
{ {
foreach (var pair in start) foreach (var (vertex, location) in start)
_queue.Add(pair); SetLocation(vertex, location);
} }
private (int, Color) Dequeue() private (int, Location) Dequeue()
{ {
while (_queue.Count > 0) while (_queue.Count > 0)
{ {
@ -36,7 +35,7 @@ namespace Assets.Map
_queue.RemoveAt(index); _queue.RemoveAt(index);
if (_graph.Vertices[pair.Item1].Type == Color.clear) return pair; if (_graph.Vertices[pair.Item1].Location == null) return pair;
} }
throw new Exception("No more elements."); throw new Exception("No more elements.");
@ -46,17 +45,22 @@ namespace Assets.Map
{ {
try try
{ {
var (vertex, color) = Dequeue(); var (vertex, location) = Dequeue();
_graph.Vertices[vertex].Type = color; SetLocation(vertex, location);
foreach (var neighbour in _graph.Neighbours(vertex))
if (_graph.Vertices[neighbour].Type == Color.clear)
_queue.Add((neighbour, color));
} }
catch (Exception ex) catch (Exception ex)
{ {
} }
} }
private void SetLocation(int vertex, Location location)
{
_graph.Vertices[vertex].Location = location;
foreach (var neighbour in _graph.Neighbours(vertex))
if (_graph.Vertices[neighbour].Location == null)
_queue.Add((neighbour, location));
}
} }
} }

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using Assets.Common;
using Assets.Voronoi;
using UnityEngine;
namespace Assets.Map
{
public class Location
{
public List<LocationSite> Sites;
public List<Point> BoundaryPoints;
public LocationType Type;
}
public class LocationSite
{
public readonly Site Site;
public Location Location;
public LocationSite(Site site)
{
Site = site;
}
}
}

View File

@ -5,6 +5,6 @@ namespace Assets.Map
[Serializable] [Serializable]
public class Map public class Map
{ {
public readonly Graph<Location> Sections = new Graph<Location>(); public readonly Graph<LocationSite> Sections = new Graph<LocationSite>();
} }
} }

View File

@ -248,20 +248,31 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 06dfaa94f8713f12fbe207b61b694c90, type: 3} m_Script: {fileID: 11500000, guid: 06dfaa94f8713f12fbe207b61b694c90, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
seed: 500 sections:
- name:
color: {r: 1, g: 0, b: 0, a: 1}
- name:
color: {r: 0.18382645, g: 1, b: 0, a: 1}
- name:
color: {r: 1, g: 0, b: 0.74144936, a: 1}
- name:
color: {r: 0, g: 0.06698942, b: 1, a: 1}
- name:
color: {r: 0, g: 1, b: 0.94361734, a: 1}
seed: 120
size: {x: 200, y: 200} size: {x: 200, y: 200}
debug: debug:
enabled: 1 enabled: 1
displayPoints: 1 displayPoints: 0
displayBeachLine: 1 displayBeachLine: 0
displayParabolas: 0 displayParabolas: 0
displayVertices: 0 displayVertices: 0
displayNeighbours: 0 displayNeighbours: 0
displayLabels: 0 displayLabels: 0
displayHalfEdges: 0 displayHalfEdges: 0
displayEdges: 1 displayEdges: 0
displayLocations: 1 displayLocations: 1
radius: 8 radius: 5
--- !u!33 &528199734 --- !u!33 &528199734
MeshFilter: MeshFilter:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -27,7 +27,7 @@ namespace Assets
} }
[Serializable] [Serializable]
public class Section public class LocationType
{ {
public string name; public string name;
public Color color; public Color color;
@ -44,14 +44,16 @@ namespace Assets
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter)), ExecuteInEditMode] [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter)), ExecuteInEditMode]
public class GraphGenerator : MonoBehaviour public class GraphGenerator : MonoBehaviour
{ {
MeshFilter _filter;
private PoissonDiskSampler _sampler; private PoissonDiskSampler _sampler;
private Random _random;
List<Vector3> _points = new List<Vector3>();
public List<Section> sections = new List<Section>();
private VoronoiGenerator _voronoiGenerator; private VoronoiGenerator _voronoiGenerator;
private LocationGenerator _locationGenerator; private LocationGenerator _locationGenerator;
private List<Vector3> _points = new List<Vector3>();
private List<Location> _locations = new List<Location>();
public List<LocationType> types = new List<LocationType>();
public VoronoiGenerator VoronoiGenerator => _voronoiGenerator; public VoronoiGenerator VoronoiGenerator => _voronoiGenerator;
public LocationGenerator LocationGenerator => _locationGenerator; public LocationGenerator LocationGenerator => _locationGenerator;
@ -59,20 +61,15 @@ namespace Assets
public int seed = Environment.TickCount; public int seed = Environment.TickCount;
public Vector2 size = new Vector2(); public Vector2 size = new Vector2();
public GraphGeneratorDebug debug; public GraphGeneratorDebug debug;
public GenerationStage Stage { get; internal set; } = GenerationStage.Start; public GenerationStage Stage { get; private set; } = GenerationStage.Start;
[Range(2.0f, 64.0f)] [Range(2.0f, 64.0f)]
public float radius = 8; public float radius = 8;
private double _directrix = 0.0f; private double _directrix = 0.0f;
private Random _random;
private Graph<Location> _locations;
void Start() void Start()
{ {
_filter = GetComponent<MeshFilter>();
Reset(); Reset();
} }
@ -84,16 +81,20 @@ namespace Assets
_sampler.Generator = _random; _sampler.Generator = _random;
_points = new List<Vector3>(); _points = new List<Vector3>();
_points.Add(new Vector3(0, -0.1f)); _points.Add(new Vector3(-size.x/8, size.y / 2 + 0.1f));
_points.Add(new Vector3(size.x, 0.1f)); _points.Add(new Vector3(size.x * 1.125f, size.y / 2 - 0.1f));
_points.Add(new Vector3(size.x, size.y - 0.1f)); _points.Add(new Vector3(size.x / 2 - 0.1f, -size.y/8));
_points.Add(new Vector3(0, size.y + 0.1f)); _points.Add(new Vector3(size.x / 2 + 0.1f, size.y * 1.125f));
_points.AddRange(_sampler.Generate(size.x, size.y)); _points.AddRange(_sampler.Generate(size.x, size.y));
Stage = GenerationStage.Voronoi; Stage = GenerationStage.Voronoi;
_voronoiGenerator = new VoronoiGenerator(_points.Select(x => new Point(x.x, x.y)).ToList()); _voronoiGenerator = new VoronoiGenerator(_points.Select(x => new Point(x.x, x.y)).ToList());
_locationGenerator = null; _locationGenerator = null;
_locations = new List<Location>() { new Location() { Type = new LocationType() { color = Color.clear, name = "Ocean" } } };
_locations.AddRange(types.Select(type => new Location { Type = type }));
} }
public void Generate() public void Generate()
@ -115,10 +116,10 @@ namespace Assets
{ {
Stage = GenerationStage.Location; Stage = GenerationStage.Location;
_locationGenerator = new LocationGenerator(_voronoiGenerator.Delaunay.Morph(p => new Location(p)), _random); _locationGenerator = new LocationGenerator(_voronoiGenerator.Delaunay.Morph(site => new LocationSite(site)), _random);
_locationGenerator.Init( _locationGenerator.Init(
sections.Select(section => (_random.Next(_voronoiGenerator.Delaunay.Vertices.Count), section.color)) _locations.Select(location => (_random.Next(_voronoiGenerator.Delaunay.Vertices.Count), location))
.Concat(new List<(int, Color)> { (0, Color.white), (1, Color.white), (2, Color.white), (3, Color.white)}) .Concat(new List<int> { 0, 1, 2, 3 }.Select(i => (i, _locations[0]))) // borders should be water
.ToArray() .ToArray()
); );
} }
@ -139,13 +140,13 @@ namespace Assets
if (debug.displayPoints) if (debug.displayPoints)
{ {
Gizmos.color = Color.white; Gizmos.color = Color.white;
DisplayGraphVertices(_voronoiGenerator.Delaunay); DisplayGraphVertices(_voronoiGenerator.Delaunay.Morph(x => x.Point));
} }
if (debug.displayNeighbours) if (debug.displayNeighbours)
{ {
Gizmos.color = Color.yellow; Gizmos.color = Color.yellow;
DisplayGraphEdges(_voronoiGenerator.Delaunay); DisplayGraphEdges(_voronoiGenerator.Delaunay.Morph(x => x.Point));
} }
if (debug.displayVertices) if (debug.displayVertices)
@ -205,10 +206,10 @@ namespace Assets
if (debug.displayLocations && LocationGenerator != null) if (debug.displayLocations && LocationGenerator != null)
{ {
foreach (var location in LocationGenerator.Result.Vertices.Where(l => l.Type != Color.white)) foreach (var location in LocationGenerator.Result.Vertices.Where(l => l.Location != null && l.Location != _locations[0]))
{ {
Gizmos.color = location.Type; Gizmos.color = location.Location.Type.color;
Gizmos.DrawSphere(location.Center.ToVector3(), 2); Gizmos.DrawSphere(location.Site.Point.ToVector3(), 2);
} }
} }
} }

View File

@ -50,7 +50,7 @@ namespace Assets.Voronoi
public IPriorityQueue<IEvent, double> Queue { get; internal set; } public IPriorityQueue<IEvent, double> Queue { get; internal set; }
public Graph<Point> Voronoi; public Graph<Point> Voronoi;
public Graph<Point> Delaunay; public Graph<Site> Delaunay;
public List<HalfEdge> HalfEdges; public List<HalfEdge> HalfEdges;
@ -72,10 +72,10 @@ namespace Assets.Voronoi
Line = new BeachLine(); Line = new BeachLine();
Voronoi = new Graph<Point>(); Voronoi = new Graph<Point>();
Delaunay = new Graph<Point>(); Delaunay = new Graph<Site>();
HalfEdges = new List<HalfEdge>(); HalfEdges = new List<HalfEdge>();
Delaunay.Vertices.AddRange(from site in Sites select site.Point); Delaunay.Vertices.AddRange(Sites);
foreach (var site in Sites) foreach (var site in Sites)
{ {