Physics engine - Part 7: Friction


There is still one glaring problem with our simulation: It’s still all very slick. Boxes just skid off the floor. We’re lacking friction.

In order to start simple, lets just assume everything has infinite friction (i.e. super-sticky). That means anything that’s in contact should never slide. In other words, there should be no relative tangential movement at the contact points.

We can compute the relative movement using PrevPos:

$$ \Delta\vec p = (\vec p_a - \vec p_{a,prev})-(\vec p_b - \vec p_{b,prev}) $$

And the tangential part is:

$$ \Delta p_t = \Delta \vec p \cdot \vec n_\perp $$

So we simply have to apply a correction of

$$ \Delta \vec x = \Delta p_t \vec n_\perp $$

We can add this constraint to our solve_pos_box_box system quite easily:

let relative_movement = (pos_a.0 - prev_pos_a.0) - (pos_b.0 - prev_pos_b.0);

Currently, we’ve worked with restitution, which operates on the normal velocity, $v_n$, friction on the other hand by limiting the tangential velocity, $v_t$, which is perpendicular to the normal.

That is, for each contact, we simply compute the current tangential velocity:

$$ v_t = \vec v_{rel} \cdot \vec n_\perp $$

Or in code:

let tangent_vel = relative_vel.perp_dot(n);

Now we can simply remove this velocity by adding an opposite velocity correction: