Quantcast
Channel: Envato Tuts+ Game Development
Viewing all articles
Browse latest Browse all 728

WebGL Physics and Collision Detection Using Babylon.js and Oimo.js

$
0
0

Today, I’d like to share with you the basics of collisions, physics and bounding boxes by playing with the WebGL Babylon.js engine and a physics engine companion named Oimo.js.

Here’s the demo we’re going to build together: Babylon.js Espilit Physics demo with Oimo.js.

Babylonjs Espilit Physics demo with Oimojs

You can launch it in a WebGL-compatible browser—like IE11, Firefox, Chrome, Opera, Safari 8, or Microsoft Edge in Windows 10 Technical Preview—and then move inside the scene like in an FPS game. Press the s key to launch some spheres/balls and the b key to launch some boxes. Using your mouse, you can also click on one of the spheres or boxes to apply some impulse force on it.

1. Understanding Collisions

Looking at the Wikipedia collision detection definition, we can read that: 

Collision detection typically refers to the computational problem of detecting the intersection of two or more objects. While the topic is most often associated with its use in video games and other physical simulations, it also has applications in robotics. In addition to determining whether two objects have collided, collision detection systems may also calculate time of impact (TOI), and report a contact manifold (the set of intersecting points). Collision response deals with simulating what happens when a collision is detected (see physics engine, ragdoll physics). Solving collision detection problems requires extensive use of concepts from linear algebra and computational geometry.

Let’s now unpack that definition into a cool 3D scene that will act as our starting base for this tutorial.

You can move in this great museum as you would in the real world. You won’t fall through the floor, walk through walls, or fly. We’re simulating gravity. All of that seems pretty obvious, but it requires a bunch of computation to simulate that in a 3D virtual world. 

The first question we need to resolve when we think about collision detection is how complex it should be. Indeed, testing whether two complex meshes are colliding could cost a lot of CPU, even more with a JavaScript engine where it’s complex to offload that on something other than the UI thread.

To better understand how we’re managing this complexity, navigate into the Espilit museum near this desk:

the Espilit museum near the desk

You’re blocked by the table even if there seems to be some space available on the right. Is it a bug in our collision algorithm? No, it’s not (Babylon.js is free of bugs!). It’s because Michel Rousseau, the 3D artist who built this scene, has done this by choice. To simplify the collision detection, he has used a specific collider.

What’s a Collider?

Rather than testing the collisions against the complete detailed meshes, you can put them into simple invisible geometries. Those colliders will act as the mesh representation and will be used by the collision engine instead. Most of the time, you won’t see the differences but it will allow us to use much less CPU, as the math behind that is much simpler to compute.

Every engine supports at least two types of colliders: the bounding box and the bounding sphere. You’ll better understand by looking at this picture:

Illustration of bounding box and bounding sphere
Extracted from: Computer Visualization, Ray Tracing, Video Games, Replacement of Bounding Boxes

This beautiful yellow duck is the mesh to be displayed. Rather than testing the collisions against each of its faces, we can try to insert it into the best bounding geometry. In this case, a box seems a better choice than a sphere to act as the mesh impostor. But the choice really depends on the mesh itself.

Let’s go back to the Espilit scene and display the invisible bounding element in a semitransparent red color:

invisible bounding element in a semitransparent red color

You can now understand why you can’t move by the right side of the desk. It’s because you’re colliding (well, the Babylon.js camera is colliding) with this box. If you’d like to do so, simply change its size by lowering the width to perfectly fit the width of the desk.

Note: if you’d like to start learning Babylon.js, you can follow the free training course at Microsoft Virtual Academy (MVA). For instance, you can jump directly to Introduction to WebGL 3D with HTML5 and Babylon.js: Using Babylon.js for Beginners where we cover this collision part of Babylon.js. You can also have a look at the code inside our interactive playground tool, Babylon.js playground: Collisions sample.

Based on the complexity of the collision or physics engine, there are other types of colliders available: the capsule and the mesh, for instance.

Box sphere capsule and mesh colliders
Extracted from: Getting Started with Unity - Colliders & UnityScript

Capsule is useful for humans or humanoids as it better fits our body than a box or a sphere. Mesh is almost never the complete mesh itself—rather, it’s a simplified version of the original mesh you’re targeting—but it is still much more precise than a box, a sphere, or a capsule.

2. Loading the Starting Scene

To load our Espilit scene, you have various options:

Option 1: Download it from our GitHub repository, and then follow the Introduction to WebGL 3D with HTML5 and Babylon.js: Loading Assets module of our MVA course to learn how to load a .babylon scene. Basically, you need to host the assets and the Babylon.js engine into a web server and set the proper MIME types for the .babylon extension.

Option 2: Download this premade Visual Studio solution (.zip file).  

Note: If you are unfamiliar with Visual Studio, take a look at this article: Web developers, Visual Studio could be a great free tool to develop with… Please note also that the Pro version is now free for a lot of different scenarios. It’s named Visual Studio 2013 Community Edition.

