diff --git a/app/components/story/NotebookStage3D.tsx b/app/components/story/NotebookStage3D.tsx index a879e0a..e9e7816 100644 --- a/app/components/story/NotebookStage3D.tsx +++ b/app/components/story/NotebookStage3D.tsx @@ -63,15 +63,20 @@ function createMaterials(): MaterialMap { }; } -function cloneNotebookScene(scene: THREE.Object3D): { +type ClonedNotebookScene = { root: THREE.Object3D; materials: MaterialMap; -} { + meshes: THREE.Mesh[]; +}; + +function cloneNotebookScene(scene: THREE.Object3D): ClonedNotebookScene { const root = scene.clone(true); const materials = createMaterials(); + const meshes: THREE.Mesh[] = []; root.traverse((object) => { if (!(object instanceof THREE.Mesh)) return; + meshes.push(object); object.geometry = object.geometry.clone(); const sourceMaterial = Array.isArray(object.material) @@ -87,7 +92,7 @@ function cloneNotebookScene(scene: THREE.Object3D): { object.frustumCulled = false; }); - return { root, materials }; + return { root, materials, meshes }; } function updateMaterialOpacity(materials: MaterialMap, opacity: number) { @@ -96,14 +101,13 @@ function updateMaterialOpacity(materials: MaterialMap, opacity: number) { materials.screen.opacity = opacity; } -function disposeNotebookScene(root: THREE.Object3D, materials: MaterialMap) { - root.traverse((object) => { - if (!(object instanceof THREE.Mesh)) return; - object.geometry.dispose(); - }); - materials.body.dispose(); - materials.frame.dispose(); - materials.screen.dispose(); +function disposeNotebookScene(cloned: ClonedNotebookScene) { + for (const mesh of cloned.meshes) { + mesh.geometry.dispose(); + } + cloned.materials.body.dispose(); + cloned.materials.frame.dispose(); + cloned.materials.screen.dispose(); } function LoadingNotebook() { @@ -196,10 +200,7 @@ function NotebookScene({ } }); - useEffect( - () => () => disposeNotebookScene(cloned.root, cloned.materials), - [cloned], - ); + useEffect(() => () => disposeNotebookScene(cloned), [cloned]); return (