Parenting nodes from different asset containers results in sending children to limbo when parent removed

I’m working on a viewer that should allow users to select a base model (from a gltf file) + additional items (from other gltf files) anchored somewhere on the base. One use case is to change the base model, with all additional items expected to jump to the new base.

I create AssetContainer for all loaded models, addAllToScene and link them via attachement_container.rootNodes[0].parent = anchor_node_from_main_container

Now, if the main model is removed via main_container.removeAllFromScene the children are gone to nowhere. Resetting parent does not bring them back.

Scenario in playground:

  1. select a base model // it is added to scene
  2. attach attachment // it is added to scene at 0,
  3. anchor attachment // it is moved on top of the base model (under the node “anchor”)
  4. change base model // old base model is removed, new model is added, the attachment goes to nowhere
  5. re-toggle ‘anchor’ // attachment is kinda re-parented to the new model but still not rendered

Dev console lists scene.getNodes() after each operation.

When initial base is removed, the scene somehow still contains attachment#root (a TransformNode used to be parented to anchor) but not attachment#item (actual Mesh parented to the root).

When the root is re-parented to a new node, both the root and the lost mesh are accessible in Inspector, but the mesh is not listed from scene.getNodes()

Working scenario impies de-anchoring attachment, changing base, and then re-anchoring attachment.


Apparently, that’s not a bug, but rather an improper usage of containers. Technically, it is “The Asset Container hierarchy is not valid“ but not detected, and the behavior is somewhat unpredictable.

A workaround is to track source containers somehow (like, setting node.id = url#name) and to scan all the nodes in container before removal to detect foreign children. That seems quite inefficient. Probably, some better solution should exist.

just to be sure, you read this:
Parents and Children | Babylon.js Documentation

When you call parent = , you take the current local transform and keep them so the frame of reference changes but the local values will now be off.

In your case I think you want to use setParent()