【问题标题】:Deallocating BufferGeometry?释放BufferGeometry?
【发布时间】:2014-09-27 09:06:43
【问题描述】:

作为我的场景对象的基础,我有一个根 Object3D。我的数据作为 Object3Ds 的树结构从这个根目录加载。使用 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 中进行测试

【问题讨论】:

  • 你能为此创建一个 jsfiddle 吗?
  • 您可以在此处查看我的 jsfiddle (jsfiddle.net/TheJim01/mw9Df/51),但该演示大部分都按预期工作——它确实完全删除了 Mesh 和 Material 对象,所以我的代码必须挂在网格物体在其他地方。也就是说,上面的小提琴并没有完全删除 BufferGeometry 对象,但这可能是因为我是如何定义它的。
  • 我今天做了更多的测试,我的版本一定是混乱的。 r68 确实正确清除内存,但 r69dev 没有。如果尚未解决/修复错误,我将尝试将其追溯到根本原因,并提交错误。
  • 哦!如果你能找到罪魁祸首那就太好了:)

标签: javascript three.js buffer-geometry


【解决方案1】:

在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]);
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2018-01-18
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2015-01-30
    • 2018-01-23
    • 2015-04-01
    • 2011-05-03
    相关资源
    最近更新 更多