const negInfinity = [-Infinity, -Infinity, -Infinity];
const posInfinity = [Infinity, Infinity, Infinity];
class BBox {
constructor(min = BBox.negInfinity, max = BBox.posInfinity) {
this.bounds = [BBox.negInfinity, BBox.posInfinity];
this.bounds[0] = min;
this.bounds[1] = max;
}
static create() {
return new BBox();
}
centroid() {
return [
(this.bounds[0][0] + this.bounds[1][0]) * 0.5,
(this.bounds[0][1] + this.bounds[1][1]) * 0.5,
(this.bounds[0][2] + this.bounds[1][2]) * 0.5,
];
}
extendBy(p) {
if (p[0] < this.bounds[0][0]) {
this.bounds[0][0] = p[0];
}
if (p[1] < this.bounds[0][1]) {
this.bounds[0][1] = p[1];
}
if (p[2] < this.bounds[0][2]) {
this.bounds[0][2] = p[2];
}
if (p[0] > this.bounds[1][0]) {
this.bounds[1][0] = p[0];
}
if (p[1] > this.bounds[1][1]) {
this.bounds[1][1] = p[1];
}
if (p[2] > this.bounds[1][2]) {
this.bounds[1][2] = p[2];
}
return this;
}
min() {
return this.bounds[0];
}
max() {
return this.bounds[1];
}
}
BBox.negInfinity = [-Infinity, -Infinity, -Infinity];
BBox.posInfinity = [Infinity, Infinity, Infinity];
class Extents {
constructor(numPlaneSetNormals = 7, op = createObjectPool(createMatrix3_1)) {
this.numPlaneSetNormals = numPlaneSetNormals;
this.op = op;
this.d = [];
for (let i = 0; i < numPlaneSetNormals; ++i) {
this.d[i] = [Infinity, -Infinity];
}
}
static create(numPlaneSetNormals = 7, op = createObjectPool(createMatrix3_1)) {
return new Extents(numPlaneSetNormals, op);
}
extendBy(e) {
for (let i = 0; i < this.numPlaneSetNormals; ++i) {
if (e.d[i][0] < this.d[i][0]) {
this.d[i][0] = e.d[i][0];
}
if (e.d[i][1] > this.d[i][1]) {
this.d[i][1] = e.d[i][1];
}
}
}
centroid() {
const ret = this.op.malloc();
ret[0] = this.d[0][0] + this.d[0][1] * 0.5;
ret[1] = this.d[1][0] + this.d[1][1] * 0.5;
ret[2] = this.d[2][0] + this.d[2][1] * 0.5;
return ret;
}
}
class OctreeNode {
constructor() {
this.child = [
null, null, null, null, null, null, null, null,
];
this.isLeaf = true;
this.nodeExtents = Extents.create();
this.nodeExtentsList = [];
}
static create() {
return new OctreeNode();
}
}
class Octree {
constructor(sceneExtents) {
this.bbox = BBox.create();
this.root = OctreeNode.create();
const xDiff = sceneExtents.d[0][1] - sceneExtents.d[0][0];
const yDiff = sceneExtents.d[1][1] - sceneExtents.d[1][0];
const zDiff = sceneExtents.d[2][1] - sceneExtents.d[2][0];
const maxDiff = Math.max(xDiff, Math.max(yDiff, zDiff));
const minPlusMax = [
sceneExtents.d[0][0] + sceneExtents.d[0][1],
sceneExtents.d[1][0] + sceneExtents.d[1][1],
sceneExtents.d[2][0] + sceneExtents.d[2][1],
];
this.bbox.bounds[0][0] = (minPlusMax[0] - maxDiff) * 0.5;
this.bbox.bounds[0][1] = (minPlusMax[1] - maxDiff) * 0.5;
this.bbox.bounds[0][2] = (minPlusMax[2] - maxDiff) * 0.5;
this.bbox.bounds[1][0] = (minPlusMax[0] + maxDiff) * 0.5;
this.bbox.bounds[1][1] = (minPlusMax[1] + maxDiff) * 0.5;
this.bbox.bounds[1][2] = (minPlusMax[2] + maxDiff) * 0.5;
}
static create(sceneExtents) {
return new Octree(sceneExtents);
}
_build(node, bbox) {
if (node.isLeaf) {
node.nodeExtentsList.forEach((e) => {
node.nodeExtents.extendBy(e);
});
}
else {
for (let i = 0; i < 8; ++i) {
const child = node.child[i];
if (child) {
const childBBox = BBox.create();
;
const centroid = bbox.centroid();