(click anywhere to close)

[Three.js] Physics with Physijs!

category: Games | course: Threejs | difficulty:

There are many great javascript physics engines out there, but PhysiJS was made specifically for Three.js, so I think it's the best fit.


First, get the necessary file(s) on GitHub

To add Physijs to a Three.js project, you simply need to follow a few easy steps.

But first of all, don't forget to add a <script> tag that points to the physi.js file.

Requiring core libraries

That header sounds intriguing, but it's nothing more than including the following two lines in your code (PhysiJS depends on the famous ammo.js javascript physics library):

Physijs.scripts.worker = '/js/physijs_worker.js';
Physijs.scripts.ammo = '/js/ammo.js';

Some small alterations

Then, instead if initiating a Three.js scene like you always do, create a Physijs scene (this is exactly the same as a Three.js scene, but with a physics layer built on top of it):

scene = new Physijs.Scene();

And when you're creating a mesh, instead of calling any of the THREE.Mesh types, call one from the Physijs ones, for example:

// Box
box = new Physijs.BoxMesh(
   new THREE.CubeGeometry( 5, 5, 5 ),
   new THREE.MeshBasicMaterial({ color: 0x888888 })
scene.add( box );

Make it all work!

And last but not least, next to the render call for the Three.js renderer, we need to call the physics system to make its usual iterations and check for collisions and what not.


Scene configuration

When creating the Physics scene, you can configure it a little. When calling new Physijs.scene(), you can pass in an object as the parameter. This object can have these properties:

var scene = new Physijs.Scene({fixedTimeStep: (1/60), blabla});

//Attributes to pass in the object
fixedTimeStep (default 1 / 60) //How much time one simulation step takes to simulate
reportsize (default 50) //If you know how much objects your world will have, you can set this to optimize

//Methods to call on it
setGravity (default Vector3( 0, -10, 0 ) ) //Sets the direction and strength of the gravity
setFixedTimeStep //Resets the timestep dynamically (do not call it every frame!)

//The simulation call also can take a parameter:
//The maximum steps/iterations the physics system is allowed to perform (more = even more accurate collisions, but slower performance)
scene.simulate({ maxSteps: someValue});

Please note!

There are a few things you need to keep in mind all the time when adding those physics to your Three.js Here's a small list:

No scaling after creation

Once you've created a physics mesh from some geometry, you cannot scale it afterwards. However, before that moment, you can scale it anyway you like.

Notify the system when things have changed outside the physics system

If an object needs to change position or rotation manually, you need to tell the system you've just changed it. Don't worry, Position/rotation change from the Physijs engine (like bouncing, gravity, etc.) is taken care of already. You need to set these flags to true:

mesh.__dirtyPosition = true;
mesh.__dirtyRotation = true;
Creating static objects

Objects that are always going to be static, simply need to have their mass set to 0.

Objects that will sometimes be static, and other times be dynamic, need to have the following applied:

//Completely freeze an object
object.setAngularFactor = THREE.Vector3(0,0,0);
object.setLinearFactor = THREE.Vector3( 0, 0, 0 );

//You can also clear any velocities the same way (setting them to a 0 vector3)

//To reset, simply change the factors back to Vector3(1,1,1);

Now you can go on to the second part of the 3D Physics section!

Do you like my tutorials?
To keep this site running, donate some motivational food!
Chocolate Milk