Properly destroying a 3D object (React Three Fiber), its meshes, animations and all

Viewed 554

How do I destroy the whole three object, along with its animation and all

I have a glb file (created with Blender and exported to gltf 2.0)

Then I mount it to react with (and react Three Fiber)

const { scene, nodes, materials, animations } = useGLTF('/studio.glb');

I also start an animation, the code is

const Office = (props) => {
    const { scene, nodes, materials, animations } = useGLTF('/studio.glb');
    let mixer = new THREE.AnimationMixer(scene); // <-- other object
    animations.forEach((clip) => {
        const action = mixer.clipAction(clip);
        action.play();
    });
    useFrame((state, delta) => {
        mixer.update(delta);
    });
    const group = useRef();
    useThree(({ camera }) => {
        camera.position.set(xPos, yPos, 7);
        camera.rotation.set(0.1, -0.75, 0.08);
        camera.fov = 35;
        camera.updateProjectionMatrix();
    });
    return (
        <group ref={group} dispose={null}>
            <group rotation={[ Math.PI / 2, 0, 0 ]} scale={[ 0.01, 0.01, 0.01 ]}>
                <group name="Character">
                    <primitive object={nodes.pasted__Hips} />
                    <skinnedMesh
                        geometry={nodes.pasted__MocapGuy_Caruncula.geometry}
                    ... 
                    ... 
                    ...
}

(I destructured the whole glb file using https://gltf.pmnd.rs/, which is in the React Three Fiber documentation https://docs.pmnd.rs/react-three-fiber/tutorials/loading-models)

(I could have used

return <primitive object={scene} />

but I need to change some meshes by code later on)

HOW DO I DESTROY IT ALL?

I found many references to it, and almost all of them use something like

scene.remove( selectedObject );

The problem is that in my code, I have several objects, not just the scene, and I'm not sure that it will work properly in my case

I want to be able to destroy and dispose of all these objects in order to create them again when needed

The reason why I need it is that when switching to other pages with React Router, and switching back to the page, it is all created again, and the previous objects remain in memory

I tried serializing them in order to store them, but serialization makes the whole process too slow

How do I destroy it all?

Rafael

2 Answers

According to https://discoverthreejs.com/tips-and-tricks/ Disposing of Things

First of all, consider not doing that, especially if you will add it back again later. You can hide objects temporarily using object.visible = false (works for lights too), or material.opacity = 0. You can set light.intensity = 0 to disable a light without causing shaders to recompile.

Acoording to https://docs.pmnd.rs/react-three-fiber/advanced/pitfalls

I'll try by changing some property on the state but making sure it doesn't propagate to react three fiber.

You should conditionally render it in React, having a react component within your means it is calling scene.add on the content of the component, when you unmount it from the Canvas component scene.remove is called.

It will still stay in your browser cache though, will be overwritten when other things are added to the cache and it reaches its limit.

Read more here about conditional rendering: https://reactjs.org/docs/conditional-rendering.html

Related