From 678e36eb25f43b86d92fc5e198b2a61ba06b9e28 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 28 Jan 2024 22:55:46 -0600 Subject: [PATCH] chore(map): move doodad culling into doodad manager --- src/lib/map/DoodadManager.ts | 29 +++++++++++++++++++++++------ src/lib/map/MapManager.ts | 14 ++------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/lib/map/DoodadManager.ts b/src/lib/map/DoodadManager.ts index 7b8537b..4720dcc 100644 --- a/src/lib/map/DoodadManager.ts +++ b/src/lib/map/DoodadManager.ts @@ -16,8 +16,9 @@ class DoodadManager { #host: AssetHost; #modelManager: ModelManager; - #loadedAreas = new Map(); #loadingAreas = new Map>(); + #loadedAreas = new Map(); + #areaBounds = new Map(); #doodads = new Map(); #doodadDefs = new Map(); @@ -33,6 +34,15 @@ class DoodadManager { }); } + cull(cullingFrustum: THREE.Frustum) { + for (const [areaId, areaGroup] of this.#loadedAreas.entries()) { + const areaBounds = this.#areaBounds.get(areaId); + + const visible = cullingFrustum.intersectsSphere(areaBounds); + areaGroup.visible = visible; + } + } + getArea(areaId: number, area: MapAreaSpec): Promise { const loaded = this.#loadedAreas.get(areaId); if (loaded) { @@ -51,6 +61,7 @@ class DoodadManager { } removeArea(areaId: number) { + this.#areaBounds.delete(areaId); this.#loadedAreas.delete(areaId); // Dereference doodads @@ -111,8 +122,10 @@ class DoodadManager { // Only load newly referenced doodad defs (defs can be shared across multiple areas) const doodadDefs = area.doodadDefs.filter((doodadDef) => this.#refDoodad(doodadDef.id) === 1); - const group = new THREE.Group(); - group.name = 'doodads'; + const areaGroup = new THREE.Group(); + areaGroup.name = 'doodads'; + + const areaBoundingBox = new THREE.Box3(); const doodadModels = await Promise.all( doodadDefs.map((doodadDef) => this.#modelManager.get(doodadDef.name)), @@ -130,15 +143,19 @@ class DoodadManager { model.updateMatrixWorld(); - group.add(model); + areaGroup.add(model); + areaBoundingBox.expandByObject(model); this.#doodads.set(def.id, model); } - this.#loadedAreas.set(areaId, group); + const areaBounds = areaBoundingBox.getBoundingSphere(new THREE.Sphere()); + this.#areaBounds.set(areaId, areaBounds); + + this.#loadedAreas.set(areaId, areaGroup); this.#loadingAreas.delete(areaId); - return group; + return areaGroup; } } diff --git a/src/lib/map/MapManager.ts b/src/lib/map/MapManager.ts index 2f0289c..30ecf83 100644 --- a/src/lib/map/MapManager.ts +++ b/src/lib/map/MapManager.ts @@ -195,6 +195,8 @@ class MapManager extends EventTarget { // Cull entire groups to save on frustum intersection cost this.#cullGroups(); + + this.#doodadManager.cull(this.#cullingFrustum); } dispose() { @@ -210,13 +212,6 @@ class MapManager extends EventTarget { terrainGroup.userData.boundingSphere, ); } - - // Doodad groups - for (const doodadGroup of this.#doodadGroups.values()) { - doodadGroup.visible = this.#cullingFrustum.intersectsSphere( - doodadGroup.userData.boundingSphere, - ); - } } #handleAreaTableChange() { @@ -325,11 +320,6 @@ class MapManager extends EventTarget { this.#terrainGroups.set(areaId, terrainGroup); this.#root.add(terrainGroup); - const doodadBoundingSphere = new THREE.Box3() - .setFromObject(doodadGroup) - .getBoundingSphere(new THREE.Sphere()); - doodadGroup.userData.boundingSphere = doodadBoundingSphere; - this.#doodadGroups.set(areaId, doodadGroup); this.#root.add(doodadGroup); }