public Building(EdgeLoop <CityEdge> footprint, float floorHeight, int floors, City city) { this.footprint = footprint; Vector2[] footprintPoints = footprint.GetPoints(); basePoints = new Vector3[footprintPoints.Length]; float highestBasePoint = float.MinValue; for (int i = 0; i < basePoints.Length; i++) { Vector2 fpPt = footprintPoints[i]; basePoints[i] = new Vector3(fpPt.x, city.SampleElevation(fpPt.x, fpPt.y), fpPt.y); if (basePoints[i].y > highestBasePoint) { highestBasePoint = basePoints[i].y; } } this.foundationFirstFloorGap = 0.2f; this.elevation = highestBasePoint; this.floorHeight = floorHeight; this.floors = floors; this.city = city; }
public Mesh GetMesh() { List <Vector3> verts = new List <Vector3>(); List <int> tris = new List <int>(); HashSet <int> borderVerts = new HashSet <int>(); Polygon footprintPoly = footprint.GetPolygon(); Rect bounds = footprint.GetBounds(); Vector2 centroid = footprintPoly.centroid; Vector2[] points = footprint.GetPoints(); for (int i = 0; i < points.Length; i++) { Vector2 p1 = points[i]; Vector2 p2 = points[(i + 1) % points.Length]; float dist = Vector2.Distance(p1, p2) * pointsPerUnit; float p1Elev = city.SampleElevation(p1.x, p1.y); float p2Elev = city.SampleElevation(p2.x, p2.y); int numPointsAlongEdge = Mathf.CeilToInt(dist); for (int j = 0; j < numPointsAlongEdge; j++) { float t = (float)j / (numPointsAlongEdge); Vector2 lerpP = Vector2.Lerp(p1, p2, t); Vector3 p3D = new Vector3(lerpP.x, Mathf.Lerp(p1Elev, p2Elev, t), lerpP.y); verts.Add(p3D); borderVerts.Add(verts.Count - 1); } } int numPointsX = Mathf.CeilToInt(bounds.width * pointsPerUnit); int numPointsY = Mathf.CeilToInt(bounds.height * pointsPerUnit); Polygon[] triangleFan = new Polygon[points.Length]; for (int i = 0; i < points.Length; i++) { triangleFan[i] = new Polygon(new Vector2[] { points[i], points[(i + 1) % points.Length], centroid }); } float edgeBlendDist = 3f; for (int x = 0; x < numPointsX; x++) { for (int y = 0; y < numPointsY; y++) { float xT = (float)x / (numPointsX - 1); float yT = (float)y / (numPointsY - 1); Vector2 realPos = new Vector2(xT * bounds.width + bounds.xMin, yT * bounds.height + bounds.yMin); float perimDist = footprint.DistToPerimeter(realPos); if (footprintPoly.ContainsPoint(realPos) && perimDist > 0.5f) { float elevation = city.SampleElevation(realPos.x, realPos.y); if (perimDist < edgeBlendDist) { for (int i = 0; i < triangleFan.Length; i++) { if (triangleFan[i].ContainsPoint(realPos)) { Vector2 vert1 = triangleFan[i].points[0]; Vector2 vert2 = triangleFan[i].points[1]; Vector2 vert3 = triangleFan[i].points[2]; float elev1 = city.SampleElevation(vert1.x, vert1.y); float elev2 = city.SampleElevation(vert2.x, vert2.y); float elev3 = city.SampleElevation(vert3.x, vert3.y); float blendElevation = HelperFunctions.TriangleInterp(realPos, vert1, vert2, vert3, elev1, elev2, elev3); elevation = Mathf.Lerp(blendElevation, elevation, perimDist / edgeBlendDist); } } } verts.Add(new Vector3(realPos.x, elevation, realPos.y)); } } } return(HelperFunctions.GetTriangulationMesh(verts.ToArray(), borderVerts, footprintPoly)); }
public Mesh GetMesh() { Vector2[] footprintVerts = footprint.GetPoints(); List <Vector3> verts = new List <Vector3>(); List <int> tris = new List <int>(); int[,] floorLoopVerts = new int[floors + 2, footprintVerts.Length]; for (int i = 0; i < floors + 2; i++) { float vertElev = elevation + floorHeight * (i - 1) + foundationFirstFloorGap; for (int j = 0; j < footprintVerts.Length; j++) { if (i == 0) { vertElev = basePoints[j].y; } verts.Add(new Vector3(footprintVerts[j].x, vertElev, footprintVerts[j].y)); floorLoopVerts[i, j] = verts.Count - 1; } } for (int i = 0; i < floors + 1; i++) { for (int j = 0; j < footprintVerts.Length; j++) { int nextI = (i + 1); int nextJ = (j + 1) % footprintVerts.Length; tris.Add(floorLoopVerts[i, j]); tris.Add(floorLoopVerts[nextI, nextJ]); tris.Add(floorLoopVerts[i, nextJ]); tris.Add(floorLoopVerts[i, j]); tris.Add(floorLoopVerts[nextI, j]); tris.Add(floorLoopVerts[nextI, nextJ]); } } Vector3 center = footprint.GetCenter(); center = new Vector3(center.x, (floors + 1) * floorHeight + elevation + foundationFirstFloorGap, center.y); verts.Add(center); int centerVertIndex = verts.Count - 1; for (int j = 0; j < footprintVerts.Length; j++) { int nextJ = (j + 1) % footprintVerts.Length; tris.Add(floorLoopVerts[floors + 1, nextJ]); tris.Add(floorLoopVerts[floors + 1, j]); tris.Add(centerVertIndex); } Mesh mesh = new Mesh(); mesh.vertices = verts.ToArray(); mesh.triangles = tris.ToArray(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); return(mesh); }