This question was asked many times on SO, but there hasn’t been any appropriate and simple solution so far. I can’t say though that mine is just what we need, but anyway, here it is. Based on the method .toGrid()
from this showcase Grids of Waves (shaders).
https://jsfiddle.net/prisoner849/8hqy99jj/
GridBoxGeometry
. Takes two parameters.
The first one geometry
is of the type THREE.BoxBufferGeometry
.
The second one independent
is optional boolean. Default value is false
. If set to true
, the resulting geometry will have a cloned copy of the buffer attribute position
from the first parameter, otherwise, it shares this attribute.
Criticism is very welcomed.
function GridBoxGeometry(geometry, independent) {
if (!(geometry instanceof THREE.BoxBufferGeometry)) {
console.log("GridBoxGeometry: the parameter 'geometry' has to be of the type THREE.BoxBufferGeometry");
return geometry;
}
independent = independent !== undefined ? independent : false;
let newGeometry = new THREE.BoxBufferGeometry();
let position = geometry.attributes.position;
newGeometry.attributes.position = independent === false ? position : position.clone();
let segmentsX = geometry.parameters.widthSegments || 1;
let segmentsY = geometry.parameters.heightSegments || 1;
let segmentsZ = geometry.parameters.depthSegments || 1;
let startIndex = 0;
let indexSide1 = indexSide(segmentsZ, segmentsY, startIndex);
startIndex += (segmentsZ + 1) * (segmentsY + 1);
let indexSide2 = indexSide(segmentsZ, segmentsY, startIndex);
startIndex += (segmentsZ + 1) * (segmentsY + 1);
let indexSide3 = indexSide(segmentsX, segmentsZ, startIndex);
startIndex += (segmentsX + 1) * (segmentsZ + 1);
let indexSide4 = indexSide(segmentsX, segmentsZ, startIndex);
startIndex += (segmentsX + 1) * (segmentsZ + 1);
let indexSide5 = indexSide(segmentsX, segmentsY, startIndex);
startIndex += (segmentsX + 1) * (segmentsY + 1);
let indexSide6 = indexSide(segmentsX, segmentsY, startIndex);
let fullIndices = [];
fullIndices = fullIndices.concat(indexSide1);
fullIndices = fullIndices.concat(indexSide2);
fullIndices = fullIndices.concat(indexSide3);
fullIndices = fullIndices.concat(indexSide4);
fullIndices = fullIndices.concat(indexSide5);
fullIndices = fullIndices.concat(indexSide6);
newGeometry.setIndex(fullIndices);
function indexSide(x, y, shift) {
let indices = [];
for (let i = 0; i < y + 1; i++) {
let index11 = 0;
let index12 = 0;
for (let j = 0; j < x; j++) {
index11 = (x + 1) * i + j;
index12 = index11 + 1;
let index21 = index11;
let index22 = index11 + (x + 1);
indices.push(shift + index11, shift + index12);
if (index22 < ((x + 1) * (y + 1) - 1)) {
indices.push(shift + index21, shift + index22);
}
}
if ((index12 + x + 1) <= ((x + 1) * (y + 1) - 1)) {
indices.push(shift + index12, shift + index12 + x + 1);
}
}
return indices;
}
return newGeometry;
};