Position-Based Dynamics
A C++ simulator built on position-based dynamics: rather than mass-spring forces, it projects predicted positions directly onto geometric constraints.
╌╌╌╌
A C++ body simulator built on position-based dynamics (PBD), following Müller et al. Instead of accumulating spring forces and integrating them into velocities, PBD works directly on positions: it predicts where particles will move, then projects those positions onto a set of constraints. The scheme is stabler than mass-spring at large timesteps, generalizes to many constraint types, and costs less per step.
Each step first moves every particle by its external forces alone, producing a predicted position . The predictions ignore internal interactions and generally violate the constraints (a stretched edge, an overlapping pair), so the solver corrects them. Each constraint is enforced by a position correction along its gradient,
where is the inverse mass, so heavier particles move less. The scaling lands the correction exactly on the constraint for a linearized , and weighting by inverse mass conserves linear and angular momentum.
Geometrically, points normal to the constraint surface, so the correction moves each particle along that normal; the factor sets how far, chosen so a single step reaches when the constraint is locally linear and is re-solved when it is not.
Constraints are projected one after another in a Gauss-Seidel sweep, each seeing the corrections of the ones before it, and the whole set is swept a few times per step, with more iterations stiffening the material toward rigid. Once the projections settle, velocities are read back from how far each particle actually moved:
- 1input: timestep , positions , velocities , constraints , solver iterations
- 2for each particle do
- 3
- 4
- 5for to do
- 6for each constraint do
- 7project so that
- 8for each particle do
- 9
- 10
Because a correction is a position projection rather than a force, there is no stiff spring constant to overshoot and blow up the integrator. A force-based solver picks a stiffness and then must keep , so a rigid material demands a tiny timestep; PBD instead moves the particle straight onto the constraint, and stiffness becomes the number of solver iterations — a quantity that can only converge, never diverge. That is why PBD holds together at the large, fixed timestep a game loop runs on, and why the same solver handles distance, volume, and collision constraints without retuning: each is just another to project onto.
References
- Project repository
- Reference notes: Linear Algebra
╌╌ END ╌╌