# Friction due to gravity in an impulse based physics engine

In my physics engine, I'm using impulses to solve collisions. I'm basing all calculations on these equations:

impulse = desired_velocity_change * mass
impulse = force * time
friction_force <= normal_force * coefficient


If an object moves along flat ground (infinite mass), after integration it'll be moving slowly "into" the ground due to gravity. This means that the impulse needed to react to that (given the restitution equals 0) will be the velocity in the direction of the contact normal, multiplied by mass.

The issue here is that gravity is a constant acceleration, which means that the object, no matter the mass, will always "dip" by the same amount given a constant frame rate. So the mass is never a factor in this situation, outside of the impulse calculation, which is just a flat velocity change.

Now, I can use impulse to calculate the force that was needed to react to the collision, this force can then be used in the friction equation as such:

friction_impulse / time <= normal_impulse * coefficient / time


Since time is always greater than 0, I can just multiply both sides by it, and then I can use the impulse equation, as such:

planar_velocity_change * mass <= velocity_change_along_normal * mass * coefficient


And again, I can just remove mass from the equation, which leaves me with:

planar_velocity_change * mass <= velocity_change_along_normal * mass * coefficient


This is the desired velocity change along the contact surface due to friction. The issue is, obviously, that none of this depends on mass, which means that no matter how heavy or light an object is, it'll always continue sliding along the surface by the same amount given a constant initial velocity.

What am I missing? It really looks like there's a logical mistake here. Should the dynamic friction depend on the mass in the first place? Moving a heavy object requires higher force, so static friction should be modeled properly, since it just flat-out removes velocity, though it'd be nice to hear if this has merit or just "looks good".

• Dynamic friction does not depend on mass. Jan 7, 2013 at 3:05
• @Steve That should be an answer.
– Anko
Mar 10, 2013 at 14:08
• @SteveH yeah dude, if you added a reference i'd be very happy to accept that as the answer Mar 11, 2013 at 7:01
• Gravity does not cause friction.
– Almo
May 16, 2017 at 21:01

Your pseudo code uses non standard notation (you seem to be using assignment in the <= comparison expressions, that is really confusing), which is makes it hard to read, but If I understand the issue correctly, its that there is some confusion with friction.

Friction in real life is caused by microscopic perturbations in the surface of a plane an object is standing on, characterized by a friction coefficient for simplicity sake eg: u. The magnitude of the force of friction is this (see wikipedia for an illustration):

friction_magnitude = u * magnitude(force_anti_normal_to_friction_plane);


A plane can be arbitrarily oriented, not just flat horizontal. But see that we use force_anti_normal_to_friction_plane and in your equations, you appear to only care about the acceleration due to gravity, when the force equation is actually F = M*A. The mass is accounted for in the force of friction. In this way your friction magnitude assuming gravity is the only force normal to the plane of friction should be:

friction_magnitude = u * magnitude(G * mass);


You then take this and multiply it with the part of the velocity parallel to the plane of friction, for a horizontal plane this is just your non vertical components (in my system this is normally x, and z) normalized.

friction_force = -u * magnitude(G * mass) * normalize(vec3(velocity.x, 0.0, velocity.z));


In the case where you have an arbitrarily oriented friction plane it is the rejection of the velocity vector with the normal of the plane which contains the components which to normalize, and the projection of the force to figure out what components of the force actually apply to the plane of friction. This rejection contains the orthogonal vector to the normal of the plane, which contains the parallel velocity component to the plane, the projection contains the components parallel to the the given vector.

// need to guarantee that the forces are at least pointing towards the plane
// and not away, if forces do not point towards plane, then there is no
// force anti normal to the plane of friction pressing down to cause contact

if(dot(forces,friction_normal) < 0.0){
force_anti_normal_to_friction_plane = projection(force, friction_normal);
}else{
force_anti_normal_to_friction_plane = 0.0;
}

friction_force = -u * magnitude(force_anti_normal_to_friction_plane) * normalize(reject(velocity, friction_normal));


Another thing you need to watch out with dynamic friction is that you don't want to apply it past when the object would have stopped moving in the parallel velocity to the plane. Ie if you have a very tiny vector moving across the floor of your friction plane, friction doesn't scale less because of that, and doing a naive calculation would cause your velocity vector to move back and forth forever across the plane. You need to halt your movement along that vector to adequately handle this case. In otherwords, if the magnitude of your velocity along the plane of friction is less than the magnitude of velocity change contributed soley by the force of friction you need to stop moving!. To do this for arbitrary orientations of the friction plane, take the velocity components rejected by the normal and subtract them from the velocity to cancel out that movement.