UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

242 lines 9.95 kB
import { Matrix, Vector3, Vector4 } from "../../Maths/math.vector.js"; import { Color4 } from "../../Maths/math.color.js"; import { Mesh } from "../mesh.js"; import { VertexData } from "../mesh.vertexData.js"; import { CreateTiledPlaneVertexData } from "./tiledPlaneBuilder.js"; import { useOpenGLOrientationForUV } from "../../Compat/compatibilityOptions.js"; const OP_ADD = 1; const OP_SUB = -1; /** * Creates the VertexData for a tiled box * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/tiled_box * @param options an object used to set the following optional parameters for the tiled box, required but can be empty * * pattern sets the rotation or reflection pattern for the tiles, * * size of the box * * width of the box, overwrites size * * height of the box, overwrites size * * depth of the box, overwrites size * * tileSize sets the size of a tile * * tileWidth sets the tile width and overwrites tileSize * * tileHeight sets the tile width and overwrites tileSize * * faceUV an array of 6 Vector4 elements used to set different images to each box side * * faceColors an array of 6 Color4 elements used to set different colors to each box side * * alignHorizontal places whole tiles aligned to the center, left or right of a row * * alignVertical places whole tiles aligned to the center, left or right of a column * @param options.pattern * @param options.size * @param options.width * @param options.height * @param options.depth * @param options.tileSize * @param options.tileWidth * @param options.tileHeight * @param options.faceUV * @param options.faceColors * @param options.alignHorizontal * @param options.alignVertical * @param options.sideOrientation * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE * @returns the VertexData of the TiledBox */ export function CreateTiledBoxVertexData(options) { const nbFaces = 6; const faceUV = options.faceUV || new Array(6); const faceColors = options.faceColors; const flipTile = options.pattern || Mesh.NO_FLIP; const width = options.width || options.size || 1; const height = options.height || options.size || 1; const depth = options.depth || options.size || 1; const tileWidth = options.tileWidth || options.tileSize || 1; const tileHeight = options.tileHeight || options.tileSize || 1; const alignH = options.alignHorizontal || 0; const alignV = options.alignVertical || 0; const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE; // default face colors and UV if undefined for (let f = 0; f < nbFaces; f++) { if (faceUV[f] === undefined) { faceUV[f] = new Vector4(0, 0, 1, 1); } if (faceColors && faceColors[f] === undefined) { faceColors[f] = new Color4(1, 1, 1, 1); } } const halfWidth = width / 2; const halfHeight = height / 2; const halfDepth = depth / 2; const faceVertexData = []; for (let f = 0; f < 2; f++) { //front and back faceVertexData[f] = CreateTiledPlaneVertexData({ pattern: flipTile, tileWidth: tileWidth, tileHeight: tileHeight, width: width, height: height, alignVertical: alignV, alignHorizontal: alignH, sideOrientation: sideOrientation, }); } for (let f = 2; f < 4; f++) { //sides faceVertexData[f] = CreateTiledPlaneVertexData({ pattern: flipTile, tileWidth: tileWidth, tileHeight: tileHeight, width: depth, height: height, alignVertical: alignV, alignHorizontal: alignH, sideOrientation: sideOrientation, }); } let baseAlignV = alignV; if (alignV === Mesh.BOTTOM) { baseAlignV = Mesh.TOP; } else if (alignV === Mesh.TOP) { baseAlignV = Mesh.BOTTOM; } for (let f = 4; f < 6; f++) { //top and bottom faceVertexData[f] = CreateTiledPlaneVertexData({ pattern: flipTile, tileWidth: tileWidth, tileHeight: tileHeight, width: width, height: depth, alignVertical: baseAlignV, alignHorizontal: alignH, sideOrientation: sideOrientation, }); } const positions = []; const normals = []; let uvs = []; let indices = []; const colors = []; const facePositions = []; const faceNormals = []; const newFaceUV = []; let lu = 0; let li = 0; for (let f = 0; f < nbFaces; f++) { const len = faceVertexData[f].positions.length; facePositions[f] = []; faceNormals[f] = []; for (let p = 0; p < len / 3; p++) { facePositions[f].push(new Vector3(faceVertexData[f].positions[3 * p], faceVertexData[f].positions[3 * p + 1], faceVertexData[f].positions[3 * p + 2])); faceNormals[f].push(new Vector3(faceVertexData[f].normals[3 * p], faceVertexData[f].normals[3 * p + 1], faceVertexData[f].normals[3 * p + 2])); } // uvs lu = faceVertexData[f].uvs.length; newFaceUV[f] = []; for (let i = 0; i < lu; i += 2) { newFaceUV[f][i] = faceUV[f].x + (faceUV[f].z - faceUV[f].x) * faceVertexData[f].uvs[i]; newFaceUV[f][i + 1] = faceUV[f].y + (faceUV[f].w - faceUV[f].y) * faceVertexData[f].uvs[i + 1]; if (useOpenGLOrientationForUV) { newFaceUV[f][i + 1] = 1.0 - newFaceUV[f][i + 1]; } } uvs = uvs.concat(newFaceUV[f]); indices = indices.concat(faceVertexData[f].indices.map((x) => x + li)); li += facePositions[f].length; if (faceColors) { const color = faceColors[f]; for (let p = 0; p < facePositions[f].length; p++) { colors.push(color.r, color.g, color.b, color.a); } } } // Define transforms for each face const faceTransforms = [ // FRONT { m: Matrix.RotationY(Math.PI), t: new Vector3(0, 0, halfDepth), op: OP_ADD }, // BACK { m: Matrix.Identity(), t: new Vector3(0, 0, halfDepth), op: OP_SUB }, // RIGHT { m: Matrix.RotationY(-Math.PI / 2), t: new Vector3(halfWidth, 0, 0), op: OP_ADD }, // LEFT { m: Matrix.RotationY(Math.PI / 2), t: new Vector3(halfWidth, 0, 0), op: OP_SUB }, // TOP { m: Matrix.RotationX(Math.PI / 2), t: new Vector3(0, halfHeight, 0), op: OP_ADD }, // BOTTOM { m: Matrix.RotationX(-Math.PI / 2), t: new Vector3(0, halfHeight, 0), op: OP_SUB }, ]; // Assemble positions and normals for (let f = 0; f < nbFaces; f++) { const { m, t, op } = faceTransforms[f]; for (const v of facePositions[f]) { const p = Vector3.TransformCoordinates(v, m); const final = op === OP_ADD ? p.add(t) : p.subtract(t); positions.push(final.x, final.y, final.z); } for (const n of faceNormals[f]) { const nn = Vector3.TransformNormal(n, m); normals.push(nn.x, nn.y, nn.z); } } // Result const vertexData = new VertexData(); vertexData.indices = indices; vertexData.positions = positions; vertexData.normals = normals; vertexData.uvs = uvs; if (faceColors) { const totalColors = sideOrientation === VertexData.DOUBLESIDE ? colors.concat(colors) : colors; vertexData.colors = totalColors; } return vertexData; } /** * Creates a tiled box mesh * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/tiled_box * @param name defines the name of the mesh * @param options an object used to set the following optional parameters for the tiled box, required but can be empty * * pattern sets the rotation or reflection pattern for the tiles, * * size of the box * * width of the box, overwrites size * * height of the box, overwrites size * * depth of the box, overwrites size * * tileSize sets the size of a tile * * tileWidth sets the tile width and overwrites tileSize * * tileHeight sets the tile width and overwrites tileSize * * faceUV an array of 6 Vector4 elements used to set different images to each box side * * faceColors an array of 6 Color3 elements used to set different colors to each box side * * alignHorizontal places whole tiles aligned to the center, left or right of a row * * alignVertical places whole tiles aligned to the center, left or right of a column * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE * @param options.pattern * @param options.width * @param options.height * @param options.depth * @param options.tileSize * @param options.tileWidth * @param options.tileHeight * @param options.alignHorizontal * @param options.alignVertical * @param options.faceUV * @param options.faceColors * @param options.sideOrientation * @param options.updatable * @param scene defines the hosting scene * @returns the box mesh */ export function CreateTiledBox(name, options, scene = null) { const box = new Mesh(name, scene); options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation); box._originalBuilderSideOrientation = options.sideOrientation; const vertexData = CreateTiledBoxVertexData(options); vertexData.applyToMesh(box, options.updatable); return box; } /** * Class containing static functions to help procedurally build meshes * @deprecated use CreateTiledBox instead */ export const TiledBoxBuilder = { // eslint-disable-next-line @typescript-eslint/naming-convention CreateTiledBox, }; VertexData.CreateTiledBox = CreateTiledBoxVertexData; //# sourceMappingURL=tiledBoxBuilder.js.map