Javascript Threejs从场景中删除所有对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29417374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:20:09  来源:igfitidea点击:

Threejs remove all together object from scene

javascriptthree.js

提问by Stefano Maglione

I tried to make a function to remove all object from scene in one shoot but it removes only one object for invocation.

我试图制作一个函数,在一次拍摄中从场景中删除所有对象,但它只删除了一个对象以供调用。

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

another solution I tried and that works is this:

我尝试过的另一个解决方案是这样的:

scene.children={};

but I am not sure if it is correct.

但我不确定它是否正确。

回答by gaitat

You have to do the opposite:

你必须做相反的事情:

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

because in each iteration the .childrenarray changes once you do a .remove()from the start and the indexing of that array changes.

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

If you want to understand it better, unroll the for loop and follow what the index into the array is.

如果您想更好地理解它,请展开 for 循环并遵循数组中的索引。

回答by csblo

You can accomplish that with while:

你可以用while来实现:

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

Explanations :

说明:

object.children.length return trueif object.children.length is not 0, if it's equal to 0 it return false.

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

So you just have to remove the first child element as long as object has children.

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

回答by austin_ce

A preferred method is using the scene's traversefunction. All objects have this function and will do a depth-first search through the parent's children.

首选方法是使用场景的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;

        ...

    }
});

And here's a bit from r82's source:

这里有一些来自 r82 的来源:

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

You can also use traverseVisiblein your case:

您还可以traverseVisible在您的情况下使用:

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

回答by james_womack

The existing answer is good, I just want to provide a fuller response for those running into this same issue. When I'm using hot module reloading with Three.js, I often want to recreate all objects other than the plane and camera. To do that I do the following:

现有的答案很好,我只想为遇到同一问题的人提供更全面的答复。当我在 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.')
}