How do you properly remove an object from the scene?

Ok silly beginner question here.

How do you properly remove an object from the scene?

In this playground, a mesh and ground is created, then I attempt to use:

scene.removeMesh(sphere);

visually it looks like it works, but with the inspector open you can see that the sphere is actually still in the scene. So clearly it’s just removing the mesh and leaving some sort of parent node?

5 Likes

Use the .dispose() method on meshes.
https://playground.babylonjs.com/#3UW6W3#2

6 Likes

Awesome! Thanks @Devin_Wright

The following goes beyond a single object, and (attempts to) clean up entire scenes.

    /******************************- unload -******************************/
    var unloadScene = function(){
        console.log('BEFORE-UNLOAD')
        console.log(nx.scene.meshes.length)
        console.log(nx.scene.materials.length)
        console.log('____')
        for(var i=0;i<sceneMesh.length;i++){
            if(sceneMesh[i].fn){nx.scene.unregisterBeforeRender(sceneMesh[i].fn)}
            sceneMesh[i].dispose();
            sceneMesh[i] = null;
        }
        sceneMesh= sceneMesh.filter(function(obj) { return obj });
        console.log('AFTER-UNLOAD')
        console.log(nx.scene.meshes.length)
        console.log(nx.scene.materials.length)
        console.log('____')
        // scene.onMeshRemovedObservable.add(mesh => {
        //    if (mesh.skeleton) {
        //       mesh.skeleton.dispose()
        //    }
        // });
    }

I like how it handles multiple aspects of unloading a scene (materials/bones) and shows if it isn’t.

Still need to add bone removal and registerBeforeRender removal.

scene.dispose() should do all the work :wink:

1 Like

Ok let’s increase the complication level a little bit.

What if we add Physics and triggers into the equation.

https://playground.babylonjs.com/#VVN2AD#1

In the example above, the sphere has an action to dispose of itself if it ever intersects the “killbox.”

However as you can see it doesn’t like that. :frowning:

Thoughts?

2 Likes

Seems like an easy way to achieve making the sphere dispose correctly is setting the action manager to be on the killBox rather than the sphere. The actionManager also has a dispose method, but calling that before calling sphere.dispose didn’t seem to work.

https://playground.babylonjs.com/#VVN2AD#2

Edit:
If you do actually need it to be attached to the sphere, this seems to work.
https://playground.babylonjs.com/#VVN2AD#3

Basically wrap the dispose in a setTimeout, which I found a similar issue/answer here:

1 Like

so … smurf. A big waste of time explaining all that.

delete

definitely a bug…will be fixed by next nightly

Found some advices to dispose meshes with null as well:

mesh.dispose();
mesh = null;

Is it necessary to tell GC that he can collect that garbage? I have a problem in typescript with such approach because it doesn’t allow to set mesh to null. I can do following:

mesh.dispose();
( mesh as any ) = null; // <-- this line

Is that a good solution for GC or not?

The method you want to use does depend on if you enumerate through “map”-object of your meshes, then using delete is prefered, because it will be undefined (inexistent) and your loops don’t consider the mesh anymore. Else if it has to be equal null, because you need this mesh as null-property in any of your evaluations afterwards. Else if scope is going to be left anyway, I would just use dispose(), but I’m new to TypeScript, aswell. So maybe someone can correct me if I’m wrong.

I have created a playground:

2 Likes

FWIW, if anyone else comes here - if you’re disposing of individual nodes in a scene, DO NOT iterate via scene.transformNodes.forEach() ! If you call transformNode.dispose() inside your iterator, it will modify the array out from under your iterator causing nodes to be skipped seemingly at random.

I ended up copying the array first with splice( 0 ), then iteration became stable despite nodes being disposed.

Yes I tried scene.removeTransformNode() instead - no help there.

One of reliable ways to dispose

while(scene.meshes.length) {
const mesh = scene.meshes[0]
mesh.dispose();
}
4 Likes