Skip to content

Instantly share code, notes, and snippets.

@sorab2142
Last active September 30, 2019 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sorab2142/a95995224ebc936b02179945ee5775d0 to your computer and use it in GitHub Desktop.
Save sorab2142/a95995224ebc936b02179945ee5775d0 to your computer and use it in GitHub Desktop.
Port of wallBuilder and buildHouseFromFloorPlan to Typescript - BabylonJS
import { Vector3, Scene, Vector4, Color4, PolygonMeshBuilder, Vector2, VertexData, Mesh } from '@babylonjs/core/Legacy/legacy';
import earcut from 'earcut';
export const corner = (x: number, y: number) => {
return new Vector3(x, 0, y);
}
class door {
constructor(public width: number, public height: number) { }
}
class doorSpace {
constructor(public door: door, public left: number) { }
}
class window {
constructor(
public width: number,
public height: number,
public left: number = 0,
public bottom: number = 0) { }
}
class windowSpace {
constructor(public window: window, public left: number, public top: number) { }
}
class wall {
constructor(public corner: Vector3, public doorSpaces: doorSpace[], public windowSpaces: windowSpace[]) { }
}
PolygonMeshBuilder.prototype.wallBuilder = function (w0: any, w1: any) {
var positions: any = [];
var iuvs = [];
var euvs = [];
var icolors = [];
var ecolors = [];
var direction = w1.corner.subtract(w0.corner).normalize();
var angle = Math.acos(direction.x);
if (direction.z != 0) {
angle *= direction.z / Math.abs(direction.z);
}
this.points.elements.forEach(function (p: any) {
positions.push(p.x * Math.cos(angle) + w0.corner.x, p.y, p.x * Math.sin(angle) + w0.corner.z);
});
var indices = [];
var res = earcut(this.epoints, this.eholes, 2);
for (var i = res.length; i > 0; i--) {
indices.push(res[i - 1]);
};
return { positions: positions, indices: indices };
}
export const buildFromPlan = (walls: wall[], ply: number, height: number, options: any, scene: Scene) => {
//Arrays for vertex positions and indices
var positions: any = [];
var indices: any = [];
var uvs = [];
var colors = [];
var interiorUV = options.interiorUV || new Vector4(0, 0, 1, 1);
var exteriorUV = options.exteriorUV || new Vector4(0, 0, 1, 1);
var interiorColor = options.interiorColor || new Color4(1, 1, 1, 1);
var exteriorColor = options.exteriorColor || new Color4(1, 1, 1, 1);
var interior = options.interior || false;
if (!interior) {
walls.push(walls[0]);
}
var interiorIndex;
//Arrays to hold wall corner data
var innerBaseCorners = [];
var outerBaseCorners = [];
var innerTopCorners = [];
var outerTopCorners = [];
var innerDoorCorners = [];
var outerDoorCorners = [];
var innerWindowCorners = [];
var outerWindowCorners = [];
var angle = 0;
var direction = 0;
var line = Vector3.Zero();
var nextLine = Vector3.Zero();
var nbWalls = walls.length;
var lineNormal = new Vector3;
if (nbWalls === 2) {
walls[1].corner.subtractToRef(walls[0].corner, line);
lineNormal = new Vector3(line.z, 0, -1 * line.x).normalize();
line.normalize();
innerBaseCorners[0] = walls[0].corner;
outerBaseCorners[0] = walls[0].corner.add(lineNormal.scale(ply));
innerBaseCorners[1] = walls[1].corner;
outerBaseCorners[1] = walls[1].corner.add(lineNormal.scale(ply));
} else if (nbWalls > 2) {
for (var w = 0; w < nbWalls - 1; w++) {
walls[w + 1].corner.subtractToRef(walls[w].corner, nextLine);
angle = Math.PI - Math.acos(Vector3.Dot(line, nextLine) / (line.length() * nextLine.length()));
direction = Vector3.Cross(nextLine, line).normalize().y;
lineNormal = new Vector3(line.z, 0, -1 * line.x).normalize();
line.normalize();
innerBaseCorners[w] = walls[w].corner
outerBaseCorners[w] = walls[w].corner.add(lineNormal.scale(ply)).add(line.scale(direction * ply / Math.tan(angle / 2)));
line = nextLine.clone();
}
if (interior) {
lineNormal = new Vector3(line.z, 0, -1 * line.x).normalize();
line.normalize();
innerBaseCorners[nbWalls - 1] = walls[nbWalls - 1].corner
outerBaseCorners[nbWalls - 1] = walls[nbWalls - 1].corner.add(lineNormal.scale(ply));
walls[1].corner.subtractToRef(walls[0].corner, line);
lineNormal = new Vector3(line.z, 0, -1 * line.x).normalize();
line.normalize();
innerBaseCorners[0] = walls[0].corner;
outerBaseCorners[0] = walls[0].corner.add(lineNormal.scale(ply));
} else {
walls[1].corner.subtractToRef(walls[0].corner, nextLine);
angle = Math.PI - Math.acos(Vector3.Dot(line, nextLine) / (line.length() * nextLine.length()));
direction = Vector3.Cross(nextLine, line).normalize().y;
lineNormal = new Vector3(line.z, 0, -1 * line.x).normalize();
line.normalize();
innerBaseCorners[0] = walls[0].corner
outerBaseCorners[0] = walls[0].corner.add(lineNormal.scale(ply)).add(line.scale(direction * ply / Math.tan(angle / 2)));
innerBaseCorners[nbWalls - 1] = innerBaseCorners[0];
outerBaseCorners[nbWalls - 1] = outerBaseCorners[0]
}
}
// inner and outer top corners
for (var w = 0; w < nbWalls; w++) {
innerTopCorners.push(new Vector3(innerBaseCorners[w].x, height, innerBaseCorners[w].z));
outerTopCorners.push(new Vector3(outerBaseCorners[w].x, height, outerBaseCorners[w].z));
}
var maxL = 0;
for (w = 0; w < nbWalls - 1; w++) {
maxL = Math.max(innerBaseCorners[w + 1].subtract(innerBaseCorners[w]).length(), maxL);
}
var maxH = height;
// for when gables introduced
/******House Mesh Construction********/
// Wall Construction
var polygonCorners;
var polygonTriangulation: PolygonMeshBuilder;
var wallData;
var wallDirection = Vector3.Zero();
var wallNormal = Vector3.Zero();
var wallLength: number;
var exteriorWallLength;
var doorData;
var windowData;
var uvx, uvy;
var wallDiff: number;
var compareLeft = function (a: any, b: any) {
return a.left - b.left
}
for (var w = 0; w < nbWalls - 1; w++) {
walls[w + 1].corner.subtractToRef(walls[w].corner, wallDirection);
wallLength = wallDirection.length();
wallDirection.normalize();
wallNormal.x = wallDirection.z;
wallNormal.z = -1 * wallDirection.x;
exteriorWallLength = outerBaseCorners[w + 1].subtract(outerBaseCorners[w]).length();
wallDiff = exteriorWallLength - wallLength;
var gableHeight = 0;
//doors
if (walls[w].doorSpaces) {
walls[w].doorSpaces.sort(compareLeft);
}
var doors = walls[w].doorSpaces.length;
//Construct INNER wall polygon starting from (0, 0) using wall length and height and door data
polygonCorners = [];
polygonCorners.push(new Vector2(0, 0));
for (var d = 0; d < doors; d++) {
polygonCorners.push(new Vector2(walls[w].doorSpaces[d].left, 0));
polygonCorners.push(new Vector2(walls[w].doorSpaces[d].left, walls[w].doorSpaces[d].door.height));
polygonCorners.push(new Vector2(walls[w].doorSpaces[d].left + walls[w].doorSpaces[d].door.width, walls[w].doorSpaces[d].door.height));
polygonCorners.push(new Vector2(walls[w].doorSpaces[d].left + walls[w].doorSpaces[d].door.width, 0));
}
polygonCorners.push(new Vector2(wallLength, 0));
polygonCorners.push(new Vector2(wallLength, height));
polygonCorners.push(new Vector2(0, height));
//Construct triangulation of polygon using its corners
polygonTriangulation = new PolygonMeshBuilder("", polygonCorners, scene);
//windows
//Construct holes and add to polygon from window data
var windows = walls[w].windowSpaces.length;
var holes = [];
for (var ws = 0; ws < windows; ws++) {
var holeData = [];
holeData.push(new Vector2(walls[w].windowSpaces[ws].left, height - walls[w].windowSpaces[ws].top - walls[w].windowSpaces[ws].window.height));
holeData.push(new Vector2(walls[w].windowSpaces[ws].left + walls[w].windowSpaces[ws].window.width, height - walls[w].windowSpaces[ws].top - walls[w].windowSpaces[ws].window.height));
holeData.push(new Vector2(walls[w].windowSpaces[ws].left + walls[w].windowSpaces[ws].window.width, height - walls[w].windowSpaces[ws].top));
holeData.push(new Vector2(walls[w].windowSpaces[ws].left, height - walls[w].windowSpaces[ws].top));
holes.push(holeData);
}
for (var h = 0; h < holes.length; h++) {
polygonTriangulation.addHole(holes[h]);
}
// wallBuilder produces wall vertex positions array and indices using the current and next wall to rotate and translate vertex positions to correct place
wallData = polygonTriangulation.wallBuilder(walls[w], walls[w + 1]);
var nbIndices = positions.length / 3;
// current number of indices
var polyPositions = polygonTriangulation.buildVertexData().positions as [];
for (var p = 0; p < polyPositions.length / 3; p++) {
uvx = interiorUV.x + polyPositions[3 * p] * (interiorUV.z - interiorUV.x) / maxL;
uvy = interiorUV.y + polyPositions[3 * p + 1] * (interiorUV.w - interiorUV.y) / height;
uvs.push(uvx, uvy);
colors.push(interiorColor.r, interiorColor.g, interiorColor.b, interiorColor.a);
};
//Add inner wall positions (repeated for flat shaded mesh)
positions = positions.concat(wallData.positions);
interiorIndex = positions.length / 3;
indices = indices.concat(wallData.indices.map(function (idx: number) {
return idx + nbIndices;
}));
//wallData has format for inner wall [base left, 0 or more doors, base right, top right, top left, windows]
//extract door and wall data
windowData = wallData.positions.slice(12 * (doors + 1));
//4 entries per door + 4 entries for wall corners, each entry has 3 data points
doorData = wallData.positions.slice(3, 3 * (4 * doors + 1));
//For each inner door save corner as an array of four Vector3s, base left, top left, top right, base right
//Extend door data outwards by ply and save outer door corners
var doorCornersIn = [];
var doorCornersOut = [];
for (var p = 0; p < doorData.length / 12; p++) {
var doorsIn = [];
var doorsOut = [];
for (var d = 0; d < 4; d++) {
doorsIn.push(new Vector3(doorData[3 * d + 12 * p], doorData[3 * d + 12 * p + 1], doorData[3 * d + 12 * p + 2]));
doorData[3 * d + 12 * p] += ply * wallNormal.x;
doorData[3 * d + 12 * p + 2] += ply * wallNormal.z;
doorsOut.push(new Vector3(doorData[3 * d + 12 * p], doorData[3 * d + 12 * p + 1], doorData[3 * d + 12 * p + 2]));
}
doorCornersIn.push(doorsIn);
doorCornersOut.push(doorsOut);
}
innerDoorCorners.push(doorCornersIn);
outerDoorCorners.push(doorCornersOut);
//For each inner window save corner as an array of four Vector3s, base left, top left, top right, base right
//Extend window data outwards by ply and save outer window corners
var windowCornersIn = [];
var windowCornersOut = [];
for (var p = 0; p < windowData.length / 12; p++) {
var windowsIn = [];
var windowsOut = [];
for (var d = 0; d < 4; d++) {
windowsIn.push(new Vector3(windowData[3 * d + 12 * p], windowData[3 * d + 12 * p + 1], windowData[3 * d + 12 * p + 2]));
windowData[3 * d + 12 * p] += ply * wallNormal.x;
windowData[3 * d + 12 * p + 2] += ply * wallNormal.z;
windowsOut.push(new Vector3(windowData[3 * d + 12 * p], windowData[3 * d + 12 * p + 1], windowData[3 * d + 12 * p + 2]));
}
windowCornersIn.push(windowsIn);
windowCornersOut.push(windowsOut);
}
innerWindowCorners.push(windowCornersIn);
outerWindowCorners.push(windowCornersOut);
//Construct OUTER wall facet positions from inner wall
//Add outer wall corner positions back to wallData positions
wallData.positions = [];
wallData.positions.push(outerBaseCorners[w].x, outerBaseCorners[w].y, outerBaseCorners[w].z);
wallData.positions = wallData.positions.concat(doorData);
wallData.positions.push(outerBaseCorners[w + 1].x, outerBaseCorners[w + 1].y, outerBaseCorners[(w + 1) % nbWalls].z);
wallData.positions.push(outerTopCorners[w + 1].x, outerTopCorners[w + 1].y, outerTopCorners[(w + 1) % nbWalls].z);
wallData.positions.push(outerTopCorners[w].x, outerTopCorners[w].y, outerTopCorners[w].z);
wallData.positions = wallData.positions.concat(windowData);
//Calulate exterior wall uvs
for (var p = 0; p < polyPositions.length / 3; p++) {
if (polyPositions[3 * p] == 0) {
uvx = exteriorUV.x;
}
else if (wallLength - polyPositions[3 * p] < 0.000001) {
uvx = exteriorUV.x + (wallDiff + polyPositions[3 * p]) * (exteriorUV.z - exteriorUV.x) / (maxL + wallDiff)
}
else {
uvx = exteriorUV.x + (0.5 * wallDiff + polyPositions[3 * p]) * (exteriorUV.z - exteriorUV.x) / (maxL + wallDiff);
}
uvy = exteriorUV.y + polyPositions[3 * p + 1] * (exteriorUV.w - exteriorUV.y) / height;
uvs.push(uvx, uvy);
};
nbIndices = positions.length / 3;
// current number of indices
//Add outer wall positions, uvs and colors (repeated for flat shaded mesh)
positions = positions.concat(wallData.positions);
//Reverse indices for correct normals
wallData.indices.reverse();
indices = indices.concat(wallData.indices.map(function (idx: number) {
return idx + nbIndices;
}));
//Construct facets for base and door top and door sides, repeating positions for flatshaded mesh
var doorsRemaining = doors;
var doorNb = 0;
if (doorsRemaining > 0) {
//base
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerBaseCorners[w].x, innerBaseCorners[w].y, innerBaseCorners[w].z);
//tl
positions.push(outerBaseCorners[w].x, outerBaseCorners[w].y, outerBaseCorners[w].z);
//bl
positions.push(innerDoorCorners[w][doorNb][0].x, innerDoorCorners[w][doorNb][0].y, innerDoorCorners[w][doorNb][0].z);
//tr
positions.push(outerDoorCorners[w][doorNb][0].x, outerDoorCorners[w][doorNb][0].y, outerDoorCorners[w][doorNb][0].z);
//br
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].doorSpaces[doorNb].left / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].doorSpaces[doorNb].left / maxL, exteriorUV.y);
//base right
indices.push(nbIndices, nbIndices + 2, nbIndices + 3, nbIndices + 3, nbIndices + 1, nbIndices);
//left side
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerDoorCorners[w][doorNb][0].x, innerDoorCorners[w][doorNb][0].y, innerDoorCorners[w][doorNb][0].z);
//br
positions.push(innerDoorCorners[w][doorNb][1].x, innerDoorCorners[w][doorNb][1].y, innerDoorCorners[w][doorNb][1].z);
//tr
positions.push(outerDoorCorners[w][doorNb][0].x, outerDoorCorners[w][doorNb][0].y, outerDoorCorners[w][doorNb][0].z);
//bl
positions.push(outerDoorCorners[w][doorNb][1].x, outerDoorCorners[w][doorNb][1].y, outerDoorCorners[w][doorNb][1].z);
//tl
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top right
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top Left
indices.push(nbIndices, nbIndices + 1, nbIndices + 3, nbIndices, nbIndices + 3, nbIndices + 2);
//top
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerDoorCorners[w][doorNb][1].x, innerDoorCorners[w][doorNb][1].y, innerDoorCorners[w][doorNb][1].z);
//bl
positions.push(innerDoorCorners[w][doorNb][2].x, innerDoorCorners[w][doorNb][2].y, innerDoorCorners[w][doorNb][2].z);
//br
positions.push(outerDoorCorners[w][doorNb][1].x, outerDoorCorners[w][doorNb][1].y, outerDoorCorners[w][doorNb][1].z);
//tl
positions.push(outerDoorCorners[w][doorNb][2].x, outerDoorCorners[w][doorNb][2].y, outerDoorCorners[w][doorNb][2].z);
//tr
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].doorSpaces[doorNb].door.width / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].doorSpaces[doorNb].door.width / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
indices.push(nbIndices + 2, nbIndices + 1, nbIndices + 3, nbIndices + 2, nbIndices, nbIndices + 1);
//right side
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerDoorCorners[w][doorNb][2].x, innerDoorCorners[w][doorNb][2].y, innerDoorCorners[w][doorNb][2].z);
//tl
positions.push(innerDoorCorners[w][doorNb][3].x, innerDoorCorners[w][doorNb][3].y, innerDoorCorners[w][doorNb][3].z);
//bl
positions.push(outerDoorCorners[w][doorNb][2].x, outerDoorCorners[w][doorNb][2].y, outerDoorCorners[w][doorNb][2].z);
//tr
positions.push(outerDoorCorners[w][doorNb][3].x, outerDoorCorners[w][doorNb][3].y, outerDoorCorners[w][doorNb][3].z);
//br
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top Left
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top right
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y);
//base right
indices.push(nbIndices, nbIndices + 3, nbIndices + 2, nbIndices, nbIndices + 1, nbIndices + 3);
}
doorsRemaining--
doorNb++
while (doorsRemaining > 0) {
//base
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerDoorCorners[w][doorNb - 1][3].x, innerDoorCorners[w][doorNb - 1][3].y, innerDoorCorners[w][doorNb - 1][3].z);
//bl
positions.push(innerDoorCorners[w][doorNb][0].x, innerDoorCorners[w][doorNb][0].y, innerDoorCorners[w][doorNb][0].z);
//br
positions.push(outerDoorCorners[w][doorNb - 1][3].x, outerDoorCorners[w][doorNb - 1][3].y, outerDoorCorners[w][doorNb - 1][3].z);
//tl
positions.push(outerDoorCorners[w][doorNb][0].x, outerDoorCorners[w][doorNb][0].y, outerDoorCorners[w][doorNb][0].z);
//tr
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * (walls[w].doorSpaces[doorNb].left - (walls[w].doorSpaces[doorNb - 1].left + walls[w].doorSpaces[doorNb - 1].door.width)) / maxL / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * (walls[w].doorSpaces[doorNb].left - (walls[w].doorSpaces[doorNb - 1].left + walls[w].doorSpaces[doorNb - 1].door.width)) / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
indices.push(nbIndices, nbIndices + 1, nbIndices + 3, nbIndices + 3, nbIndices + 2, nbIndices);
//left side
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerDoorCorners[w][doorNb][0].x, innerDoorCorners[w][doorNb][0].y, innerDoorCorners[w][doorNb][0].z);
//br
positions.push(innerDoorCorners[w][doorNb][1].x, innerDoorCorners[w][doorNb][1].y, innerDoorCorners[w][doorNb][1].z);
//tr
positions.push(outerDoorCorners[w][doorNb][0].x, outerDoorCorners[w][doorNb][0].y, outerDoorCorners[w][doorNb][0].z);
//bl
positions.push(outerDoorCorners[w][doorNb][1].x, outerDoorCorners[w][doorNb][1].y, outerDoorCorners[w][doorNb][1].z);
//tl
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top right
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top Left
indices.push(nbIndices, nbIndices + 1, nbIndices + 3, nbIndices, nbIndices + 3, nbIndices + 2);
//top
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerDoorCorners[w][doorNb][1].x, innerDoorCorners[w][doorNb][1].y, innerDoorCorners[w][doorNb][1].z);
//bl
positions.push(innerDoorCorners[w][doorNb][2].x, innerDoorCorners[w][doorNb][2].y, innerDoorCorners[w][doorNb][2].z);
//br
positions.push(outerDoorCorners[w][doorNb][1].x, outerDoorCorners[w][doorNb][1].y, outerDoorCorners[w][doorNb][1].z);
//tl
positions.push(outerDoorCorners[w][doorNb][2].x, outerDoorCorners[w][doorNb][2].y, outerDoorCorners[w][doorNb][2].z);
//tr
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].doorSpaces[doorNb].door.width / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].doorSpaces[doorNb].door.width / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
indices.push(nbIndices + 2, nbIndices + 1, nbIndices + 3, nbIndices + 2, nbIndices, nbIndices + 1);
//right side
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerDoorCorners[w][doorNb][2].x, innerDoorCorners[w][doorNb][2].y, innerDoorCorners[w][doorNb][2].z);
//tl
positions.push(innerDoorCorners[w][doorNb][3].x, innerDoorCorners[w][doorNb][3].y, innerDoorCorners[w][doorNb][3].z);
//bl
positions.push(outerDoorCorners[w][doorNb][2].x, outerDoorCorners[w][doorNb][2].y, outerDoorCorners[w][doorNb][2].z);
//tr
positions.push(outerDoorCorners[w][doorNb][3].x, outerDoorCorners[w][doorNb][3].y, outerDoorCorners[w][doorNb][3].z);
//br
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top Left
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].doorSpaces[doorNb].door.height / maxH);
//top right
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y);
//base right
indices.push(nbIndices, nbIndices + 3, nbIndices + 2, nbIndices, nbIndices + 1, nbIndices + 3);
doorsRemaining--
doorNb++
}
doorNb--;
nbIndices = positions.length / 3;
// current number of indices
//final base
if (doors > 0) {
positions.push(innerDoorCorners[w][doorNb][3].x, innerDoorCorners[w][doorNb][3].y, innerDoorCorners[w][doorNb][3].z);
//bl
positions.push(innerBaseCorners[w + 1].x, innerBaseCorners[w + 1].y, innerBaseCorners[w + 1].z);
//br
positions.push(outerDoorCorners[w][doorNb][3].x, outerDoorCorners[w][doorNb][3].y, outerDoorCorners[w][doorNb][3].z);
//tl
positions.push(outerBaseCorners[w + 1].x, outerBaseCorners[w + 1].y, outerBaseCorners[w + 1].z);
//tr
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * (wallLength - (walls[w].doorSpaces[doorNb].left + walls[w].doorSpaces[doorNb].door.width)) / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * (wallLength - (walls[w].doorSpaces[doorNb].left + walls[w].doorSpaces[doorNb].door.width)) / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
} else {
positions.push(innerBaseCorners[w].x, innerBaseCorners[w].y, innerBaseCorners[w].z);
//bl
positions.push(innerBaseCorners[w + 1].x, innerBaseCorners[w + 1].y, innerBaseCorners[w + 1].z);
//br
positions.push(outerBaseCorners[w].x, outerBaseCorners[w].y, outerBaseCorners[w].z);
//tl
positions.push(outerBaseCorners[w + 1].x, outerBaseCorners[w + 1].y, outerBaseCorners[w + 1].z);
//tr
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * wallLength / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * wallLength / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
}
indices.push(nbIndices, nbIndices + 1, nbIndices + 3, nbIndices + 3, nbIndices + 2, nbIndices);
//Construct facets for window base, top and sides, repeating positions for flatshaded mesh
for (let ww = 0; ww < innerWindowCorners[w].length; ww++) {
//left side
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerWindowCorners[w][ww][3].x, innerWindowCorners[w][ww][3].y, innerWindowCorners[w][ww][3].z);
//tr
positions.push(innerWindowCorners[w][ww][0].x, innerWindowCorners[w][ww][0].y, innerWindowCorners[w][ww][0].z);
//br
positions.push(outerWindowCorners[w][ww][3].x, outerWindowCorners[w][ww][3].y, outerWindowCorners[w][ww][3].z);
//tl
positions.push(outerWindowCorners[w][ww][0].x, outerWindowCorners[w][ww][0].y, outerWindowCorners[w][ww][0].z);
//bl
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].windowSpaces[ww].window.height / maxH);
//top right
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].windowSpaces[ww].window.height / maxH);
//top Left
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
indices.push(nbIndices + 1, nbIndices, nbIndices + 3, nbIndices + 2, nbIndices + 3, nbIndices);
//base
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerWindowCorners[w][ww][0].x, innerWindowCorners[w][ww][0].y, innerWindowCorners[w][ww][0].z);
//tl
positions.push(innerWindowCorners[w][ww][1].x, innerWindowCorners[w][ww][1].y, innerWindowCorners[w][ww][1].z);
//tr
positions.push(outerWindowCorners[w][ww][0].x, outerWindowCorners[w][ww][0].y, outerWindowCorners[w][ww][0].z);
//bl
positions.push(outerWindowCorners[w][ww][1].x, outerWindowCorners[w][ww][1].y, outerWindowCorners[w][ww][1].z);
//br
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].windowSpaces[ww].window.width / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].windowSpaces[ww].window.width / maxL, exteriorUV.y);
//base right
indices.push(nbIndices + 1, nbIndices, nbIndices + 3, nbIndices + 3, nbIndices, nbIndices + 2);
//right side
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerWindowCorners[w][ww][1].x, innerWindowCorners[w][ww][1].y, innerWindowCorners[w][ww][1].z);
//bl
positions.push(innerWindowCorners[w][ww][2].x, innerWindowCorners[w][ww][2].y, innerWindowCorners[w][ww][2].z);
//tl
positions.push(outerWindowCorners[w][ww][1].x, outerWindowCorners[w][ww][1].y, outerWindowCorners[w][ww][1].z);
//br
positions.push(outerWindowCorners[w][ww][2].x, outerWindowCorners[w][ww][2].y, outerWindowCorners[w][ww][2].z);
//tr
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].windowSpaces[ww].window.height / maxH);
//top Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * ply / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x), exteriorUV.y + (exteriorUV.w - exteriorUV.y) * walls[w].windowSpaces[ww].window.height / maxH);
//top right
indices.push(nbIndices + 1, nbIndices + 2, nbIndices + 3, nbIndices, nbIndices + 2, nbIndices + 1);
//top
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerWindowCorners[w][ww][2].x, innerWindowCorners[w][ww][2].y, innerWindowCorners[w][ww][2].z);
//br
positions.push(innerWindowCorners[w][ww][3].x, innerWindowCorners[w][ww][3].y, innerWindowCorners[w][ww][3].z);
//bl
positions.push(outerWindowCorners[w][ww][2].x, outerWindowCorners[w][ww][2].y, outerWindowCorners[w][ww][2].z);
//tr
positions.push(outerWindowCorners[w][ww][3].x, outerWindowCorners[w][ww][3].y, outerWindowCorners[w][ww][3].z);
//tl
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].windowSpaces[ww].window.width / maxL, exteriorUV.y);
//base right
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * walls[w].windowSpaces[ww].window.width / maxL, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
uvs.push(exteriorUV.x, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
indices.push(nbIndices + 3, nbIndices, nbIndices + 2, nbIndices + 1, nbIndices, nbIndices + 3);
}
//Construction of top of wall facets
nbIndices = positions.length / 3;
// current number of indices
positions.push(innerTopCorners[w].x, innerTopCorners[w].y, innerTopCorners[w].z);
//tl
positions.push(innerTopCorners[w + 1].x, innerTopCorners[w + 1].y, innerTopCorners[w + 1].z);
//tr
positions.push(outerTopCorners[w].x, outerTopCorners[w].y, outerTopCorners[w].z);
//bl
positions.push(outerTopCorners[w + 1].x, outerTopCorners[w + 1].y, outerTopCorners[w + 1].z);
//br
uvx = exteriorUV.x + 0.5 * wallDiff * (exteriorUV.z - exteriorUV.x) / maxL;
uvs.push(uvx, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top Left
uvx = exteriorUV.x + (0.5 * wallDiff + wallLength) * (exteriorUV.z - exteriorUV.x) / maxL;
uvs.push(uvx, exteriorUV.y + (exteriorUV.w - exteriorUV.y) * ply / maxH);
//top right
uvs.push(exteriorUV.x, exteriorUV.y);
//base Left
uvs.push(exteriorUV.x + (exteriorUV.z - exteriorUV.x) * exteriorWallLength / (maxL + wallDiff), exteriorUV.y);
//base right
indices.push(nbIndices + 1, nbIndices, nbIndices + 3, nbIndices + 2, nbIndices + 3, nbIndices);
for (var p = interiorIndex; p < positions.length / 3; p++) {
colors.push(exteriorColor.r, exteriorColor.g, exteriorColor.b, exteriorColor.a);
}
}
var normals: any = [];
VertexData.ComputeNormals(positions, indices, normals);
VertexData._ComputeSides(Mesh.FRONTSIDE, positions, indices, normals, uvs);
//Create a custom mesh
var customMesh = new Mesh("custom", scene);
//Create a vertexData object
var vertexData = new VertexData();
//Assign positions and indices to vertexData
vertexData.positions = positions;
vertexData.indices = indices;
vertexData.normals = normals;
vertexData.uvs = uvs;
vertexData.colors = colors;
//Apply vertexData to custom mesh
vertexData.applyToMesh(customMesh);
return customMesh;
}
//***********************************************************************************
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment