Трижды удаляют все вместе объект из сцены
Я попытался сделать функцию для удаления всего объекта из сцены за один раз, но он удаляет только один объект для вызова.
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);
}
});