Example #1
0
    private static void AddPlaneComplex(BuildrRoofDesign design, Vector3 w0, Vector3 w1, Vector3 w2, Vector3 w3, int subMesh, bool flipped, Vector3 facadeNormal)
    {
        Vector3[] verts = new Vector3[4] { w0, w1, w2, w3 };
        Vector2[] uvs = BuildrProjectUVs.Project(verts, Vector2.zero, facadeNormal);
        int[] tris = new int[6] { 1, 0, 2, 1, 2, 3 };

        float xDiff = uvs[1].x - uvs[0].x;
        float yDiff = uvs[1].y - uvs[0].y;
        for (int p = 1; p < 4; p++)
        {
            Vector2 uv = uvs[p];
            float ratio = (uv.x - uvs[0].x) / xDiff;
            uv.y += -yDiff * ratio;
            uvs[p] = uv;
        }

        mesh.AddData(verts, uvs, tris, subMesh);
    }
Example #2
0
    private static void Hipped(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfFloors = volume.numberOfFloors;
        float baseHeight = data.floorHeight * numberOfFloors;
        float roofHeight = design.height;
        int numberOfVolumePoints = volume.points.Count;
        int subMesh = design.GetTexture(BuildrRoofDesign.textureNames.tiles);

        Vector2[] volumePoints = new Vector2[numberOfVolumePoints];
        for(int i = 0; i < numberOfVolumePoints; i++)
        {
            volumePoints[i] = area.points[volume.points[i]].vector2;
        }

        Vector2[][] meshData = StraightSkeleton.Calculate(volumePoints);
        Vector2[] triData = meshData[0];
        List<Vector2> interiorPoints = new List<Vector2>(meshData[1]);
        int numberOfVerts = triData.Length;
        Vector3[] verts = new Vector3[numberOfVerts];
        Vector2[] uvs = new Vector2[numberOfVerts];
        int[] tris = new int[numberOfVerts];
        for(int i = 0; i < triData.Length; i+=3)
        {
            Vector2 pa = triData[i];
            Vector2 pb = triData[i+1];
            Vector2 pc = triData[i+2];

            float ah = baseHeight + (interiorPoints.Contains(pa) ? roofHeight : 0);
            float bh = baseHeight + (interiorPoints.Contains(pb) ? roofHeight : 0);
            float ch = baseHeight + (interiorPoints.Contains(pc) ? roofHeight : 0);

            Vector3 v0 = new Vector3(pa.x, ah, pa.y);
            Vector3 v1 = new Vector3(pb.x, bh, pb.y);
            Vector3 v2 = new Vector3(pc.x, ch, pc.y);

            verts[i] = v0;
            verts[i+1] = v1;
            verts[i+2] = v2;

            Vector3 roofBaseDir = (interiorPoints.Contains(pc)) ? v1 - v0 : v2 - v1;
            Vector3 roofBaseNormal = Vector3.Cross(roofBaseDir, Vector3.up);
            Vector2[] uvsMansard = BuildrProjectUVs.Project(new Vector3[3] { v0, v1, v2 }, Vector2.zero, roofBaseNormal);

            uvs[i] = uvsMansard[0];
            uvs[i + 1] = uvsMansard[1];
            uvs[i + 2] = uvsMansard[2];

            tris[i] = i;
            tris[i + 1] = i+2;
            tris[i + 2] = i+1;
        }

        AddData(verts,uvs,tris,subMesh);

        /*Vector3 ridgeVector = Vector3.up * design.height;

        Vector3[] basePoints = new Vector3[4];
        if (design.direction == 0)
        {
            basePoints[0] = area.points[volume.points[0]].vector3 + volumeFloorHeight;
            basePoints[1] = area.points[volume.points[1]].vector3 + volumeFloorHeight;
            basePoints[2] = area.points[volume.points[2]].vector3 + volumeFloorHeight;
            basePoints[3] = area.points[volume.points[3]].vector3 + volumeFloorHeight;
        }
        else
        {
            basePoints[0] = area.points[volume.points[1]].vector3 + volumeFloorHeight;
            basePoints[1] = area.points[volume.points[2]].vector3 + volumeFloorHeight;
            basePoints[2] = area.points[volume.points[3]].vector3 + volumeFloorHeight;
            basePoints[3] = area.points[volume.points[0]].vector3 + volumeFloorHeight;
        }
        Vector3 centrePoint = Vector3.zero;
        for (int l = 0; l < 4; l++)
            centrePoint += area.points[volume.points[l]].vector3;
        centrePoint = (centrePoint / 4) + volumeFloorHeight + ridgeVector;

        Vector3 r0 = Vector3.Lerp(basePoints[0], basePoints[1], 0.5f) + ridgeVector;
        Vector3 r1 = Vector3.Lerp(basePoints[2], basePoints[3], 0.5f) + ridgeVector;
        Vector3 ridgeDirection = (r1 - r0);
        float roofLength = Vector3.Distance(r0, r1);
        float ridgeLengthA = Vector3.Distance(basePoints[0], basePoints[1]);
        if (ridgeLengthA > roofLength)
            ridgeLengthA = roofLength;
        float ridgeLengthB = Vector3.Distance(basePoints[2], basePoints[3]);
        if (ridgeLengthB > roofLength)
            ridgeLengthB = roofLength;
        r0 += ridgeDirection.normalized * ridgeLengthA / 2;
        r1 += -ridgeDirection.normalized * ridgeLengthB / 2;

        int subMesh = design.GetTexture(BuildrRoofDesign.textureNames.tiles);
        bool flipped = design.IsFlipped(BuildrRoofDesign.textureNames.tiles);
        AddPlane(design, basePoints[0], r0, basePoints[3], r1, subMesh, flipped);//top
        AddPlane(design, basePoints[2], r1, basePoints[1], r0, subMesh, flipped);//top

        Vector3[] vertsA = new Vector3[3] { basePoints[0], basePoints[1], r0 };
        Vector3[] vertsB = new Vector3[3] { basePoints[2], basePoints[3], r1 };
        float uvWdithA = Vector3.Distance(basePoints[0], basePoints[1]);
        float uvWdithB = Vector3.Distance(basePoints[2], basePoints[3]);
        float uvHeight = design.height;
        BuildrTexture texture = textures[subMesh];

        if (texture.tiled)
        {
            uvWdithA *= (1.0f / texture.textureUnitSize.x);
            uvWdithB *= (1.0f / texture.textureUnitSize.x);
            uvHeight *= (1.0f / texture.textureUnitSize.y);
            if (texture.patterned)
            {
                Vector2 uvunits = texture.tileUnitUV;
                uvWdithA = Mathf.Ceil(uvWdithA / uvunits.x) * uvunits.x;
                uvWdithB = Mathf.Ceil(uvWdithB / uvunits.x) * uvunits.x;
                uvHeight = Mathf.Ceil(uvHeight / uvunits.y) * uvunits.y;
            }
        }
        else
        {
            uvWdithA = texture.tiledX;
            uvWdithB = texture.tiledX;
            uvHeight = texture.tiledY;
        }
        Vector2[] uvsA = new Vector2[3] { new Vector2(-uvWdithA / 2, 0), new Vector2(uvWdithA / 2, 0), new Vector2(0, uvHeight) };
        Vector2[] uvsB = new Vector2[3] { new Vector2(-uvWdithB / 2, 0), new Vector2(uvWdithB / 2, 0), new Vector2(0, uvHeight) };
        int[] tri = new int[3] { 1, 0, 2 };
        AddData(vertsA, uvsA, tri, subMesh);
        AddData(vertsB, uvsB, tri, subMesh);*/
    }
