Conversation
remove clipPoint
shape distance in relative space
Pull request overview
This PR introduces “large world” support via an optional double-precision world-position boundary (BOX2D_DOUBLE_PRECISION). It adds new world-space types (b2Position, b2WorldTransform), updates world queries and callbacks to accept an origin for robust far-from-origin behavior, and adjusts serialization/recording/snapshot formats to preserve full precision.
Changes:
- Add
BOX2D_DOUBLE_PRECISIONbuild option and propagate it publicly to enforce ABI consistency; add runtime detection (b2IsDoublePrecision). - Introduce
b2Position/b2WorldTransformand migrate world-facing APIs, queries (with origins), debug draw origin handling, and sample/test code accordingly. - Update broad-phase AABB construction to be conservative via directed rounding, and update recording/snapshot formats to encode precision mode and new query arguments.
Reviewed changes
Copilot reviewed 73 out of 74 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/test_world.c | Updates tests to use b2Position conversions (b2MakePosition, b2ToVec2) and new callback signatures. |
| test/test_snapshot.c | Migrates body definitions to b2Position for snapshot test coverage. |
| test/test_shape.c | Updates AABB tests to use b2WorldTransform_identity. |
| test/test_recording.c | Updates query/cast callbacks and exercises non-zero query origins for recording/replay. |
| test/test_math.c | Adds unit tests for new world-position boundary helpers and large-world precision behavior. |
| test/test_distance.c | Updates distance/cast tests for new relative-transform distance API and world transforms. |
| test/test_determinism.c | Splits determinism expectations for float vs double-precision builds. |
| test/test_collision.c | Adds large-world manifold/AABB tests validating far-from-origin correctness. |
| test/main.c | Registers and runs the new large-world test. |
| test/CMakeLists.txt | Adds test_large_world.c to the test target. |
| src/world_snapshot.c | Bumps snapshot version, adds precision flag, rejects cross-precision loads, hashes positions at full width. |
| src/wheel_joint.c | Adjusts joint force computations to avoid unnecessary full transforms and to use position deltas. |
| src/weld_joint.c | Uses b2PositionDelta for center deltas. |
| src/solver.c | Recenters continuous collision work, uses conservative fat AABBs, reconstructs contact hit points from anchors/centers. |
| src/shape.h | Switches world transform usage and adds b2ComputeFatShapeAABB API. |
| src/shape.c | Migrates shape world queries to b2Position/origin-relative math; updates recording wire types; updates closest-point API. |
| src/sensor.c | Uses relative world transforms for sensor distance queries (origin-independent). |
| src/revolute_joint.c | Simplifies angle computation and uses b2PositionDelta for center deltas. |
| src/recording.h | Adds position/world-transform wire types, position hashing helper, and bumps recording version. |
| src/recording.c | Implements POSITION/WORLDXF writers (double on wire when enabled); updates writers for new types. |
| src/recording_replay.h | Adds reader declarations for F64/POSITION/WORLDXF and updates recorded hit/origin types. |
| src/recording_ops.inl | Updates op signatures to use POSITION/WORLDXF and adds query origin args to spatial query ops. |
| src/prismatic_joint.c | Recenters world computations and uses b2PositionDelta to keep precision far from origin. |
| src/motor_joint.c | Uses b2PositionDelta for center deltas. |
| src/math_functions.c | Adds validators for b2Position and b2WorldTransform. |
| src/joint.c | Recenters joint separation queries and debug drawing relative to draw->origin. |
| src/geometry.c | Implements conservative outward-rounded AABB building and fat-AABB helper for shapes. |
| src/distance.c | Makes distance queries origin-independent (relative transform), returns results in frame A, projects back where needed. |
| src/distance_joint.c | Recenters length/force computations and uses b2PositionDelta for deltas. |
| src/core.c | Adds b2IsDoublePrecision() runtime query. |
| src/contact.h | Changes cached contact data to store relative pose/rotations for far-from-origin stability. |
| src/contact.c | Updates manifold/collision plumbing to use b2WorldTransform and reconstructs debug point from anchors. |
| src/CMakeLists.txt | Adds BOX2D_DOUBLE_PRECISION option handling and propagates compile definition publicly. |
| src/box2d.natvis | Adds debugger visualizers for b2Position and b2WorldTransform. |
| src/body.h | Upgrades body sim world fields to b2WorldTransform/b2Position; introduces relative sweep builder. |
| src/body.c | Migrates body APIs to world-position types and updates force/impulse/velocity point math accordingly. |
| src/aabb.h | Adds outward-rounded b2OffsetAABB helper for lifting relative AABBs to world coordinates. |
| src/aabb.c | Updates raycast output point to b2Position. |
| shared/human.c | Migrates sample helper to new position API for joints/poses. |
| shared/determinism.c | Hashes float transforms in a precision-independent way while using b2WorldTransform APIs. |
| shared/benchmarks.c | Migrates benchmark world positions/transforms to new APIs. |
| samples/sample.h | Updates mouse APIs and stored mouse point to b2Position. |
| samples/sample.cpp | Uses origin-relative picking queries; sets debug draw origin to camera center in double-precision builds. |
| samples/sample_replay.cpp | Renames replay sample and updates picking/selection drawing for camera-relative behavior. |
| samples/sample_large_world.cpp | Adds a dedicated large-world sample scene far from origin. |
| samples/sample_issues.cpp | Updates cast shape call to include origin. |
| samples/sample_events.cpp | Updates debug visualization to use anchors instead of removed/unsafe clip points (float build only). |
| samples/sample_determinism.cpp | Updates overlap query to include origin parameter. |
| samples/sample_collision.cpp | Updates distance/cast/overlap calls and manifold visualization to use anchors/origin-aware APIs. |
| samples/sample_character.cpp | Updates mover queries to pass origin. |
| samples/sample_benchmark.cpp | Updates world queries and distance benchmarking to new relative-transform semantics and projects outputs for drawing. |
| samples/main.cpp | Migrates camera click points to b2Position and updates zoom/pan math accordingly. |
| samples/draw.h | Migrates camera center to b2Position; adds CameraRelative helpers for double-precision builds. |
| samples/draw.c | Makes screen/world conversions robust far from origin; rounds view bounds outward; adjusts projection in DP mode. |
| samples/draw_text.cpp | Updates world-string drawing to accept b2Position. |
| samples/CMakeLists.txt | Splits sample sets so float-only samples aren’t built under double precision; ensures replay viewer remains available. |
| include/box2d/types.h | Migrates world-facing structs/callbacks to b2Position/b2WorldTransform; adds debug draw origin. |
| include/box2d/math_functions.h | Defines b2Position/b2WorldTransform and boundary helpers (rounding, deltas, transforms) plus C++ operators. |
| include/box2d/constants.h | Raises B2_HUGE under double precision to stay above broad-phase float range. |
| include/box2d/collision.h | Migrates AABB APIs to world transforms; changes distance input to relative transform; removes clipPoint guidance; updates cast outputs. |
| include/box2d/box2d.h | Migrates many public APIs to b2Position and adds origin parameters to spatial queries; adds link-time mismatch guard. |
| include/box2d/base.h | Adds b2IsDoublePrecision() declaration and includes <stdbool.h>. |
| docs/recording.md | Adds doxygen anchor. |
| docs/large_worlds.md | New documentation for enabling and using large world mode and query origins. |
| docs/CMakeLists.txt | Adds large_worlds.md to generated docs. |
| docs/character.md | Documents query origin usage for mover APIs in large world mode. |
| CMakeLists.txt | Adds BOX2D_DOUBLE_PRECISION CMake option. |
| .gitignore | Ignores build-dp/. |
| .github/workflows/build.yml | Refactors CI to a matrix, adds double-precision builds and sample builds. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This was referenced Jun 15, 2026
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
WARNING: This PR is API breaking. There are new types and some function signatures have changed.
Added CMake option:
BOX2D_DOUBLE_PRECISIONThis gives all bodies a position that is double precision to support large worlds. Up to around 10,000km becomes feasible. All calculations are done in relative coordinates using single precision. This means the performance overhead is only around 3%.
The broad-phase remains single precision. So shape AABBs are snapped from double precision to the bounding single precision number. This means bounding boxes get significant padding far from the origin. This is one of the main reasons for the 10,000km limit. There you can get AABB padding of around 1 meter, which could lead to a lot of extra contacts in stacking scenarios. If this doesn't matter for your game, you can push beyond 10,000km.
There is a new type for positions:
b2Poswhich can hold double precision coordinates. This aliases tob2Vec2in single precision. There is alsob2WorldTransformthat holds ab2Pos.Many queries have been updated to take an origin. In single precision this is optional. In double precision you should use this to localize your queries in world space. Most query math is still done in relative coordinates using single precision.
I recommend to use this option if your game world exceeds 20km.
If your game world exceeds 10,000km and has heavy stacking scenarios, I recommend to fork Box2D, disable SIMD, and convert all floats to doubles. Full doubles is not on the roadmap.
This implementation is inspired by Jolt.
Migration:
For migration the biggest change will be the world queries. These now take an origin. Just pass
b2Pos_zerofor these until you adopt double precision. In some cases you may prefer to use the origin because then things like AABBs and shape proxies become relative. But you can make that conversion in a later pass.Also b2Manifold::clipPoint is gone. Use anchorA/anchorB and some math instead if needed. See the header comments.
Fix for #1067 and #1069