Gltf loader overrides mesh extension with node extension in Object3D.userData

From what I can see, if you have a gltf extension that is present in gltf node or mesh, the data from the extension ends up in Object3D.userData.gltfExtensions.

However, it seems that when a gltf extension is present in both a gltf mesh and a gltf node that references the mesh, the gltf loader will only keep the data from the gltf node and the data from the gltf mesh will be lost.

Is this a bug or am I doing something wrong?

An example demonstrating this issue can be found here:

Maybe someone from the GLTFLoader authors/maintainers can provide a better explanation.

My guess is that the loader does not aggregate the contents of various instances of custom extension data. This is, if you have extension TST_example defined twice for an object, only one of them will be used.

For example, here in line 2242, an extension is ignored if it is already existing in userData:

When GLTFLoader sees a glTF node having one mesh, and that mesh has only one “mesh primitive” (in glTF terms), it tries to flatten the result into just a THREE.Mesh instead of having something like THREE.Object3D > THREE.Group > THREE.Mesh. If the mesh has multiple primitives, or the node also has other children, then it cannot flatten as that way.

It sounds like in the flattening process, unrecognized extensions from one object are overwriting those of another object. I’m not sure what “should” happen here – if both objects had unrecognized extensions of the same name, three.js cannot really know how to merge them. But if there’s a simple workaround for your use case, please feel free to open a PR to discuss.