How to interact with .glb parts or meshes?

I am trying to show/hide parts of a 3D model exported as .glb
I have no idea how to read the name or id of the parte int glb file and make them hide or show from a list of buttons.

I could not use playground because it do not read my file so I have to use my host instead.
https://toca.com.co/3D/-colmena.html

Thanka!


The isVisible property controls whether the object is displayed

GPU picking point and normal | Babylon.js Playground (babylonjs.com)
This example shows two ways to load the model on lines 405 and 437, respectively. Look at the callback input parameters and youā€™ll find what you want.

Thank you!, I will try how to make it works!

I usually use sandbox to check all of the parts of the object.

You drag n drop your glb into sandbox

Then you can target whatever you want with

scene.getMeshByName(name);
or
scene.getTransformNodeByName(name);

Thank you for answering!.
I know the sandbox. I understand there, how the .gld file is loaded and the porperties that I can control. However, I have not been able to make any intercaction with the ā€œmeshesā€ or nodes only with the whole object.
I do not how to hide /show the parts, how to code that.

1 - // Get object from the scene

const myMesh = scene.getMeshByName("meshName");

2 - // Show/Hide Object

myMesh.setEnabled(false/true)  OR mesh.isVisible = false/true;

Just figure out how to connect this with the event listener on the button.

So in theory it would be something like

button.addEventListener('click', () => {
   myMesh.setEnabled(!myMesh.isEnabled());
})

where myMesh is

const myMesh = scene.getMeshByName('meshName');

Note that this works if the node is type of Mesh. If you are dealing with the TransformNodes you would use

const myNode = scene.getTransformNodeByName('nodeName');

The rest is the same.

button.addEventListener('click', () => {
   myNode.setEnabled(!myNode.isEnabled());
})
3 Likes

Hi,
As briefly explained by @nogalo, there are different ways to show/hide a mesh.
Though, Iā€™m not sure that as a newcomer I would have understood it all :grinning:
So, hereā€™s just a quick example PG for you.

My advise, use the ā€˜Inspectorā€™ in your scene. Simply call

scene.debugLayer.show();

towards the end of your script (before returning ā€˜sceneā€™)


From the Inspector, in tab ā€˜scene explorerā€™, unfold the first category of ā€˜Nodesā€™. This will show all the meshes loaded or created in your scene. Click on any plus button to unfold the hierarchy. This is where you will find all nodes/meshes that have been parented to this root node. In nodes, everything that has a cube icon is a mesh. The other icon shows a transformNode which does not have geometry.
Typically, hiding a tranformNode will not hide the meshes set as child of this transformNode.
The eye icon you see to the right of the mesh or transformNode name is the show/hide. Better said, it calls the property of ā€˜isVisibleā€™ (mesh.isVisible = true) to show a mesh, or (mesh.isVisible = false) to hide it. You can click on it in the Inspector to display or hide the mesh.


You can act with any mesh (or transformNode) loaded through a model AFTER the model is successfuly loaded or within the IMPORT function.

You can select a mesh (after import) by its ā€˜nameā€™ or its ā€˜idā€™.
You can also declare a mesh after or within the import sequence and next use this variable to access it.

I hope this helps and meanwhile, have a great day :sunglasses:

Hello!.. Thank you for your answer. I could figure out how to turn on and of a mesh but I canā€™t add more buttons, checks buttosn to do itā€¦ could you please tellme how can I add more buttons?
Thanks

look how it is working nowā€¦ Babylon.js sample code

Hi,
At what time do you want to add more buttons? Do you want to have just more buttons visible at all time OR do you want to add a button depending on certain condition(s)?
To really help here we would need a PG.

Did you check how to [import external assets in PG] ?(Using External Assets In the Playground | Babylon.js Documentation)
Else, we donā€™t really care about the model. You could use any model (I.E. those from the asset library)
What we need to see here is the code you are using to create your button(s) and how you hook them to whatever function. From there, we can simply debug or enhance your PG and explain on the side.

Hi Mawa, thanks for answering

I could make the code works wiith in the playground with a babylon asset.
But It does not work on my web site with my own model.

I am using 9 checkboxes to make visible/invisible some meshes.
They need to be visible all the time.

I used gui.babylon to create the GUI
Ofcourse, I changed names and URL, and snipets for .json file
https://toca.com.co/3D/3DBee.html

1 Like

In your website, you need to wait for the gui to be parsed.

vs the playground:

I am getting all these errors

Hi,
First, congrats for the PG set-up. This works for me.
As for the above quote after the :+1:comment from @sebavan, I would say ā€œnot really :stuck_out_tongue_winking_eye:ā€

You forgot the promise (await in this case), meaning your script is processing elements that have not yet loaded. This includes the ADT AND the meshes.

So, for the adt (when loaded async), it should read somethink like:

async function loadFsGUI() {
    var fs_gui = ā€œ/guiTexture.jsonā€

    //Fs GUI
    const adtfsgui = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI('adtfsgui', undefined, undefined, BABYLON.Texture.NEAREST_NEAREST);
    await adtfsgui.parseFromURLAsync(fs_gui);
}
loadFsGUI();

ā€¦or just the alternate/simple version you can find in the doc
IMPORTANT IS YOU ā€™ AWAIT ā€™ before doing anything else with it.


And then, before you access the meshes, you also need to make sure these are loaded. You can do with a promise or simply use

*.then(() => {
console.log (ā€œpromise(s) are doneā€);
//now do anything with the imported meshes
})

I.E.:

BABYLON.NodeMaterial.ParseFromSnippetAsync("#3FU5FG#90", scene).then((watermat) => { waterwall.material = watermat; });

You can also use ā€˜awaitā€™ (same as for the gui loading example above). But then note that ā€˜awaitā€™ only works within an async function. I.E::

class Valkyrie {
    static async create(scene) {
        const asset = {};
        await BABYLON.SceneLoader.AppendAsync("https://spacepirates.babylonjs.com/assets/gltf/", "valkyrie_mesh.glb").then((result) => {
// do anything with your imported meshes, I.E.
            for (let index in result.rootNodes) {
                if (result.rootNodes[index].name === "__root__") {
                    for (let child in result.rootNodes[index]._children) {
                        if (result.rootNodes[index]._children[child].getClassName() === "Mesh" && result.rootNodes[index]._children[child].name === "valkyrie_mesh") {
                            asset.valkyrieMesh = result.rootNodes[index]._children[child];
                            asset.valkyrieRoot = result.rootNodes[index];
                            for (let valkyrieChild in asset.valkyrieMesh._children) {
                                if (asset.valkyrieMesh._children[valkyrieChild].name === "valkyrieShield_mesh") {
                                    asset.valkyrieMesh._children[valkyrieChild].setEnabled(false);
                                }
                            }
                        }
                    }
                }
            }
            asset.valkyrieRoot.scaling = new BABYLON.Vector3(3200, 3200, -3200);
            asset.valkyrieRoot.position = new BABYLON.Vector3(1750, -680, 730);
            asset.valkyrieRoot.rotation = new BABYLON.Vector3(0, 120/57.29, 0)
        });
    }
}

Above script courtesy of patrickRyan for the SpacePirates demo :smiley: Check it out if you havenā€™t done yet :stuck_out_tongue_winking_eye: