Multiple models in gltf file

This is really more of a gltf/blender question than a three.js question, but here goes.

So, my game engine loads hundreds of models for characters and scenery - to keep the number of network requests down to a reasonable number, I store dozens of models in each .blend file and each corresponding .gtb file. Individual models are parented to the root scene within the .glb file, and I can then reference/clone/instantiate copies as needed; which copying technique I use depends on the nature of the model and how it is used, so for purely static objects I can use instanced meshes for example.

This works great for most models, but I am seeing something odd with skinned models that I don’t quite understand. Say have characters A1 and A2 in the same .glb file, both sharing the same armature (A) and the same set of animation loops. For skinned models, I use a traverse()/clone() method to get a unique instance of the character (this only copies the Object3ds, the buffers are shared between them). So now we have copies A1-prime and A2-prime, which are placed in the scene. A1-prime looks correct, but A2-prime is rendering the skins of both A1 and A2.

My suspicion is that this may have something to do with how the skins are linked to the armature within the Blender file. But I’ve never been able to grok the mental model of how data structures are linked in Blender (despite having written a .blend file parser long ago…)

I think that normally Blender writes the armature/joints into a separate subtree from the skinned mesh, something like:

  • Scene
    • SkinnedMesh
    • Bone
      • Bone
      • Bone

I’m not sure if it will write the skeleton once for each skinned mesh that depends on it, or multiple times… that might be worth checking first, here — do your characters A1–A2 still share a skeleton once loaded in three.js? After cloning?

Actually, it appears that, in the .glb file exported from Blender, the armature is the Scene (root object), and the two skinned meshes are both children of the armature.

This is not the structure within the .blend file, which looks like this:

  • Scene Collection/
    • Armature
    • Characters/
      • HumanFemaleTunic
      • HumanFemaleDress

OK I figured out a solution, it’s a hack but it works:

  • Find the skin I want to instantiate.
  • Remove all non-Bone children from the armature.
  • Add back in the skin as a child of the armature.
  • Call SkeletonUtils.clone()

This gives me a copy of the armature and the skin I want.

…aaaand it turns out it was a bug in my code all along. Never mind! :slight_smile:

Got some cool-looking characters though: :slight_smile:
Screen Shot 2021-08-19 at 7.06.34 PM

1 Like