Of course, you can still follow this tutorial if you don’t want to use Visual Studio. Here is the code to load our scene. Remember that most browsers support WebGL now—remember to test for Internet Explorer even on your Mac.

Using this material, you will only benefit from the embedded collision engine of Babylon.js. Indeed, we’re making a difference between our collision engine and a physics engine. 

The collision engine is mostly dedicated to the camera interacting with the scene. You can enable gravity or not on the camera, and you can enable the checkCollision option on the camera and on the various meshes. 

The collision engine can also help you to know if two meshes are colliding. But that’s all (this is already a lot, in fact!). The collision engine won’t generate actions, force or impulse after two Babylon.js objects are colliding. You need a physics engine for that to bring life to the objects.

The way we’ve been integrating physics in Babylon.js is via a plugin mechanism. You can read more about that here: Adding your own physics engine plugin to Babylon.js. We’re supporting two open-source physics engines: Cannon.js and Oimo.js. Oimo is now the preferred default physics engine.

If you’ve chosen Option 1 to load the scene, you then need to download Oimo.js from our GitHub. It’s a slightly updated version we’ve made to better support Babylon.js. If you’ve chosen Option 2, it’s already referenced and available in the VS solution under the scripts folder.

3. Enabling Physics Support in the Scene and Transforming Colliders Into Physics Impostors

The first thing to do is to enable physics on the scene. For that, please add these lines of code:

You’re setting up the gravity level (-10 on the Y axis in this sample code, which is more or less like what we have on Earth) and the physics engine you’d like to use. We’ll use Oimo.js, but the commented line shows how to use Cannon.js.

Now, we need to iterate through all non-visible colliders used by the collision engine and activate physics properties on it. For that, you simply need to find all meshes where checkCollisions is set to true but not visible in the scene:

Please declare the meshesColliderList also:

And we’re done! We’re ready to throw some objects in our scene and put a lot of mess in this beautiful but way-too-calm museum.

4. Creating Spheres & Boxes With Physics States

We’re now going to add some spheres (with an Amiga texture) and some boxes (with a wood texture) to the scene. 

These meshes will have physics state set. For instance, this means that they will bounce on the floor if you launch them in the air, bounce between them after a collision has been detected, and so on. The physics engine needs to know which kind of impostor you’d like to use for the mesh (plane, sphere, or box today), as well as the mass and friction properties.

If you’ve chosen Option 1, you can download the two textures here.

Add this code to your project:

You can see that boxes are heavier than the spheres by a factor of 4.

Note: If you need to understand how material works in Babylon.js, watch the module Introduction to WebGL 3D with HTML5 and Babylon.js: Understanding Materials and Inputs, or play with our dedicated Playground sample, Babylon.js Playground: Materials sample.

Add these two lines of code after the scene.enablePhysics line:

And launch the web project. Navigate to the center of the museum and press the s or b keys. You’ll obtain this fun result:

Demo scene with spheres and boxes floating in the air

5. Adding Picking Support to Click on Meshes

Let’s add another cool feature: the ability to click on one of the objects to throw it away. For that, you need to send a ray from the 2D coordinates of the mouse inside the 3D scene, check whether this ray touches one of the interesting meshes, and if so, apply an impulse force on it to try to move it.

Note: to understand how picking works, please view the MVA module Introduction to WebGL 3D with HTML5 and Babylon.js: Advanced Features. Or play with our online sample, Babylon.js Playground: Picking sample.

Add this code into the addListeners() function:

Launch your code in your favorite browser. You can now click on your physic meshes to play with them.

6. Displaying the Bounding Boxes to Better Understand the Whole Story

Finally, we’re going to create a debug scene to let you display/hide the colliders and activate/deactivate the physics properties on them.

We’re going to inject the UI into this div:

And we’ll use this function to handle the UI:

I know, it generates a very ugly UI, but I was too lazy to spend more time on it. Feel free to improve it!

Call this new function and launch the web project. Now, for instance, display the colliders 12 and 17:

colliders 12 and 17

You can also, with the second checkbox, enable/disable the physics properties. For instance, if you disable the physics properties on collider 12 and launch the spheres, they will now go through this wall! This is shown in the following screenshot as the sphere surrounded by the red square:

sphere going through wall

You can play with this debugging sample directly in your browser here: Babylon.js Espilit Physicsdebug demo.

Please also have a look at this awesome demo built by Samuel Girardin that also uses Oimo.js on some funny characters:

demo built by Samuel Girardi

I hope you’ve enjoyed this tutorial! Feel free to ping me on Twitter to comment about it, or use the comments field below.

This article is part of the web dev tech series from Microsoft. We’re excited to share Microsoft Edge and the new EdgeHTML rendering engine with you. Get free virtual machines or test remotely on your Mac, iOS, Android, or Windows device @ http://dev.modern.ie/.


Viewing all articles
Browse latest Browse all 728

Trending Articles