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 vertices = new List(); List uv = new List(); List triangles = new List(); 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; // Side 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)); 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)); triangles.AddRange(new[] { vIndex, vIndex + 1, vIndex + 2 }); triangles.AddRange(new[] { vIndex, vIndex + 2, vIndex + 3 }); vIndex = vertices.Count; // Top side 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)); triangles.AddRange(new[] { vIndex + 2, vIndex + 1, vIndex + 0 }); 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.mesh = mesh; MeshRenderer meshRenderer = inters.AddComponent(); meshRenderer.materials = new[] { BuildingMaterial }; } } }