Loading a new scene in Android

Hi everyone,

I’m currently exploring the Babylon Native library on Android and have run into a tricky issue that I haven’t been able to solve.

My app allows users to select from a list of .glb files and view them in a separate Activity using BabylonView. The first time I launch the Activity, everything works fine — the selected model is loaded and rendered correctly.

The problem comes when I exit the Activity and select a different .glb. When the Activity restarts, it still shows the previous scene, even though I’m updating the path and attempting to load a new file.

I’ve tried cleaning things up in onStop() and onDestroy() using:

scene.dispose();
engine.dispose();

To load the .glb file I use a slightly modified version of the experience.js that is available in the Android’s project in github: BabylonNative/Apps/Playground/Scripts/experience.js at master · BabylonJS/BabylonNative · GitHub
My modifications (around line 47):

let path = typeof globalThis.modelPath !== "undefined" 
    ? globalThis.modelPath 
    : "app:///Scenes/brie_comte_robert.glb";

BABYLON.SceneLoader.AppendAsync(path).then(function () {
    BABYLON.Tools.Log("PlaygroundActivity BJS, Loaded");

And here’s how my Activity loads the script:

    override fun onViewReady() {
        loadScene()
    }

    fun loadScene() {
        Log.i("BabylonNative", "load: $modelPath")
        isSceneInitialized = true

        val injectedJs = "globalThis.modelPath = '$modelPath';"
        val sourceUrl = "runtime-injected.js"

        mView.eval(injectedJs, sourceUrl)
        mView.loadScript("app:///Scripts/experience_variant.js")
    }

Thank you all for reading, and a big thanks to the Babylon team for all the impressive work!

EDIT: I’ve tried with and without the scene.dispose()and engine.dispose().

Just a few thoughts.
You append a new scene to an engine that just destroyed the original scene, maybe the append gets confused? Why not loadAsync the new scene.

The loader you use is deprecated and the replacement is a much better loader. (Check the documentation for it)

Does your mView.loadscript fires the second time? Maybe a caching thing.

Hope one of these help you out.

cc @BabylonNative

A simple test I would do:

  • console.log(path) in the AppendAsync promise, to be sure variables are properly set function is called
  • add scene.dispose() before AppendAsync
  • do not load if path is empty and try with an empty path after using a non empty path
1 Like

Hello Niels, thank you for your answer! :slight_smile:

I’ve tried with and without the scene.dispose() and engine.dispose functions.
Without calling those, the previously loaded scene stills play, but if I dispose of the engine and/or the scene, nothing happens (I just have a black screen or the previous scene that’s frozen).
The mView.loadscript() function is called the second time (the Android logs show that this part of the code runs as expected), but the JS code isn’t executed (the JS logs don’t appear the second time).

Concerning the deprecated function,
I should then replace BABYLON.SceneLoader.AppendAsync(path) by BABYLON.AppendSceneAsync("path/to/model", scene);. Is it the ‘module level function’ to use as recommended here: https://doc.babylonjs.com/typedoc/classes/BABYLON.SceneLoader ?

Hello Cedric, thanks for the advices!

The logs show that the path are as expected, and I still have a default file path in case it is not the case.
I’ve tried adding the scene.dispose() before the AppendAsync, but, I still end up with the same result, it seems that once I’ve left the Activity, the mView.loadScript() method don’t work anymore.

Can you do a repro with BN playground example?

Hello,
Sorry for the late response, it took me some time to prepare an isolated test project.
I can update it if necessary.

Here’s the repository: https://github.com/HalTobin/BabylonNativeTest
The project shows what happens when exiting the PlaygroundActivity and opening it again.