How to get transformNodes and meshes to render

I am trying to load in objects from a .blend file converted into a .glb file. I have objects nested in empty objects so that I can try and detect which objects are parents/children of other objects, and so I can hide/show children of a certain group based on object naming conventions.

A snippet of my object hierarchy in blender can be seen below:

I got my application working by using:

const result = await SceneLoader.ImportMeshAsync(null, “assets/babylon-models/”, this.modelID, this._scene);

this returned meshes and rendered everything fine.

But I noticed that it just returns the mesh primitives, so I looked to try and use this instead:

const result = await SceneLoader.LoadAssetContainerAsync(“assets/babylon-models/”, this.modelID, this._scene);

however, this returns an AssetContainer.

I tried to access the transformNodes (result.transformNodes) so that I can then access the parent transform nodes and the children meshes of all of the transformNodes. However, when I tried to access individual transformNode of transformNodes, I don’t know how to get and render all of the meshes.

This could be really obvious, but I’ve been coding all night and have a ton of brain fog.

TLDR: I’m trying to create a list of meshes with the empty objects from my blend file, so that I can show and hide and collide with groups of meshes in my scene. I am not sure what to use, and using await SceneLoader.LoadAssetContainerAsync in public async _loadAsset() (which is called in public async load()) seems to lead to the scene not rendering all of my meshes. Any help in regards to gathering a list of meshes (and empty objects from blender, so the hierarchy is maintained and all I have to do is check the parent’s name and descendants) would be much appreciated! Thanks!

Here I guess you could load everything and then use scene.getTransformNodeByName() or getMeshByName() to find and enable/disable on demand with setEnabled some part of your scene graph ?

That seems it would be super expensive everytime I am trying to access a mesh. I am trying to parse out the meshes/transformnodes into lists so that I can hide and show them easily. I just don’t know how to retrieve all the meshes and nest them under transformNodes and still render everything. (I don’t know which function is best to use to import the data from the glb file for this purpose)

Ohhhhh you would not do it everytime, actually you should do it only once:

  • call your import function
  • in the call back, get all the meshes/transform (root of your use case) by names and store them
  • disable/enable what you want
  • later during the experience (you can still use your previously stored reference) enable/disable what you need

If this would not work, I am probably not getting the use case here ?

I don’t want to manually add every single mesh and transform to a list by getting them by their name strings.

The use case is that I have a model in a blend file and converted it to glb. I’m reading in the glb and I want to maintain the object hierarchy of the blend scene. In the blend scene, I created object hierarchy by nesting objects (some empty, some meshes, some cameras) underneath other empty objects. In babylon, I want to be able to check to see which objects are underneath which parents, so that I can add collisions, hide/show the objects, move camera to the transform of the object, etc.
The only way that has worked for me, so far, to get the mesh data is by calling ImportMeshAsync. But this just returns a list of AbstractMeshPrimitives. I can check their _parentNode but not all of the objects of the file are listed as _parentNodes in that returned result. This is because it just gets the meshes, not the empty objects as well. So the empty objects do not show up in the results (some do as parents of the primitive mesh, but most do not because they are empty object parents of empty objects). This severely limits how I can maintain and check the object hierarchy that I had like in the blend file.

So I am trying to figure out how I can get all of the empty objects, and nest the associated meshes of that empty object’s group name under them.

What is also related, is that the ImportMeshAsync function returns a list of AbstractMeshes. I am trying to add these meshes to a highlight layer dynamically when the mouse hovers over the meshes, but HighlightLayer.addMesh() takes a Mesh parameter, not an AbstractMesh. Is there a way to convert from AbstractMesh to Mesh?

Highlight layer does not support instances hence the type as Mesh. You could nevertheless check with getClassName() if it is a “Mesh” and cast safely to Mesh in this case.

Let me add @bghgary for the hierarchy parsing part.

In Babylon, Node -> TransformNode -> AbstractMesh -> Mesh or InstancedMesh. Every node can have child nodes (as well as a parent node) to create a scene graph. You can use node.getDescendants, node.getChildMeshes, or node.getChildren for different way to get the graph.

ImportMeshAsync will get all the TransformNode and AbstractMesh objects that were created. You can use this along with the functions I noted above to get at any part of the tree if you don’t want to use names. glTF objects without a mesh will create a TransformNode.

I’m not sure why there is a need to store every single mesh. When you disable or set visibility to 0, it affects the node/mesh it applies to as well as all the descendants.

Hope this helps.

1 Like

Thanks for the help! But it seems that ImportMeshAsync only returns:

{animationGroups:
meshes:
particleSystems:
skeletons:
proto: Object}

How can I access the Nodes so that I can cast them down from Node to TransformNode and/or Mesh?
Thanks!

What version of Babylon.js are you running? The result should have a transformNodes property.

4.2.0-beta-16. Also, in the returned meshes, I can see that it returns Mesh and InstanceMesh, but it doesn’t return any of of the transformNodes

am I forced to use an earlier version? or a later version?

Can you share a playground of this? It should be working with the latest.

Here is the best I understood how to set it up.

https://playground.babylonjs.com/#S3XVIF#1

This PG doesn’t work for me.

Uncaught SyntaxError: Cannot use import statement outside a module

Yeah I’m honestly not sure how to set it up. The playground seems to run just with the createScene() function. My code has a bunch of different functions and frameworks with asyncs. Not sure how to showcase it in the playground. I’m open to suggestions.

Ideally, if you can simplify the problem to as small of a repo as possible, that would be best. If not, can you share the model you are having issues with?

I tried shrinking the code a bit. I got rid of the angular code and DOM function. Not sure if that will shroud the problem though. I wonder if it’s an async issue with loading the model.:
I still get a “null is not a function” error. I’m not very familiar with the playground, but hopefully this is easier to plug into.:

I can send you the file, though not sure how on here…is there a way to direct message it? It’s 80.3MB and can’t be dropped into this text input box.

If you zip it up, you should be able to drop it here. Or you can direct message me and include the file the same way.

Touche. although i zipped it and its still 76MB. it keeps timing out in the messenger. I sent you a message anyway though.