Hello! I was asked by someone on SO to post this as a demo here. Here’s a simple way to make a 3D grid of lines from a grid of points, using the index
attribute of BufferGeometry
.
The interesting bit is:
let xSize = 3;
let ySize = 4;
let zSize = 5;
let n = xSize * ySize * zSize;
let geometry = new THREE.BufferGeometry();
function mapTo3D(i) {
let z = Math.floor(i / (xSize * ySize));
i -= z * xSize * ySize;
let y = Math.floor(i / xSize);
let x = i % xSize;
return { x: x, y: y, z: z };
}
function mapFrom3D(x, y, z) {
return x + y * xSize + z * xSize * ySize;
}
let positions = [];
for (let i = 0; i < n; i++) {
let p = mapTo3D(i);
positions.push((p.x - xSize / 2) / xSize);
positions.push((p.y - ySize / 2) / ySize);
positions.push((p.z - zSize / 2) / zSize);
}
let positionAttribute = new THREE.Float32BufferAttribute(positions, 3);
geometry.addAttribute("position", positionAttribute);
let indexPairs = [];
for (let i = 0; i < n; i++) {
let p = mapTo3D(i);
if (p.x + 1 < xSize) {
indexPairs.push(i);
indexPairs.push(mapFrom3D(p.x + 1, p.y, p.z));
}
if (p.y + 1 < ySize) {
indexPairs.push(i);
indexPairs.push(mapFrom3D(p.x, p.y + 1, p.z));
}
if (p.z + 1 < zSize) {
indexPairs.push(i);
indexPairs.push(mapFrom3D(p.x, p.y, p.z + 1));
}
}
geometry.setIndex(indexPairs);
let lines = new THREE.LineSegments(geometry, new THREE.LineBasicMaterial());
scene.add(lines);
A dynamic 2D grid would be very similar (simpler).
One example of this being useful is this thing I made.