using System.Collections.Generic; using System.Linq; using Assets.AnnotationPass; using Assets.Cities; using Assets.Common; using UnityEngine; namespace Assets.RenderPass { public class CityRenderer : IRenderer { public void Render(Map map, Component component) { var go = new GameObject(); go.AddComponent(); go.AddComponent(); var cities = map.GetProperty>(LocateCitiesPass.CitiesProperty); var meshes = cities.Select(city => new CombineInstance { mesh = CreateCityMesh(city), transform = component.transform.localToWorldMatrix }); var mesh = new Mesh(); mesh.CombineMeshes(meshes.ToArray()); go.GetComponent().sharedMesh = mesh; } private Mesh CreateCityMesh(City city) { List vertices = new List(); List normals = new List(); List triangles = new List(); int start = 0, n = 0; foreach (var field in city.Fields) { start = vertices.Count; n = field.Boundary.Count; vertices.AddRange(field.Boundary.Select(p => p.ToVector3() + Vector3.up * 5)); normals.AddRange(field.Boundary.Select(v => Vector3.up)); triangles.AddRange(Triangulate(field).Select(x => x + start)); start = vertices.Count; vertices.AddRange(field.Boundary.Select(p => p.ToVector3() + Vector3.up * 5)); normals.AddRange(PointUtils.CalculateNormals(field.Boundary).Select(p => p.ToVector3())); vertices.AddRange(field.Boundary.Select(p => p.ToVector3())); normals.AddRange(PointUtils.CalculateNormals(field.Boundary).Select(p => p.ToVector3())); for (int i = 0; i < n; i++) { triangles.AddRange(new []{ start + i, start + n + i, start + n + (i + 1) % n }); triangles.AddRange(new []{ start + i, start + n + (i + 1) % n, start + (i + 1) % n }); } } return new Mesh { vertices = vertices.ToArray(), normals = normals.ToArray(), triangles = triangles.ToArray(), }; } private static IEnumerable Triangulate(CityField field) { return new Triangulator(field.Boundary.Select(p => new Vector2((float)p.x, (float)p.y)).ToArray()).Triangulate(); } public void DrawGizmos(Map map, Component component) { } } }