Skip to content

Dynamic mover - #1072

Open
erincatto wants to merge 41 commits into
mainfrom
dmover
Open

Dynamic mover#1072
erincatto wants to merge 41 commits into
mainfrom
dmover

Conversation

@erincatto

@erincatto erincatto commented Jun 21, 2026

Copy link
Copy Markdown
Owner
  • Experimental dynamic mover.
  • Added mover and pogo joints for the dynamic mover.
  • Refactored geometric mover.
  • Redesigned pre-solve callback
  • Added config.h

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an experimental “dynamic mover” feature set to Box2D, including new joint types to drive a character-style dynamic body, plus determinism/recording/snapshot updates needed to support rollback/replay and cross-platform builds.

Changes:

  • Introduces mover joint and pogo joint (core + public API) and adds new sample implementations (dynamic + geometric movers).
  • Updates pre-solve callback API (manifold-edit based) and adds a pre-continuous callback for TOI filtering.
  • Improves determinism tooling: snapshot restore event-buffer reset, world state hashing, recording opcode/version updates, CI/build hardening.

Reviewed changes

Copilot reviewed 68 out of 73 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
test/test_world.c Updates world API coverage test for pre-solve callback signature/args.
test/test_snapshot.c Adds regression test for restore clearing transient event buffers; validates state hash.
test/test_recording.c Updates joint destroy call to new signature.
test/test_distance.c Extends distance tests; initializes new input fields; adds short-edge regression coverage.
test/main.c Routes MSVC CRT error/assert reporting to stderr for headless runs.
src/world_snapshot.c Clears transient event buffers on restore; hashes new joint types; adds state-hash API impl.
src/wheel_joint.c Adjusts limit setter behavior; updates debug draw transform composition.
src/weld_joint.c Updates debug draw transform composition.
src/timer.c Fixes Windows header include casing for MinGW-on-Linux.
src/solver.c Hooks pre-continuous callback; adds determinism note; adjusts validation call site.
src/shape.c Removes wakeBodies plumbing from shape/contact teardown/reset proxy paths.
src/revolute_joint.c Clamps limits to valid range; updates debug draw transform composition.
src/recording.h Bumps recording minor version; adds mover/pogo joint defs to recording types.
src/recording.c Adds mover/pogo joint writers; wraps record ops with a mutex for thread-safe writes.
src/recording_replay.h Adds mover/pogo joint def readers.
src/recording_replay.c Adds mover/pogo joint replay support; updates DestroyJoint replay; guards dispatch on rdr->ok.
src/recording_ops.inl Reassigns opcodes; adds mover/pogo ops; removes wakeAttached arg from DestroyJoint op.
src/prismatic_joint.c Adjusts limit setter behavior; updates debug draw transform composition.
src/pogo_joint.c New pogo joint implementation (API + solver integration helpers).
src/physics_world.h Adds preContinuousFcn slot; formatting cleanup.
src/physics_world.c Adds denormal-flush warning; updates casts for origin-relative queries; expands pre-solve API; validation placement.
src/mover.c Renames plane solver result field to delta.
src/mover_joint.c New mover joint implementation (API + solver integration helpers).
src/motor_joint.c Removes dead debug dump block and an unused include.
src/joint.h Adds mover/pogo joint sim structs and solver hooks; simplifies destroy-joint internal signature.
src/distance.c Adjusts overlap/cache handling and numerical epsilon criteria in GJK distance.
src/distance_joint.c Changes length-range setter to no longer reset impulses (behavioral change).
src/contact.h Updates destroy-contact signature to remove wakeBodies parameter.
src/contact.c Makes pre-solve manifold-edit based; always wakes touching bodies on contact destruction.
src/CMakeLists.txt Adds new source files; adds public config header; enables asserts in RelWithDebInfo; clarifies validation message.
src/body.h Removes outdated todo about fixed rotation inertia.
src/body.c Removes wakeBodies parameter from contact/joint destruction paths; fixed-rotation inertia handling; mass-data extents update.
src/atomic.h Refines MSVC atomic loads; adds denormal-flush detection helper.
shared/utils.c Fixes Windows header include casing for MinGW-on-Linux.
shared/human.c Updates joint destroy calls to new signature.
shared/determinism.c Minor assertion simplification.
samples/sample.cpp Updates joint destroy call; updates pause key display strings.
samples/sample_joints.cpp Updates joint destroy calls to new signature.
samples/sample_issues.cpp Adds a note about impulse application point for stability.
samples/sample_events.cpp Removes old platformer pre-solve sample; updates joint destroy call; minor cleanup.
samples/sample_determinism.cpp Adjusts which steps issue queries; formatting cleanup.
samples/sample_collision.cpp Minor cleanup to reuse radius variable.
samples/sample_benchmark.cpp Tweaks benchmark content (joint destroy call; sensor benchmark density/layout).
samples/main.cpp Changes pause hotkey from Space to P; fixes preprocessor nesting for alloc hook.
samples/geometric_mover.h New geometric mover helper declarations and tuning struct.
samples/geometric_mover.cpp New geometric mover implementation using collide/cast mover APIs and plane solver.
samples/dynamic_mover.h New dynamic mover helper declarations and tuning struct.
samples/dynamic_mover.cpp New dynamic mover implementation using mover+pogo joints.
samples/draw.c Migrates sample renderer arrays to new container macros.
samples/doohickey.cpp Updates joint destroy calls to new signature.
samples/data/map04.svg Adds new map asset.
samples/data/map03.svg Updates SVG metadata/path (Inkscape version + edits).
samples/data/map_right.svg Adds new map asset.
samples/data/map_left.svg Updates SVG metadata/path (Inkscape version + edits).
samples/container.h Reworks dynamic array/container macros used by samples.
samples/CMakeLists.txt Adds new mover source files to samples build.
samples/car.cpp Removes unused locals; updates joint destroy calls.
README.md Documents where LLMs are used in the project.
include/box2d/types.h Adds mover/pogo public types; revises callbacks; enhances event/result documentation.
include/box2d/math_functions.h Adjusts normalization thresholds; rewrites angle unwind to avoid remainderf dependency.
include/box2d/config.h Adds public compile-time configuration header.
include/box2d/collision.h Renames plane solver result field translation→delta; doc tweaks.
include/box2d/box2d.h Exposes new APIs/types (state hash, mover/pogo, callback signature changes, destroy-joint signature change).
include/box2d/base.h Adds config include plumbing; allows custom export macro override; adjusts Windows detection.
docs/simulation.md Minor wording fix about mass properties.
docs/layout.xml Updates Doxygen layout version and visibility attributes.
docs/foundation.md Adds a blank line in multithreading section for formatting.
CMakeLists.txt Sanitizer flag refinements; deterministic FP contraction flag logic; option ordering; Emscripten pthread flags positioning.
benchmark/main.c Improves CLI parsing (long options, list, benchmark by name) and help text.
.gitignore Removes some ignored files/dirs entries.
.github/workflows/build.yml Adds workflow_dispatch; adds RelWithDebInfo runs; adds Emscripten build-only job; tweaks draft gating and sanitizer env.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread include/box2d/types.h
Comment on lines 1247 to +1251
/// Prototype for a pre-solve callback.
/// This is called after a contact is updated. This allows you to inspect a
/// contact before it goes to the solver. If you are careful, you can modify the
/// contact manifold (e.g. modify the normal).
/// This is called after a contact manifold is updated. This allows you to inspect a
/// manifold before it goes to the solver. If you are careful, you can modify the
/// manifold (e.g. modify the normal). You can set the manifold point count to zero disable
/// collision.
Comment thread test/test_world.c Outdated
}

