作为场景对象的基础,我有一个根对象Object3D。我的数据从此根作为Object3D的树结构加载。使用BufferGeometry / MeshPhongMaterial将网格添加到叶Object3D。我通过将根Object3D传递给此方法来清除现有树:

clearScene:
    function (obj) {
        if (obj instanceof THREE.Mesh)
        {
            obj.geometry.dispose();
            obj.geometry = undefined;
            obj.material.dispose();
            obj.material = undefined;
            obj = undefined;
        }
        else
        {
            if (obj.children !== undefined) {
                while (obj.children.length > 0) {
                    this.clearScene(obj.children[0]); // removing children changes the length of the array.
                    obj.remove(obj.children[0]);
                }
            }
        }
    }


考虑下面的简单树:


场景(场景)

根(Object3D)

分支(Object3D)

叶(网)





一旦这个结构出现在场景中,我将观察堆(使用Chrome的开发工具)。我可以看到3个Object3Ds对象和2个Mesh对象(额外的是原型)。

当我调用clearScene(Root)时,我看到它穿过树,删除了Object3D,并清理了网格。但是,当我观察到堆时,我看到尽管删除了Object3D,但仍然保留了2个Mesh对象(及其关联的BufferGoemetry和Material对象)。如果清除后第二次加载数据,我会看到3个Object3D(可以)和4个网格(不可以)。

我相信这意味着无法正确清除引用,但是我没有在堆中看到任何可以这样做的保持器。

我一定会错过一些其他东西,这些东西会导致这些对象徘徊。

r69dev(我在r68中也看到了同样的东西),在Chrome 36.0.1985.125中进行了测试

最佳答案

在github上提交的问题(关注):https://github.com/mrdoob/three.js/issues/5175

r69dev需要对网格的dispose方法进行显式调用,以正确删除渲染器保存的引用。

工作代码:

clearScene:
function (obj) {
    if (obj instanceof THREE.Mesh)
    {
        obj.geometry.dispose();
        obj.geometry = null;
        obj.material.dispose();
        obj.material = null;
        obj.dispose(); // required in r69dev to remove references from the renderer.
        obj = null;
    }
    else
    {
        if (obj.children !== undefined) {
            while (obj.children.length > 0) {
                this.clearScene(obj.children[0]);
                obj.remove(obj.children[0]);
            }
        }
    }
}

07-25 22:38