Super weird behavior with "add()" and looping "scene.children"

So, this is my GLTF model in Blender:

Blender

This code…

new GLTFLoader(manager).load('./model.glb', (gltf) => {
    console.log("scene.children : ", gltf.scene.children);
    gltf.scene.children.forEach((mesh) => {
        console.log("Iterating scene.children : ", mesh);
        scene.add(mesh);
    });
});

…prints out this: (notice how the names don’t match!)

Console1

While the same code without the “add” function call…

new GLTFLoader(manager).load('./model.glb', (gltf) => {
    console.log("scene.children : ", gltf.scene.children);
    gltf.scene.children.forEach((mesh) => {
        console.log("Iterating scene.children : ", mesh);
        // scene.add(mesh);
    });
});

…correctly prints out this:

Console2

While trying for hours, I just assumed this is probably some deep multithreading problem. I tried adding more loops because why not:

new GLTFLoader(manager).load('./model.glb', (gltf) => {
    console.log("scene.children : ", gltf.scene.children);
    gltf.scene.children.forEach((mesh) => {
        console.log("Iterating scene.children : ", mesh);
        scene.add(mesh);
    });
    gltf.scene.children.forEach((mesh) => {
        console.log("Iterating scene.children : ", mesh);
        scene.add(mesh);
    });
    gltf.scene.children.forEach((mesh) => {
        console.log("Iterating scene.children : ", mesh);
        scene.add(mesh);
    });
});

And it actually worked! What! But scene.children is empty.

Console3

Please tell me I’m missing something super basic… This is driving me insane

The problem is that calling scene.add(mesh) removes that mesh from its current parent, gltf.scene, and immediately shortens the gltf.scene.children array. Iterating over an array while removing things from that array is a recipe for weirdness, so you probably want to do one of these instead:

// (A) more concise
scene.add( ... gltf.scene.children );

// (B) more robust if you don't know exactly what's in the file
var meshes = [];
gltf.scene.traverse((object) => {
  if (object.isMesh) meshes.push(object);
});
meshes.forEach((mesh) => {
  scene.add(mesh);
});

// (C) or just add the whole thing
scene.add( gltf.scene );
3 Likes