@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
130 lines (109 loc) • 3.31 kB
JavaScript
import { Box3, BufferAttribute, BufferGeometry, Sphere, Vector3 } from "three";
/**
*
* @param {BinaryNode|LeafNode} tree
* @returns {BufferGeometry}
* @constructor
*/
function BVHGeometry(tree) {
//create array of positions
const aVertices = [];
let numVertices = 0;
const aIndices = [];
let numFaces = 0;
/**
*
* @param {number} x
* @param {number} y
* @param {number} z
* @returns {number}
*/
function makeVertex(x, y, z) {
aVertices.push(x);
aVertices.push(y);
aVertices.push(z);
return numVertices++;
}
/**
*
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
*/
function makeQuad(a, b, c, d) {
aIndices.push(a);
aIndices.push(b);
aIndices.push(c);
//
aIndices.push(a);
aIndices.push(c);
aIndices.push(d);
numFaces += 2;
}
/**
*
* @param {number} x0
* @param {number} y0
* @param {number} z0
* @param {number} x1
* @param {number} y1
* @param {number} z1
*/
function makeCube(x0, y0, z0, x1, y1, z1) {
//near
const ntl = makeVertex(x0, y0, z0),
nbl = makeVertex(x0, y1, z0),
nbr = makeVertex(x1, y1, z0),
ntr = makeVertex(x1, y0, z0), //far
ftl = makeVertex(x0, y0, z1),
fbl = makeVertex(x0, y1, z1),
fbr = makeVertex(x1, y1, z1),
ftr = makeVertex(x1, y0, z1);
//make faces
makeQuad(ntl, ntr, nbr, nbl); //near
makeQuad(fbl, fbr, ftr, ftl); //far
makeQuad(ftl, ftr, ntr, ntl); //top
makeQuad(nbl, nbr, fbr, fbl); //bottom
makeQuad(ftl, ntl, nbl, fbl); //left
makeQuad(fbr, nbr, ntr, ftr); //right
}
/**
*
* @param {BinaryNode|LeafNode} n
*/
function processNode(n) {
const x0 = n.x0;
const y0 = n.y0;
const z0 = n.z0;
const x1 = n.x1;
const y1 = n.y1;
const z1 = n.z1;
if (n.isBinaryNode) {
if (n.left !== null) {
processNode(n.left);
}
if (n.right !== null) {
processNode(n.right);
}
} else {
makeCube(x0, y0, z0, x1, y1, z1);
}
}
const root = tree;
processNode(root);
//convert positions and indices to buffer geometry
const positions = new Float32Array(numVertices * 3);
const indices = new Uint32Array(numFaces * 3);
//
//copy
positions.set(aVertices, 0);
indices.set(aIndices, 0);
const geometry = new BufferGeometry();
geometry.setIndex(new BufferAttribute(indices, 1));
geometry.setAttribute('position', new BufferAttribute(positions, 3));
const box3 = geometry.boundingBox = new Box3(new Vector3(root.x0, root.y0, root.z0), new Vector3(root.x1, root.y1, root.z1));
geometry.boundingSphere = new Sphere(box3.min.clone().add(box3.max).multiplyScalar(0.5), box3.max.clone().sub(box3.min).length());
return geometry;
}
export default BVHGeometry;