I don’t want to use this method - https://www.babylonjs-playground.com/#JA1ND3#48 because I cannot load 100mb worth of files in one function and have to split them up. I am making a slideshow of 3d models and need to be able to cycle through a bunch of highly customized and large scenes.
So does anyone have a simple example of how to clear out the old scene which contains a .babylon or .glb or .gltf file in the canvas and render a completely new one using event listeners on a button?
Some more context for what I am doing … I have created a UI that is outside of Babyon and loads up a scene using ES6 module. Inside the .js file i am importing something like this code below:
export const loadScene = canvasElementID => {
var canvas = document.getElementById(canvasElementID);
var engine = new BABYLON.Engine(canvas, true);
/******* Add the create scene function ******/
var createScene = function() {
var scene = new BABYLON.Scene(engine);
var camera = new BABYLON.ArcRotateCamera(
"Camera",
0,
0,
0,
new BABYLON.Vector3(0, 6, 0),
scene
);
camera.setPosition(new BABYLON.Vector3(0, 5, 60));
camera.attachControl(canvas, true);
var light1 = new BABYLON.HemisphericLight(
"light1",
new BABYLON.Vector3(80, 0, 420),
scene
);
// import glb
var exampleGLB = BABYLON.SceneLoader.Append(
"./scenes/car/gltf/",
"Car.glb",
scene,
function(scene) {}
);
return scene;
};
};
I need to properly destroy/dispose/garbage collect that scene and load up another one when the user clicks a button. I have 50 scenes and am looking for a good way to do this so the user can jump around these scenes relatively quickly, ideally with some sort of caching enabled as they will be coming back to scenes they have already opened a lot.
Thanks for your reply. The first link you gave is the same as the one I provided in the top post and as far as I can see this does not solve my question.
Let me put this in a different way because I may not have explained it properly.
I have a a project which consists of 3 project files.
The index.html contains 2 buttons which will allow me to load up either scene when the button is pressed.
So what is the correct way to load the code in the links above but by storing that code in separate files and clearing out the scene when another one is loaded?
This should be a super simple answer I would imagine.
you’re already doing what i did in my example, except if you want the scenes to be released / garbage collected, add scene.dispose() before creating a new
function loadLeft() {
if(scene) {
scene.dispose();
}
scene = createScene();
}
etc
update;
I think this might help you more:
I added
var sceneIndex = 0;
var scenes_arr = ;
// now simply scenes_arr.push( createSceneFunction ) for each scene file you have
the buttons now loop through this array, so if first scene is being rendered and you go back/left, last scene will be rendered, and vice versa.
Don’t follow you. When I try to use this method i get the following error and the scenes do not always load - “Added non-passive event listener to a scroll-blocking ‘wheel’ event.”
I think the problem is related to the fact that I am using “ES6 module” to load the code from external files… I am starting to think that no one has tried to load scenes this way yet.
Does anyone have working examples of how to load scenes stored in external .js files into an index.html using ES6 module or a similar method?
The above methods give me various errors and do not work consistently. I do not want to have an index.html file with 50 scenes that is 5000 lines of code.
No. I can load external .glb .gltf, .babylon files no problem in their own scenes one at a time.
The problem I am having is that I have 50 babylon scenes with a bunch of custom code in each which also contain 3d models I have created in Maya, Zbrush and Blender and each one of those scenes contains a bunch of custom code for babylon particles and animation and all sorts. Each one of those files is Babylon code and 3d files (glb) consisting of 2mb -20mb file sizes. And I want to know what is the best way to keep all that code split up into their own little nicely compartmentalized files and only import them into my main index.html and initialize them when the user wants to see them. Like a sketchfab gallery in a single page application.
In short what is the best/recommended way to switch out “FirstScene” with “SecondScene” in the runRenderLoop() ?
I am currently using ES6 module imports like this
<script type="module">
import * as FirstScene from './scenes/FirstScene/FirstScene.js';
import * as SecondScene from './scenes/SecondScene/SecondScene.js';
import * as ThirdScene from './scenes/ThirdScene/ThirdScene.js';
import * as FourthScene from './scenes/FourthScene/FourthScene.js';
var scenes = [
{"name": FirstScene},
{"name": SecondScene},
{"name": ThirdScene},
{"name": FourthScene},
];
var createScene = scenes[0].name.loadScene();
var canvas = document.getElementById("renderCanvas"); // Get the canvas element
var engine = new BABYLON.Engine(canvas, true);
// Register a render loop to repeatedly render the scene
engine.runRenderLoop(function() {
createScene.render();
});
</script>
But I was having some problems switching out the scenes dynamically and was looking for the recommended way to do this.
I think i’m nearly there now but still looking for working examples if there is a recommended way to organize and load scenes from external files and have them garbage collect properly.
Thanks Deltakosh … this is what I am currently doing and I am having some problems with the scenes not loading correctly. I will do some debugging and if I cannot figure it out will upload some code to reproduce the problem somewhere.
I am facing a problem similar to the problem being discussed here. I have 2 scenes, a “HomeScene” and a “GameplayScene”, the former being the 1st scene of the game. The “GameplayScene” uses a lot of assets (textures, models, sounds, fonts etc), so I want to preload all those assets and cache them in memory.
My initial idea was to load all those assets at the start of the game, before the “HomeScene” is displayed. I tried to use AssetsManager as well as AssetContainer, but both of them work only with the scene currently being loaded, and there is no clear-cut way to transfer all the loaded assets to another scene.
This is a very common task and I have done the same task in other game engines before. But in those other game engines, loaded assets are not tied to a specific “scene”. I am curious why this is the case in Babylon.js, and would like to hear an explanation.
Hi @randle_mcmurphy, can’t you use different AssetContainers to populate the one scene and/or different AssetsManagers for different scenes? They seem quite flexible in that regard, but maybe I’m not understanding your use case.
Im confused kinda, do you have all your scenes and assets preloaded? Or are you talking about cascading the scenes to the client and rending the first ready one then like toggling between different scenes? If that’s the case then just store them in an array as they come in and switch out which one is being used in your render loop by a selected Id? If I understand what your trying to do. If you need to switch between there is gonna have to be some sort of parsing unless you have all the assets already spun up. You could in that case have a secondary engine parsing the scenes that are loading but not being displayed then freezing them on complete. Then using that canvas data as a screen shot, so you don’t have to actually run the scenes constantly but still have a preview.