Spaces:
Sleeping
Sleeping
| import { BufferGeometry } from '../core/BufferGeometry.js'; | |
| import { Float32BufferAttribute } from '../core/BufferAttribute.js'; | |
| import { Vector3 } from '../math/Vector3.js'; | |
| class BoxGeometry extends BufferGeometry { | |
| constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { | |
| super(); | |
| this.type = 'BoxGeometry'; | |
| this.parameters = { | |
| width: width, | |
| height: height, | |
| depth: depth, | |
| widthSegments: widthSegments, | |
| heightSegments: heightSegments, | |
| depthSegments: depthSegments, | |
| }; | |
| const scope = this; | |
| // segments | |
| widthSegments = Math.floor(widthSegments); | |
| heightSegments = Math.floor(heightSegments); | |
| depthSegments = Math.floor(depthSegments); | |
| // buffers | |
| const indices = []; | |
| const vertices = []; | |
| const normals = []; | |
| const uvs = []; | |
| // helper variables | |
| let numberOfVertices = 0; | |
| let groupStart = 0; | |
| // build each side of the box geometry | |
| buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px | |
| buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx | |
| buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py | |
| buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny | |
| buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz | |
| buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz | |
| // build geometry | |
| this.setIndex(indices); | |
| this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); | |
| this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); | |
| this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); | |
| function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) { | |
| const segmentWidth = width / gridX; | |
| const segmentHeight = height / gridY; | |
| const widthHalf = width / 2; | |
| const heightHalf = height / 2; | |
| const depthHalf = depth / 2; | |
| const gridX1 = gridX + 1; | |
| const gridY1 = gridY + 1; | |
| let vertexCounter = 0; | |
| let groupCount = 0; | |
| const vector = new Vector3(); | |
| // generate vertices, normals and uvs | |
| for (let iy = 0; iy < gridY1; iy++) { | |
| const y = iy * segmentHeight - heightHalf; | |
| for (let ix = 0; ix < gridX1; ix++) { | |
| const x = ix * segmentWidth - widthHalf; | |
| // set values to correct vector component | |
| vector[u] = x * udir; | |
| vector[v] = y * vdir; | |
| vector[w] = depthHalf; | |
| // now apply vector to vertex buffer | |
| vertices.push(vector.x, vector.y, vector.z); | |
| // set values to correct vector component | |
| vector[u] = 0; | |
| vector[v] = 0; | |
| vector[w] = depth > 0 ? 1 : -1; | |
| // now apply vector to normal buffer | |
| normals.push(vector.x, vector.y, vector.z); | |
| // uvs | |
| uvs.push(ix / gridX); | |
| uvs.push(1 - iy / gridY); | |
| // counters | |
| vertexCounter += 1; | |
| } | |
| } | |
| // indices | |
| // 1. you need three indices to draw a single face | |
| // 2. a single segment consists of two faces | |
| // 3. so we need to generate six (2*3) indices per segment | |
| for (let iy = 0; iy < gridY; iy++) { | |
| for (let ix = 0; ix < gridX; ix++) { | |
| const a = numberOfVertices + ix + gridX1 * iy; | |
| const b = numberOfVertices + ix + gridX1 * (iy + 1); | |
| const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); | |
| const d = numberOfVertices + (ix + 1) + gridX1 * iy; | |
| // faces | |
| indices.push(a, b, d); | |
| indices.push(b, c, d); | |
| // increase counter | |
| groupCount += 6; | |
| } | |
| } | |
| // add a group to the geometry. this will ensure multi material support | |
| scope.addGroup(groupStart, groupCount, materialIndex); | |
| // calculate new start value for groups | |
| groupStart += groupCount; | |
| // update total number of vertices | |
| numberOfVertices += vertexCounter; | |
| } | |
| } | |
| static fromJSON(data) { | |
| return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); | |
| } | |
| } | |
| export { BoxGeometry, BoxGeometry as BoxBufferGeometry }; | |