UNPKG

gpu-curtains

Version:

gpu-curtains is a 3D WebGPU rendering engine. It can be used as a standalone 3D engine, but also includes extra classes focused on mapping 3d objects to DOM elements; It allows users to synchronize values such as position, sizing, or scale between them.

118 lines (117 loc) 3.94 kB
import { IndexedGeometry } from "./IndexedGeometry.mjs"; //#region src/core/geometries/PlaneGeometry.ts /** * Used to create an indexed plane geometry based on the number of segments along the X and Y axis. * * This is how it will look for a 3x2 quad. Indexing will take care of drawing the right vertices in the right order. * * <pre> * 3---2---1---0 * | /| /| /| * |/ |/ |/ | * 7---6---5---4 * | /| /| /| * |/ |/ |/ | * 11--10--9---8 * </pre> * * @example * ```javascript * const planeGeometry = new PlaneGeometry() * ``` */ var PlaneGeometry = class extends IndexedGeometry { /** * PlaneGeometry constructor * @param parameters - {@link PlaneGeometryParams | parameters} used to create our PlaneGeometry */ constructor({ widthSegments = 1, heightSegments = 1, instancesCount = 1, vertexBuffers = [], topology } = {}) { super({ verticesOrder: "ccw", topology, instancesCount, vertexBuffers, mapBuffersAtCreation: true }); this.type = "PlaneGeometry"; widthSegments = Math.floor(widthSegments); heightSegments = Math.floor(heightSegments); this.definition = { id: widthSegments * heightSegments + widthSegments, width: widthSegments, height: heightSegments, count: widthSegments * heightSegments }; const verticesCount = (this.definition.width + 1) * (this.definition.height + 1); const attributes = this.getIndexedVerticesAndUVs(verticesCount); for (const attribute of Object.values(attributes)) this.setAttribute(attribute); this.setIndexArray(); } /** * Set our PlaneGeometry index array */ setIndexArray() { const indexArray = this.useUint16IndexArray ? new Uint16Array(this.definition.count * 6) : new Uint32Array(this.definition.count * 6); let index = 0; for (let y = 0; y < this.definition.height; y++) for (let x = 0; x < this.definition.width; x++) { indexArray[index++] = x + y * (this.definition.width + 1); indexArray[index++] = this.definition.width + x + 1 + y * (this.definition.width + 1); indexArray[index++] = x + 1 + y * (this.definition.width + 1); indexArray[index++] = x + 1 + y * (this.definition.width + 1); indexArray[index++] = this.definition.width + x + 1 + y * (this.definition.width + 1); indexArray[index++] = this.definition.width + x + 2 + y * (this.definition.width + 1); } this.setIndexBuffer({ array: indexArray, bufferFormat: this.useUint16IndexArray ? "uint16" : "uint32" }); } /** * Compute the UV and position arrays based on our plane widthSegments and heightSegments values and return the corresponding attributes * @param verticesCount - {@link Geometry#verticesCount | number of vertices} of our {@link PlaneGeometry} * @returns - our position and uv {@link VertexBufferAttributeParams | attributes} */ getIndexedVerticesAndUVs(verticesCount) { const uv = { name: "uv", type: "vec2f", bufferFormat: "float32x2", size: 2, array: new Float32Array(verticesCount * 2) }; const position = { name: "position", type: "vec3f", bufferFormat: "float32x3", size: 3, array: new Float32Array(verticesCount * 3) }; const normal = { name: "normal", type: "vec3f", bufferFormat: "float32x3", size: 3, array: new Float32Array(verticesCount * 3) }; let positionOffset = 0; let normalOffset = 0; let uvOffset = 0; for (let y = 0; y <= this.definition.height; y++) for (let x = 0; x <= this.definition.width; x++) { uv.array[uvOffset++] = 1 - x / this.definition.width; uv.array[uvOffset++] = 1 - y / this.definition.height; position.array[positionOffset++] = 1 - x * 2 / this.definition.width; position.array[positionOffset++] = y * 2 / this.definition.height - 1; position.array[positionOffset++] = 0; normal.array[normalOffset++] = 0; normal.array[normalOffset++] = 0; normal.array[normalOffset++] = 1; } return { position, uv, normal }; } }; //#endregion export { PlaneGeometry };