mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
100.6k stars 35.21k forks source link

GLTFLoader outputs an empty Group when multiple scenes refer to the same root node #27993

Open wlinna opened 3 months ago

wlinna commented 3 months ago

Description

GLTFLoader outputs an empty Group when multiple scenes refer to the same root node. I created a simple cube in Blender, exported to glTF. This works fine. But when I duplicate the scenes array in glTF file and try to view it in ThreeJS, glTF loader returns an empty group.

So this works:

    "scene":0,
    "scenes":[
        {
            "name":"Scene",
            "nodes":[0]
        }
    ],

... while this doesn't:

    "scene":0,
    "scenes":[
        {
            "name":"Scene",
            "nodes":[0]
        },
        {
            "name":"Scene2",
            "nodes":[0]
        }
    ],

glTF specification allows referring to the same root nodes from multiple scenes, so I consider this a bug.

While I have no reason to duplicate scenes, we do sometimes load such models from external sources, and have no practical way to preprocess the files to remove

Reproduction steps

  1. Download the attached GLB file
  2. Add it to threejs editor, gltfviewer or any three.js scene
  3. Admire the empty scene

duplicatescene.zip

Code


 const loader = new GLTFLoader();
 loader.parse(e.target.result, '', gltf => {
            console.log(gltf)
            if (gltf.scene.isGroup && gltf.scene.children.length === 0) {
                    console.error('gltf.scene is a group with no children!')
            }
  });

Live example

https://jsfiddle.net/jteq8mov/2/

Screenshots

No response

Version

r156 and r162 at least

Device

No response

Browser

No response

OS

No response

donmccurdy commented 3 months ago

Agreed, while glTF models with multiple scenes are fairly rare, I would consider this a bug as well. Note that we'll need to either parse the node subtree a second time, or use SkeletonUtils.clone to make a copy. Calling node.clone() alone will break connections to the bones of skinned meshes.