




















































In this article by Julien Moreau-Mathis, the author of the book, Babylon.JS Essentials, you will learn about creating and customizing the scenes using the materials and meshes provided by the designer.
(For more resources related to this topic, see here.)
In this article, let's play with the gameplay itself and create interactions with the objects in the scene by creating collisions and physics simulations. Collisions are important to add realism in your scenes if you want to walk without crossing the walls. Moreover, to make your scenes more alive, let's introduce the physics simulation with Babylon.js and, finally, see how it is easy to integrate these two notions in your scenes. We are going to discuss the following topics:
Starting from the concept, configuring and checking collisions in a scene can be done without mathematical notions. We all have the notions of gravity and ellipsoid even if the ellipsoid word is not necessarily familiar.
Let's start with the following scene (a camera, light, plane, and box):
The goal is to block the current camera of the scene in order not to cross the objects in the scene. In other words, we want the camera to stay above the plane and stop moving forward if it collides with the box.
To perform these actions, the collisions system provided by Babylon.js uses what we call a collider. A collider is based on the bounding box of an object that looks as follows:
A bounding box simply represents the minimum and maximum positions of a mesh's vertices and is computed automatically by Babylon.js. This means that you have to do nothing particularly tricky to configure collisions on objects.
All the collisions are based on these bounding boxes of each mesh to determine if the camera should be blocked or not.
You'll also see that the physics engines use the same kind of collider to simulate physics.
If the geometry of a mesh has to be changed by modifying the vertices' positions, the bounding box information can be refreshed by calling the following code:
myMesh.refreshBoundingInfo();
To draw the bounding box of an object, simply set the .showBoundingBox property of the mesh instance to true with the following code:
myMesh.showBoundingBox = true;
Let's practice with the Babylon.js collisions engine itself. You'll see that the engine is particularly well hidden as you have to enable checks on scenes and objects only.
First, configure the scene to enable collisions and then wake the engine up. If the following property is false, all the next properties will be ignored by Babylon.js and the collisions engine will be in stand-by mode. Then, it's easy to enable or disable collisions in a scene without modifying more properties:
scene.collisionsEnabled = true; // Enable collisions in scene
Next, configure the camera to check collisions. Then, the collisions engine will check collisions for all the rendered cameras that have collisions enabled. Here, we have only one camera to configure:
camera.checkCollisions = true; // Check collisions for THIS camera
To finish, just set the .checkCollisions property of each mesh to true to active collisions (the plane and box):
plane.checkCollisions = true;
box.checkCollisions = true;
Now, the collisions engine will check the collisions in the scene for the camera on both the plane and box meshes.
You guessed it; if you want to enable collisions only on the plane and you want the camera to walk across the box, you'll have to set the .checkCollisions property of the box to false:
plane.checkCollisions = true;
box.checkCollisions = false;
In the previous section, the camera checks the collision on the plane and box but is not submitted to a famous force named gravity. To enrich the collisions in your scene, you can apply the gravitational force, for example, to go down the stairs.
First, enable the gravity on the camera by setting the .applyGravity property to true:
camera.applyGravity = true; // Enable gravity on the camera
Customize the gravity direction by setting BABYLON.Vector3 to the .gravity property of your scene:
scene.gravity = new BABYLON.Vector3(0.0, -9.81, 0.0); // To stay on earth
Of course, the gravity in space should be as follows:
scene.gravity = BABYLON.Vector3.Zero(); // No gravity in space
Don't hesitate to play with the values in order to adjust the gravity to your scene referential.
The last parameter to enrich the collisions in your scene is the camera's ellipsoid. The ellipsoid represents the camera's dimensions in the scene. In other words, it adjusts the collisions according to the X, Y, and Z axes of the ellipsoid (an ellipsoid is represented by BABYLON.Vector3).
For example, the camera must measure 1m80 (Y axis) and the minimum distance to collide on the X (sides) and Z (forward) axes must be 1 m. Then, the ellipsoid must be (X=1, Y=1.8, Z=1). Simply set the .ellipsoid property of the camera as follows:
camera.ellipsoid = new BABYLON.Vector3(1, 1.8, 1);
The default value of the cameras ellipsoids is (X=0.5, Y=1.0, Z=0.5)
As for the gravity, don't hesitate to adjust the X, Y, and Z values to your scene referential.
Physics simulation is pretty different from the collisions system as it does not occur on the cameras but on the objects of the scene themselves. In other words, if physics is enabled (and configured) on a box, the box will interact with the other meshes in the scene and will try to represent the real physical movements.
For example, let's take a sphere in the air. If you apply physics on the sphere, the sphere will fall until it collides with another mesh and, according to the given parameters, will tend to bounce and roll in the scene.
The example files reproduce the behavior with a sphere that falls on the box in the middle of the sphere.
In Babylon.js, physics simulations can be done using plugins only. Two plugins are available using either the Cannon.js framework or the Oimo.js framework. These two frameworks are included in the Babylon.js GitHub repository in the dist folder.
Each scene has its own physics simulations system and can be enabled with the following lines:
var gravity = new BABYLON.Vector3(0, -9.81, 0);
scene.enablePhysics(gravity, new BABYLON.OimoJSPlugin());
// or
scene.enablePhysics(gravity, new BABYLON.CannonJSPlugin());
The .enablePhysics(gravity, plugin) function takes the following two arguments:
To disable physics in a scene, simply call the .disablePhysicsEngine() function using the following code:
scene.disablePhysicsEngine();
Once the physics simulations are enabled in a scene, you can configure the physics properties (or physics states) of the scene meshes. To configure the physics properties of a mesh, the BABYLON.Mesh class provides a function named .setPhysicsState(impostor, options).
The parameters are as follows:
Let's have a box named box with a mass of 1 and set its physics properties:
box.setPhysicsState(BABYLON.PhysicsEngine.BoxImpostor, { mass: 1 });
This is all; the box is now configured to interact with other configured meshes by following the physics equations. Let's imagine that the box is in the air. It will fall until it collides with another configured mesh.
Now, let's have a sphere named sphere with a mass of 2 and set its physics properties:
sphere.setPhysicsState(BABYLON.PhysicsEngine.SphereImpostor, { mass: 2 });
You'll notice that the sphere, which is a particular kind of mesh, has its own impostor (sphere impostor). In contrast to the box, the physics equations of the plugin will make the sphere roll while the box will slip on other meshes.
According to their mass, if the box and sphere collide together, then the sphere will tend to push harder the box.
The available impostors in Babylon.js are as follows:
In fact, in Babylon.js, the box, plane, and cylinder impostors are the same according to the Cannon.js and Oimo.js plugins.
Regardless of the impostor parameter, the options parameter is the same. In these options, there are three parameters, which are as follows:
In the example files, these parameters are set and if you play, you'll see that these three parameters are linked together in the physics equations.
At any moment, you can apply a new force or impulse to a configured mesh. Let's take an explosion: a box is located at the coordinates (X=0, Y=0, Z=0) and an explosion happens above the box at the coordinates (X=0, Y=-5, Z=0). In real life, the box should be pushed up: this action is possible by calling a function named .applyImpulse(force, contactPoint) provided by the BABYLON.Mesh class.
Once the mesh is configured with its options and impostor, you can, at any moment, call this function to apply a force to the object. The parameters are as follows:
For example, the explosion generates a force only on Y that is equal to 10 (10 is an arbitrary value) and has its origin at the coordinates (X=0, Y=-5, Z=0):
mesh.applyImpulse(new BABYLON.Vector3(0, 10, 0), new BABYLON.Vector3(0, -5, 0));
Once the impulse is applied to the mesh (only once), the box is pushed up and will fall according to its physics options (mass, friction, and restitution).
You are now ready to configure collisions in your scene and simulate physics. Whether by code or by the artists, you learned the pipeline to make your scenes more alive.
Further resources on this subject: