Another gltf import question

Hi gang. I hope you like questions because I’m just getting warmed up :stuck_out_tongue:

So my current issue is in loading a series of .gltf files from blender. I initially had some problems with the imports being rotated backwards and incompatible with standard materials without flipping sideOrientation to 0, however this seems fixed by using PBR materials and forcing a 180-degree y-axis rotation on the incoming __root__ node; please let me know if there’s a superior way to get blender (2.8 beta) assets importing cleanly.

Beyond that, even importing just a couple of files using either SceneLoader.Append or SceneLoader.AppendAsync and manipulating the results as they come in seems to cause a couple issues:

  • Duplicated __root__ mesh; currently i’m renaming these to __${filename}__root__ as they come in, although this seems to make no difference because what still happens is
  • Some race condition causes multiple files imported simultaneously to conflate the __root__ namespace, so my handlers on glTF import (tweaking specific incoming meshes/materials and disposing of superfluous assets) act on the wrong __root__

for example, glTF A contains a complex model that i want positioned specifically in the scene and glTF B contains some scenery that can go in as-is, but also some other cruft that i do not need. I need meshes and materials from both. when i import, often the import callback for B will remove the model from A in a simple loop that removes the unwanted assets from (supposedly) its own root mesh, or the import callback from A will fail to position its model because it can’t find it in (supposedly) its own root mesh.

From what i can tell this seems to revolve around which __root__ gets imported first and if the other is at that time still in process of importing. I hope this makes sense.

One solution I can think of is to await completion of all loading and then loop through the scene’s children (since requesting __root__ by name is now useless) and test for presence or absence of desired nodes, and do followup accordingly at that point, however this would never be scalable.

any thoughts?

Pinging @bghgary

@derelict Can you provide a playground so I can repro?

I’ll see what i can do

1 Like

having a hard time getting my files shared to playground – trying to use some example files with content i’ve actually experienced the issue with but my server isn’t giving the appropriate CORS accept headers :frowning: . should have it figured out momentarily.

Ok, here we go:

Now; it probably won’t break the first time you load it; you may have to load it a few times to ensure the files are cached for you (when developing locally it happens every time, presumably because the files load immediately).
EDIT: Just hit ‘Run’ a few times and you should see the error pretty quickly.
RE-EDIT: Problem seems more prevalent on some computers than others; this brand new iMac seems to have the problem frequently where my aging Windows machine less so. On Windows, the order of the imports seems to matter, as well as whether the files are embedded gltf or paired with .bin files, (embedded seems to work better; import order seems to favor embedded-first, but no conslusive ‘solution’). On the iMac, it breaks consistently in all combinations.

what you’ll notice is that one of the models disappears, and the transforms on the other do not occur, due to a confusion of which ‘root’ node is receiving which handler code.

By the way, is there a reason about this __root__ naming convention?

Because as derelict notice, it could be more readable to get something like, for example, the filename rather than this __root__ naming

We have to use a constant for the root name (saved in the gltd content) and not the filename as users can rename the file:)

Even from a coding standpoint we need to have a constant name for the root so you know what to search for

any thoughts on this? also worth noting in my example above that the instances of the one model are inside out – the original seems to import fine and the material maps correctly, but the instances created from it are flipped. adding a standard material to any of the meshes also displays them inside out, as originally mentioned. probably has to do with the handedness and y orientation shifts between blender->gltf->babylon somewhere, same as the rotation issue. I can create another playground to make this more obvious if desired.

Yes please so that @bghgary can check it out

I think this is what you want:

Basically, you should not rely on the name of the root node but instead use ImportMesh so that it returns the meshes that were loaded. The first mesh is always the root.

1 Like

The inside out issue is probably because of the right-hand to left-hand conversion. The glTF loader inverts all the side orientation (winding order) by inverting the sideOrientation property of the loaded materials. If you just assign a material created by default to a mesh created by the glTF loader, it will have the wrong side orientation. To fix, set sideOrientation of the material to Clockwise.

You can also fix this by setting the scene to be in right-handed mode (scene.useRightHandedSystem = true)

1 Like

Thanks @bghgary! I was not aware that ImportMesh also pulled the associated Materials for the mesh – does it also pick up any other associated data from the file? I’m not using any animations in my initial testing, but want to make sure that the assets pulled from a given export get their other associated bits as well. This is a great solution since generally i know the names of the meshes i want from a file anyway, so i can specify them in the import instead of disposing everything i don’t need after import.

Also it seems like the ‘useRightHandedSystem’ is the overall solution for the inside-out issues, as this fixes the instance-inside-out issue as well; i had a vague idea that the handedness was responsible, but thanks for the thorough winding order explanation. i’m guessing the need for rotation is due to a disconnect in positive-z vs negative-z in the two systems?

you guys have been immensely helpful. i’ve been a programmer for 20 years but this is my first deep dive into the 3d world, so i apologize for any density or misinterpretation on my part about concepts or implementations, etc.

1 Like

does it also pick up any other associated data from the file?

For the glTF, ImportMesh, Append/Load all do the same thing underneath. The only difference is that ImportMesh allows you to specify what meshes to load. Note that it will load the whole node tree of each specified node name.

i apologize for any density or misinterpretation on my part about concepts or implementations

No worries. Let us know if you have any suggestions on how to improve our documentation.

1 Like