Hey folks - we recently made some fairly big changes to SceneLoader:
Introduced module level loading functions, which improves tree shaking (bundle size)
The new module level functions take an options object, which includes options for the load call, options for the specific loader (e.g. glTF), and in the case of glTF options for individual glTF extensions.
You can now make calls this:
const assetContainer = await loadAssetContainerAsync("path/to/model", scene, {
rootUrl: "path/to", // load function option
pluginOptions: { // options for loader plugins
gltf: { // options specifically for the glTF loader
skipMaterials: true, // a glTF loader option
extensionOptions: { // options for glTF extensions
MSFT_lod: { // options specifically for the MSFT_lod extension
maxLODsToLoad: 1, // a MSFT_lod option
},
}
},
},
});
This is intended to make configuring model loading easier and more discoverable. Prior to this, you would have had to do something like:
Just to confirm then - does this change how general (GLTF) models should best be loaded? I currently use SceneLoader.ImportMeshAsync, would it now be better to use e.g. appendSceneAsync?
If so, then: When importing meshes I currently make use of the ImportMeshAsync progress callback to have a loading bar, as well as the result.meshes it returns (in a .then((result) => {})), can the same be achieved with the new functions? From a quick look at the appendSceneAsync documentation it doesn’t mention anything about that.
Ah - thank you, I am indeed using es6 imports. I’d looked at the appendSceneAsync documentation but hadn’t noticed the onLoad in the LoadAssetContainerOptions. Hopefully it shouldn’t be too much work to switch it over as it seems to work in a very similar way - and for my use case any reduction in bundled size is important, so if it helps with that it’s worth it
appendSceneAsync doesn’t seem to return the appended meshes into a .then((result) => { result.meshes }) after the promise - do you know if there’s any other way to easily get a reference to the appended meshes?
Yes, pretty much what @noname0310 said on all accounts (better for tree shaking / bundle size, prefer loadAssetContainerAsync, and use the options for getting progress).
There is a typo in the above example in that it is both using await and a then, but you probably get the idea.
If there is some reason that ImportMeshAsync works for your use case, but loadAssetContainerAsync does not, please share details. We had not planned to introduce a module level function equivalent of ImportMeshAsync since I believe all its use cases can be hanlded with loadAssetContainerAsync.
Perfect, thank you (and thank you @noname0310!) for the confirmation on that. I’ll migrate my project over to the new API tomorrow and hopefully it’ll all work fine. As you say, as long as loadAssetContainerAsync is no less performant than ImportMeshAsync then any possible improvements to tree shaking etc. are of course worth it!
I’m all for improvements even if they do require some refactoring as long as they’re announced etc. as this one has been, progress is great!
What about the “animated start mode (autoplay)” on GLTF/GLB, is that disabled out of the box with the new LoadAssetContainerAsync, or is still needed some “tweaking” the way it was done via plugins in the case of SceneLoader?
//deshabilito autoplay tras carga de ficheros GLTF/GLB
BABYLON.SceneLoader.OnPluginActivatedObservable.add(function (plugin) {
if (plugin.name === "gltf" && plugin instanceof BABYLON.GLTFFileLoader) {
plugin.animationStartMode = BABYLON.GLTFLoaderAnimationStartMode.NONE;
}
});
For backward compatibility AssetManager is handled a little differently internally, but addMeshTask does accept the same options and behave the same way.
SceneLoader is deprecated, but we’re not going to remove it. The deprecation is saying “hey, there is a newer better API for this now that makes it much easier to specify options and is much more tree shakeable, so we recommend you use these newer APIs.” We may port AssetManager to the newer APIs in the future, but really that should be considered an implementation detail of AssetManager.
I perfectly understand your point here and, at the same time, hope that the aforementioned enhancements for the AssetManager by means of the new APIs, are going to be a reality in a near future.
The case is that, as I’m gaining experience with BJS, I’m definitively finding the several “managers” in it more and more useful, in order to not “reinvent the wheel” in the case of generic tasks.