How to use an imported mesh outside the async BABYLON.SceneLoader.ImportMesh function

Hi everybody,

I have a problem when i want to import a mesh and use it AFTER the import async function. I’m not interested in writing all the code inside the function

Is there a way to know if the mesh is loaded and find it back outside the function ?

Thanks.

3 Likes

I normally just call another setup or initialise method inside the load finished callback in order to keep the code separate but still ensure everything is loaded. It’d probably get messy any other way e.g. you may need to set a global isLoaded flag and watch/check that periodically, which is not ideal.

But if you just want to know if a mesh is loaded or not, doing a scene.getMeshByName() - if it returms a mesh you’re good to go, if null then not. Again, I don’t think this is as clean as just calling a setup or initialise method within the load finished callback.

3 Likes

You could also use the importMeshAsync function ?

1 Like

ImportMeshAsync seems the way to go for me - the async/await paradigm helps a lot avoiding those huge callback functions :slight_smile:

You can do it on the playground by adding “async” on the “createScene” function definition:

var createScene = async function () {

and using:

const result = await BABYLON.SceneLoader.ImportMeshAsync(...);

Then the function will pause execution while it waits for the results of the async operation. You can check an example in this playground here - it waits for the mesh to load before changing its materials:

https://playground.babylonjs.com/#ZQDDPC

7 Likes

The author probably wants to preload the mesh and separate the implementation from the io. IE: Something equivalent to something like BABYLON.SceneLoader.PreloadMeshAsync(…) => void.

@bvaisman
I’ve been wondering the same thing actually. Have you tried using BABYLON.SceneLoader.ImportMeshAsync(…) { () => void(0) } to preload ,
then just calling again BABYLON.SceneLoader.ImportMeshAsync(…) {actual implementation}
when you want to use? This is how most routers “preload” React.lazy imports.

–io strategies–
If that doesn’t work well, you could preload the data into indexdb and then import it from a data uri. You can also clone fetches (Response.clone() - Web APIs | MDN).
If the resources are on the same domain, you can use dynamic import to get a little better perf than fetch. They’re essentially the same thing, but dynamic import skips some checks.
Another solution, and probably best, is to preload in service workers (this works really well but its a mind fuck to implement). That has the benefit of sharing the module across v8 isolates on the same domain. (ie: across iframes/embeds) , if that’s a concern for you.

–cpu work–
It would be nice to have some clear way to tell Babylon parse the data into its internal structure before use, ideally in a worker. Maybe there’s some way to do it, maybe not and we can implement it!

1 Like

@jeremy-coleman this is kind of our asset container can be used for Asset Containers | Babylon.js Documentation

1 Like

@carolhmj gave me the solution. It is the simple way to work without any promises.

So I created a function loadgltf which returns the mesh i want to import and now i’m able to change whatever i want (positions, materials) AFTER the loading.

Thanks very much

2 Likes

Can you please share the code?
I’ve been stuck cause of this issue

Hi @Harsh_Rathore,

The code is quite simple but the function must be asynchronous.

async load_Objet(file,path){
var data = await BABYLON.SceneLoader.ImportMeshAsync(“”,path,file,scene)
var mesh = data.meshes[0] //the created mesh
}

Boris

2 Likes