three-stdlib
Version:
stand-alone library of threejs examples
77 lines (76 loc) • 2.59 kB
JavaScript
import { Vector3, Matrix4 } from "three";
const inverseProjectionMatrix = /* @__PURE__ */ new Matrix4();
class CSMFrustum {
constructor(data) {
data = data || {};
this.vertices = {
near: [new Vector3(), new Vector3(), new Vector3(), new Vector3()],
far: [new Vector3(), new Vector3(), new Vector3(), new Vector3()]
};
if (data.projectionMatrix !== void 0) {
this.setFromProjectionMatrix(data.projectionMatrix, data.maxFar || 1e4);
}
}
setFromProjectionMatrix(projectionMatrix, maxFar) {
const isOrthographic = projectionMatrix.elements[2 * 4 + 3] === 0;
inverseProjectionMatrix.copy(projectionMatrix).invert();
this.vertices.near[0].set(1, 1, -1);
this.vertices.near[1].set(1, -1, -1);
this.vertices.near[2].set(-1, -1, -1);
this.vertices.near[3].set(-1, 1, -1);
this.vertices.near.forEach(function(v) {
v.applyMatrix4(inverseProjectionMatrix);
});
this.vertices.far[0].set(1, 1, 1);
this.vertices.far[1].set(1, -1, 1);
this.vertices.far[2].set(-1, -1, 1);
this.vertices.far[3].set(-1, 1, 1);
this.vertices.far.forEach(function(v) {
v.applyMatrix4(inverseProjectionMatrix);
const absZ = Math.abs(v.z);
if (isOrthographic) {
v.z *= Math.min(maxFar / absZ, 1);
} else {
v.multiplyScalar(Math.min(maxFar / absZ, 1));
}
});
return this.vertices;
}
split(breaks, target) {
while (breaks.length > target.length) {
target.push(new CSMFrustum());
}
target.length = breaks.length;
for (let i = 0; i < breaks.length; i++) {
const cascade = target[i];
if (i === 0) {
for (let j = 0; j < 4; j++) {
cascade.vertices.near[j].copy(this.vertices.near[j]);
}
} else {
for (let j = 0; j < 4; j++) {
cascade.vertices.near[j].lerpVectors(this.vertices.near[j], this.vertices.far[j], breaks[i - 1]);
}
}
if (i === breaks.length - 1) {
for (let j = 0; j < 4; j++) {
cascade.vertices.far[j].copy(this.vertices.far[j]);
}
} else {
for (let j = 0; j < 4; j++) {
cascade.vertices.far[j].lerpVectors(this.vertices.near[j], this.vertices.far[j], breaks[i]);
}
}
}
}
toSpace(cameraMatrix, target) {
for (let i = 0; i < 4; i++) {
target.vertices.near[i].copy(this.vertices.near[i]).applyMatrix4(cameraMatrix);
target.vertices.far[i].copy(this.vertices.far[i]).applyMatrix4(cameraMatrix);
}
}
}
export {
CSMFrustum
};
//# sourceMappingURL=CSMFrustum.js.map