Selecting meshes imported using a GLB file

Hello,
I’m trying to learn Babylon reading the guides and following tutorials.

I have a question about something that was explained to me in a different way.
Basically, if I want to select a mesh imported using a .glb file, how can I do it after this was imported?
I explain better. I know that you can import a file and after adding it include the .then(function()) to execute additional commands (such as adding a material, etc.).
What if I want to do that outside the function? For example, if I want to hide an element on click or move one of the meshes when something happens, is there a way to?

I have this playground I’m working on that includes some diamonds and the floor.
When I add the shadows, I need to create the shadow generator inside the .then(function()) to add each single element to the shadow Caster array. But let’s say I have some imported models and some primitives generated directly in Babylon… Is there a way to say for example:

[shadowGenerator.addShadowCaster(diam.meshes[1], true);](https://shadowGenerator.addShadowCaster(diam.meshes[1], true):wink:

outside the function executed right after the import command? In this way I can add also the primitives and keep the code in order.

Thank you very much for your help! :slightly_smiling_face:

This is more a general JS question so let me give you an example here.
The best way to deal with your need is to use async / await:

var delayCreateScene = async function () {
    // Create a scene.
    var scene = new BABYLON.Scene(engine);

    // Create a default skybox with an environment.
    var hdrTexture = BABYLON.CubeTexture.CreateFromPrefilteredData("textures/environment.dds", scene);
    var currentSkybox = scene.createDefaultSkybox(hdrTexture, true);

    // Append glTF model to scene.
    await BABYLON.SceneLoader.AppendAsync("scenes/BoomBox/", "BoomBox.gltf", scene);

    // Create a default arc rotate camera and light.
    scene.createDefaultCameraOrLight(true, true, true);

    // The default camera looks at the back of the asset.
    // Rotate the camera by 180 degrees to the front of the asset.
    scene.activeCamera.alpha += Math.PI;

    return scene;
};

glTF Loader Demo | Babylon.js Playground (babylonjs-playground.com)

Thanks to the await (and the async keyword on the function itself) you can consider all async call like they were synchronous :wink:

1 Like

Hey @Deltakosh
This is definitely something I didn’t even imagine at all… it is kinda hard to grasp for a newby but also REALLY COOL!

So basically it is like it creates all the elements before actually adding them to the scene… and because of that the elements are still “tweakable” in the meantime (if I understood right).
But now I get a question… how can I select a single element of the beatbox (or any other model imported)?
In your example the await function does not have a name… so I guess I need to write it as

var beatboxy = await BABYLON.SceneLoader.AppendAsync("scenes/BoomBox/", "BoomBox.gltf", scene);

And then select the single elements using the array?

beatboxy.meshes[1].material = newMatThatICreated;

Also… I noticed that in some cases, examples show the elements selected by name. In my Diamonds example, in Blender I called the objects diamond01, diamond02, etc. and the floor, FLOOR.
Are those names still in use in the .glb file?

Something like beatboxy.meshes.frontPart.material = newMatThatICreated;?

Thank you! :slightly_smiling_face:

Hello @Deltakosh
It worked!!!

I managed to assign the material outside the function! I really love this!
This is the code I’m working on… it is not complete as I am reorganizing everything, but I tested on a single diamond, and it seems working well and is also really legible :grinning_face_with_smiling_eyes:
https://playground.babylonjs.com/#FEEK7G#322

Do you know if there is a way to select the elements by name and not by position in the array?
Something like
objs.meshes.diamante01.material = diamond;

Thank you!!!

1 Like

Glad that it worked!

1 Like

something like: scene.getMeshByName("diamante01").material = diamond;

1 Like

Wow… it is similar to the HTML DOM…
I thought I had to use the variable name I used to load the meshes as main object…
So basically when I search for a mesh I uploaded it is like it is “floating” in the code and I take it out using the “getMeshByName”.

This is really cool also because I can apply other stuff rather than just the material… like a vector to move a single mesh!!! :grinning_face_with_smiling_eyes:

Glad you like it :slight_smile:
Please flag post with “solution” when you get the correct answer. It helps others figure out where is the right topic (i did it for this one no worries)

Yes.
I guess that with this post, I asked several questions… should I flag as solved and post my Diamond shader WIP somewhere else?

I am still learning, so there will be other questions…

Overall the best you can do is to focus on one question per thread (so it is easier for others to find them later)

1 Like

The async function to create the scene really helps the legibility of the code…
I struggled a little adding the material to the element I load via a .glb file as it had to be done inside the function created after .then

It is true that it doesn’t change much as the code is executed, so there are no changes when it is launched… but yet the feeling is to have more control. I think that for now I’m using this method to create all the scenes :sweat_smile:

1 Like