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