From 9b8ca44288264dc9204001468732b7f0f8653c2a Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Wed, 29 Apr 2026 23:00:46 +0200 Subject: [PATCH] Implement dynamic LOD visibility for terrain and refine resource disposal logic --- src/viewport-three/viewport-host.ts | 50 +++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/viewport-three/viewport-host.ts b/src/viewport-three/viewport-host.ts index a68eeb6b..c6f6d265 100644 --- a/src/viewport-three/viewport-host.ts +++ b/src/viewport-three/viewport-host.ts @@ -6481,6 +6481,40 @@ export class ViewportHost { }; } + private updateTerrainLodVisibility() { + const activeCamera = this.getActiveCamera(); + const perspective = activeCamera === this.perspectiveCamera; + const cameraPosition = { + x: activeCamera.position.x, + y: activeCamera.position.y, + z: activeCamera.position.z + }; + + for (const [terrainId, renderObjects] of this.terrainRenderObjects) { + const selected = isTerrainSelected(this.currentSelection, terrainId); + + for (const chunk of renderObjects.chunks) { + const nextLevelIndex = resolveTerrainLodLevelIndex({ + levelCount: chunk.levels.length, + chunkDiagonal: chunk.diagonal, + cameraPosition, + chunkWorldCenter: chunk.worldCenter, + perspective + }); + + if (chunk.activeLevelIndex !== nextLevelIndex) { + chunk.activeLevelIndex = nextLevelIndex; + } + + for (let levelIndex = 0; levelIndex < chunk.levels.length; levelIndex += 1) { + const active = levelIndex === chunk.activeLevelIndex; + chunk.levels[levelIndex]!.visible = active; + chunk.debugLevels[levelIndex]!.visible = selected && active; + } + } + } + } + private createPathLineGeometry(path: ScenePath): BufferGeometry { const points = path.points.map( (point) => @@ -9544,9 +9578,19 @@ export class ViewportHost { private clearTerrains() { for (const renderObjects of this.terrainRenderObjects.values()) { - this.terrainGroup.remove(renderObjects.mesh); - renderObjects.mesh.geometry.dispose(); - renderObjects.mesh.material.dispose(); + this.terrainGroup.remove(renderObjects.group); + + for (const chunk of renderObjects.chunks) { + for (const mesh of chunk.levels) { + mesh.geometry.dispose(); + } + } + + renderObjects.material.dispose(); + + for (const material of renderObjects.debugMaterials) { + material.dispose(); + } } this.terrainRenderObjects.clear();