Contents · Physics Engines
Part 0 · Orientation
Part 1 · Mathematical Foundations
Part 2 · Equations of Motion
Part 3 · Time Integration
Part 4 · Collision Detection
Part 5 · Contact & Constraints
Part 6 · Constraint Solvers
- Constraint Solvers: PGS, TGS, Newton, Convex
Part 7 · Position-Based Dynamics
Part 8 · GPU & Parallelism
Part 9 · Differentiable Simulation
Part 6 · Constraint Solvers
Constraint Solvers: PGS, TGS, Newton, Convex
Collision detection handed the solver a list of contacts. Turning those into forces is, at heart, solving a linear system: find the contact impulses that stop bodies from interpenetrating. The choice of how to solve it is what separates a game engine from a robotics simulator.
The contact solve is a linear system
Stack the active constraints into a Jacobian that maps generalized velocity to relative velocity at the contacts. The impulses that produce a target relative velocity satisfy
is the Delassus operator: the inverse inertia seen in contact space. It is symmetric positive semidefinite, and its entry measures how much an impulse at contact disturbs contact . For a contact that can push but not pull, the impulse is one-sided, so the equality becomes a linear complementarity problem (LCP):
Either a contact carries force and its velocity error is zero, or it is separating and carries no force. A dense factorization of costs in the number of contacts, and changes every step. Engines never pay that; they iterate.
Splitting the matrix: Jacobi, Gauss-Seidel, PGS
Write : diagonal, strictly lower, strictly upper. Each split gives a stationary iteration.
Jacobi updates every component from old values at once:
Gauss-Seidel uses each freshly updated value immediately, which is the split and converges faster:
Projected Gauss-Seidel (PGS) adds the projection after each component update, which is what keeps contacts from pulling:
Applied one contact at a time, reusing the latest impulses, this is exactly the sequential impulse method that Box2D and Bullet run.12
A stack, solved by hand
Take a column of three unit boxes, , . Let be the ground contact, and the contacts above it, with a free surface over the top box. Static equilibrium of each box is : a contact holds up everything above it plus the box it touches. In matrix form,
Solving row for its diagonal unknown gives the PGS update
swept over one shared array. The coupling is to , the next index, which this sweep has not touched yet, so is the stale value from the previous iteration. Start from :
| sweep | note | |||
|---|---|---|---|---|
| start | 0 | 0 | 0 | |
| 1 | 10 | 10 | 10 | each contact learns of one box |
| 2 | 20 | 20 | 10 | correct |
| 3 | 30 | 20 | 10 | converged |
Trace sweep 2: using the stale ; then ; then . Three sweeps for three boxes. Because every row couples upward to a not-yet-updated neighbor, the true load propagates down exactly one contact per sweep, and the ground contact is the last to learn the full weight it carries.
- sweeps
- 0 of 3 needed
- residual max|c − c*|
- 30.00
When one contact per sweep is too slow
That -sweeps-per--stack behavior is the whole problem with PGS. A tall pile, a long chain, or a heavy body resting on a light one all couple many constraints, and information crawls through them one contact at a time. With a fixed iteration budget the solve stays soft and the stack sags, exactly as the demo shows below .
Three families push past this. TGS, PhysX's temporal Gauss-Seidel, splits the timestep into substeps and re-solves each, which tightens convergence and handles large mass ratios far better than plain PGS at the same total cost.3 Newton solvers linearize the full nonlinear complementarity system and take a few large, well-scaled steps instead of many cheap ones. Convex solvers, such as MuJoCo's, recast the contact problem as a convex optimization and solve it with conjugate-gradient or Newton iterations, trading higher per-iteration cost for far fewer iterations and much better conditioning.2 The engine's pick is a direct bet on how tightly its contacts couple: cheap sweeps where they do not, second-order steps where they do.
Footnotes
-
Catto, Iterative Dynamics with Temporal Coherence (GDC 2005). ↩
-
Bender, Erleben, Trinkle & Coumans, Interactive Simulation of Rigid Body Dynamics in Computer Graphics (CGF 2014). ↩ ↩2
-
NVIDIA PhysX 5.4.1 docs, Rigid Body Dynamics. ↩