city-generation/Game/Assets/Scripts/Unity/BuildingMeshGenerator.cs

98 lines
3.4 KiB
C#
Raw Normal View History

2015-06-10 08:49:43 +00:00
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 };
}
}
}