Skip to content
Yuval Greenfield edited this page Mar 22, 2016 · 4 revisions

To get hard contacts and stiff constraints you need to do some parameter tweaking. Here is a list of things you may want to look at when building the perfect simulation.

Timestep size

world.step(1/60); // Steps forward in time from t=0 to t=0.01666...

The time step size is very important for simulation quality. Using a smaller timestep will increase precision in most things that happen in Cannon.js, with the cost of more computations. Some real-time simulators suggests that a timestep of 1/60=0.01666... seconds is enough for most use cases. May be true in many cases, but not all. For most HTML5 rendering engines, we are rendering at 60Hz. Therefore a time step of around 60Hz is good. If you want a smaller time step size for higher precision, it can be convenient to do two half-steps instead of a single step:

world.step(1/120); // Steps forward in time from t=0 to t=0.008333...
world.step(1/120); // Steps forward in time from t=0.008333 to t=0.01666...

Solver iterations

world.solver.iterations = 10;

In the case of contacts, the Solver process equations to find out what force to add to the bodies in contact. The solver is iterative, which means that it solves the equations incrementally. It will get closer to the solution for each iteration. Using too few solver iterations will cause the Solver to produce inaccurate contact forces, but more iterations will increase precision.

Solver parameters

The solver parameters are set on the CANNON.Equation objects. You provide constraint stiffness and regularization, like so:

equation.stiffness = 1e8;
equation.regularizationTime = 10;

The mostly used equation is probably the ContactEquation. These are automatically generated by Cannon.js as contacts appear in your scene. Therefore, you control their stiffness and regularization through the CANNON.ContactMaterial properties instead:

world.defaultContactMaterial.contactEquationStiffness = 1e8;
world.defaultContactMaterial.contactEquationRegularizationTime = 3;

The stiffness approximately corresponds to the stiffness of a spring, which gives a force F=-k*x where x is the displacement of the spring. Regularization time is corresponds to the number of time steps you need to take to stabilize the constraint (larger value => softer contact).

Gravity

This may not be obvious but the gravity does have impact on constraints. If you have a ball resting on a plane, a contact constraint will push it up from that plane. The gravity will push in the other direction. A smaller gravity force will make it easier for the contact solver to get to a solution.

To conclude, smaller gravity force can make contacts better.

world.gravity.set(0,0,-10);

Air Resistance

If you want objects to slow down when unhindered you can use linearDamping.

var sphereBody = new CANNON.Body({mass: 5});
sphereBody.linearDamping = 0.3;