inz-00/Assets/Scripts/MapRenderer.cs
2019-09-01 15:34:28 +02:00

119 lines
4.0 KiB
C#

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<Vector3> _vertices;
private List<Vector2> _uv;
private List<Vector3> _normals;
private List<int> _triangles;
public void Generate()
{
var graph = GetComponent<GraphGenerator>();
graph.Reset();
graph.Generate();
var points = graph.VoronoiGenerator.Voronoi.Vertices;
_vertices = new List<Vector3>();
_normals = new List<Vector3>();
_uv = new List<Vector2>();
_triangles = new List<int>();
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();
GetComponent<MeshFilter>().sharedMesh = mesh;
}
private void GenerateLocationMesh(Location location, IList<Point> points)
{
foreach (var vertices in location.Sites.Select(site => site.Site.Edges.Select(x => points[x.Item1]).Reverse()))
{
int start = _vertices.Count;
foreach (var vertex in vertices)
{
var v = PointToVector(location, vertex);
_vertices.Add(v);
_normals.Add(Vector3.up);
_uv.Add(new Vector2(v.x, v.z) / uvScale);
}
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<Point> 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);
_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;
}
}
}
}