private static void AddPlane(BuildrRoofDesign design, Vector3 w0, Vector3 w1, Vector3 w2, Vector3 w3, int subMesh, bool flipped) { int textureSubmesh = subMesh; BuildrTexture texture = textures[textureSubmesh]; Vector2 uvSize = Vector2.one; if (texture.tiled) { float planeWidth = Vector3.Distance(w0, w1); float planeHeight = Vector3.Distance(w0, w2); uvSize = new Vector2(planeWidth * (1.0f / texture.textureUnitSize.x), planeHeight * (1.0f / texture.textureUnitSize.y)); if (texture.patterned) { Vector2 uvunits = texture.tileUnitUV; uvSize.x = Mathf.Ceil(uvSize.x / uvunits.x) * uvunits.x; uvSize.y = Mathf.Ceil(uvSize.y / uvunits.y) * uvunits.y; } } else { uvSize.x = texture.tiledX; uvSize.y = texture.tiledY; } if (!flipped) { mesh.AddPlane(w0, w1, w2, w3, Vector2.zero, uvSize, textureSubmesh); } else { uvSize = new Vector2(uvSize.y, uvSize.x); mesh.AddPlane(w0, w1, w2, w3, Vector2.zero, uvSize, textureSubmesh); } }
private static void AddPlane(Vector3 w0, Vector3 w1, Vector3 w2, Vector3 w3, int subMesh, bool flipped, Vector2 facadeUVStart, Vector2 facadeUVEnd) { int textureSubmesh = subMesh; BuildrTexture texture = textures[textureSubmesh]; Vector2 uvStart = facadeUVStart; Vector2 uvEnd = facadeUVEnd; if (texture.tiled) { uvStart = new Vector2(facadeUVStart.x * (1.0f / texture.textureUnitSize.x), facadeUVStart.y * (1.0f / texture.textureUnitSize.y)); uvEnd = new Vector2(facadeUVEnd.x * (1.0f / texture.textureUnitSize.x), facadeUVEnd.y * (1.0f / texture.textureUnitSize.y)); if (texture.patterned) { Vector2 uvunits = texture.tileUnitUV; uvStart.x = Mathf.Max(Mathf.Floor(uvStart.x / uvunits.x), 0) * uvunits.x; uvStart.y = Mathf.Max(Mathf.Floor(uvStart.y / uvunits.y), 0) * uvunits.y; uvEnd.x = Mathf.Max(Mathf.Ceil(uvEnd.x / uvunits.x), 1) * uvunits.x; uvEnd.y = Mathf.Max(Mathf.Ceil(uvEnd.y / uvunits.y), 1) * uvunits.y; } } else { uvStart = Vector2.zero; uvEnd.x = texture.tiledX; uvEnd.y = texture.tiledY; } if (!flipped) { mesh.AddPlane(w2, w3, w0, w1, uvStart, uvEnd, textureSubmesh); } else { uvStart = new Vector2(uvStart.y, uvStart.x); uvEnd = new Vector2(uvEnd.y, uvEnd.x); mesh.AddPlane(w3, w1, w2, w0, uvStart, uvEnd, textureSubmesh); } }
public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data) { // timestart = Time.realtimeSinceStartup; data = _data; mesh = _mesh; textures = data.textures.ToArray(); BuildrPlan plan = data.plan; int facadeIndex = 0; numberOfFacades = 0; int numberOfVolumes = data.plan.numberOfVolumes; LogTimer("Start"); //define rectangles that represent the facades packedTexturePositions.Clear(); for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int numberOfVolumePoints = volume.points.Count; for (int f = 0; f < numberOfVolumePoints; f++) { if (!volume.renderFacade[f]) { continue; } int indexA = f; int indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0; Vector2z p0 = plan.points[volume.points[indexA]]; Vector2z p1 = plan.points[volume.points[indexB]]; float facadeWidth = Vector2z.Distance(p0, p1) * PIXELS_PER_METER; int floorBase = plan.GetFacadeFloorHeight(v, volume.points[indexA], volume.points[indexB]); int numberOfFloors = volume.numberOfFloors - floorBase; if (numberOfFloors < 1)//no facade - adjacent facade is taller and covers this one { continue; } float floorHeight = data.floorHeight; float facadeHeight = (volume.numberOfFloors - floorBase) * floorHeight * PIXELS_PER_METER; if (facadeHeight < 0) { facadeWidth = 0; facadeHeight = 0; } Rect newFacadeRect = new Rect(0, 0, facadeWidth, facadeHeight); packedTexturePositions.Add(newFacadeRect); numberOfFacades++; } } //Build ROOF DynamicMeshGenericMultiMaterialMesh dynMeshRoof = new DynamicMeshGenericMultiMaterialMesh(); dynMeshRoof.name = "Roof Mesh"; dynMeshRoof.subMeshCount = textures.Length; BuildrRoof.Build(dynMeshRoof, data, true); dynMeshRoof.CheckMaxTextureUVs(data); LogTimer("Roof A"); roofTextures.Clear(); roofTextureIndex.Clear(); foreach (BuildrRoofDesign roofDesign in data.roofs) { foreach (int textureIndex in roofDesign.textureValues) { if (!roofTextureIndex.Contains(textureIndex)) { BuildrTexture bTexture = data.textures[textureIndex]; Vector2 largestSubmeshPlaneSize = new Vector2(1, 1); Vector2 minWorldUvSize = dynMeshRoof.MinWorldUvSize(textureIndex); Vector2 maxWorldUvSize = dynMeshRoof.MaxWorldUvSize(textureIndex); largestSubmeshPlaneSize.x = maxWorldUvSize.x - minWorldUvSize.x; largestSubmeshPlaneSize.y = maxWorldUvSize.y - minWorldUvSize.y; int roofTextureWidth = Mathf.RoundToInt(largestSubmeshPlaneSize.x * PIXELS_PER_METER); int roofTextureHeight = Mathf.RoundToInt(largestSubmeshPlaneSize.y * PIXELS_PER_METER); Rect newRoofTexutureRect = new Rect(0, 0, roofTextureWidth, roofTextureHeight); packedTexturePositions.Add(newRoofTexutureRect); roofTextures.Add(bTexture); roofTextureIndex.Add(textureIndex); } } } //run a custom packer to define their postions textureWidth = RectanglePack.Pack(packedTexturePositions, ATLAS_PADDING); //determine the resize scale and apply that to the rects packedScale = 1; int numberOfRects = packedTexturePositions.Count; if (textureWidth > MAXIMUM_TEXTURESIZE) { packedScale = MAXIMUM_TEXTURESIZE / (float)textureWidth; for (int i = 0; i < numberOfRects; i++) { Rect thisRect = packedTexturePositions[i]; thisRect.x *= packedScale; thisRect.y *= packedScale; thisRect.width *= packedScale; thisRect.height *= packedScale; packedTexturePositions[i] = thisRect; //Debug.Log("Rects "+roofTextures[i-+packedTexturePositions[i]); } textureWidth = Mathf.RoundToInt(packedScale * textureWidth); } else { textureWidth = (int)Mathf.Pow(2, (Mathf.FloorToInt(Mathf.Log(textureWidth - 1, 2)) + 1));//find the next power of two } //Debug.Log("Texture Width "+textureWidth); //TODO: maybe restrict the resize to a power of two? LogTimer("Packed Rect Generated"); textureSize = textureWidth * textureWidth; colourArray = new Color32[textureSize]; //TestRectColours();//this test paints all the facades with rainbow colours - real pretty BuildTextures(); LogTimer("texture created"); Texture2D packedTexture = new Texture2D(textureWidth, textureWidth, TextureFormat.ARGB32, true); packedTexture.filterMode = FilterMode.Bilinear; packedTexture.SetPixels32(colourArray); packedTexture.Apply(true, false); LogTimer("apply"); if (data.LODTextureAtlas != null) { Object.DestroyImmediate(data.LODTextureAtlas); } data.LODTextureAtlas = packedTexture; data.LODTextureAtlas.name = "Low Detail Texture"; //build the model with new uvs if (data.drawUnderside) { for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; Vector3[] newEndVerts = new Vector3[numberOfVolumePoints]; Vector2[] newEndUVs = new Vector2[numberOfVolumePoints]; for (int i = 0; i < numberOfVolumePoints; i++) { newEndVerts[i] = plan.points[volume.points[i]].vector3; newEndUVs[i] = Vector2.zero; } List <int> tris = new List <int>(data.plan.GetTrianglesBySectorBase(s)); tris.Reverse(); mesh.AddData(newEndVerts, newEndUVs, tris.ToArray(), 0); } } LogTimer("Floor"); //Build facades for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; for (int f = 0; f < numberOfVolumePoints; f++) { if (!volume.renderFacade[f]) { continue; } int indexA = f; int indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0; Vector3 p0 = plan.points[volume.points[indexA]].vector3; Vector3 p1 = plan.points[volume.points[indexB]].vector3; int floorBase = plan.GetFacadeFloorHeight(s, volume.points[indexA], volume.points[indexB]); int numberOfFloors = volume.numberOfFloors - floorBase; if (numberOfFloors < 1) { //no facade - adjacent facade is taller and covers this one continue; } float floorHeight = data.floorHeight; Vector3 floorHeightStart = Vector3.up * (floorBase * floorHeight); Vector3 wallHeight = Vector3.up * (volume.numberOfFloors * floorHeight) - floorHeightStart; p0 += floorHeightStart; p1 += floorHeightStart; Vector3 w0 = p0; Vector3 w1 = p1; Vector3 w2 = w0 + wallHeight; Vector3 w3 = w1 + wallHeight; Rect facadeRect = packedTexturePositions[facadeIndex]; float imageSize = textureWidth; Vector2 uvMin = new Vector2(facadeRect.xMin / imageSize, facadeRect.yMin / imageSize); Vector2 uvMax = new Vector2(facadeRect.xMax / imageSize, facadeRect.yMax / imageSize); mesh.AddPlane(w0, w1, w2, w3, uvMin, uvMax, 0); facadeIndex++; } } LogTimer("Facades"); //ROOF Textures int roofRectBase = numberOfFacades; List <Rect> newAtlasRects = new List <Rect>(); for (int i = roofRectBase; i < packedTexturePositions.Count; i++) { Rect uvRect = new Rect();//generate a UV based rectangle off the packed one uvRect.x = packedTexturePositions[i].x / textureWidth; uvRect.y = packedTexturePositions[i].y / textureWidth; uvRect.width = packedTexturePositions[i].width / textureWidth; uvRect.height = packedTexturePositions[i].height / textureWidth; newAtlasRects.Add(uvRect); } dynMeshRoof.Atlas(roofTextureIndex.ToArray(), newAtlasRects.ToArray(), data.textures.ToArray()); //Add the atlased mesh data to the main model data at submesh 0 mesh.AddData(dynMeshRoof.vertices, dynMeshRoof.uv, dynMeshRoof.triangles, 0); LogTimer("Roof B"); data = null; mesh = null; textures = null; //atlasRects = null; LogTimer("Done"); System.GC.Collect(); }
public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data) { // timestart = Time.realtimeSinceStartup; data = _data; mesh = _mesh; textures = data.textures.ToArray(); BuildrPlan plan = data.plan; int facadeIndex = 0; numberOfFacades = 0; int numberOfVolumes = data.plan.numberOfVolumes; LogTimer("Start"); //define rectangles that represent the facades packedTexturePositions.Clear(); for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int numberOfVolumePoints = volume.points.Count; for (int f = 0; f < numberOfVolumePoints; f++) { if (!volume.renderFacade[f]) continue; int indexA = f; int indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0; Vector2z p0 = plan.points[volume.points[indexA]]; Vector2z p1 = plan.points[volume.points[indexB]]; float facadeWidth = Vector2z.Distance(p0, p1) * PIXELS_PER_METER; int floorBase = plan.GetFacadeFloorHeight(v, volume.points[indexA], volume.points[indexB]); int numberOfFloors = volume.numberOfFloors - floorBase; if (numberOfFloors < 1)//no facade - adjacent facade is taller and covers this one continue; float floorHeight = data.floorHeight; float facadeHeight = (volume.numberOfFloors - floorBase) * floorHeight * PIXELS_PER_METER; if (facadeHeight < 0) { facadeWidth = 0; facadeHeight = 0; } Rect newFacadeRect = new Rect(0, 0, facadeWidth, facadeHeight); packedTexturePositions.Add(newFacadeRect); numberOfFacades++; } } //Build ROOF DynamicMeshGenericMultiMaterialMesh dynMeshRoof = new DynamicMeshGenericMultiMaterialMesh(); dynMeshRoof.name = "Roof Mesh"; dynMeshRoof.subMeshCount = textures.Length; BuildrRoof.Build(dynMeshRoof, data, true); dynMeshRoof.CheckMaxTextureUVs(data); LogTimer("Roof A"); roofTextures.Clear(); roofTextureIndex.Clear(); foreach (BuildrRoofDesign roofDesign in data.roofs) { foreach (int textureIndex in roofDesign.textureValues) { if (!roofTextureIndex.Contains(textureIndex)) { BuildrTexture bTexture = data.textures[textureIndex]; Vector2 largestSubmeshPlaneSize = new Vector2(1,1); Vector2 minWorldUvSize = dynMeshRoof.MinWorldUvSize(textureIndex); Vector2 maxWorldUvSize = dynMeshRoof.MaxWorldUvSize(textureIndex); largestSubmeshPlaneSize.x = maxWorldUvSize.x - minWorldUvSize.x; largestSubmeshPlaneSize.y = maxWorldUvSize.y - minWorldUvSize.y; int roofTextureWidth = Mathf.RoundToInt(largestSubmeshPlaneSize.x * PIXELS_PER_METER); int roofTextureHeight = Mathf.RoundToInt(largestSubmeshPlaneSize.y * PIXELS_PER_METER); Rect newRoofTexutureRect = new Rect(0, 0, roofTextureWidth, roofTextureHeight); packedTexturePositions.Add(newRoofTexutureRect); roofTextures.Add(bTexture); roofTextureIndex.Add(textureIndex); } } } //run a custom packer to define their postions textureWidth = RectanglePack.Pack(packedTexturePositions,ATLAS_PADDING); //determine the resize scale and apply that to the rects packedScale = 1; int numberOfRects = packedTexturePositions.Count; if (textureWidth > MAXIMUM_TEXTURESIZE) { packedScale = MAXIMUM_TEXTURESIZE / (float)textureWidth; for (int i = 0; i < numberOfRects; i++) { Rect thisRect = packedTexturePositions[i]; thisRect.x *= packedScale; thisRect.y *= packedScale; thisRect.width *= packedScale; thisRect.height *= packedScale; packedTexturePositions[i] = thisRect; //Debug.Log("Rects "+roofTextures[i-+packedTexturePositions[i]); } textureWidth = Mathf.RoundToInt(packedScale * textureWidth); } else { textureWidth = (int)Mathf.Pow(2, (Mathf.FloorToInt(Mathf.Log(textureWidth - 1, 2)) + 1));//find the next power of two } //Debug.Log("Texture Width "+textureWidth); //TODO: maybe restrict the resize to a power of two? LogTimer("Packed Rect Generated"); textureSize = textureWidth * textureWidth; colourArray = new Color32[textureSize]; //TestRectColours();//this test paints all the facades with rainbow colours - real pretty BuildTextures(); LogTimer("texture created"); Texture2D packedTexture = new Texture2D(textureWidth, textureWidth, TextureFormat.ARGB32, true); packedTexture.filterMode = FilterMode.Bilinear; packedTexture.SetPixels32(colourArray); packedTexture.Apply(true, false); LogTimer("apply"); if (data.LODTextureAtlas != null) Object.DestroyImmediate(data.LODTextureAtlas); data.LODTextureAtlas = packedTexture; data.LODTextureAtlas.name = "Low Detail Texture"; //build the model with new uvs if (data.drawUnderside) { for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; Vector3[] newEndVerts = new Vector3[numberOfVolumePoints]; Vector2[] newEndUVs = new Vector2[numberOfVolumePoints]; for (int i = 0; i < numberOfVolumePoints; i++) { newEndVerts[i] = plan.points[volume.points[i]].vector3; newEndUVs[i] = Vector2.zero; } List<int> tris = new List<int>(data.plan.GetTrianglesBySectorBase(s)); tris.Reverse(); mesh.AddData(newEndVerts, newEndUVs, tris.ToArray(), 0); } } LogTimer("Floor"); //Build facades for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; for (int f = 0; f < numberOfVolumePoints; f++) { if (!volume.renderFacade[f]) continue; int indexA = f; int indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0; Vector3 p0 = plan.points[volume.points[indexA]].vector3; Vector3 p1 = plan.points[volume.points[indexB]].vector3; int floorBase = plan.GetFacadeFloorHeight(s, volume.points[indexA], volume.points[indexB]); int numberOfFloors = volume.numberOfFloors - floorBase; if (numberOfFloors < 1) { //no facade - adjacent facade is taller and covers this one continue; } float floorHeight = data.floorHeight; Vector3 floorHeightStart = Vector3.up * (floorBase * floorHeight); Vector3 wallHeight = Vector3.up * (volume.numberOfFloors * floorHeight) - floorHeightStart; p0 += floorHeightStart; p1 += floorHeightStart; Vector3 w0 = p0; Vector3 w1 = p1; Vector3 w2 = w0 + wallHeight; Vector3 w3 = w1 + wallHeight; Rect facadeRect = packedTexturePositions[facadeIndex]; float imageSize = textureWidth; Vector2 uvMin = new Vector2(facadeRect.xMin / imageSize, facadeRect.yMin / imageSize); Vector2 uvMax = new Vector2(facadeRect.xMax / imageSize, facadeRect.yMax / imageSize); mesh.AddPlane(w0, w1, w2, w3, uvMin, uvMax, 0); facadeIndex++; } } LogTimer("Facades"); //ROOF Textures int roofRectBase = numberOfFacades; List<Rect> newAtlasRects = new List<Rect>(); for (int i = roofRectBase; i < packedTexturePositions.Count; i++) { Rect uvRect = new Rect();//generate a UV based rectangle off the packed one uvRect.x = packedTexturePositions[i].x / textureWidth; uvRect.y = packedTexturePositions[i].y / textureWidth; uvRect.width = packedTexturePositions[i].width / textureWidth; uvRect.height = packedTexturePositions[i].height / textureWidth; newAtlasRects.Add(uvRect); } dynMeshRoof.Atlas(roofTextureIndex.ToArray(), newAtlasRects.ToArray(), data.textures.ToArray()); //Add the atlased mesh data to the main model data at submesh 0 mesh.AddData(dynMeshRoof.vertices, dynMeshRoof.uv, dynMeshRoof.triangles, 0); LogTimer("Roof B"); data = null; mesh = null; textures = null; //atlasRects = null; LogTimer("Done"); System.GC.Collect(); }
public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data) { data = _data; mesh = _mesh; BuildrPlan plan = data.plan; int facadeIndex = 0; int numberOfVolumes = data.plan.numberOfVolumes; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; Vector3[] newEndVerts = new Vector3[numberOfVolumePoints]; Vector2[] newEndUVs = new Vector2[numberOfVolumePoints]; Vector3 volumeHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight); for (int i = 0; i < numberOfVolumePoints; i++) { newEndVerts[i] = plan.points[volume.points[i]].vector3 + volumeHeight; newEndUVs[i] = Vector2.zero; } List<int> tris = new List<int>(data.plan.GetTrianglesBySectorBase(s)); mesh.AddData(newEndVerts, newEndUVs, tris.ToArray(), 0); } //Build ROOF //Build facades for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int numberOfVolumePoints = volume.points.Count; for (int f = 0; f < numberOfVolumePoints; f++) { if (!volume.renderFacade[f]) continue; int indexA = f; int indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0; Vector3 p0 = plan.points[volume.points[indexA]].vector3; Vector3 p1 = plan.points[volume.points[indexB]].vector3; int floorBase = plan.GetFacadeFloorHeight(v, volume.points[indexA], volume.points[indexB]); int numberOfFloors = volume.numberOfFloors - floorBase; if (numberOfFloors < 1) { //no facade - adjacent facade is taller and covers this one continue; } float floorHeight = data.floorHeight; Vector3 floorHeightStart = Vector3.up * (floorBase * floorHeight); Vector3 wallHeight = Vector3.up * (volume.numberOfFloors * floorHeight) - floorHeightStart; float facadeWidth = Vector3.Distance(p0, p1); p0 += floorHeightStart; p1 += floorHeightStart; Vector3 w0 = p0; Vector3 w1 = p1; Vector3 w2 = w0 + wallHeight; Vector3 w3 = w1 + wallHeight; Vector2 uvMin = new Vector2(0, 0); Vector2 uvMax = new Vector2(facadeWidth, floorHeight); mesh.AddPlane(w0, w1, w2, w3, uvMin, uvMax, 0); facadeIndex++; } } data = null; mesh = null; }
private static void BuildSimple(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data) { BuildrData data = _data; DynamicMeshGenericMultiMaterialMesh mesh = _mesh; BuildrPlan plan = data.plan; int facadeIndex = 0; int numberOfVolumes = data.plan.numberOfVolumes; //Build Floor if (data.drawUnderside) { for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; Vector3[] newEndVerts = new Vector3[numberOfVolumePoints]; Vector2[] newEndUVs = new Vector2[numberOfVolumePoints]; for (int i = 0; i < numberOfVolumePoints; i++) { newEndVerts[i] = plan.points[volume.points[i]].vector3; newEndUVs[i] = Vector2.zero; } List <int> tris = new List <int>(data.plan.GetTrianglesBySectorBase(s)); tris.Reverse(); mesh.AddData(newEndVerts, newEndUVs, tris.ToArray(), 0); } } //Build ROOF DynamicMeshGenericMultiMaterialMesh dynMeshRoof = new DynamicMeshGenericMultiMaterialMesh(); dynMeshRoof.subMeshCount = data.textures.Count; BuildrRoof.Build(dynMeshRoof, data, true); mesh.AddData(dynMeshRoof.vertices, dynMeshRoof.uv, dynMeshRoof.triangles, 0); Vector3 foundationVector = Vector3.down * data.foundationHeight; //Build facades for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; for (int l = 0; l < numberOfVolumePoints; l++) { int indexA = l; int indexB = (l < numberOfVolumePoints - 1) ? l + 1 : 0; Vector3 p0 = plan.points[volume.points[indexA]].vector3; Vector3 p1 = plan.points[volume.points[indexB]].vector3; int floorBase = plan.GetFacadeFloorHeight(s, volume.points[indexA], volume.points[indexB]); int numberOfFloors = volume.numberOfFloors - floorBase; if (numberOfFloors < 1) { //no facade - adjacent facade is taller and covers this one continue; } float floorHeight = data.floorHeight; Vector3 floorHeightStart = Vector3.up * (floorBase * floorHeight); Vector3 wallHeight = Vector3.up * (volume.numberOfFloors * floorHeight) - floorHeightStart; p0 += floorHeightStart; p1 += floorHeightStart; Vector3 w0 = p0; Vector3 w1 = p1; Vector3 w2 = w0 + wallHeight; Vector3 w3 = w1 + wallHeight; if (floorBase == 0) { w0 += foundationVector; w1 += foundationVector; } mesh.AddPlane(w0, w1, w2, w3, Vector2.zero, Vector2.zero, 0); facadeIndex++; } } data = null; mesh = null; }
public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data) { data = _data; mesh = _mesh; BuildrPlan plan = data.plan; int facadeIndex = 0; int numberOfVolumes = data.plan.numberOfVolumes; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; Vector3[] newEndVerts = new Vector3[numberOfVolumePoints]; Vector2[] newEndUVs = new Vector2[numberOfVolumePoints]; Vector3 volumeHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight); for (int i = 0; i < numberOfVolumePoints; i++) { newEndVerts[i] = plan.points[volume.points[i]].vector3 + volumeHeight; newEndUVs[i] = Vector2.zero; } List <int> tris = new List <int>(data.plan.GetTrianglesBySectorBase(s)); mesh.AddData(newEndVerts, newEndUVs, tris.ToArray(), 0); } //Build ROOF //Build facades for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int numberOfVolumePoints = volume.points.Count; for (int f = 0; f < numberOfVolumePoints; f++) { if (!volume.renderFacade[f]) { continue; } int indexA = f; int indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0; Vector3 p0 = plan.points[volume.points[indexA]].vector3; Vector3 p1 = plan.points[volume.points[indexB]].vector3; int floorBase = plan.GetFacadeFloorHeight(v, volume.points[indexA], volume.points[indexB]); int numberOfFloors = volume.numberOfFloors - floorBase; if (numberOfFloors < 1) { //no facade - adjacent facade is taller and covers this one continue; } float floorHeight = data.floorHeight; Vector3 floorHeightStart = Vector3.up * (floorBase * floorHeight); Vector3 wallHeight = Vector3.up * (volume.numberOfFloors * floorHeight) - floorHeightStart; float facadeWidth = Vector3.Distance(p0, p1); p0 += floorHeightStart; p1 += floorHeightStart; Vector3 w0 = p0; Vector3 w1 = p1; Vector3 w2 = w0 + wallHeight; Vector3 w3 = w1 + wallHeight; Vector2 uvMin = new Vector2(0, 0); Vector2 uvMax = new Vector2(facadeWidth, floorHeight); mesh.AddPlane(w0, w1, w2, w3, uvMin, uvMax, 0); facadeIndex++; } } data = null; mesh = null; }