예제 #1
0
    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;
    }
예제 #2
0
    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));
    }
예제 #3
0
    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);
    }