using System.Collections.Generic; using System.Linq; using Assets.Common; using Assets.Map; using UnityEngine; namespace Assets { [RequireComponent(typeof(MeshFilter))] [RequireComponent(typeof(MeshRenderer))] [RequireComponent(typeof(GraphGenerator))] public class MapRenderer : MonoBehaviour { public float uvScale = 1.0f; private List _vertices; private List _uv; private List _normals; private List _colors; private List _triangles; public void Generate() { var graph = GetComponent(); graph.Reset(); graph.Generate(); var points = graph.VoronoiGenerator.Voronoi.Vertices; _vertices = new List(); _normals = new List(); _uv = new List(); _colors = new List(); _triangles = new List(); foreach (var location in graph.LocationGenerator.Result.Vertices.Skip(1)) { GenerateLocationMesh(location, points); GenerateLocationWall(location, points); } Mesh mesh = new Mesh(); mesh.vertices = _vertices.ToArray(); mesh.uv = _uv.ToArray(); mesh.normals = _normals.ToArray(); mesh.triangles = _triangles.ToArray(); mesh.colors = _colors.ToArray(); GetComponent().sharedMesh = mesh; } private void GenerateLocationMesh(Location location, IList points) { foreach (var vertices in location.Sites.Select(site => site.Site.Edges.Select(x => x.Item1).Reverse())) { int start = _vertices.Count; foreach (var i in vertices) { var vertex = points[i]; var v = PointToVector(location, vertex); _vertices.Add(v); _normals.Add(Vector3.up); _uv.Add(new Vector2(v.x, v.z) / uvScale); _colors.Add(location.BoundaryPoints.Contains(i) ? Color.red : Color.blue); } int end = _vertices.Count; for (int i = start + 1; i < end - 1; i++) { _triangles.AddRange(new []{ start, i, i+1 }); } } } private static Vector3 PointToVector(Location location, Point vertex) { return new Vector3((float)vertex.x, location.Type.height + Mathf.PerlinNoise((float)vertex.x, (float)vertex.y) / 4, (float)vertex.y); } private void GenerateLocationWall(Location location, IList points) { var length = 0.0; foreach (var (a, b) in location.BoundaryEdges.Select(x => (points[x.Item1], points[x.Item2]))) { int start = _vertices.Count; var dist = Point.Dist(a, b); var veca = PointToVector(location, a); var vecb = PointToVector(location, b); _vertices.Add(veca); _vertices.Add(new Vector3((float)a.x, -10,(float)a.y)); _vertices.Add(vecb); _vertices.Add(new Vector3((float)b.x, -10,(float)b.y)); _normals.Add(Vector3.up); _normals.Add(Vector3.up); _normals.Add(Vector3.up); _normals.Add(Vector3.up); _colors.Add(Color.red); _colors.Add(Color.red); _colors.Add(Color.red); _colors.Add(Color.red); _triangles.AddRange(new [] { start, start + 2, start + 1, start + 1, start + 2, start + 3 }); _uv.AddRange(new [] { new Vector2((float)length, veca.y) / uvScale, new Vector2((float)length, -10) / uvScale, new Vector2((float)(length + dist), vecb.y) / uvScale, new Vector2((float)(length + dist), -10) / uvScale, }); length += dist; } } } }