First: you are correct, the problem is that you do not consider the moment of inertia (which is the rotational analog of mass). Look at the code:
b._linearVelocity.x += (impulse.x/ b._mass);
b._linearVelocity.y += (impulse.y/ b._mass);
b._angularVelocity += ((position.x - b._position.x) * impulse.y -
(position.y - b._position.y) * impulse.x);
When you calculate linear velocity, you divide by mass; you should do something similar for angular motion.
If the position of the rigidBody
is its center of gravity, then the job will be easy.
The moment of inertia is mr2, summed over the particles. That is, each particle contributes m*r*r
, where m
is the mass of the particle, and r
is the distance from the particle to the center of gravity.
For example, if your shape is 2 spheres, one at (0,10) and one at (0,-10), both of mass 5, then the center of gravity is at
C = (5*(0,10)+5*(0,-10))/(5+5) = (0,0)
and the moment of inertia is
I = 5*10*10 + 5*(-10)*(-10) = 1000
The change in angular velocity will be
b._angularVelocity += (((position.x - b._position.x) * impulse.y -
(position.y - b._position.y) * impulse.x))/I;
If your shape is 2 spheres, one at (0,10) with mass 5, and one at (0,-10) with mass 10, then the center of gravity is at
C = (5*(0,10)+10*(0,-10))/(5+10) = (0,-10/3)
and the moment of inertia is
I = 5*(40/3)*(40/3) + 5*(-20/3)*(-20/3) = 10000/9
EDIT:
A problem appears in the special case of a single sphere (or collocated spheres). These spheres are treated as point masses, so the moment of inertia (I
) will be zero. And all impulses are directed through the center of a sphere, so the torque (the angular "force") will be zero. So there should be no angular velocity, but by the method above it will be 0/0
. One solution: each sphere makes a small constant contribution to the inertial moment (this means that the sphere is not a point mass-- it has a slight extent, so it can spin). Now the contribution of each sphere is m*r*r + d
, where d
is, e.g. 0.0001
. So the lone sphere has a positive moment of inertia (and will not rotate), and all of the other objects still have realistic physics.