In-house · C++23 · 2D Physics

Manifold2D

Deterministic 2D rigid-body physics, modeled on Box2D v3.

  • C++23
  • 2D
  • Deterministic

Deterministic replays

TGS-Soft, 4 sub-steps

SIMD contact solve

7 joint types

The step

One step, four sub-steps.

Every world.Step(dt) runs these six stages four times over. Contacts persist between steps, so each solve starts warm.

  1. 1Integratevelocities
  2. 2Warm-startpersisted contacts
  3. 3Biased solveTGS-Soft
  4. 4Integratepositions
  5. 5Relaxunbiased pass
  6. 6Restitutionfinal pass
Capabilities

What it does.

From the broadphase to the last restitution pass, every stage is ours, and every stage is deterministic.

Rotation-aware narrowphase

GJK distance, EPA penetration, MPR, and polygon clipping produce stable contact manifolds.

TGS-Soft solver

A sub-stepped soft-constraint solver with warm-starting, friction, and restitution.

SIMD contact solve

Lane-wide passes over graph-colored Structure-of-Arrays batches, with a scalar overflow path.

Selectable broadphase

Dynamic tree, spatial hash, or sweep-and-prune, plus tile grids for statics.

Bodies, fixtures & shapes

Static/kinematic/dynamic bodies, multi-fixture layers, sensors, collision filtering; circles, capsules, polygons, and boxes.

Seven joint types

Distance, revolute, weld, prismatic, mouse, wheel, and motor joints.

Continuous collision

Anti-tunneling bullet sweeps for fast movers, with island-based sleeping.

Deterministic by design

Index-ordered iteration replays to identical results — and matches across broadphase backends.

Joints

Seven joint types.

The ropes, ragdolls, suspensions and presses in the world above are all built from these.

Distance
Revolute
Weld
Prismatic
Mouse
Wheel
Motor
In code

A body and a joint.

Create a dynamic body from a shape

BodyDef def;
def.type     = BodyType::Dynamic;
def.position = pos;
def.shape    = MakeCircle(Real(1));
def.density  = Real(1);
BodyHandle body = world.AddBody(def);

Add a revolute joint and step the world

JointDef jd;
jd.kind   = JointKind::Revolute;
jd.a      = anchor;
jd.b      = bob;
jd.anchor = Vec2(Real(100), Real(50));
world.AddJoint(jd);
world.Step(dt);
Manifold2D

Read the solver.

Deterministic, sub-stepped, and modeled on Box2D v3. The source is on GitHub.

  • C++23
  • 2D
  • Deterministic