This is yet another post about physics. This one is about physijs by Chandler Prall. It easily bind ammo.js and three.js. We will walk thru an example using it. Physics is always important in 3D graphics. It makes scenes more realistic. Additionally, if you simple put your object into the scene, it will move nicely and realisticly. So you spend less time tuning each moves. I am quite lazy so it matters :) The screencast presents the demo we gonna code and various examples of what is possible with ammo.js.
What About Physics Engines ?
We already did physics with three.js. It was with microphysics.js for marblesoccer minigame. It is a micro library implementing 3D physics. We talked quite a bit about it in “Lets Make a 3D Game: microphysics.js” and “Lets Make a 3D Game: microphysics.js, Even Easier”. It is only 500lines! Unfortunatly, this tiny size comes limitations.
bullet is a full-blown physics engine well-known in the 3D community. It can do a lot as you can see in its docs. ammo.js supports all the features you can expect from a mature 3D physics engine. Charles J. Cliffe, aka @ccliffe, did several demos using ammo.js. This one is a heighfield And look at this stunt track! Both are on top of cubicvr, @ccliffe own library.
Lets Get Started
The code of today is a copy of the collision example from physijs using it thru tQuery API. It may usefull to reimplement the same thing, just to be sure they both perform the same way. :) Try it out. So we got object falling on the ground and slightly bouncing on it. Let’s do just that.
First a classic. We create a tQuery.World. So you immediatly got
a scene, a renderer, camera and its controls. All that already
setup according to reasonable default.
the “three.js boilerplate”
we did last year. We disable the camera controls as it will stay still in this scene.
.start() to launch the render loop.
Now we setup the camera to be a bit far from the scene center. Thus we got room to display larger objects
Now we need to tell the renderer that shadow has to be casted. This is done by the simple lines below. We saw the details in “Casting Shadows” post.
1 2 3
Now we enable the physics into the world. this is important. From now on, all the physics-enabled object of this world will move according to realistic physics rules.
Enlight your world
Here we setup the lights. For simplicity sake, we will use only one directional light.
First we tune the position and color to fit our tastes. Dont be shy, play with those parameters to get a feel of it.
Then we tune shadow parameters.
Those can be tricky to tune.
You can find more details in “Casting Shadow” post.
It helps if you make the shaddow camera visible. You can do so with
1 2 3 4 5
Let’s create a ground to stand on
First we create the texture for our ground. We use
rocks.jpg to have like a rock
effect. We use
.RepeatWrapping to repeat the texture on the faces and get a
1 2 3
In fact, the ground is only a cube which is wide and flat, a bit like the old-vision of earth :) It is usual now, we setup the position, material and shadow.
1 2 3 4
Now we just have to setup the physics for the ground. This is done
mass parameter define the mass
of the object in the physics.
By default, it is automatically computed depending on the volume of the object.
Here zeroing the mass is a special case, which say
“the mass is infinite, dont move, ever” :)
1 2 3
Spawning object in a 3D world
Spawning is always a delicate matter in our world. But first let’s load the texture for the spawned objects. It is done outside of the loop thus it get reused. Aka it is sent only once to the GPU for all the objects. This is an important point from performance point of view. Last year, “Performance: Caching Material” post was about this very topic.
Now we declare
spawnObject() which gonna take care of spawning one object.
So we create a cube, setup its position, rotation and material. This is all good. Oh dont
forget to use
.castShadow() as got shadow mapping going on :)
1 2 3 4 5 6
Here we enable the physics on this object. So the world will handle all its move from now on. It will object to physics laws according to the parameters you setup. friction is the force resisting when 2 objects slides against each other. resititution is how bouncy the object is. For scientific definition, go read a book :)
1 2 3 4
Now we gonna play with the ‘collision’ event. Physijs is able to notify
you when an object collide with another. Just use
.addEventListener() on ‘collision’.
Here we gonna change the color of the object depending on the number of collisions
1 2 3 4 5 6 7 8 9
Now we simply use
spawn an object every seconds.
And we are DONE! We got a realistic physics in our 3D world! not bad hey :)
So, thanks to physijs, it is now possible to get full blown realistic physics using three.js and tQuery. It is a simple way to make scene more realistic. It is nice to experiment with. I will do more on this very soon!
Thanks all folks! have fun :)