The GLTF2 Exporter seems to be ignoring any Mesh or TransformNode that does not have children in the scene hierarchy before exporting/serializing the scene.
Here is the line of code that seems to be responsible for this behaviour:
https://github.com/BabylonJS/Babylon.js/blob/v4.0.0/serializers/src/glTF/2.0/glTFExporter.ts#L1342
This can be troublesome as sometimes it is useful to have an empty transform that stores a location (for example a spawn point for a prefab instance, a player, etc) or an orientation, etc. I'm not sure if this is something that is necessary because of the way the GLTF specs are, if it is I would be glad to know more about this subject.
The repro code in the Babylon Playground creates two sets of Mesh and TransformNode instances. If you export them and reimport them in the Babylon Sandbox for example, you will noticed in the Inspector that the nodes without children have been ignored at export-time.
These instructions can also be found in the repro playground:
NOTE: To export to GLB:
1- Select the GEAR icon in the Babylon Inspector toolbar above
2- Select Inspector in the displayed menu
3- In the Inspector panel that should have opened to the right, select the WRENCH icon.
4- In the SCENE EXPORT section, select Export to GLB
5- Load the downloaded file in https://sandbox.babylonjs.com/ by dragging it in the middle of the scene.
6- Open the Babylon Inspector at the bottom of the window
7- Expand the + Nodes section
8- Notice that only meshes and transform nodes that have children haven been exported
Tested in BabylonJS 4.0.3, seems to also be occurring in latest version (master branch).
Exported scene should have all the meshes and transform nodes regardless of if they have children or not?
Any Mesh or TransformNode without children will be ignored when exporting to GLB
It seems like an easy workaround would be to add a temporary child mesh to the meshes we wish to preserve.
@CedricGuillemet do you mind having a look?
Should we even be ignoring any nodes at export?
No. Unless this is specified by the user
Should we even be ignoring any nodes at export?
I think its useful to be able to ignore some nodes manually like we already can with the shouldExportNode predicate that is already provided (and works without issues).
I'm not sure why it was needed to ignore nodes that don't have descendents. The code seems to be doing this intentionally so I figured there might have been a technical reason. The workaround of adding a temp child works great for now. That temp child also ends up not being exported, which works out well too for now. :)
We should not ignore them. It is a mistake for sure
@osmanzeki fancy doing a PR to fix it?
@osmanzeki fancy doing a PR to fix it?
Sure thing, should I address backwards compatibility first? I could probably add an option to disable this if the user wants to. It would have to be enabled by default to preserve BC. I'm not sure how you would like to proceed. What do you think?
Well this is more a bug so no worries for backward compat
All good here?
@Drigax do you have a fix for this one? It is flagged as bug so I would like to kill it asap
PR for the fix is up 馃槉
Hey guys, sorry for late replies and thank you for the PR! I'm not sure but I think the same bug could also affect the regular GLTF export function as well.
I wanted to take some time to test the bug on both and then a fix on both. I've only tested this bug/behaviour on the GLB export for now.
This is the line that I think might cause the same issues in .gltf exports:
https://github.com/BabylonJS/Babylon.js/blob/d8987e26309b5e2b7ff1553b62ba25059ba5a7ed/serializers/src/glTF/2.0/glTFExporter.ts#L1285
Hey @osmanzeki, I'm not too sure if we need to worry about GLTF vs GLB export, as both share the same scene creation logic:
See:
https://github.com/BabylonJS/Babylon.js/blob/0747ba1e623fba5b5c1eba3117e19b4a7998fb88/serializers/src/glTF/2.0/glTFExporter.ts#L754-L756
vs:
https://github.com/BabylonJS/Babylon.js/blob/0747ba1e623fba5b5c1eba3117e19b4a7998fb88/serializers/src/glTF/2.0/glTFExporter.ts#L811-L813
Where both call _generateBinaryAsync() which calls createSceneAsync(), which calls createNodeMapAndAnimationsAsync() where we remove the extra node checks before adding it to our exported scene:
https://github.com/BabylonJS/Babylon.js/blob/0747ba1e623fba5b5c1eba3117e19b4a7998fb88/serializers/src/glTF/2.0/glTFExporter.ts#L783-L786
We shouldn't see a difference in behavior between those cases, right?
@Drigax It seems like there are two places where a nodemap is created, in the createNodeMapAndAnimationsAsync function and in the createSceneAsync function too at this position:
I'm not 100% sure but it seems like the same behavior will occur here too.
I will finally have some time to test all of this weekend. I will report my tests here for both the GLB and GLTF exports.
Most helpful comment
Well this is more a bug so no worries for backward compat