繁体   English   中英

如何清除 THREE.JS 场景

[英]How do I clear THREE.JS Scene

我试图找到在不破坏场景本身的情况下清除场景中所有对象的方法。 我知道命名 object 是一种方法,然后当我们想删除 object 时,我们只需按其名称“获取”它。 但是,我想找到一种快速清除场景中所有对象的方法,无论它们的名称如何。 有简单的方法吗? 谢谢!

您可以遍历场景的子对象并一一移除它们。

正如评论中所建议的,这应该以相反的顺序完成,以免修改您正在迭代的元素。

while(scene.children.length > 0){ 
    scene.remove(scene.children[0]); 
}

注意:这只是对对象层次结构的快速清除。 如果您计划大量执行此操作,则可能会因上述代码而导致内存泄漏,因为渲染器引用了对象材质、纹理和几何图形。 完全清理场景更复杂,还有很多其他问题需要详细说明:

我有一个更简洁的方法来做到这一点。 我注意到 Object3D 的remove方法接受多个用于对象删除的参数。 这允许我们通过利用函数的内置apply方法修改调用以使用每个元素作为单独的参数来使用整个children数组。 这像这样工作:

scene.remove.apply(scene, scene.children);

遍历所有子元素并调用它们的几何、材质和纹理的 dispose。 下面的代码是我的解决方案。

function clearThree(obj){
  while(obj.children.length > 0){ 
    clearThree(obj.children[0]);
    obj.remove(obj.children[0]);
  }
  if(obj.geometry) obj.geometry.dispose();

  if(obj.material){ 
    //in case of map, bumpMap, normalMap, envMap ...
    Object.keys(obj.material).forEach(prop => {
      if(!obj.material[prop])
        return;
      if(obj.material[prop] !== null && typeof obj.material[prop].dispose === 'function')                                  
        obj.material[prop].dispose();                                                      
    })
    obj.material.dispose();
  }
}   

clearThree(scene);

清除场景的下一种方法也对我有用:

const n = scene.children.length - 1; 
for (var i = n; i > -1; i--) {
    scene.remove(scene.children[i]); 
} 

以相反的顺序迭代项目,它不会遇到当前数组索引的问题。

亲切的问候,阿德里安 B.

一定要删除所有东西,尤其是纹理贴图。

    function removeObjectsWithChildren(obj){

        if(obj.children.length > 0){
            for (var x = obj.children.length - 1; x>=0; x--){
                removeObjectsWithChildren( obj.children[x]);
            }
        }

        if (obj.geometry) {
            obj.geometry.dispose();
        }

        if (obj.material) {
            if (obj.material.length) {
                for (let i = 0; i < obj.material.length; ++i) {

    
                    if (obj.material[i].map) obj.material[i].map.dispose();
                    if (obj.material[i].lightMap) obj.material[i].lightMap.dispose();
                    if (obj.material[i].bumpMap) obj.material[i].bumpMap.dispose();
                    if (obj.material[i].normalMap) obj.material[i].normalMap.dispose();
                    if (obj.material[i].specularMap) obj.material[i].specularMap.dispose();
                    if (obj.material[i].envMap) obj.material[i].envMap.dispose();

                    obj.material[i].dispose()
                }
            }
            else {
                if (obj.material.map) obj.material.map.dispose();
                if (obj.material.lightMap) obj.material.lightMap.dispose();
                if (obj.material.bumpMap) obj.material.bumpMap.dispose();
                if (obj.material.normalMap) obj.material.normalMap.dispose();
                if (obj.material.specularMap) obj.material.specularMap.dispose();
                if (obj.material.envMap) obj.material.envMap.dispose();

                obj.material.dispose();
            }
        }

        obj.removeFromParent();

        return true;
    }

scene.clear() 是您所需要的。 这是示例代码,首先将其变为 function,然后每次要更改 object 时调用 function。

function loadscene(path)
{
    scene.clear();
    loader.load(path,function(gltf)
    {
        const model = gltf.scene;
        model.position.set(0,0,0);
        model.rotation.set(0,0,0);
        model.scale.set(1,1,1);
        scene.add(model);
        animate();
    }, 
    undefined, function(e)
    {
        console.error(e);
    });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM