Трижды удаляют все вместе объект из сцены

Я попытался сделать функцию для удаления всего объекта из сцены за один раз, но он удаляет только один объект для вызова.

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

другое решение, которое я пробовал, и это работает:

scene.children={};

но я не уверен, что это правильно.

Ответ 1

Вы должны сделать обратное:

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

потому что на каждой итерации массив .children изменяется после того, как вы начинаете .remove() с самого начала, и индексирование этого массива изменяется.

Если вы хотите это лучше понять, разверните цикл for и следуйте указаниям индекса в массиве.

Ответ 2

Вы можете выполнить это с помощью в то время как:

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

Объяснения:

object.children.length return true, если object.children.length не 0, если он равен 0, он возвращает false.

Итак, вам просто нужно удалить первый дочерний элемент, если у объекта есть дочерние элементы.

Ответ 3

Существующий ответ хорош, я просто хочу дать более полный ответ тем, кто работает в этой же проблеме. Когда я использую перезагрузку горячего модуля с помощью 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.')
}

Ответ 4

Предпочтительным методом является использование функции traverse сцены. Все объекты имеют эту функцию и будут выполнять поиск по глубине через родительские дети.

Вот фрагмент от самого г-на Доба.

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