How do I get a reference to a mesh after loading it?

I’m loading an obj with the following:

BA.SceneLoader.Append("./models/", "ship.obj", scene, (scene) => {
    // do something with the scene
});

but how do I store the mesh in a variable so I can change its position, etc?

Hi @Kochab and welcome to the forum.

// do something with the scene
for(var mesh of scene.meshes) {
mesh.position = …
}

2 Likes

Hi @Arte, thanks. That works to change the position, but I’d also like to store the mesh I just added to a variable so I can refer to it outside of that callback. Given a scene can have many meshes, how do I know when I get to the mesh I’m looking for?

I think I found what I needed, which was a different way of importing:
BA.SceneLoader.ImportMesh("ship", "./models/", "ship.obj", scene);

And then I can refer to it by name:
let ship = scene.getMeshByName("ship");

6 Likes

Thank you, Kochab! I was also having trouble figuring out how to refer to a particular mesh in a Blender-generated scene, trying to bend over backwards to make my script more complex than it needed to be. Your simple solution worked for me right away. :smiley:

1 Like

I’m trying this and it’s not working…
My model loads fine if I leave the first argument of SceneLoader.ImportMesh blank - like SceneLoader.ImportMesh("", "./models/", "ship.obj", scene);
However if I add a name into the first argument, the model fails to load and I get an error Failed to find node 'name'
Any idea why this might be?

1 Like

Here is very simple PG - https://playground.babylonjs.com/#8IMNBM#291

One needs to call to imported mesh inside the callback.
Then you find the main transform node - meshes[0], or other meshes (for example, with scene.getMeshByName function) and whatever you want with them :slight_smile:
You’ll find tons of examples how to do it when performing simple search in PG and API.

1 Like

The meshNames parameter is a filter, so I think the problem is that none of the meshes of the model is named ‘name’. :beers:

1 Like

Ahh so you’re saying you can only reference a mesh inside the callback? I’m looking for a method to access a model from outside of the ImportMesh callback function. How would you go about doing this?
scene.meshes is returning an empty array.

1 Like

sounds like you call before the import is ready? have you tried scene.executeWhenReady(() => {
// do something here
}); ?

When you call SceneLoader.ImportMesh, if you pass a name or array of names as the first parameter, then only mesh(es) with that name(s) will be loaded. I think you just need to make sure that you’re passing the correct name of the mesh that you want to load or else use “” if you want to load all of them, then scene.meshes should be populated and scene.getMeshByName should work then as well… :slightly_smiling_face:

You could also use the promise based version with const result = await ImportMeshAsync(...); and you ll have what you need in the result.

2 Likes

You can also do something like…

let mesh;
BABYLON.Scene.ImportMesh(...,function(meshes) {
   mesh = meshes[0];
});
scene.onBeforeRenderObservable.add(() => {
  if (mesh) {
    mesh.position.y += 0.01;
  }
});

In other words, have a variable outside the scope of the callback. Set it in the callback, and then just check that it’s been set anywhere else that you use it.

3 Likes

async await is the best thing, Thank you for the reponse.

1 Like

One thing I didn’t realize when using ImportMesh is that you are not specifying an arbitrary identifier name for the mesh that you can simply refer to later. It is for importing a specific mesh (or meshes) from the file:

ship.obj

# Blender 3.4.1
# www.blender.org
o fighter
v 1 -3 0
...

In this case, I could import the obj without specifying any meshNames, and for getMeshByName, I would specify “fighter”.

If you use await ImportMeshAsync, you can use getMeshByName right away. If you use ImportMesh, you need to call scene.executeWhenReady.

1 Like