J'ai essayé de créer une fonction pour supprimer tous les objets de la scène en une seule prise de vue, mais cela ne supprime qu'un seul objet à invoquer.
GeometryModel.prototype.clearScene = function(scene) {
var i;
for(i=0; i < scene.children.length; i++){
obj = scene.children[i];
scene.remove(obj);
}
}
une autre solution que j'ai essayée et qui fonctionne est la suivante:
scene.children={};
mais je ne suis pas sûr si c'est correct.
Vous devez faire le contraire:
for( var i = scene.children.length - 1; i >= 0; i--) { }
parce que dans chaque itération, le tableau .children
change une fois que vous effectuez un .remove()
à partir du début et que l'indexation de ce tableau change.
Si vous voulez mieux le comprendre, déroulez la boucle for et suivez l'index dans le tableau.
Vous pouvez accomplir cela avec while :
while (object.children.length)
{
object.children.remove(object.children[0]);
}
Explications:
object.children.length return true si object.children.length n'est pas 0 , s'il est égal à 0 il retourne false .
Il suffit donc de supprimer le premier élément enfant tant que l'objet a des enfants.
La réponse existante est bonne, je souhaite simplement fournir une réponse plus complète à ceux qui se heurtent au même problème. Lorsque j'utilise le rechargement de module à chaud avec Three.js, je souhaite souvent recréer tous les objets autres que l'avion et la caméra. Pour ce faire, je fais ce qui suit:
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.')
}
Une méthode préférée consiste à utiliser la fonction traverse
de la scène. Tous les objets ont cette fonction et effectueront une recherche approfondie dans les enfants du parent.
Voici un extrait de M. Doob lui-même .
scene.traverse( function ( object ) {
if ( object instanceof THREE.Mesh ) {
var geometry = object.geometry;
var matrixWorld = object.matrixWorld;
...
}
});
Et voici un peu de la source de r82:
traverse: function ( callback ) {
callback( this );
var children = this.children;
for ( var i = 0, l = children.length; i < l; i ++ ) {
children[ i ].traverse( callback );
}
}
Vous pouvez également utiliser traverseVisible
dans votre cas:
scene.traverseVisible(function(child) {
if (child.type !== 'Scene') {
scene.remove(child);
}
});