Hi, I have sketched out a few frustum options for the grid, maybe you have some other ideas?
...
const squadMatrix = [
2, 2,
1, 2,
0, 2,
0, 1,
0, 0,
1, 0,
2, 0,
2, 1,
1, 1
];
export const squadMatrixIndexes = [
[4, 3, 2],
[5, 8, 1],
[6, 7, 0],
];
...
public update(dt: number): void {
const cameraPos = this._cameraEntity.getPosition();
const cemeraDir = this._cameraEntity.forward;
this._frustumV1(cameraDir);
this._frustumV2(cameraPos);
}
...
private _frustumV2(cameraPos: pcx.Vec3) {
if (!this._meshesInstLod1) return;
const checkRadius = this.radius / 2;
const frustumPlanes = this._camera.frustum.planes;
const checkIsVisible = (min: pcx.Vec3, max: pcx.Vec3) => {
let inside = 1;
for (let p = 0; p < 6; p++) {
const frustumPlane = frustumPlanes[p] as unknown as number[];
const d = Math.max(min.x * frustumPlane[0], max.x * frustumPlane[0])
+ Math.max(min.y * frustumPlane[1], max.y * frustumPlane[1])
+ Math.max(min.z * frustumPlane[2], max.z * frustumPlane[2])
+ frustumPlane[3];
inside = inside & (d <= -checkRadius / 2 ? 0 : 1);
}
return inside;
}
for (let i = 0; i < 8; i++) {
const mi = this._meshesInstLod1[i];
const centerX = cameraPos.x + this.radius * (squadMatrix[i * 2 + 0] - 1);
const centerZ = cameraPos.z + this.radius * (squadMatrix[i * 2 + 1] - 1);
const min = new pc.Vec3(
centerX - checkRadius,
this._terrainEditor.terrain.minHeight,
centerZ - checkRadius
);
const max = new pc.Vec3(
centerX + checkRadius,
this._terrainEditor.terrain.maxHeight,
centerZ + checkRadius
);
const visible = !!checkIsVisible(min, max);
mi.visible = visible;
mi.visibleThisFrame = visible;
}
}
...
private _frustumV1(cemeraDir: pcx.Vec3) {
if (this._meshesInstLod1) {
for (const mi of this._meshesInstLod1) {
mi.visible = false;
mi.visibleThisFrame = false;
}
let x = cemeraDir.x;
let z = cemeraDir.z;
const lengthSq = x * x + z * z;
if (lengthSq > 0) {
const invLength = 1 / Math.sqrt(lengthSq);
x *= invLength;
z *= invLength;
}
const squadX = Math.round(x) + 1;
const squadZ = Math.round(z) + 1;
const visibleRadius = 2;
const visibleIndex = squadMatrixIndexes[squadX][squadZ];
const minVisibleIndex = visibleIndex - visibleRadius;
const maxVisibleIndex = visibleIndex + visibleRadius + 1;
for (let i = minVisibleIndex; i < maxVisibleIndex; i++) {
const normalizeIndex = i < 0 ? i + 8 : i % 8;
const visibleMI = this._meshesInstLod1[normalizeIndex];
visibleMI.visible = true;
visibleMI.visibleThisFrame = true;
}
}
}