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 ?
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.
ImportMeshAsync seems the way to go for me - the async/await paradigm helps a lot avoiding those huge callback functions
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:
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!
@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.