static bool PreSolveStatic( b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Pos point, b2Vec2 normal, void* context )
static bool PreSolveStatic( b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Manifold* manifold, void* context )
Comment thread src/revolute_joint.c
Comment on lines 137 to 149
void b2RevoluteJoint_SetLimits( b2JointId jointId, float lower, float upper )
{
B2_ASSERT( lower <= upper );

b2World* world = b2GetWorld( jointId.world0 );
B2_REC( world, RevoluteJointSetLimits, jointId, lower, upper );
B2_ASSERT( lower <= upper );
B2_ASSERT( lower >= -0.99f * B2_PI );
B2_ASSERT( upper <= 0.99f * B2_PI );

b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_revoluteJoint );
if ( lower != joint->revoluteJoint.lowerAngle || upper != joint->revoluteJoint.upperAngle )
{
joint->revoluteJoint.lowerAngle = b2MinFloat( lower, upper );
joint->revoluteJoint.upperAngle = b2MaxFloat( lower, upper );
joint->revoluteJoint.lowerImpulse = 0.0f;
joint->revoluteJoint.upperImpulse = 0.0f;
}
float lowerAngle = b2MinFloat( lower, upper );
float upperAngle = b2MaxFloat( lower, upper );
joint->revoluteJoint.lowerAngle = b2ClampFloat( lowerAngle, -0.99f * B2_PI, 0.99f * B2_PI );
joint->revoluteJoint.upperAngle = b2ClampFloat( upperAngle, -0.99f * B2_PI, 0.99f * B2_PI );
}
Comment thread src/prismatic_joint.c
Comment on lines 108 to 117
void b2PrismaticJoint_SetLimits( b2JointId jointId, float lower, float upper )
{
b2World* world = b2GetWorld( jointId.world0 );
B2_REC( world, PrismaticJointSetLimits, jointId, lower, upper );
B2_ASSERT( lower <= upper );

b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_prismaticJoint );
if ( lower != joint->prismaticJoint.lowerTranslation || upper != joint->prismaticJoint.upperTranslation )
{
joint->prismaticJoint.lowerTranslation = b2MinFloat( lower, upper );
joint->prismaticJoint.upperTranslation = b2MaxFloat( lower, upper );
joint->prismaticJoint.lowerImpulse = 0.0f;
joint->prismaticJoint.upperImpulse = 0.0f;
}
joint->prismaticJoint.lowerTranslation = b2MinFloat( lower, upper );
joint->prismaticJoint.upperTranslation = b2MaxFloat( lower, upper );
}
Comment thread src/wheel_joint.c
Comment on lines 95 to 104
void b2WheelJoint_SetLimits( b2JointId jointId, float lower, float upper )
{
b2World* world = b2GetWorld( jointId.world0 );
B2_REC( world, WheelJointSetLimits, jointId, lower, upper );
B2_ASSERT( lower <= upper );

b2JointSim* joint = b2GetJointSimCheckType( jointId, b2_wheelJoint );
if ( lower != joint->wheelJoint.lowerTranslation || upper != joint->wheelJoint.upperTranslation )
{
joint->wheelJoint.lowerTranslation = b2MinFloat( lower, upper );
joint->wheelJoint.upperTranslation = b2MaxFloat( lower, upper );
joint->wheelJoint.lowerImpulse = 0.0f;
joint->wheelJoint.upperImpulse = 0.0f;
}
joint->wheelJoint.lowerTranslation = b2MinFloat( lower, upper );
joint->wheelJoint.upperTranslation = b2MaxFloat( lower, upper );
}
Comment thread src/distance_joint.c
Comment on lines 54 to 65
void b2DistanceJoint_SetLengthRange( b2JointId jointId, float minLength, float maxLength )
{
b2World* world = b2GetWorld( jointId.world0 );
B2_REC( world, DistanceJointSetLengthRange, jointId, minLength, maxLength );
b2JointSim* base = b2GetJointSimCheckType( jointId, b2_distanceJoint );
b2DistanceJoint* joint = &base->distanceJoint;

minLength = b2ClampFloat( minLength, B2_LINEAR_SLOP, B2_HUGE );
maxLength = b2ClampFloat( maxLength, B2_LINEAR_SLOP, B2_HUGE );
joint->minLength = b2MinFloat( minLength, maxLength );
joint->maxLength = b2MaxFloat( minLength, maxLength );
joint->impulse = 0.0f;
joint->lowerImpulse = 0.0f;
joint->upperImpulse = 0.0f;
}
{
m_planeCount = 0;

b2World_CollideMover( m_worldId, m_position, &m_capsule, m_filter, PlaneResultFcn, this );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants