Spaces:
Running
Running
File size: 4,132 Bytes
2b7aae2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | 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 };
|