inz-00/Assets/Scripts/RenderPass/CityRenderer.cs
2019-11-17 20:33:32 +01:00

78 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
{
private GameObject _cities;
public CityRenderer(GameObject cities)
{
_cities = cities;
}
public void Render(Map map, Component component)
{
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());
_cities.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()));
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()));
normals.AddRange(PointUtils.CalculateNormals(field.Boundary).Select(p => p.ToVector3()));
vertices.AddRange(field.Boundary.Select(p => p.ToVector3() + Vector3.down * 25));
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)
{
}
}
}