98 lines
3.4 KiB
C#
98 lines
3.4 KiB
C#
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using TransportGame.Model;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
namespace TransportGame.Unity
|
|||
|
{
|
|||
|
public class BuildingMeshGenerator
|
|||
|
{
|
|||
|
public Material BuildingMaterial { get; set; }
|
|||
|
|
|||
|
private GameObject parent = new GameObject("buildings");
|
|||
|
private Map map;
|
|||
|
|
|||
|
public IEnumerable Generate(Map map)
|
|||
|
{
|
|||
|
this.map = map;
|
|||
|
|
|||
|
foreach (var building in map.Buildings)
|
|||
|
{
|
|||
|
GenerateBuilding(building);
|
|||
|
yield return null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void GenerateBuilding(Building building)
|
|||
|
{
|
|||
|
List<Vector3> vertices = new List<Vector3>();
|
|||
|
List<UnityEngine.Vector2> uv = new List<UnityEngine.Vector2>();
|
|||
|
List<int> triangles = new List<int>();
|
|||
|
int vIndex = 0;
|
|||
|
|
|||
|
if (building.Polygons.Length == 0)
|
|||
|
return;
|
|||
|
|
|||
|
float terrainHeight = building.Polygons[0].SelectMany(poly => poly.Points).Min(pt => map.GetHeight((int)pt.X, (int)pt.Y));
|
|||
|
float minY, maxY = terrainHeight;
|
|||
|
|
|||
|
for (int i = 0; i < building.Polygons.Length; i++)
|
|||
|
{
|
|||
|
// Update minY and maxY
|
|||
|
minY = maxY;
|
|||
|
maxY += building.LevelHeights[i];
|
|||
|
|
|||
|
for (int p = 0; p < building.Polygons[i].Length; p++)
|
|||
|
{
|
|||
|
// Build mesh
|
|||
|
var center = building.Polygons[i][p].Position;
|
|||
|
var pts = building.Polygons[i][p].Points;
|
|||
|
|
|||
|
for (int j = 0; j < pts.Length; j++)
|
|||
|
{
|
|||
|
int k = (j + 1) % pts.Length;
|
|||
|
|
|||
|
vertices.Add(new Vector3(pts[j].Y, minY, pts[j].X));
|
|||
|
vertices.Add(new Vector3(pts[k].Y, minY, pts[k].X));
|
|||
|
vertices.Add(new Vector3(pts[k].Y, maxY, pts[k].X));
|
|||
|
vertices.Add(new Vector3(pts[j].Y, maxY, pts[j].X));
|
|||
|
vertices.Add(new Vector3(center.Y, maxY, center.X));
|
|||
|
|
|||
|
uv.Add(new UnityEngine.Vector2(0, 0));
|
|||
|
uv.Add(new UnityEngine.Vector2(0, 1));
|
|||
|
uv.Add(new UnityEngine.Vector2(1, 1));
|
|||
|
uv.Add(new UnityEngine.Vector2(1, 0));
|
|||
|
uv.Add(new UnityEngine.Vector2(0.5f, 0.5f));
|
|||
|
|
|||
|
triangles.AddRange(new[] { vIndex, vIndex + 1, vIndex + 2 });
|
|||
|
triangles.AddRange(new[] { vIndex, vIndex + 2, vIndex + 3 });
|
|||
|
triangles.AddRange(new[] { vIndex + 4, vIndex + 3, vIndex + 2 }); // top side
|
|||
|
|
|||
|
vIndex = vertices.Count;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Construct mesh
|
|||
|
Mesh mesh = new Mesh();
|
|||
|
mesh.vertices = vertices.ToArray();
|
|||
|
mesh.triangles = triangles.ToArray();
|
|||
|
mesh.uv = uv.ToArray();
|
|||
|
mesh.RecalculateNormals();
|
|||
|
|
|||
|
// Construct game object
|
|||
|
GameObject inters = new GameObject("building");
|
|||
|
inters.transform.parent = parent.transform;
|
|||
|
|
|||
|
MeshFilter meshFilter = inters.AddComponent<MeshFilter>();
|
|||
|
meshFilter.mesh = mesh;
|
|||
|
|
|||
|
MeshRenderer meshRenderer = inters.AddComponent<MeshRenderer>();
|
|||
|
meshRenderer.materials = new[] { BuildingMaterial };
|
|||
|
}
|
|||
|
}
|
|||
|
}
|