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); }
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);*/ }
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 }