从场景中删除所有对象的正确方法

时间:2018-05-17 15:50:49

标签: javascript three.js

我知道有很多SO问题要求从场景中删除所有内容,但是我所尝试的一切都不像我希望的那样工作。似乎也没有一种明确的方法可以从场景中删除所有内容(在文档或类似内容中),所以我希望有人可以告诉我正确的方法。

以下是我目前用于删除场景中所有内容的功能:

function removeAll() {
    while (scene.children.length > 0) {
        scene.remove(scene.children[0]);
        if (scene.children[0] == THREE.Mesh || scene.children[0] == THREE.Object3D || scene.children[0] == THREE.Group) {
            scene.children[0].dispose();
            scene.children[0].geometry.dispose();
            scene.children[0].material.dispose();
        }
    }
}

这可以好的,并且似乎可以直观地删除场景中的所有内容。

我的问题是,如果我调用此函数然后重新调用创建场景的函数,或者创建新场景的函数(请参阅上下文部分,我有多个),那里场景中的对象比第一次调用场景创建函数(init())后的对象更多 - 在控制台中使用renderer.info进行检查。

我还注意到在调用removeAll()函数然后重新加载场景之后,我做的越多,场景得到的 laggier ,我认为是因为并非一切都被删除正常。

所以我问:

从场景中删除所有内容的正确方法是什么。

上下文:

我有一个HTML菜单,用户可以在其中选择他们想要“跳过”的场景。我需要在执行此操作时删除所有内容,然后仅重新加载该特定场景的对象。我有所有这些功能,唯一的问题是在加载新场景之前删除对象。

1 个答案:

答案 0 :(得分:2)

我看到的重要一点是你只处理顶级场景的孩子。如果这些物品本身就有孩子,那么它们不一定被妥善处理。

老实说,确保清理所有内容的最佳方法只是处理渲染器并制作一个新渲染器并转储场景并让它进行GCed。

如果你想坚持尝试使用方法清除所有东西,那么你需要递归到孩子们并处理他们可能拥有的任何几何,材料和纹理。

您可以在this相关帖子中找到一个非常全面的处理功能。我要做的唯一改变是修改diposeHierarchy以将对象彼此分离,如下所示:

function disposeHierarchy (node, callback)
{
    for (var i = node.children.length - 1; i >= 0; i--)
    {
        var child = node.children[i];
        disposeHierarchy (child, callback);
        callback (child);
        node.remove(child);
    }
}