Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
13746ad
doxygen update
erincatto Jun 2, 2026
56b6c9b
wip
erincatto Jun 4, 2026
fcc546f
Merge remote-tracking branch 'origin/main' into dmover
erincatto Jun 8, 2026
0f420fd
wip
erincatto Jun 8, 2026
914e48f
wip
erincatto Jun 10, 2026
36de47d
Merge remote-tracking branch 'origin' into dmover
erincatto Jun 17, 2026
30c1ed2
wip
erincatto Jun 19, 2026
c7a044a
fix bug in snapshot restore
erincatto Jun 20, 2026
68e36ec
fixes
erincatto Jun 21, 2026
d7f263c
wip
erincatto Jun 23, 2026
249f8d4
recording mutex
erincatto Jun 23, 2026
0b0155b
wip
erincatto Jul 2, 2026
49fce4f
wip
erincatto Jul 19, 2026
fbbfe79
improve sanitizer usage
erincatto Jul 20, 2026
8f825b8
wip
erincatto Jul 26, 2026
1fb8ee0
CI fix
erincatto Jul 26, 2026
eb68158
determinism tests in optimized builds
erincatto Jul 26, 2026
f093f90
CI fix
erincatto Jul 26, 2026
af2c8f2
pogo joint
erincatto Jul 27, 2026
605fdf1
wip
erincatto Jul 31, 2026
e866438
Remove lots of bools that disable waking bodies for simplification.
erincatto Aug 2, 2026
3d910d2
wip
erincatto Aug 11, 2026
b3ff7fd
wip
erincatto Aug 13, 2026
9c7693f
separate mover classes
erincatto Aug 14, 2026
fcfb52a
unify mover samples
erincatto Aug 14, 2026
4288a51
improve tolerances
erincatto Aug 14, 2026
01c39f2
mover clean up
erincatto Aug 15, 2026
31107d0
improved pre-solve callbacks
erincatto Aug 16, 2026
32e082c
CI fix
erincatto Aug 16, 2026
7eda852
CI fix
erincatto Aug 16, 2026
a33ba7a
hook up new joints to recording
erincatto Aug 16, 2026
dbc836c
fixes
erincatto Aug 17, 2026
16d0af7
CI fix
erincatto Aug 17, 2026
f403d6b
dynamic mover tweaks
erincatto Aug 17, 2026
200c0be
fix comment
erincatto Aug 17, 2026
4d557c1
revise mover state machine
erincatto Aug 18, 2026
92b6fa2
improve jumping
erincatto Aug 18, 2026
103cbdb
reorder mover logic
erincatto Aug 18, 2026
9407f1b
jump consistency
erincatto Aug 18, 2026
86014a0
CI fix
erincatto Aug 18, 2026
7022983
surface velocity
erincatto Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 41 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:

env:
BUILD_TYPE: Debug
Expand All @@ -14,7 +15,7 @@ jobs:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
timeout-minutes: ${{ matrix.timeout || 4 }}
if: github.event_name == 'push' || github.event.pull_request.draft == false
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -50,6 +51,17 @@ jobs:
os: windows-11-arm
args: -A arm64 -DBOX2D_DISABLE_SIMD=TRUE -DBOX2D_SANITIZE=ON
test: ./bin/Debug/test
# Optimized runs. The determinism golden hash is otherwise only checked at -O0,
# and -O2 is where a value changing float transform would first show up.
- name: windows-relwithdebinfo
os: windows-latest
msvc: true
config: RelWithDebInfo
test: ./bin/RelWithDebInfo/test
- name: macos-relwithdebinfo
os: macos-latest
config: RelWithDebInfo
test: ./bin/test
- name: ubuntu-gcc-double
os: ubuntu-latest
args: -DBOX2D_DOUBLE_PRECISION=ON
Expand All @@ -69,23 +81,27 @@ jobs:
arch: x64

- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DBOX2D_VALIDATE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON ${{ matrix.args }}
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ matrix.config || env.BUILD_TYPE }} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DBOX2D_VALIDATE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON ${{ matrix.args }}

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
run: cmake --build ${{github.workspace}}/build --config ${{ matrix.config || env.BUILD_TYPE }}

- name: Test
working-directory: ${{github.workspace}}/build
env:
MSAN_OPTIONS: ${{ matrix['msan-options'] || '' }}
UBSAN_OPTIONS: print_stacktrace=1
run: ${{ matrix.test }}

# mingw needs some extra setup so keeping it separate from the matrix.
# Debug -O0 copies whole structs and can hide padding bugs. RelWithDebInfo tests
# -O2 codegen while B2_ENABLE_ASSERT keeps asserts alive, heavy validation stays
# Debug only.
build-windows-mingw:
name: windows-mingw
runs-on: windows-latest
timeout-minutes: 4
if: github.event_name == 'push' || github.event.pull_request.draft == false
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
defaults:
run:
shell: msys2 {0}
Expand All @@ -103,20 +119,38 @@ jobs:
mingw-w64-ucrt-x86_64-ninja

- name: Configure CMake
run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DBOX2D_VALIDATE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON
run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DBOX2D_VALIDATE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON

- name: Build
run: cmake --build build --config ${{env.BUILD_TYPE}}
run: cmake --build build --config RelWithDebInfo

- name: Test
working-directory: build
run: ./bin/test

# Build-only: running the wasm test needs a node + pthread/SharedArrayBuffer harness.
# This still catches compile breaks in the box2d library and the test target.
emscripten:
name: emscripten
runs-on: ubuntu-latest
timeout-minutes: 8
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
steps:
- uses: actions/checkout@v6

- uses: mymindstorm/setup-emsdk@v14

- name: Configure CMake
run: emcmake cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DBOX2D_VALIDATE=ON

- name: Build
run: cmake --build build --config ${{env.BUILD_TYPE}}

samples:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
timeout-minutes: 8
if: github.event_name == 'push' || github.event.pull_request.draft == false
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
strategy:
fail-fast: false
matrix:
Expand Down
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,4 @@ CMakeUserPresets.json
.idea/
.claude/
.tmp/
AGENTS.md
GEMINI.md
*.b2rec
build-dp/
build_float/
55 changes: 37 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ if (MSVC OR APPLE OR (UNIX AND NOT APPLE))
add_compile_options("$<$<CONFIG:Debug>:/fsanitize=address>")
add_link_options("$<$<CONFIG:Debug>:/INCREMENTAL:NO>")
elseif(APPLE)
add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined)
# UBSan recovers by default, no-recover makes the first report fatal so CI fails
add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined -fno-sanitize-recover=all)
add_link_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined)
elseif(UNIX)
# use-after-scope is clang only, leave it off so gcc builds work
add_compile_options(-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer)
add_link_options(-fsanitize=address -fsanitize=undefined)
endif()
else()
if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND PROJECT_IS_TOP_LEVEL)
Expand All @@ -44,12 +49,17 @@ endif()

