75 lines
2.7 KiB
C#
75 lines
2.7 KiB
C#
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<MeshFilter>();
|
|
go.AddComponent<MeshRenderer>();
|
|
|
|
var cities = map.GetProperty<IEnumerable<City>>(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<MeshFilter>().sharedMesh = mesh;
|
|
}
|
|
|
|
private Mesh CreateCityMesh(City city)
|
|
{
|
|
List<Vector3> vertices = new List<Vector3>();
|
|
List<Vector3> normals = new List<Vector3>();
|
|
List<int> triangles = new List<int>();
|
|
|
|
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<int> 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)
|
|
{
|
|
|
|
}
|
|
}
|
|
} |