Threejs从场景中删除所有对象

时间:2015-04-02 16:00:07

标签: javascript three.js

我尝试在一次拍摄中创建一个从场景中删除所有对象的函数,但它只删除了一个用于调用的对象。

GeometryModel.prototype.clearScene = function(scene) {
var i;
for(i=0; i < scene.children.length; i++){
     obj = scene.children[i];
     scene.remove(obj);
  }
}

我尝试过的另一个解决方案是有效的:

scene.children={};

但我不确定它是否正确。

4 个答案:

答案 0 :(得分:20)

你必须做相反的事情:

for( var i = scene.children.length - 1; i >= 0; i--) { }

因为在每次迭代中,.children数组从一开始就进行.remove()更改,并且该数组的索引会发生变化。

如果您想更好地理解它,请展开for循环并按照索引进入数组。

答案 1 :(得分:8)

您可以使用

来实现这一目标
ToList()

说明:

object.children.length如果object.children.length 不为0 则返回 true ,如果它等于0,则返回 false

所以只要对象有子元素,你就必须删除第一个子元素。

答案 2 :(得分:2)

现有的答案很好,我只想为那些遇到同样问题的人提供更全面的答复。当我使用Three.js重新加载热模块时,我经常想要重建除平面和相机之外的所有对象。为此,我执行以下操作:

export const reload = (/* updatedDependencies */) => {
  console.info('Canceling the run loop...')
  cancelAnimationFrame(runLoopIdentifier) // the return value of `requestAnimationFrame`, stored earlier

  console.info('Removing all children...')
  for (let i = scene.children.length - 1; i >= 0 ; i--) {
    let child = scene.children[ i ];

    if ( child !== plane && child !== camera ) { // plane & camera are stored earlier
      scene.remove(child);
    }
  }

  while (renderer.domElement.lastChild) // `renderer` is stored earlier
    renderer.domElement.removeChild(renderer.domElement.lastChild)

  document.removeEventListener( 'DOMContentLoaded', onDOMLoad )
  conicalDendriteTreeSegments = require('./plantae/conical-dendrite-trees').default

  initializeScene() // re-add all your objects
  runLoopIdentifier = startRenderRunLoop() // render on each animation frame

  console.info('Reload complete.')
}

答案 3 :(得分:1)

首选方法是使用场景的traverse功能。所有对象都具有此功能,并将通过父亲的孩子进行深度优先搜索。

Here's a snippet from Mr. Doob himself

scene.traverse( function ( object ) {
    if ( object instanceof THREE.Mesh ) {
        var geometry = object.geometry;
        var matrixWorld = object.matrixWorld;

        ...

    }
});

这里有点来自r82的来源:

traverse: function ( callback ) {
    callback( this );
    var children = this.children;
    for ( var i = 0, l = children.length; i < l; i ++ ) {
        children[ i ].traverse( callback );
    }
}

您也可以在案例中使用traverseVisible

scene.traverseVisible(function(child) {
   if (child.type !== 'Scene') {
      scene.remove(child);
   }
});