Alternative to SceneLoader.GetPluginForExtension

Currently the class SceneLoader is deprecated, so when being imported it generates a warning, methods like ImportMesh have alternative that is not deprecated, but there is no non-deprecated alternative found in code for SceneLoader.GetPluginForExtension

@ryantrem will have a look tomorrow as today is labor day in the us :slight_smile:

Hey @kzhsw, can you share a little more about your use case? I just want to understand the scenario so we can expose the API in whatever way makes the most sense!

Case 1: Customized babylon loader
I’m loading from a .babylon file, but need to customize (preprocess the json data), so I need to parse the json before it comes to SceneLoader. And I want to avoid another json serialize/parse forced by babylonFileLoader for performance.
Using SceneLoader.GetPluginForExtension will allow the synchronized loadAssetContainer method, so I can safely override JSON.parse and recover it without side-effects to other async code.

    let jsonParse = JSON.parse;
    JSON.parse = (val) => val;
    const plugin = SceneLoader.GetPluginForExtension('.babylon');
    let container;
    try {
        container = plugin.loadAssetContainer(scene, data, '', onError);
    }finally {
        JSON.parse = jsonParse;
    }

Case 1: Globally configured loader options

I want to globally configure loader options like setting animationStartMode of gltf loader to NONE globally, not per call.

const gltf2Plugin = SceneLoader.GetPluginForExtension('.gltf');
if (gltf2Plugin) {
    gltf2Plugin.animationStartMode = 0;
    if (gltf2Plugin.createPlugin) {
        const createPlugin = gltf2Plugin.createPlugin;
        gltf2Plugin.createPlugin = function createPluginAndApplyOptions() {
            let plugin = createPlugin.apply(this, arguments);
            if (plugin) {
                plugin.animationStartMode = 0;
            }
            return plugin;
        };
    }
}

We’re trying to move away from synchronous loading as well as “options” specified directly on the plugin instance (e.g. we don’t plan to add any new options this way, and rather only add new options through the options passed into the various load functions). Given this, could the following work for you?

  1. For the first scenario, what if we had an onParsed callback option (similar to what we have in the glTF loader)? Then you could do something like LoadAssetContainerAsync(source, scene, { onParsed: (json: object) => { /* do your pre-processing here */ })
  2. For the second scenario, can you not just create a wrapper function that always passes in the options you want, and then in your code always use the wrapper function? Alternatively, what if we directly exposed a way for you to change the defaults, maybe something like DefaultGLTFLoaderOptions.animationStartMode = GLTFLoaderAnimationStartMode.None?
1 Like

I would rather not break existing synchronous code and rewrite all them to async, since making function async would force all callers to await (or .then) on them, which could be a massive change.
Or maybe it’s ok to export the .babylon loader from babylonFileLoader.ts instead of just registering to SceneLoader.

The json comes from some complex processing, and it contains complex references so I don’t want it to be serialized, or maybe passing a placeholder “{}” to source, and return the actual json in onParsed.

If the method was imported by class, it’s sure I can create a wrapper and override the original one, but if imported directly as function, seems it can not be assigned globally.

That sounds good.

I have a draft PR that I think addresses your concerns: Configurable default glTF loader options + expose function to load AssetContainer from serialized Babylon scene by ryantrem · Pull Request #17117 · BabylonJS/Babylon.js

For issue 1: You would be able to just call LoadAssetContainerFromSerializedScene directly. You would be able to pass in either the string to be JSON.parsed, or you could pass in pre-parsed object.

For issue 2: You would be able to simply set GLTFLoaderDefaultOptions.animationStartMode = GLTFLoaderAnimationStartMode.None.

Anything I’m missing, or is this good for your needs?

1 Like

Yeah, that’s good, thank you. I’ll try this after released. :grinning_face:

PR is merged, but heads up I marked LoadAssetContainerFromSerializedScene as @experimental mostly because we could change the name and/or params in the future if we ended up fleshing out more of these lower level format specific loader functions.

1 Like