# Deterministic math
# https://box2d.org/posts/2024/08/determinism/
if (MINGW OR UNIX)
add_compile_options(-ffp-contract=off)
elseif (MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang")
# clang-cl contracts multiply add into FMA under AVX2, diverging from non FMA builds.
# The plain driver flag is dropped, so force it through to the frontend.
add_compile_options(/clang:-ffp-contract=off)
# Contraction into FMA is the one value changing transform enabled by default, and whether
# it fires depends on the target. Test the compiler, not the platform, so every gcc and
# clang gets the flag including a clang that is neither MinGW nor clang-cl.
if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
if (CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
# clang-cl contracts multiply add into FMA under AVX2, diverging from non FMA builds.
# The plain driver flag is dropped, so force it through to the frontend.
add_compile_options(/clang:-ffp-contract=off)
else()
add_compile_options(-ffp-contract=off)
endif()
endif()

option(BOX2D_DISABLE_SIMD "Disable SIMD math (slower)" OFF)
Expand All @@ -60,37 +70,46 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
cmake_dependent_option(BOX2D_AVX2 "Enable AVX2" OFF "NOT BOX2D_DISABLE_SIMD" OFF)
endif()

# These are read by the library build, so they must precede add_subdirectory(src),
# otherwise the first configure and a re-configure produce different libraries.
# Top level only, so they stay hidden from FetchContent consumers.
if(PROJECT_IS_TOP_LEVEL)
option(BOX2D_PROFILE "Enable profiling with Tracy" OFF)
option(BOX2D_VALIDATE "Enable heavy validation" ON)
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Leaving this here for testing
# set(CMAKE_VERBOSE_MAKEFILE ON)

# Emscripten pthread support. Must precede add_subdirectory(src) so the box2d library
# objects are built with the same atomics/bulk-memory features as the executables that
# link them, otherwise wasm-ld rejects --shared-memory. Top level only, so a FetchContent
# consumer keeps control of its own threading model.
if (EMSCRIPTEN AND PROJECT_IS_TOP_LEVEL)
set(EMSCRIPTEN_PTHREADS_COMPILER_FLAGS "-pthread -s USE_PTHREADS=1")
set(EMSCRIPTEN_PTHREADS_LINKER_FLAGS "${EMSCRIPTEN_PTHREADS_COMPILER_FLAGS} -s ALLOW_MEMORY_GROWTH")
string(APPEND CMAKE_C_FLAGS " ${EMSCRIPTEN_PTHREADS_COMPILER_FLAGS}")
string(APPEND CMAKE_CXX_FLAGS " ${EMSCRIPTEN_PTHREADS_COMPILER_FLAGS}")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${EMSCRIPTEN_PTHREADS_LINKER_FLAGS}")
endif()

add_subdirectory(src)

# This hides samples, test, and doxygen from apps that use box2d via FetchContent
if(PROJECT_IS_TOP_LEVEL)
option(BOX2D_SAMPLES "Build the Box2D samples" ON)
option(BOX2D_BENCHMARKS "Build the Box2D benchmarks" OFF)
option(BOX2D_DOCS "Build the Box2D documentation" OFF)
option(BOX2D_PROFILE "Enable profiling with Tracy" OFF)
option(BOX2D_VALIDATE "Enable heavy validation" ON)
option(BOX2D_UNIT_TESTS "Build the Box2D unit tests" ON)

# Needed for samples.exe to find box2d.dll
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")

if(BOX2D_UNIT_TESTS OR BOX2D_SAMPLES OR BOX2D_BENCHMARKS)
# Emscripten pthread support
if(EMSCRIPTEN)
set(EMSCRIPTEN_PTHREADS_COMPILER_FLAGS "-pthread -s USE_PTHREADS=1")
set(EMSCRIPTEN_PTHREADS_LINKER_FLAGS "${EMSCRIPTEN_PTHREADS_COMPILER_FLAGS} -s ALLOW_MEMORY_GROWTH")
string(APPEND CMAKE_C_FLAGS " ${EMSCRIPTEN_PTHREADS_COMPILER_FLAGS}")
string(APPEND CMAKE_CXX_FLAGS " ${EMSCRIPTEN_PTHREADS_COMPILER_FLAGS}")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${EMSCRIPTEN_PTHREADS_LINKER_FLAGS}")
endif()

add_subdirectory(shared)
endif()

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ Support development of Box2D through [Github Sponsors](https://github.com/sponso

Please consider starring this repository and subscribing to my [YouTube channel](https://www.youtube.com/@erin_catto).

## LLM Usage

LLMs are used in the following areas:

- unit tests
- samples app
- migrating code between Box2D and Box3D
- build configuration
- code reviews
- benchmarking

Elsewhere all code is developed and written by me. I take responsibility for every line of code in Box2D/3D.

## External ports, wrappers, and bindings (unsupported)

- Beef bindings - https://github.com/EnokViking/Box2DBeef
Expand Down
Loading
Loading