Example #3
0
    private static void Mansard(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfVolumePoints = volume.points.Count;
        int numberOfFloors = volume.numberOfFloors;
        float floorHeight = data.floorHeight;
        Vector3 volumeFloorHeight = Vector3.up * (numberOfFloors * floorHeight);

        //add top base of the flat roof
        Vector3[] topVerts = new Vector3[numberOfVolumePoints];
        Vector2[] topUVs = new Vector2[numberOfVolumePoints];
        int topTextureID = design.GetTexture(BuildrRoofDesign.textureNames.floorB);
        BuildrTexture texture = textures[topTextureID];

        for (int l = 0; l < numberOfVolumePoints; l++)
        {
            int indexA, indexB, indexA0, indexB0;
            Vector3 p0, p1, p00, p10;
            indexA = l;
            indexB = (l < numberOfVolumePoints - 1) ? l + 1 : 0;
            indexA0 = (l > 0) ? l - 1 : numberOfVolumePoints - 1;
            indexB0 = (l < numberOfVolumePoints - 2) ? l + 2 : l + 2 - numberOfVolumePoints;

            p0 = area.points[volume.points[indexA]].vector3;
            p1 = area.points[volume.points[indexB]].vector3;
            p00 = area.points[volume.points[indexA0]].vector3;
            p10 = area.points[volume.points[indexB0]].vector3;

            float facadeWidth = Vector3.Distance(p0, p1);
            Vector3 facadeDirection = (p1 - p0).normalized;
            Vector3 facadeDirectionLeft = (p0 - p00).normalized;
            Vector3 facadeDirectionRight = (p10 - p1).normalized;
            Vector3 facadeNormal = Vector3.Cross(facadeDirection, Vector3.up);
            Vector3 facadeNormalLeft = Vector3.Cross(facadeDirectionLeft, Vector3.up);
            Vector3 facadeNormalRight = Vector3.Cross(facadeDirectionRight, Vector3.up);

            float roofHeight = design.height;
            float baseDepth = design.floorDepth;
            float cornerLeftRad = Vector3.Angle(facadeDirection, -facadeDirectionLeft) * Mathf.Deg2Rad / 2;
            float cornerRightRad = Vector3.Angle(-facadeDirection, facadeDirectionRight) * Mathf.Deg2Rad / 2;
            float cornerDepthLeft = baseDepth / Mathf.Sin(cornerLeftRad);
            float cornerDepthRight = baseDepth / Mathf.Sin(cornerRightRad);
            float topDepth = design.depth;
            float cornerTopDepthLeft = topDepth / Mathf.Sin(cornerLeftRad);
            float cornerTopDepthRight = topDepth / Mathf.Sin(cornerRightRad);

            Vector3 pr = facadeDirection * facadeWidth;

            Vector3 leftDir = (facadeNormal + facadeNormalLeft).normalized;
            Vector3 rightDir = (facadeNormal + facadeNormalRight).normalized;

            p0 += volumeFloorHeight;
            p1 += volumeFloorHeight;

            Vector3 w0, w1, w2, w3, w4, w5;
            w0 = p0;
            w1 = p0 + pr;
            w2 = w0 + leftDir * cornerDepthLeft;
            w3 = w1 + rightDir * cornerDepthRight;
            w4 = w2 + leftDir * cornerTopDepthLeft + Vector3.up * roofHeight;
            w5 = w3 + rightDir * cornerTopDepthRight + Vector3.up * roofHeight;

            Vector3[] verts = new Vector3[6] { w0, w1, w2, w3, w4, w5 };
//            List<Vector2> uvs = new List<Vector2>();

            Vector2[] uvsFloor = BuildrProjectUVs.Project(new Vector3[4] { w0, w1, w2, w3 }, Vector2.zero, facadeNormal);
            if(baseDepth == 0)
                uvsFloor[3].x = facadeWidth;
            Vector2[] uvsMansard = BuildrProjectUVs.Project(new Vector3[3] { w2, w4, w5 }, uvsFloor[2], facadeNormal);

            Vector3[] vertsA = new Vector3[4] { verts[0], verts[1], verts[2], verts[3] };
            Vector2[] uvsA = new Vector2[4] { uvsFloor[0], uvsFloor[1], uvsFloor[2], uvsFloor[3] };
            int[] trisA = new int[6] { 1, 0, 2, 1, 2, 3 };
            int subMeshA = design.GetTexture(BuildrRoofDesign.textureNames.floor);
            mesh.AddData(vertsA, uvsA, trisA, subMeshA);

            Vector3[] vertsB = new Vector3[4] { verts[2], verts[3], verts[4], verts[5] };
            Vector2[] uvsB = new Vector2[4] { uvsFloor[2], uvsFloor[3], uvsMansard[1], uvsMansard[2] };
            int[] trisB = new int[6] { 0, 2, 1, 1, 2, 3 };
            int subMeshB = design.GetTexture(BuildrRoofDesign.textureNames.tiles);
            mesh.AddData(vertsB, uvsB, trisB, subMeshB);

            //modify point for the top geometry
            Vector2z point = area.points[volume.points[l]];
            topVerts[l] = point.vector3 + volumeFloorHeight + Vector3.up * roofHeight + leftDir * (cornerDepthLeft + cornerTopDepthLeft);
            topUVs[l] = new Vector2(topVerts[l].x / texture.textureUnitSize.x, topVerts[l].z / texture.textureUnitSize.y);
        }

        Vector2z[] topVertV2z = new Vector2z[topVerts.Length];
        for (int i = 0; i < topVerts.Length; i++)
            topVertV2z[i] = new Vector2z(topVerts[i]);
        int[] topTris = EarClipper.Triangulate(topVertV2z);
        AddData(topVerts, topUVs, topTris, topTextureID);//top
    }