Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cleanup ThreeJS Scene - leak?

Tags:

three.js

webgl

-Three.js Version 66

-Running in Chrome v33 (latest)

-WebGL Renderer

I have a scene in which I draw objects (nodes). The objects are all children of a "root" object which I add to the scene. The user has the ability to press a button and toggle a subset of nodes to be added/removed (without changing/destroying the camera).

After each toggle the animation (camera movement) becomes slower and slower indicating to me there is a leak. I've looked everywhere inside the objects and a little bit of WebGL buffers but I can't find the leak.

Is there something I could be missing to dispose of the scene??

I do the following:

  1. Create WebGL Renderer and a Scene object
  2. Create a camera and lighting and add them to scene
  3. Create a 'root' object3d, add it to the scene
  4. For every node, create a BoxGeometry, mesh, object3d and add it to the root object

When the user presses a button:

  1. Remove all children of root from the scene
  2. For a subset of nodes, create BoxGeometry, mesh, object3d and add it to the root object

When the user presses the button again:

  1. Remove all children of root from the scene
  2. For every node, create BoxGeometry, mesh, object3d and add it to the root object

Appreciate any help!!!


EDIT

I actually just found the problem. My redraw method was calling my animate hook again so each type it was adding another additional pointless animation.

If anyone else has this problem MAKE SURE YOU ONLY CALL YOUR ANIMATE METHOD ONCE

And to help anyone looking for generic cleanup this is what I'm doing:

    function doDispose(obj)
    {
        if (obj !== null)
        {
            for (var i = 0; i < obj.children.length; i++)
            {
                doDispose(obj.children[i]);
            }
            if (obj.geometry)
            {
                obj.geometry.dispose();
                obj.geometry = undefined;
            }
            if (obj.material)
            {
                if (obj.material.materials)
                {
                    for (i = 0; i < obj.material.materials.length; i++)
                    {
                        obj.material.materials[i].dispose();
                    }
                }
                else
                {
                    obj.material.dispose();
                }
                obj.material = undefined;
            }
            if (obj.texture)
            {
                obj.texture.dispose();
                obj.texture = undefined;
            }
        }
        obj = undefined;
    }
like image 316
user3084063 Avatar asked Mar 21 '14 17:03

user3084063


1 Answers

This worked brilliantly for me, thank you!

I modified it a for Three.js Version 72

function doDispose(obj)
{
    if (obj !== null)
    {
        for (var i = 0; i < obj.children.length; i++)
        {
            doDispose(obj.children[i]);
        }
        if (obj.geometry)
        {
            obj.geometry.dispose();
            obj.geometry = undefined;
        }
        if (obj.material)
        {
            if (obj.material.map)
            {
                obj.material.map.dispose();
                obj.material.map = undefined;
            }
            obj.material.dispose();
            obj.material = undefined;
        }
    }
    obj = undefined;
}
like image 181
DARKSETH23 Avatar answered Sep 27 '22 21:09

DARKSETH23