Conversation
CI fix for pogo
There was a problem hiding this comment.
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 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. |
| } | ||
|
|
||
| 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 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 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 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 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 ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.