src/viewer/scene/math/Frustum.js
import {math} from "./math.js";
const tempVec3a = math.vec3();
const tempVec3b = math.vec3();
const tempMat4a = math.mat4();
/**
* @private
*/
class FrustumPlane {
constructor() {
this.normal = math.vec3();
this.offset = 0;
this.testVertex = math.vec3();
}
set(nx, ny, nz, offset) {
const s = 1.0 / Math.sqrt(nx * nx + ny * ny + nz * nz);
this.normal[0] = nx * s;
this.normal[1] = ny * s;
this.normal[2] = nz * s;
this.offset = offset * s;
this.testVertex[0] = (this.normal[0] >= 0.0) ? 1 : 0;
this.testVertex[1] = (this.normal[1] >= 0.0) ? 1 : 0;
this.testVertex[2] = (this.normal[2] >= 0.0) ? 1 : 0;
}
}
/**
* @private
*/
class Frustum {
constructor() {
this.planes = [
new FrustumPlane(), new FrustumPlane(), new FrustumPlane(),
new FrustumPlane(), new FrustumPlane(), new FrustumPlane()
];
}
}
Frustum.INSIDE = 0;
Frustum.INTERSECT = 1;
Frustum.OUTSIDE = 2;
/** @private */
function setFrustum(frustum, viewMat, projMat) {
const m = math.mulMat4(projMat, viewMat, tempMat4a);
const m0 = m[0];
const m1 = m[1];
const m2 = m[2];
const m3 = m[3];
const m4 = m[4];
const m5 = m[5];
const m6 = m[6];
const m7 = m[7];
const m8 = m[8];
const m9 = m[9];
const m10 = m[10];
const m11 = m[11];
const m12 = m[12];
const m13 = m[13];
const m14 = m[14];
const m15 = m[15];
frustum.planes[0].set(m3 - m0, m7 - m4, m11 - m8, m15 - m12);
frustum.planes[1].set(m3 + m0, m7 + m4, m11 + m8, m15 + m12);
frustum.planes[2].set(m3 - m1, m7 - m5, m11 - m9, m15 - m13);
frustum.planes[3].set(m3 + m1, m7 + m5, m11 + m9, m15 + m13);
frustum.planes[4].set(m3 - m2, m7 - m6, m11 - m10, m15 - m14);
frustum.planes[5].set(m3 + m2, m7 + m6, m11 + m10, m15 + m14);
}
/** @private */
function frustumIntersectsAABB3(frustum, aabb) {
let ret = Frustum.INSIDE;
const min = tempVec3a;
const max = tempVec3b;
min[0] = aabb[0];
min[1] = aabb[1];
min[2] = aabb[2];
max[0] = aabb[3];
max[1] = aabb[4];
max[2] = aabb[5];
const bminmax = [min, max];
for (let i = 0; i < 6; ++i) {
const plane = frustum.planes[i];
if (((plane.normal[0] * bminmax[plane.testVertex[0]][0]) +
(plane.normal[1] * bminmax[plane.testVertex[1]][1]) +
(plane.normal[2] * bminmax[plane.testVertex[2]][2]) +
(plane.offset)) < 0.0) {
return Frustum.OUTSIDE;
}
if (((plane.normal[0] * bminmax[1 - plane.testVertex[0]][0]) +
(plane.normal[1] * bminmax[1 - plane.testVertex[1]][1]) +
(plane.normal[2] * bminmax[1 - plane.testVertex[2]][2]) +
(plane.offset)) < 0.0) {
ret = Frustum.INTERSECT;
}
}
return ret;
}
export {
Frustum,
FrustumPlane,
frustumIntersectsAABB3,
setFrustum
};