Question

i've looked in the cannon.js examples, and they seem to mostly use between -10 and -40 for gravity and something between 1 and 10 for the mass of an object (or CANNON.RigidBody as they are called), these demo objects are "well behaved" with these values in that they are just "heavy" enough to overcome gravity and not so "heavy" that they make the ground plane look fake.. by that i mean that i have tried increasing the masses of falling objects and the more mass they have the more they make the floor look like it is made of marshmallow (i.e. spongy) when they land. (btw: yes, i do know that mass and weight are not the same thing ;-)

gravity is usually 9.8 m/s/s in mathematics so how could that be implemented in CANNON.World.gravity ?

i have found on the internet that the mass of stone is 2515 kilograms/cubic metre, so if i wanted to drop a 1x1x1 metre stone block how would that translate into mass for:

var block = new CANNON.RigidBody(mass, shape, material);

and then there is this material parameter.. would i need to have 2 materials (1 for the floor and 1 for the stone block) and then how would i set the friction coefficient and restitution values for the materials to react when they collide?

i know this seems like many questions, and i'm not aiming for absolute accuracy, just needing guidance because of a) my lack of knowledge with physics and b) not much documentation for those of us trying to use cannon.js who are not physics professors ;-)

the real question is "How to approximate realism" i guess.

cannon.js is great, works really well, and i really appreciate all the hard work that Stefan Hedman (schteppe) has put into it so far.

Was it helpful?

Solution

Cannon.js uses the MKS system of units (meter-kilogram-second). To correctly set gravity to 9.8 m/s/s, you do:

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

(assuming "up" direction is along the positive Y axis.)

For the mass calculation, you could do something like this:

var density = 2515; // kg/m^3
var mass = density * shape.volume(); // M=p*V

Then use this mass when creating your stone bodies.

If you are aiming for a game with real time physics, you may have to let go of the "correct" physical properties to increase physics performance. You can do that by changing gravity and masses, adding damping, limiting maximum velocity of bodies, etc.. There are no specific guidelines for this, but there are a number of tricks.

Regarding materials: In general you create a new CANNON.Material for each material you have in your scene. Then you create a CANNON.ContactMaterial that defines what happens when a pair of these materials meet. Here's sample code, but see the friction demo for a full example.

var slipperyMat = new CANNON.Material();
var friction = 0.0;
var restitution = 0.2;
var slipperyContact = new CANNON.ContactMaterial(slipperyMat,slipperyMat,friction,restitution);
world.addContactMaterial(slipperyContact);

If you only plan to have one type of material, you can set properties on the default contact material in the world instead. Have a look at world.defaultContactMaterial.

The sponginess question is a good one. If you want to hang on to your physically correct masses, gravity, etc., you probably need to increase precision a bit. You can do that by using a smaller time step (for example, try using two half steps per rendering frame) and/or tweaking the contact solving settings:

world.solver.iterations = 20; // Increase solver iterations (default is 10)
world.solver.tolerance = 0;   // Force solver to use all iterations

// Adjust constraint equation parameters: use to tweak sponginess
slipperyContact.contactEquationStiffness = 1e8;
slipperyContact.contactEquationRegularizationTime = 3;

The stiffness and regularization controls the "sponginess" of the contacts. If you use large stiffness and small regularization, the solver will try to make less spongy contacts for you. Provided enough solver precision (small time step and lots of iterations), you will get a better solution.

I've assumed Cannon.js 0.6.0 (dev branch at the moment) throughout this answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top