-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
Description
Note: I don't want to bury the lede for this request, so I moved a brief summary to the top of the issue. Please refer to the second and third headings for a more detailed background and rationale!
Proposal
When loading models with GLTFLoader, it would be nice if we could retain associations between glTF scene graph elements and the Three.js objects that correspond to them. I briefly discussed this problem with @donmccurdy and he suggested that one of the following approaches might be acceptable:
- Decorate Three.js objects via
userDatae.g.,material.userData.gltfMeta.index = 3 - Expose a lookup table somewhere e.g.,
parser.getDefinition( material: THREE.Material ): GLTF.Material
What do others think about this problem? Would you be willing to consider a change that makes either of the suggested enhancements?
Background
Three.js' GLTFLoader currently produces an artifact that contains a Three.js scene graph as well as a GLTFParser instance that holds the original, deserialized glTF.
The GLTFParser holds associations between the elements in the original glTF and the Three.js scene graph. These associations are expressed both by GLTFParser.prototype.getDependencies and the cache object on the GLTFParser instance.
In some cases, the relationship between the original glTF element and the associated Three.js objects is obscured and cannot be trivially re-established. For example, materials associated with a skinned mesh are cloned, and the resulting clones are cached against a key that cannot be reconstructed easily:
three.js/examples/jsm/loaders/GLTFLoader.js
Lines 2118 to 2127 in 648c4bb
| cachedMaterial = material.clone(); | |
| if ( useSkinning ) cachedMaterial.skinning = true; | |
| if ( useVertexTangents ) cachedMaterial.vertexTangents = true; | |
| if ( useVertexColors ) cachedMaterial.vertexColors = true; | |
| if ( useFlatShading ) cachedMaterial.flatShading = true; | |
| if ( useMorphTargets ) cachedMaterial.morphTargets = true; | |
| if ( useMorphNormals ) cachedMaterial.morphNormals = true; | |
| this.cache.add( cacheKey, cachedMaterial ); |
Description of the problem
Consider a model editor that allows a user to:
- Load a glTF with any shape
- Interactively change the value of any field of any element of the glTF
- See the result of the change rendered in real time
- Export a new glTF
In an ideal world, the editor should faithfully re-export the model with its original hierarchy and shape. The only meaningful change in the exported file should be the one made interactively by the user.
In the pursuit of this goal, it is very useful (and probably required) that an association between the source glTF scene graph and the Three.js scene graph be made, so that for any change we make to a glTF element, we can reflect that change in the rendered Three.js scene in real-time without completely re-loading the glTF.
Some of the information required to correctly correlate the glTF scene graph with the Three.js scene graph is lost or obscured, and this makes the above described editor scenario very difficult (perhaps impossible) to achieve.
Three.js version
- Dev
- r115
- ...
Browser
- All of them
- Chrome
- Firefox
- Internet Explorer
OS
- All of them
- Windows
- macOS
- Linux
- Android
- iOS