Load a new scene with dynamically created objects after the render loop starts

Hi everyone, I would like some advice to understand how to achieve my result.
I don’t know how to load a new scene with dynamically created objects after the render loop starts.

Let me explain, so I have a php page that uses babylon js.
In scene 0 we are on a planet and there is a “spaceport” mesh that, if clicked, changes scene, sends us to scene 1.

In scene 1 we are in space, here I have many “planets” objects (let’s say they can be even more than 500). The planets are created from the beginning by loading in babylon js from php an array which I transform into json and then it is cycled in the createScene function.

Each planet has a unique ID, because it is a player’s planet. I would like to obtain that upon collision of the player’s mesh and the planet a new scene is loaded that populates the surface of the planet with objects based on data saved on the database.

What I can’t figure out how to do is load a scene after the render loop has already started.

I also thought about creating a scene for each planet before starting the render loop but it’s too heavy, I think, it doesn’t seem like the right approach.

So I thought I’d make an ajax call when there is a collision, verify the data of that planet by reporting the array as a result of the ajax call, finally mesh the data I received. To do this, however, I have to create the scene and put it inside the engine after the engine has started …

How do I do such a thing?

As far as I understand you may use Asset Containers - Asset Containers | Babylon.js Documentation
Push all what you need to a container, then addAllToScene or removeAllFromScene.

So let’s see if I understand, taking the example you showed me.

scene0 = (planet)
scene1 = (open space)

First I put the 2 scenes in the container like this
var container = new BABYLON.AssetContainer (scene0);
container = new BABYLON.AssetContainer (scene1);

Then when there is a collision with a planet I do this
container.removeAllFromScene (scene0)
And so I delete everything on the starting planet
Then I call ajax, take the data, cycle it and create a new scene
in the end
var new_scene = new BABYLON.Scene (engine);
container.addAllToScene (new_scene)

correct?
Anyway this is the current structure of my code

var canvas = document.getElementById("renderCanvas");
var startRenderLoop = function (engine, canvas) {
engine.runRenderLoop(function () {
    if (switch_scene === 0) { //scene of space
        sceneToRender = engine.scenes[0];
    } else if (switch_scene === 1) { //scene of start planet
        sceneToRender = engine.scenes[1];
    }
    if (sceneToRender && sceneToRender.activeCamera) {
        sceneToRender.render();
    }
});
}
var engine = null;
var scene = null;
var sceneToRender = null;
var createDefaultEngine = function () {
    return new BABYLON.Engine(etc etc);
};
var creaScenaSpazio = function () {... HERE I CREATE SCENE 1}
var creaScenaPianeta = function () { HERE I CREATE SCENE 0}
var switch_scene = 1;
window.initFunction = async function () {
  var asyncEngineCreation = async function () {
      try {
          return createDefaultEngine();
      } catch (e) {
          console.log("the available createEngine function failed. Creating the default engine instead");
          return createDefaultEngine();
      }
  }
    window.engine = await asyncEngineCreation();
    var scena_spazio = creaScenaSpazio();
    var scena_pianeta = creaScenaPianeta();
    if (!engine)
        throw 'engine should not be null.';
    startRenderLoop(engine, canvas);
    window.scene = scena_pianeta;
};
initFunction().then(() => {
    sceneToRender = scene
    console.log("switch_scene" + switch_scene);
});

Should work.
Here is just PG example with scenes switching - https://playground.babylonjs.com/#JA1ND3#48

1 Like