Resident ready Static companion
kari_mikumao Lab

Physics

WMMD physics: three backends behind one interface

Bullet as the MMD-faithful reference, a pure-Rust fallback, a clean-room PGS solver, and an XPBD cloth engine — swappable at compile time.

  • wmmd
  • physics
  • bullet
  • xpbd

MMD physics is a compatibility problem before it is a simulation problem. Spring bones, rigid bodies, and joints authored for the original tool have expected behavior, and a renderer that simulates “correctly” but differently still looks wrong to the person who authored the model. WMMD’s answer is to keep several backends behind one interface and treat one of them as the reference.

The backends

All four live behind Cargo features on wmmd-runtime, so a host picks its tradeoff at compile time:

  • Bullet (default) — MMD-faithful reference behavior, reached through a thin C shim over Bullet3 in crates/wmmd-bullet-sys. It builds vendored sources, so it costs a cmake and C++17 toolchain at build time.
  • Native Rust — a built-in backend that needs no cmake, for environments where the C++ build is not worth it.
  • Native PGS — a clean-room Havok-style projected Gauss-Seidel solver with Baumgarte stabilization.
  • Loom — an experimental XPBD engine aimed at cloth and hair.

Having a reference implementation matters more than having the fastest one. When a rig behaves oddly under an alternative solver, Bullet’s result is the arbiter, and the question becomes “why does this backend disagree” rather than “which of these is right.”

What the runtime owns

The physics module sits inside wmmd-runtime alongside the IK solver and the PhysicsController, including PMX spring constraints across the format’s three modes. The runtime is CPU-only and file-free by invariant: it receives already-parsed assets and steps simulation, bone transforms, and IK in one update() call driven by the host’s frame time. Physics can be paused, resumed, reset, and staged through the same command queue that adds models — a detail that matters for an editor, where being able to freeze and re-run a rig is the difference between guessing and diagnosing.

The IK solver supports VMD IK on/off tracks, so motions that deliberately disable IK for part of a sequence play back as authored rather than being silently overridden.

The verification stance

Physics correctness is not eyeballed. The tooling crate carries a physics verifier alongside the snapshot runner, and the working rule for the whole engine is that a fix must generalize: reproduce with whatever model exposed the problem, then express the fix and its test in general terms — arbitrary bone counts, morph sets, material configurations, and rig layouts — never as a special case for one file.