Babylon JS Day 10: Terrarium
This week for my Friday Project I decided that I wanted to build a simple Terrarium with some low poly assets. My main objectives was to learn about composing a scene in Babylon JS. I started with the table/base that I made on Day 8 and what I learned about asset loading on Day 9.
I’m almost embarrassed to admit that I spent most of the day working with the asset files and trying to get them loaded into the scene. I ran into some issue with obj
files where sometimes the related mtl
file would just not show up in the scene. Eventually I decided to convert the models to glb
file instead. Lucky for me I had a copy of the Blender project for each file, so it was just a matter of opening the Blender project and exporting the model and material as a glb
file. I ended up with 13 models that I added to the scene using the assetsManager
.
// Asset loading example
var assetsManager = new BABYLON.AssetsManager(scene);
const path = "../assets/models/";
// Trees
assetsManager.addMeshTask("mesh task", "", path, "Tree1.glb").onSuccess = function (task) {
task.loadedMeshes[0].position = new BABYLON.Vector3(5, 0, 6);
task.loadedMeshes[0].rotation = new BABYLON.Vector3(0, 30, 0);
task.loadedMeshes[0].name = "Tree1";
};
// Many more files loaded....
assetsManager.load();
One interesting side note: files loaded this way are not named in the scene graph, but I found out that I can set the name property of the loaded mesh. This made it easier to work with these models in the Babylon JS inspector.
I wanted to use some of the models more than once, so I learned how to use the clone()
method on a mesh. I created these clones right in the .onSuccess
call after loading an asset. For example, I wanted a small stand of trees using the Tree3 model. I used the one imported in the loadedMeshes
results array as the first instance in the scene, then cloned it twice for the other instances.
assetsManager.addMeshTask("mesh task", "", path, "Tree3.glb").onSuccess = function (task) {
task.loadedMeshes[0].position = new BABYLON.Vector3(6.5, 0, -4);
task.loadedMeshes[0].name = "Tree3";
tree3Clone1 = task.loadedMeshes[0].clone("Tree3Clone1");
tree3Clone1.position = new BABYLON.Vector3(5, 0, -1);
tree3Clone1.rotation = new BABYLON.Vector3(0, -70, 0);
tree3Clone1.scaling = new BABYLON.Vector3(1.2, 1.2, 1.2);
tree3Clone2 = task.loadedMeshes[0].clone("Tree3Clone2");
tree3Clone2.position = new BABYLON.Vector3(6.5, 0, -1.5);
tree3Clone2.rotation = new BABYLON.Vector3(0, 50, 0);
tree3Clone2.scaling = new BABYLON.Vector3(0.9, 1.2, 0.9);
};
I spent more time than I care to admit just deciding where on this small table to place everything. This is what I ended up with for now.
One small touch at the end of the day was adding some animations to the camera. I found an interesting Playground on the Babylon JS forum that gave me some ideas using a timeouts to move the camera around the scene. When the scene loads, these animations will play out over a period of 12 seconds, mainly to demonstrate that you can move the camera around the scene.
When I started out this morning, my plans included many more features. I wanted to add some animals that would move around the scene. I also intended to create a soundtrack and some simple sound effects. Don’t get me started about clouds… Not to mention the dome that is supposed to cover the Terrarium. I just ran out of time. Even with this Friday Project complete, I may keep working on this scene. It could make an interesting place to try new concepts as I learn them.
Try the scene out for yourself here.