Full Code of erincatto/box2d for AI

main 5778d748bb06 cached
212 files
2.7 MB
712.3k tokens
2423 symbols
1 requests
Download .txt
Showing preview only (2,846K chars total). Download the full file or copy to clipboard to get everything.
Repository: erincatto/box2d
Branch: main
Commit: 5778d748bb06
Files: 212
Total size: 2.7 MB

Directory structure:
gitextract___deiibx/

├── .clang-format
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── issue_template.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── benchmark/
│   ├── CMakeLists.txt
│   ├── amd7950x_avx2/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── amd7950x_float/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── amd7950x_sse2/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   ├── tumbler.csv
│   │   └── washer.csv
│   ├── m2air_float/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── m2air_neon/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── main.c
│   └── n100_sse2/
│       ├── joint_grid.csv
│       ├── large_pyramid.csv
│       ├── many_pyramids.csv
│       ├── rain.csv
│       ├── smash.csv
│       ├── spinner.csv
│       └── tumbler.csv
├── build.sh
├── build_emscripten.sh
├── create_sln.bat
├── deploy_docs.sh
├── docs/
│   ├── CMakeLists.txt
│   ├── FAQ.md
│   ├── character.md
│   ├── collision.md
│   ├── extra.css
│   ├── foundation.md
│   ├── hello.md
│   ├── layout.xml
│   ├── loose_ends.md
│   ├── migration.md
│   ├── overview.md
│   ├── reading.md
│   ├── release_notes_v310.md
│   ├── samples.md
│   └── simulation.md
├── extern/
│   ├── glad/
│   │   ├── include/
│   │   │   ├── KHR/
│   │   │   │   └── khrplatform.h
│   │   │   └── glad/
│   │   │       └── glad.h
│   │   └── src/
│   │       └── glad.c
│   └── jsmn/
│       └── jsmn.h
├── include/
│   └── box2d/
│       ├── base.h
│       ├── box2d.h
│       ├── collision.h
│       ├── id.h
│       ├── math_functions.h
│       └── types.h
├── samples/
│   ├── CMakeLists.txt
│   ├── car.cpp
│   ├── car.h
│   ├── container.c
│   ├── container.h
│   ├── data/
│   │   ├── background.fs
│   │   ├── background.vs
│   │   ├── circle.fs
│   │   ├── circle.vs
│   │   ├── font.fs
│   │   ├── font.vs
│   │   ├── line.fs
│   │   ├── line.vs
│   │   ├── point.fs
│   │   ├── point.vs
│   │   ├── solid_capsule.fs
│   │   ├── solid_capsule.vs
│   │   ├── solid_circle.fs
│   │   ├── solid_circle.vs
│   │   ├── solid_polygon.fs
│   │   └── solid_polygon.vs
│   ├── donut.cpp
│   ├── donut.h
│   ├── doohickey.cpp
│   ├── doohickey.h
│   ├── draw.c
│   ├── draw.h
│   ├── main.cpp
│   ├── sample.cpp
│   ├── sample.h
│   ├── sample_benchmark.cpp
│   ├── sample_bodies.cpp
│   ├── sample_character.cpp
│   ├── sample_collision.cpp
│   ├── sample_continuous.cpp
│   ├── sample_determinism.cpp
│   ├── sample_events.cpp
│   ├── sample_geometry.cpp
│   ├── sample_issues.cpp
│   ├── sample_joints.cpp
│   ├── sample_robustness.cpp
│   ├── sample_shapes.cpp
│   ├── sample_stacking.cpp
│   ├── sample_world.cpp
│   ├── shader.c
│   ├── shader.h
│   ├── stb_image_write.h
│   └── stb_truetype.h
├── shared/
│   ├── CMakeLists.txt
│   ├── benchmarks.c
│   ├── benchmarks.h
│   ├── determinism.c
│   ├── determinism.h
│   ├── human.c
│   ├── human.h
│   ├── random.c
│   └── random.h
├── src/
│   ├── CMakeLists.txt
│   ├── aabb.c
│   ├── aabb.h
│   ├── arena_allocator.c
│   ├── arena_allocator.h
│   ├── array.c
│   ├── array.h
│   ├── atomic.h
│   ├── bitset.c
│   ├── bitset.h
│   ├── body.c
│   ├── body.h
│   ├── box2d.natvis
│   ├── broad_phase.c
│   ├── broad_phase.h
│   ├── constants.h
│   ├── constraint_graph.c
│   ├── constraint_graph.h
│   ├── contact.c
│   ├── contact.h
│   ├── contact_solver.c
│   ├── contact_solver.h
│   ├── core.c
│   ├── core.h
│   ├── ctz.h
│   ├── distance.c
│   ├── distance_joint.c
│   ├── dynamic_tree.c
│   ├── geometry.c
│   ├── hull.c
│   ├── id_pool.c
│   ├── id_pool.h
│   ├── island.c
│   ├── island.h
│   ├── joint.c
│   ├── joint.h
│   ├── manifold.c
│   ├── math_functions.c
│   ├── motor_joint.c
│   ├── mover.c
│   ├── physics_world.c
│   ├── physics_world.h
│   ├── prismatic_joint.c
│   ├── revolute_joint.c
│   ├── sensor.c
│   ├── sensor.h
│   ├── shape.c
│   ├── shape.h
│   ├── solver.c
│   ├── solver.h
│   ├── solver_set.c
│   ├── solver_set.h
│   ├── table.c
│   ├── table.h
│   ├── timer.c
│   ├── types.c
│   ├── weld_joint.c
│   └── wheel_joint.c
└── test/
    ├── CMakeLists.txt
    ├── main.c
    ├── test_bitset.c
    ├── test_collision.c
    ├── test_determinism.c
    ├── test_distance.c
    ├── test_dynamic_tree.c
    ├── test_id.c
    ├── test_macros.h
    ├── test_math.c
    ├── test_shape.c
    ├── test_table.c
    └── test_world.c

================================================
FILE CONTENTS
================================================

================================================
FILE: .clang-format
================================================
# Reference: https://clang.llvm.org/docs/ClangFormatStyleOptions.html
# VS 2026 uses 20.1.8
# https://releases.llvm.org/20.1.0/tools/clang/docs/ClangFormatStyleOptions.html
# https://clang-format-configurator.site/
# default values:
# https://github.com/llvm/llvm-project/blob/main/clang/lib/Format/Format.cpp
---
Language: Cpp
BasedOnStyle: Microsoft

BreakBeforeBraces: Custom
BraceWrapping:
  AfterCaseLabel: true
  AfterUnion: true
  BeforeWhile: true

ColumnLimit: 130
PointerAlignment: Left
UseTab: Always
BreakConstructorInitializers: BeforeComma

InsertNewlineAtEOF: true
IncludeBlocks: Regroup

IncludeCategories:
  - Regex:           '^"(box2d\/)'
    Priority:        3
  - Regex:           '^<.*'
    Priority:        4
  - Regex:           '^"[^.]*\.h"'
    Priority:        1
  - Regex:           '^"[^.]*\.inl"'
    Priority:        2

IndentExternBlock: NoIndent
IndentCaseLabels: true
IndentAccessModifiers: false
AccessModifierOffset: -4

SpacesInParens: Custom
SpacesInParensOptions:
  ExceptDoubleParentheses: false
  InConditionalStatements: true
  InCStyleCasts: false
  InEmptyParentheses: true
  Other: true
  

================================================
FILE: .gitattributes
================================================
* text=auto

*.c text
*.cpp text
*.h text
*.md text
*.txt text
*.sh text eol=lf

*.ttf binary


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [erincatto]
patreon: Box2D
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


================================================
FILE: .github/issue_template.md
================================================
Make sure these boxes are checked before submitting your issue - thank you!

- [ ] Ask for help on [discord](https://discord.gg/NKYgCBP)
- [ ] Consider providing a dump file using b2World::Dump


================================================
FILE: .github/pull_request_template.md
================================================
Pull requests for core Box2D code are generally not accepted. Please consider filing an issue instead.



================================================
FILE: .github/workflows/build.yml
================================================
name: CI Build

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  BUILD_TYPE: Debug

jobs:
  build-ubuntu-gcc:
    name: ubuntu-gcc
    runs-on: ubuntu-latest
    timeout-minutes: 4
    steps:
    - uses: actions/checkout@v4

    - 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

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

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ./bin/test
      
  build-ubuntu-clang:
    name: ubuntu-clang
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    
    - name: Configure CMake
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_COMPILER=clang++-18 -DCMAKE_C_COMPILER=clang -DBOX2D_SAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DBOX2D_VALIDATE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON

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

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ./bin/test
      
  build-macos:
    name: macos
    runs-on: macos-latest

    steps:
    - uses: actions/checkout@v4

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

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

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ./bin/test
      
  build-windows:
    name: windows
    runs-on: windows-latest
    steps:

    - uses: actions/checkout@v4

    - name: Setup MSVC dev command prompt
      uses: TheMrMilchmann/setup-msvc-dev@v3
      with:
        arch: x64

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

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

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ./bin/${{env.BUILD_TYPE}}/test
      
  samples-windows-static:
    name: samples-windows-static
    runs-on: windows-latest
    steps:

    - uses: actions/checkout@v4

    - name: Setup MSVC dev command prompt
      uses: TheMrMilchmann/setup-msvc-dev@v3
      with:
        arch: x64

    - name: Configure CMake
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DBOX2D_SAMPLES=ON -DBUILD_SHARED_LIBS=OFF -DBOX2D_UNIT_TESTS=OFF
      
    - name: Build
      run: cmake --build ${{github.workspace}}/build --config Release

  samples-windows-dynamic:
    name: samples-windows-dynamic
    runs-on: windows-latest
    steps:

    - uses: actions/checkout@v4

    - name: Setup MSVC dev command prompt
      uses: TheMrMilchmann/setup-msvc-dev@v3
      with:
        arch: x64

    - name: Configure CMake
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DBOX2D_SAMPLES=ON -DBUILD_SHARED_LIBS=ON -DBOX2D_UNIT_TESTS=OFF
      
    - name: Build
      run: cmake --build ${{github.workspace}}/build --config Release

  samples-macos-static:
    name: samples-macos-static
    runs-on: macos-latest

    steps:
    - uses: actions/checkout@v4

    - name: Configure CMake
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DBOX2D_SAMPLES=ON -DBUILD_SHARED_LIBS=OFF -DBOX2D_UNIT_TESTS=OFF
      
    - name: Build
      run: cmake --build ${{github.workspace}}/build --config Release

  samples-macos-dynamic:
    name: samples-macos-dynamic
    runs-on: macos-latest

    steps:
    - uses: actions/checkout@v4

    - name: Configure CMake
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DBOX2D_SAMPLES=ON -DBUILD_SHARED_LIBS=ON -DBOX2D_UNIT_TESTS=OFF
      
    - name: Build
      run: cmake --build ${{github.workspace}}/build --config Release

  samples-ubuntu-gcc-static:
    name: samples-ubuntu-gcc-static
    runs-on: ubuntu-latest
    timeout-minutes: 4
    steps:
    - uses: actions/checkout@v4

    - name: Install X11, Wayland & GL development libraries
      run: sudo apt-get update && sudo apt-get install -y libx11-dev wayland-protocols libwayland-dev libxkbcommon-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libgl-dev

    - name: Configure CMake
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DBOX2D_SAMPLES=ON -DBUILD_SHARED_LIBS=OFF -DBOX2D_UNIT_TESTS=OFF
      
    - name: Build
      run: cmake --build ${{github.workspace}}/build --config Release
      

================================================
FILE: .gitignore
================================================
build/
imgui.ini
settings.ini
.vscode/
.vs/
.cap
.DS_Store
CMakeUserPresets.json
.cache/
.idea/


================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.22)
include(FetchContent)
include(CMakeDependentOption)

project(box2d
	VERSION 3.2.0
	DESCRIPTION "A 2D physics engine for games"
	HOMEPAGE_URL "https://box2d.org"
	LANGUAGES C CXX
)

# stuff to help debug cmake
# message(STATUS "cmake tool chain: ${CMAKE_TOOLCHAIN_FILE}")
# message(STATUS "cmake source dir: ${CMAKE_SOURCE_DIR}")
# message(STATUS "library postfix: ${CMAKE_DEBUG_POSTFIX}")
message(STATUS "CMake C compiler: ${CMAKE_C_COMPILER_ID}")
message(STATUS "CMake C++ compiler: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMake system name: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMake host system processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}")

# static link to make leak checking easier (_crtBreakAlloc)
# set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

if (MSVC OR APPLE)
	option(BOX2D_SANITIZE "Enable sanitizers for some builds" OFF)
	if(BOX2D_SANITIZE)
		message(STATUS "Box2D Sanitize")
		# sanitizers need to apply to all compiled libraries to work well
		if(MSVC)
			# address sanitizer only in the debug build
			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)
			add_link_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined)
		endif()
	else()
		if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND PROJECT_IS_TOP_LEVEL)
			# enable hot reloading
			add_compile_options("$<$<CONFIG:Debug>:/ZI>")
			add_link_options("$<$<CONFIG:Debug>:/INCREMENTAL>")
		endif()
	endif()
endif()

# Deterministic math
# https://box2d.org/posts/2024/08/determinism/
if (MINGW OR APPLE OR UNIX)
	add_compile_options(-ffp-contract=off)
endif()

option(BOX2D_DISABLE_SIMD "Disable SIMD math (slower)" OFF)
option(BOX2D_COMPILE_WARNING_AS_ERROR "Compile warnings as errors" OFF)

if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
	cmake_dependent_option(BOX2D_AVX2 "Enable AVX2" OFF "NOT BOX2D_DISABLE_SIMD" OFF)
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_VERBOSE_MAKEFILE 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")

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)
	
	if(BOX2D_UNIT_TESTS OR BOX2D_SAMPLES OR BOX2D_BENCHMARKS)
		# Emscripten pthread support for enkiTS
		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()

		# Task system used in tests and samples
		set(ENKITS_BUILD_EXAMPLES OFF CACHE BOOL "Build enkiTS examples")
		FetchContent_Declare(
			enkits
			GIT_REPOSITORY https://github.com/dougbinks/enkiTS.git
			GIT_TAG master
			GIT_SHALLOW TRUE
			GIT_PROGRESS TRUE
		)
		FetchContent_MakeAvailable(enkits)

		add_subdirectory(shared)
	endif()

	# Tests need static linkage because they test internal Box2D functions
	if(NOT BUILD_SHARED_LIBS AND BOX2D_UNIT_TESTS)
		message(STATUS "Adding Box2D unit tests")
		add_subdirectory(test)
		set_target_properties(test PROPERTIES XCODE_GENERATE_SCHEME TRUE)
	else()
		message(STATUS "Skipping Box2D unit tests")
	endif()

	if(BOX2D_SAMPLES)
		add_subdirectory(samples)

		# default startup project for Visual Studio
		if(MSVC)
			set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT samples)
			set_property(TARGET samples PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
		endif()

		if(APPLE)
			set_target_properties(samples PROPERTIES
				XCODE_GENERATE_SCHEME TRUE
				XCODE_SCHEME_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
		endif()
	endif()

	if(BOX2D_BENCHMARKS)
		add_subdirectory(benchmark)
		set_target_properties(benchmark PROPERTIES XCODE_GENERATE_SCHEME TRUE)
	endif()

	if(BOX2D_DOCS)
		add_subdirectory(docs)
	endif()
endif()

# # Building on clang in windows
# cmake -S .. -B . -G "Visual Studio 17 2022" -A x64 -T ClangCL
# https://clang.llvm.org/docs/UsersManual.html#clang-cl


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2022 Erin Catto

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
![Box2D Logo](https://box2d.org/images/logo.svg)

# Build Status
[![Build Status](https://github.com/erincatto/box2d/actions/workflows/build.yml/badge.svg)](https://github.com/erincatto/box2d/actions)

# Box2D 
Box2D is a 2D physics engine for games.

[![Box2D Version 3.0 Release Demo](https://img.youtube.com/vi/dAoM-xjOWtA/0.jpg)](https://www.youtube.com/watch?v=dAoM-xjOWtA)

## Features

### Collision
- Continuous collision detection
- Contact events
- Convex polygons, capsules, circles, rounded polygons, segments, and chains
- Multiple shapes per body
- Collision filtering
- Ray casts, shape casts, and overlap queries
- Sensor system

### Physics
- Robust _Soft Step_ rigid body solver
- Continuous physics for fast translations and rotations
- Island based sleep
- Revolute, prismatic, distance, mouse joint, weld, and wheel joints
- Joint limits, motors, springs, and friction
- Joint and contact forces
- Body movement events and sleep notification

### System
- Data-oriented design
- Written in portable C17
- Extensive multithreading and SIMD
- Optimized for large piles of bodies

### Samples
- OpenGL with GLFW and enkiTS
- Graphical user interface with imgui
- Many samples to demonstrate features and performance

## Building for Visual Studio
- Install [CMake](https://cmake.org/)
- Ensure CMake is in the user `PATH`
- Run `create_sln.bat`
- Open and build `build/box2d.sln`

## Building for Linux
- Run `build.sh` from a bash shell
- Results are in the build sub-folder

## Building for Xcode
- Install [CMake](https://cmake.org)
- Add Cmake to the path in .zprofile (the default Terminal shell is zsh)
    - export PATH="/Applications/CMake.app/Contents/bin:$PATH"
- mkdir build
- cd build
- cmake -G Xcode ..
- Open `box2d.xcodeproj`
- Select the samples scheme
- Build and run the samples

## Building and installing
- mkdir build
- cd build
- cmake ..
- cmake --build . --config Release
- cmake --install . (might need sudo)

## Compatibility
The Box2D library and samples build and run on Windows, Linux, and Mac.

You will need a compiler that supports C17 to build the Box2D library.

You will need a compiler that supports C++20 to build the samples.

Box2D uses SSE2 and Neon SIMD math to improve performance. This can be disabled by defining `BOX2D_DISABLE_SIMD`.

## Documentation
- [Manual](https://box2d.org/documentation/)
- [Migration Guide](https://github.com/erincatto/box2d/blob/main/docs/migration.md)

## Community
- [Discord](https://discord.gg/NKYgCBP)

## Contributing
Please do not submit pull requests. Instead, please file an issue for bugs or feature requests. For support, please visit the Discord server.

# Giving Feedback
Please file an issue or start a chat on discord. You can also use [GitHub Discussions](https://github.com/erincatto/box2d/discussions).

## License
Box2D is developed by Erin Catto and uses the [MIT license](https://en.wikipedia.org/wiki/MIT_License).

## Sponsorship
Support development of Box2D through [Github Sponsors](https://github.com/sponsors/erincatto).

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

## External ports, wrappers, and bindings (unsupported)
- Beef bindings - https://github.com/EnokViking/Box2DBeef
- C++ bindings - https://github.com/HolyBlackCat/box2cpp
- WASM - https://github.com/Birch-san/box2d3-wasm


================================================
FILE: benchmark/CMakeLists.txt
================================================
# Box2D benchmark app

set(BOX2D_BENCHMARK_FILES
	main.c
)
add_executable(benchmark ${BOX2D_BENCHMARK_FILES})

set_target_properties(benchmark PROPERTIES
    C_STANDARD 17
    C_STANDARD_REQUIRED YES
    C_EXTENSIONS NO
)

if (BOX2D_COMPILE_WARNING_AS_ERROR)
	set_target_properties(benchmark PROPERTIES COMPILE_WARNING_AS_ERROR ON)
endif()

target_link_libraries(benchmark PRIVATE box2d shared enkiTS)

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${BOX2D_BENCHMARK_FILES})

================================================
FILE: benchmark/amd7950x_avx2/joint_grid.csv
================================================
threads,ms
1,3174.52
2,1795.2
3,1217.45
4,996.27
5,857.203
6,763.975
7,696.29
8,648.49


================================================
FILE: benchmark/amd7950x_avx2/large_pyramid.csv
================================================
threads,ms
1,1951.88
2,1026.26
3,721.553
4,563.934
5,473.542
6,415.048
7,367.646
8,362.217


================================================
FILE: benchmark/amd7950x_avx2/many_pyramids.csv
================================================
threads,ms
1,3312.37
2,1674.87
3,1116.48
4,859.268
5,691.412
6,594.236
7,513.412
8,462.289


================================================
FILE: benchmark/amd7950x_avx2/rain.csv
================================================
threads,ms
1,8415.32
2,4830.51
3,3684.98
4,3008.05
5,2568.19
6,2275.1
7,2054.01
8,1896.27


================================================
FILE: benchmark/amd7950x_avx2/smash.csv
================================================
threads,ms
1,1946.15
2,1212.81
3,937.648
4,786.533
5,699.338
6,636.796
7,597.153
8,564.691


================================================
FILE: benchmark/amd7950x_avx2/spinner.csv
================================================
threads,ms
1,5145.33
2,3090.7
3,2362.34
4,1890.21
5,1643.82
6,1473.02
7,1339.32
8,1256.21


================================================
FILE: benchmark/amd7950x_avx2/tumbler.csv
================================================
threads,ms
1,2035.14
2,1273.93
3,961.824
4,790.221
5,679.686
6,609.556
7,561.948
8,531.353


================================================
FILE: benchmark/amd7950x_float/joint_grid.csv
================================================
threads,ms
1,3070.3
2,1743.41
3,1190.54
4,973.725
5,839.892
6,749.347
7,684.411
8,639.372


================================================
FILE: benchmark/amd7950x_float/large_pyramid.csv
================================================
threads,ms
1,4324.94
2,2218.25
3,1489.84
4,1132.51
5,935.469
6,818.171
7,722.364
8,658.744


================================================
FILE: benchmark/amd7950x_float/many_pyramids.csv
================================================
threads,ms
1,6803.92
2,3421.51
3,2310.75
4,1766.54
5,1424.53
6,1213.28
7,1043.65
8,915.268


================================================
FILE: benchmark/amd7950x_float/rain.csv
================================================
threads,ms
1,10023.3
2,5685.88
3,4189.81
4,3390.77
5,2873.75
6,2522.69
7,2275.75
8,2098.4


================================================
FILE: benchmark/amd7950x_float/smash.csv
================================================
threads,ms
1,2660.24
2,1604.04
3,1208.81
4,997.755
5,871.282
6,791.138
7,731.148
8,687.379


================================================
FILE: benchmark/amd7950x_float/spinner.csv
================================================
threads,ms
1,8296.22
2,4821.7
3,3555.21
4,2816.7
5,2427.56
6,2162.31
7,2007.07
8,1896.91


================================================
FILE: benchmark/amd7950x_float/tumbler.csv
================================================
threads,ms
1,3327.12
2,1933.37
3,1436.84
4,1169.7
5,1014.31
6,907.688
7,840.671
8,786.672


================================================
FILE: benchmark/amd7950x_sse2/joint_grid.csv
================================================
threads,ms
1,2901.74
2,1679.24
3,1138.81
4,930.556
5,802.79
6,719.061
7,653.555
8,609.054


================================================
FILE: benchmark/amd7950x_sse2/large_pyramid.csv
================================================
threads,ms
1,2234.69
2,1198.39
3,821.019
4,636.813
5,533.46
6,476.708
7,422.339
8,384.637


================================================
FILE: benchmark/amd7950x_sse2/many_pyramids.csv
================================================
threads,ms
1,3718.08
2,1861.18
3,1279.77
4,968.623
5,781.502
6,667.149
7,572.954
8,511.755


================================================
FILE: benchmark/amd7950x_sse2/rain.csv
================================================
threads,ms
1,10450.7
2,6050.77
3,4647.11
4,3631.8
5,3096.74
6,2735.92
7,2460.2
8,2256.3


================================================
FILE: benchmark/amd7950x_sse2/smash.csv
================================================
threads,ms
1,1998.87
2,1206.23
3,894.774
4,732.413
5,636.455
6,571.134
7,527.128
8,493.411


================================================
FILE: benchmark/amd7950x_sse2/spinner.csv
================================================
threads,ms
1,5416.19
2,3229.11
3,2377.87
4,1903.65
5,1630.79
6,1448.68
7,1324.58
8,1237.05


================================================
FILE: benchmark/amd7950x_sse2/tumbler.csv
================================================
threads,ms
1,2338.19
2,1413.12
3,1081.55
4,883.9
5,769.756
6,696.251
7,647.607
8,612.832


================================================
FILE: benchmark/amd7950x_sse2/washer.csv
================================================
threads,ms
1,7934.7
2,4531.48
3,3218.58
4,2523.46
5,2100.84
6,1842.67
7,1638.05
8,1529.17


================================================
FILE: benchmark/m2air_float/joint_grid.csv
================================================
threads,ms
1,2367.43
2,1449.57
3,999.678
4,838.636


================================================
FILE: benchmark/m2air_float/large_pyramid.csv
================================================
threads,ms
1,2317.53
2,1252.4
3,891.763
4,694.968


================================================
FILE: benchmark/m2air_float/many_pyramids.csv
================================================
threads,ms
1,3559.49
2,1888.42
3,1357.7
4,1085.2


================================================
FILE: benchmark/m2air_float/rain.csv
================================================
threads,ms
1,7119.67
2,4144.16
3,3192.93
4,2623.99


================================================
FILE: benchmark/m2air_float/smash.csv
================================================
threads,ms
1,1757.78
2,1079.8
3,849.502
4,709.022


================================================
FILE: benchmark/m2air_float/spinner.csv
================================================
threads,ms
1,5434.23
2,3244.67
3,2462.03
4,1998.78


================================================
FILE: benchmark/m2air_float/tumbler.csv
================================================
threads,ms
1,2094.15
2,1270.1
3,1020.63
4,835.34


================================================
FILE: benchmark/m2air_neon/joint_grid.csv
================================================
threads,ms
1,2377.18
2,1444.78
3,998.22
4,837.361


================================================
FILE: benchmark/m2air_neon/large_pyramid.csv
================================================
threads,ms
1,1600.72
2,880.846
3,632.579
4,502.146


================================================
FILE: benchmark/m2air_neon/many_pyramids.csv
================================================
threads,ms
1,2455.91
2,1329.33
3,984.499
4,820.902


================================================
FILE: benchmark/m2air_neon/rain.csv
================================================
threads,ms
1,6834.98
2,4020.86
3,3123.64
4,2574.69


================================================
FILE: benchmark/m2air_neon/smash.csv
================================================
threads,ms
1,1595.13
2,1005.41
3,798.89
4,670.542


================================================
FILE: benchmark/m2air_neon/spinner.csv
================================================
threads,ms
1,4715.34
2,2939.07
3,2264.93
4,1855.98


================================================
FILE: benchmark/m2air_neon/tumbler.csv
================================================
threads,ms
1,1804.16
2,1150.51
3,945.004
4,777.227


================================================
FILE: benchmark/main.c
================================================
// SPDX-FileCopyrightText: 2024 Erin Catto
// SPDX-License-Identifier: MIT

#if defined( _MSC_VER ) && !defined( _CRT_SECURE_NO_WARNINGS )
#define _CRT_SECURE_NO_WARNINGS
#endif

#include "TaskScheduler_c.h"
#include "benchmarks.h"

#include "box2d/box2d.h"
#include "box2d/math_functions.h"

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined( _WIN64 )
#include <Windows.h>
#elif defined( __APPLE__ )
#include <unistd.h>
#elif defined( __linux__ )
#include <unistd.h>
#endif

#define ARRAY_COUNT( A ) (int)( sizeof( A ) / sizeof( A[0] ) )
#define MAYBE_UNUSED( x ) ( (void)( x ) )

typedef void CreateFcn( b2WorldId worldId );
typedef float StepFcn( b2WorldId worldId, int stepCount );

typedef struct Benchmark
{
	const char* name;
	CreateFcn* createFcn;
	StepFcn* stepFcn;
	int totalStepCount;
} Benchmark;

#define MAX_TASKS 128
#define THREAD_LIMIT 32

typedef struct TaskData
{
	b2TaskCallback* box2dTask;
	void* box2dContext;
} TaskData;

enkiTaskScheduler* scheduler;
enkiTaskSet* tasks[MAX_TASKS];
TaskData taskData[MAX_TASKS];
int taskCount;

int GetNumberOfCores()
{
#if defined( _WIN64 )
	SYSTEM_INFO sysinfo;
	GetSystemInfo( &sysinfo );
	return sysinfo.dwNumberOfProcessors;
#elif defined( __APPLE__ )
	return (int)sysconf( _SC_NPROCESSORS_ONLN );
#elif defined( __linux__ )
	return (int)sysconf( _SC_NPROCESSORS_ONLN );
#elif defined( __EMSCRIPTEN__ )
	return (int)sysconf( _SC_NPROCESSORS_ONLN );
#else
	return 1;
#endif
}

void ExecuteRangeTask( uint32_t start, uint32_t end, uint32_t threadIndex, void* context )
{
	TaskData* data = context;
	data->box2dTask( start, end, threadIndex, data->box2dContext );
}

static void* EnqueueTask( b2TaskCallback* box2dTask, int itemCount, int minRange, void* box2dContext, void* userContext )
{
	MAYBE_UNUSED( userContext );

	if ( taskCount < MAX_TASKS )
	{
		enkiTaskSet* task = tasks[taskCount];
		TaskData* data = taskData + taskCount;
		data->box2dTask = box2dTask;
		data->box2dContext = box2dContext;

		struct enkiParamsTaskSet params;
		params.minRange = minRange;
		params.setSize = itemCount;
		params.pArgs = data;
		params.priority = 0;

		enkiSetParamsTaskSet( task, params );
		enkiAddTaskSet( scheduler, task );

		++taskCount;

		return task;
	}
	else
	{
		printf( "MAX_TASKS exceeded!!!\n" );
		box2dTask( 0, itemCount, 0, box2dContext );
		return NULL;
	}
}

static void FinishTask( void* userTask, void* userContext )
{
	MAYBE_UNUSED( userContext );

	enkiTaskSet* task = userTask;
	enkiWaitForTaskSet( scheduler, task );
}

static void MinProfile( b2Profile* p1, const b2Profile* p2 )
{
	p1->step = b2MinFloat( p1->step, p2->step );
	p1->pairs = b2MinFloat( p1->pairs, p2->pairs );
	p1->collide = b2MinFloat( p1->collide, p2->collide );
	p1->solveConstraints = b2MinFloat( p1->solveConstraints, p2->solveConstraints );
	p1->transforms = b2MinFloat( p1->transforms, p2->transforms );
	p1->refit = b2MinFloat( p1->refit, p2->refit );
	p1->sleepIslands = b2MinFloat( p1->sleepIslands, p2->sleepIslands );
}

// Box2D benchmark application. On Windows it is important to use affinity avoid cross CCD
// usage or efficiency cores. Also on Windows create a power plan with Processor power management
// Min/Max of 99%. This prevents boosting and makes the benchmarks more repeatable.
// Affinity [0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x80]

// Run all benchmarks with 1 to 8 threads.
// start /affinity 0x5555 .\build\bin\Release\benchmark.exe -t=8

// Run all benchmarks with 4 workers only.
// start /affinity 0x5555 .\build\bin\Release\benchmark.exe -t=4 -w=4

// Run benchmark 3 with 4 workers and repeat 20 times. Record the step times.
// start /affinity 0x5555 .\build\bin\Release\benchmark.exe -t=4 -w=4 -b=3 -r=20 -s
// start /affinity 0x5555 .\build\bin\Release\benchmark.exe -t=8 -b=7

// Run benchmark 3 with 4 workers and run once. Disable continuous collision. Record the step times.
// start /affinity 0x5555 .\build\bin\Release\benchmark.exe -t=4 -w=4 -b=3 -r=1 -nc -s

int main( int argc, char** argv )
{
	Benchmark benchmarks[] = {
		{ "joint_grid", CreateJointGrid, NULL, 500 },
		{ "large_pyramid", CreateLargePyramid, NULL, 500 },
		{ "many_pyramids", CreateManyPyramids, NULL, 200 },
		{ "rain", CreateRain, StepRain, 1000 },
		{ "smash", CreateSmash, NULL, 300 },
		{ "spinner", CreateSpinner, StepSpinner, 500 },
		{ "tumbler", CreateTumbler, NULL, 750 },
		{ "washer", CreateWasher, NULL, 500 },
	};

	int benchmarkCount = ARRAY_COUNT( benchmarks );

	int maxSteps = benchmarks[0].totalStepCount;
	for ( int i = 1; i < benchmarkCount; ++i )
	{
		maxSteps = b2MaxInt( maxSteps, benchmarks[i].totalStepCount );
	}

	b2Profile maxProfile = {
		.step = FLT_MAX,
		.pairs = FLT_MAX,
		.collide = FLT_MAX,
		.solve = FLT_MAX,
		.prepareStages = FLT_MAX,
		.solveConstraints = FLT_MAX,
		.prepareConstraints = FLT_MAX,
		.integrateVelocities = FLT_MAX,
		.warmStart = FLT_MAX,
		.solveImpulses = FLT_MAX,
		.integratePositions = FLT_MAX,
		.relaxImpulses = FLT_MAX,
		.applyRestitution = FLT_MAX,
		.storeImpulses = FLT_MAX,
		.splitIslands = FLT_MAX,
		.transforms = FLT_MAX,
		.hitEvents = FLT_MAX,
		.refit = FLT_MAX,
		.bullets = FLT_MAX,
		.sleepIslands = FLT_MAX,
	};

	b2Profile* profiles = malloc( maxSteps * sizeof( b2Profile ) );
	for ( int i = 0; i < maxSteps; ++i )
	{
		profiles[i] = maxProfile;
	}

	float* stepResults = malloc( maxSteps * sizeof( float ) );
	memset( stepResults, 0, maxSteps * sizeof( float ) );

	int maxThreadCount = GetNumberOfCores();
	int runCount = 4;
	int singleBenchmark = -1;
	int singleWorkerCount = -1;
	b2Counters counters = { 0 };
	bool enableContinuous = true;
	bool recordStepTimes = false;

	assert( maxThreadCount <= THREAD_LIMIT );

	for ( int i = 1; i < argc; ++i )
	{
		const char* arg = argv[i];
		if ( strncmp( arg, "-t=", 3 ) == 0 )
		{
			int threadCount = atoi( arg + 3 );
			maxThreadCount = b2ClampInt( threadCount, 1, maxThreadCount );
		}
		else if ( strncmp( arg, "-b=", 3 ) == 0 )
		{
			singleBenchmark = atoi( arg + 3 );
			singleBenchmark = b2ClampInt( singleBenchmark, 0, benchmarkCount - 1 );
		}
		else if ( strncmp( arg, "-w=", 3 ) == 0 )
		{
			singleWorkerCount = atoi( arg + 3 );
		}
		else if ( strncmp( arg, "-r=", 3 ) == 0 )
		{
			runCount = b2ClampInt( atoi( arg + 3 ), 1, 1000 );
		}
		else if ( strncmp( arg, "-nc", 3 ) == 0 )
		{
			enableContinuous = false;
			printf( "Continuous disabled\n" );
		}
		else if ( strncmp( arg, "-s", 3 ) == 0 )
		{
			recordStepTimes = true;
		}
		else if ( strcmp( arg, "-h" ) == 0 )
		{
			printf( "Usage\n"
					"-t=<integer>: the maximum number of threads to use\n"
					"-b=<integer>: run a single benchmark\n"
					"-w=<integer>: run a single worker count\n"
					"-r=<integer>: number of repeats (default is 4)\n"
					"-s: record step times\n" );
			exit( 0 );
		}
	}

	if ( singleWorkerCount != -1 )
	{
		singleWorkerCount = b2ClampInt( singleWorkerCount, 1, maxThreadCount );
	}

	printf( "Starting Box2D benchmarks\n" );
	printf( "======================================\n" );

	for ( int benchmarkIndex = 0; benchmarkIndex < benchmarkCount; ++benchmarkIndex )
	{
		if ( singleBenchmark != -1 && benchmarkIndex != singleBenchmark )
		{
			continue;
		}

#ifdef NDEBUG
		int stepCount = benchmarks[benchmarkIndex].totalStepCount;
#else
		int stepCount = 10;
#endif

		Benchmark* benchmark = benchmarks + benchmarkIndex;

		bool countersAcquired = false;

		printf( "benchmark: %s, steps = %d\n", benchmarks[benchmarkIndex].name, stepCount );

		float minTime[THREAD_LIMIT] = { 0 };

		for ( int threadCount = 1; threadCount <= maxThreadCount; ++threadCount )
		{
			if ( singleWorkerCount != -1 && singleWorkerCount != threadCount )
			{
				continue;
			}

			printf( "thread count: %d\n", threadCount );

			for ( int runIndex = 0; runIndex < runCount; ++runIndex )
			{
				scheduler = enkiNewTaskScheduler();
				struct enkiTaskSchedulerConfig config = enkiGetTaskSchedulerConfig( scheduler );
				config.numTaskThreadsToCreate = threadCount - 1;
				enkiInitTaskSchedulerWithConfig( scheduler, config );

				for ( int taskIndex = 0; taskIndex < MAX_TASKS; ++taskIndex )
				{
					tasks[taskIndex] = enkiCreateTaskSet( scheduler, ExecuteRangeTask );
				}

				b2WorldDef worldDef = b2DefaultWorldDef();
				worldDef.enableContinuous = enableContinuous;
				worldDef.enqueueTask = EnqueueTask;
				worldDef.finishTask = FinishTask;
				worldDef.workerCount = threadCount;
				b2WorldId worldId = b2CreateWorld( &worldDef );

				benchmark->createFcn( worldId );

				float timeStep = 1.0f / 60.0f;
				int subStepCount = 4;

				// Initial step can be expensive and skew benchmark
				if ( benchmark->stepFcn != NULL )
				{
					stepResults[0] = benchmark->stepFcn( worldId, 0 );
				}

				assert( stepCount <= maxSteps );

				b2World_Step( worldId, timeStep, subStepCount );

				b2Profile profile = b2World_GetProfile( worldId );
				MinProfile( profiles + 0, &profile );

				taskCount = 0;

				uint64_t ticks = b2GetTicks();

				for ( int stepIndex = 1; stepIndex < stepCount; ++stepIndex )
				{
					if ( benchmark->stepFcn != NULL )
					{
						stepResults[stepIndex] = benchmark->stepFcn( worldId, stepIndex );
					}

					b2World_Step( worldId, timeStep, subStepCount );
					taskCount = 0;

					profile = b2World_GetProfile( worldId );
					MinProfile( profiles + stepIndex, &profile );
				}

				float ms = b2GetMilliseconds( ticks );
				printf( "run %d : %g (ms)\n", runIndex, ms );

				if (runIndex == 0)
				{
					minTime[threadCount - 1] = ms ;
				}
				else
				{
					minTime[threadCount - 1] = b2MinFloat( minTime[threadCount - 1], ms );
				}

				if ( countersAcquired == false )
				{
					counters = b2World_GetCounters( worldId );
					countersAcquired = true;
				}

				b2DestroyWorld( worldId );

				for ( int taskIndex = 0; taskIndex < MAX_TASKS; ++taskIndex )
				{
					enkiDeleteTaskSet( scheduler, tasks[taskIndex] );
					tasks[taskIndex] = NULL;
					taskData[taskIndex] = ( TaskData ){ 0 };
				}

				enkiDeleteTaskScheduler( scheduler );
				scheduler = NULL;

			}

			if ( recordStepTimes )
			{
				char fileName[64] = { 0 };
				snprintf( fileName, 64, "%s_t%d.dat", benchmarks[benchmarkIndex].name, threadCount );
				FILE* file = fopen( fileName, "w" );
				if ( file == NULL )
				{
					continue;
				}

				for ( int stepIndex = 0; stepIndex < stepCount; ++stepIndex )
				{
					b2Profile p = profiles[stepIndex];
					fprintf( file, "%g %g %g %g %g %g %g\n", p.step, p.pairs, p.collide, p.solveConstraints, p.transforms, p.refit, p.sleepIslands );
				}

				fclose( file );
			}
		}

		printf( "body %d / shape %d / contact %d / joint %d / stack %d\n\n", counters.bodyCount, counters.shapeCount,
				counters.contactCount, counters.jointCount, counters.stackUsed );

		char fileName[64] = { 0 };
		snprintf( fileName, 64, "%s.csv", benchmarks[benchmarkIndex].name );
		FILE* file = fopen( fileName, "w" );
		if ( file == NULL )
		{
			continue;
		}

		fprintf( file, "threads,ms\n" );
		for ( int threadIndex = 1; threadIndex <= maxThreadCount; ++threadIndex )
		{
			fprintf( file, "%d,%g\n", threadIndex, minTime[threadIndex - 1] );
		}

		fclose( file );
	}

	printf( "======================================\n" );
	printf( "All Box2D benchmarks complete!\n" );

	free( profiles );
	free( stepResults );

	return 0;
}


================================================
FILE: benchmark/n100_sse2/joint_grid.csv
================================================
threads,fps
1,75.5947
2,123.228
3,160.379
4,181.545


================================================
FILE: benchmark/n100_sse2/large_pyramid.csv
================================================
threads,fps
1,127.236
2,226.291
3,297.628
4,345.526


================================================
FILE: benchmark/n100_sse2/many_pyramids.csv
================================================
threads,fps
1,30.8828
2,55.0462
3,69.5406
4,77.7339


================================================
FILE: benchmark/n100_sse2/rain.csv
================================================
threads,fps
1,72.2901
2,118.753
3,142.61
4,162.35


================================================
FILE: benchmark/n100_sse2/smash.csv
================================================
threads,fps
1,86.2381
2,132.306
3,160.725
4,181.842


================================================
FILE: benchmark/n100_sse2/spinner.csv
================================================
threads,fps
1,156.855
2,258.638
3,303.717
4,358.492


================================================
FILE: benchmark/n100_sse2/tumbler.csv
================================================
threads,fps
1,199.492
2,313.012
3,381.983
4,441.825


================================================
FILE: build.sh
================================================
#!/usr/bin/env bash

# Use this to build box2d on any system with a bash shell
rm -rf build
mkdir build
cd build

# I haven't been able to get Wayland working on WSL but X11 works.
# https://www.glfw.org/docs/latest/compile.html
cmake -DBOX2D_BUILD_DOCS=OFF -DGLFW_BUILD_WAYLAND=OFF ..
cmake --build .


================================================
FILE: build_emscripten.sh
================================================
#!/usr/bin/env bash

# source emsdk_env.sh

# Use this to build box2d on any system with a bash shell
rm -rf build
mkdir build
cd build
emcmake cmake -DBOX2D_VALIDATE=OFF -DBOX2D_UNIT_TESTS=ON -DBOX2D_SAMPLES=OFF -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .


================================================
FILE: create_sln.bat
================================================
rem Use this batch file to build box2d for Visual Studio
rmdir /s /q build
mkdir build
cd build
cmake ..


================================================
FILE: deploy_docs.sh
================================================
#!/usr/bin/env bash

# Copies documentation to blog
cp -R build/docs/html/. ../box2d_blog/public/documentation/


================================================
FILE: docs/CMakeLists.txt
================================================
find_package(Doxygen REQUIRED dot)

set(DOXYGEN_PROJECT_NAME "Box2D")
set(DOXYGEN_GENERATE_HTML YES)
set(DOXYGEN_USE_MATHJAX YES)
set(DOXYGEN_MATHJAX_VERSION MathJax_3)
set(DOXYGEN_MATHJAX_FORMAT SVG)
set(DOXYGEN_EXTRACT_ALL NO)
set(DOXYGEN_FILE_PATTERNS *.h)
set(DOXYGEN_ENABLE_PREPROCESSING YES)
set(DOXYGEN_MACRO_EXPANSION YES)
set(DOXYGEN_EXPAND_ONLY_PREDEF YES)
set(DOXYGEN_PREDEFINED B2_API= B2_INLINE=)
set(DOXYGEN_WARN_IF_UNDOCUMENTED YES)

# In multiline comments, this takes the first line/sentence as a brief description to use in the table of functions.
# So I don't need to use @brief tags to separate the short description from the full description.
set(DOXYGEN_JAVADOC_AUTOBRIEF YES)

set(DOXYGEN_IMAGE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/images")
set(DOXYGEN_HTML_EXTRA_STYLESHEET "${CMAKE_CURRENT_SOURCE_DIR}/extra.css")
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE "${CMAKE_CURRENT_SOURCE_DIR}/overview.md")
set(DOXYGEN_PROJECT_LOGO "${CMAKE_CURRENT_SOURCE_DIR}/images/logo.svg")
set(DOXYGEN_LAYOUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/layout.xml")

set(DOXYGEN_INLINE_SIMPLE_STRUCTS YES)
set(DOXYGEN_TYPEDEF_HIDES_STRUCT YES)
# set(DOXYGEN_DISABLE_INDEX YES)
set(DOXYGEN_GENERATE_TREEVIEW YES)
set(DOXYGEN_FULL_SIDEBAR NO)

# force dark mode to work with extra.css
set(DOXYGEN_HTML_COLORSTYLE DARK)

# this tells doxygen to label structs as structs instead of classes
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_WARN_IF_INCOMPLETE_DOC NO)

doxygen_add_docs(doc
                "${CMAKE_SOURCE_DIR}/include/box2d"
                "overview.md"
                "hello.md"
                "samples.md"
                "foundation.md"
                "collision.md"
                "simulation.md"
                "loose_ends.md"
                "character.md"
                "reading.md"
                "faq.md"
                "migration.md"
                "release_notes_v310.md"
                ALL
                COMMENT "Generate HTML documentation")


================================================
FILE: docs/FAQ.md
================================================
# FAQ

## What is Box2D?
Box2D is a feature rich 2D rigid body physics engine, written in C17 by Erin Catto. It has been used in many games and in many
game engines.

Box2D uses the [MIT license](https://en.wikipedia.org/wiki/MIT_License) license and can be used free of charge. Credit
should be included if possible. Support is [appreciated](https://github.com/sponsors/erincatto). You may use the
Box2D [logo](https://box2d.org/images/logo.svg).

## What platforms does Box2D support?
Box2D is developed using C. Ports and bindings are likely available for most languages and platforms.

Erin Catto maintains the C version, but provides no support for other languages. Other languages are supported
by the community and possibly by the authors of those ports.

## Who makes it?
Erin Catto is the creator and sole contributor of the C version of Box2D, with various others supporting the ports. Box2D is an open source project, and accepts community feedback.

## How do I get help?
You should read the documentation and the rest of this FAQ first. Also, you should study the examples included in the source distribution. Then you can visit the [Discord](https://discord.gg/aM4mRKxW) to ask any remaining questions.

Please to not message or email Erin Catto directly for support. It is best to ask questions on the Discord server so that everyone can benefit from the discussion.

## Documentation

### Why isn't a feature documented?
If you grab the latest code from the git main branch you will likely find features that are not documented in the manual. New features are added to the manual after they are mature and a new point release is imminent. However, all major features added to Box2D are accompanied by example code in the samples application to test the feature and show the intended usage.

## Prerequisites

### Programming
You should have a working knowledge of C before you use Box2D. You should understand functions, structures, and pointers. There are plenty of resources on the web for learning C. You should also understand your development environment: compilation, linking, and debugging.

### Math and Physics
You should have a basic knowledge of rigid bodies, force, torque, and impulses. If you come across a math or physics concept you don't understand, please read about it on Wikipedia. Visit this [page](http://box2d.org/publications/) if you want a deeper knowledge of the algorithms used in Box2D.

## API

### What units does Box2D use?
Box2D is tuned for meters-kilograms-seconds (MKS). This is recommend as the units for your game. However, you may use
different units if you are careful.

### How do I convert pixels to meters?
Suppose you have a sprite for a character that is 100x100 pixels. You decide to use a scaling factor that is 0.01. This will make the character physics box 1m x 1m. So go make a physics box that is 1x1. Now suppose the character starts out at pixel coordinate (345,679). So position the physics box at (3.45,6.79). Now simulate the physics world. Suppose the character physics box moves to (2.31,4.98), so move your character sprite to pixel coordinates (231,498).

Now the only tricky part is choosing a scaling factor. This really depends on your game. You should try to get your moving objects in the range 0.1 - 10 meters, with 1 meter being the sweet spot.

This [repo](https://github.com/erincatto/box2d-raylib) shows how to convert meters to pixels.

### Why don't you use this awesome language?
Box2D is designed to be portable and easy to wrap with other languages, so I decided to use C17. I used C17 to get support for atomics.

### Can I use Box2D in a DLL?
Yes. See the CMake option `BUILD_SHARED_LIBS`.

### Is Box2D thread-safe?
No. Box2D will likely never be thread-safe. Box2D has a large API and trying to make such an API thread-safe would have a large performance and complexity impact. However, you can call read only functions from multiple threads. For example, all the
[spatial query](#spatial) functions are read only.

## Build Issues

### Why doesn't my code compile and/or link?
There are many reasons why a build can go bad. Here are a few that have come up:
* Using old Box2D headers with new code
* Not linking the Box2D library with your application
* Using old project files that don't include some new source files

## Rendering

### What are Box2D's rendering capabilities?
Box2D is only a physics engine. How you draw stuff is up to you.

### But the samples application draws stuff
Visualization is very important for debugging collision and physics. I wrote the samples application to help me test Box2D and give you examples of how to use Box2D. The samples are not part of the Box2D library.

### How do I draw shapes?
Implement the `b2DebugDraw` interface and call `b2World_Draw()`.

## Accuracy
Box2D uses approximate methods for a few reasons.
* Performance
* Some differential equations don't have known solutions
* Some constraints cannot be determined uniquely

What this means is that constraints are not perfectly rigid and sometimes you will see some bounce even when the restitution is zero.
Box2D uses [Gauss-Seidel](https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method) to approximately solve constraints.
Box2D also uses [Semi-implicit Euler](https://en.wikipedia.org/wiki/Semi-implicit_Euler_method) to approximately solve the differential equations.
Box2D also does not have exact collision. There is no continuous collision between dynamic shapes. Slow moving shapes may have small overlap for a few time steps. In extreme stacking scenarios, shapes may have sustained overlap.

## Making Games

### Worms Clones
Making a worms clone requires arbitrarily destructible terrain. This is beyond the scope of Box2D, so you will have to figure out how to do this on your own.

### Tile Based Environment
Using many boxes for your terrain may not work well because box-like characters can get snagged on internal corners. Box2D provides chain shapes for smooth collision, see `b2ChainDef`. In general you should avoid using a rectangular character because collision tolerances will still lead to undesirable snagging. Box2D provides capsules and rounded polygons that may work better for characters.

### Asteroid Type Coordinate Systems
Box2D does not have any support for coordinate frame wrapping. You would likely need to customize Box2D for this purpose. You may need to use a different broad-phase for this to work.

## Determinism

### Is Box2D deterministic?
For the same input, and same binary, Box2D will reproduce any simulation. Box2D does not use any random numbers nor base any computation on random events (such as timers, etc).

Box2D is also deterministic under multithreading. A simulation using two threads will give the same result as eight threads.

Box2D has cross-platform determinism as of version 3.1.

However, Box2D does not have rollback determinism.

### But I really want determinism
This naturally leads to the question of fixed-point math. Box2D does not support fixed-point math. In the past Box2D was ported to the NDS in fixed-point and apparently it worked okay. Fixed-point math is slower and more tedious to develop, so I have chosen not to use fixed-point for the development of Box2D.

## What are the common mistakes made by new users?
* Using pixels for length instead of meters
* Expecting Box2D to give pixel perfect results
* Testing their code in release mode
* Not learning C before using Box2D


================================================
FILE: docs/character.md
================================================
# Character mover

> **Caution**:
> The character mover feature is new to version 3.1 and should be considered experimental.

Box2D provides a few structures and functions you can use to build a character mover.

These features support a `geometric` character mover. This is like
a `kinematic` mover except the character mover is not a rigid body and does
not exist in the simulation world. This is done to achieve features that
would be difficult with a kinematic body.

This type of mover may not be suitable for your game. It is less physical than a rigid body, but
it gives you more control over the movement. It is the type of mover you might find
in a first-person shooter or a game with platforming elements.

The mover is assumed to be a capsule. Using a capsule helps keep movement smooth. The capsule should
have a significant radius. It does not have to be a vertical capsule, but that is likely
to be the easiest setup. There is no explicit handling of rotation. But slow rotation can
work with this system.

Let's review the features. First there are a couple world query functions.

`b2World_CastMover()` is a custom shape cast that tries to avoid getting stuck when shapes start out touching.
The feature is called _encroachment_. Since the capsule has a significant radius it can move closer
to a surface it is touching without the inner line segment generating an overlap, which would cause
the shape cast to fail. Due to the internal use of GJK, encroachment has little cost. The idea with encroachment is that
the mover is trying to slide along a surface and we don't want to stop that even if there is some small movement into the surface.

`b2World_CollideMover()` complements the cast function. This function generates collision planes for touching and/or overlapped surfaces. The character mover is assumed to have a fixed rotation, so it doesn't need contact manifolds or contact points. It just needs collision planes. Each plane is returned with the `b2Plane` and a `b2ShapeId` for each shape the mover is touching.

Once you have some collision planes from `b2World_CollideMover()`, you can process and filter them to generate an array of `b2CollisionPlane`. These collision planes can then be sent to `b2SolvePlanes()` to generate a new position for the mover
that attempts to find the optimal new position given the current position.

These collision planes support *soft collision* using a `pushLimit`. This push limit is a distance value. A rigid surface will have a push limit of `FLT_MAX`. However, you may want some surfaces to have a limited effect on the character. For example, you may want the mover to push through other players or enemies yet still resolve the collision so they are not overlapped. Another example is a door or elevator that could otherwise push the mover through the floor.

Finally after calling `b2SolverPlanes()` you can call `b2ClipVector()` to clip your velocity vector so the mover will not keep trying to push into a wall, which could lead to a huge velocity accumulation otherwise.

The `Mover` sample shows all these functions being used together. It also includes other common character features such as acceleration and friction, jumping, and a pogo stick.

![Character Mover](images/mover.png)


================================================
FILE: docs/collision.md
================================================
# Collision
Box2D provides geometric types and functions. These include:
- primitives: circles, capsules, segments, and convex polygons
- convex hull and related helper functions
- mass and bounding box computation
- local ray and shape casts
- contact manifolds
- shape distance
- time of impact
- dynamic bounding volume tree
- character movement solver

The collision interface is designed to be usable outside of rigid body simulation.
For example, you can use the dynamic tree for other aspects of your game besides physics.

However, the main purpose of Box2D is to be a rigid body physics
engine. So the collision interface only contains features that are also useful in
the physics simulation.

## Shape Primitives
Shape primitives describe collision geometry and may be used independently of
physics simulation. At a minimum, you should understand how to create
primitives that can be later attached to rigid bodies.

Box2D shape primitives support several operations:
- Test a point for overlap with the primitive
- Perform a ray cast against the primitive
- Compute the primitive's bounding box
- Compute the mass properties of the primitive

### Circles
Circles have a center and radius. Circles are solid.

![Circle](images/circle.svg)

```c
b2Circle circle;
circle.center = (b2Vec2){2.0f, 3.0f};
circle.radius = 0.5f;
```

You can also initialize a circle and other structures inline. This is an equivalent circle:

```c
b2Circle circle = {{2.0f, 3.0f}, 0.5f};
```

### Capsules
Capsules have two center points and a radius. The center points are the centers of two
semicircles that are connected by a rectangle.

![Capsule](images/capsule.svg)

```c
b2Capsule capsule;
capsule.center1 = (b2Vec2){1.0f, 1.0f};
capsule.center2 = (b2Vec2){2.0f, 3.0f};
capsule.radius = 0.25f;
```

### Polygons
Box2D polygons are solid convex polygons. A polygon is convex when all
line segments connecting two points in the interior do not cross any
edge of the polygon. Polygons are solid and never hollow. A polygon must
have 3 or more vertices.

![Convex and Concave Polygons](images/convex_concave.svg)

Polygons vertices are stored with a counter clockwise winding (CCW). We
must be careful because the notion of CCW is with respect to a
right-handed coordinate system with the z-axis pointing out of the
plane. This might turn out to be clockwise on your screen, depending on
your coordinate system conventions.

![Polygon Winding Order](images/winding.svg)

The polygon members are public, but you should use initialization
functions to create a polygon. The initialization functions create
normal vectors and perform validation.

Polygons in Box2D have a maximum of 8 vertices, as controlled by #B2_MAX_POLYGON_VERTICES.
If you have more complex shapes, I recommend to use multiple polygons.

There are a few ways to create polygons. You can attempt to create them manually,
but this is not recommended. Instead there are several functions provided to create them.

For example if you need a square or box you can use these functions:

```c
b2Polygon square = b2MakeSquare(0.5f);
b2Polygon box = b2MakeBox(0.5f, 1.0f);
```

The values provided to these functions are *extents*, which are half-widths or half-heights.
This corresponds with circles and capsules using radii instead of diameters.

Box2D also supports rounded polygons. These are convex polygons with a thick rounded skin.

```c
float radius = 0.25f;
b2Polygon roundedBox = b2MakeRoundedBox(0.5f, 1.0f, radius);
```

If you want a box that is not centered on the body origin, you can use an offset box.

```c
b2Vec2 center = {1.0f, 0.0f};
float angle = b2_pi / 4.0f;
b2Rot rotation = b2MakeRot(angle);
b2Polygon offsetBox = b2MakeOffsetBox(0.5f, 1.0f, center, rotation);
```

If you want a more general convex polygon, you can compute the hull using `b2ComputeHull()`. Then you can
create a polygon from the hull. You can make this rounded as well.

```c
b2Vec2 points[] = {{-1.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}};
b2Hull hull = b2ComputeHull(points, 3);
float radius = 0.1f;
b2Polygon roundedTriangle = b2MakePolygon(&hull, radius);
```

If you have an automatic process for generating convex polygons, you may feed a degenerate set of points to `b2ComputeHull()`. You should check that the hull was created successfully before creating the polygon or you will get an assertion.

```c
b2Hull questionableHull = b2ComputeHull(randomPoints, 8);
if (questionableHull.count == 0)
{
    // handle failure
}
```

Degenerate points may be coincident and/or collinear. For the hull to be viable, the enclosed area must be sufficiently positive.

### Segments
Segments are line segments. Segment
shapes can collide with circles, capsules, and polygons but not with other line segments.
The collision algorithms used by Box2D require that at least
one of two colliding shapes has sufficiently positive area. Segment shapes have no area, so
segment-segment collision is not possible.

```c
b2Segment segment1;
segment1.point1 = (b2Vec2){0.0f, 0.0f};
segment2.point2 = (b2Vec2){1.0f, 0.0f};

// equivalent
b2Segment segment2 = {{0.0f, 0.0f}, {1.0f, 0.0f}};
```

### Ghost Collisions
In many cases a game environment is constructed by connecting several
segment shapes end-to-end. This can give rise to an unexpected artifact
when a polygon slides along the chain of segments. In the figure below there is
 a box colliding with an internal vertex. These *ghost* collisions
are caused when the polygon collides with an internal vertex generating
an internal collision normal.

![Ghost Collision](images/ghost_collision.svg){html: width=30%}

If edge1 did not exist this collision would seem fine. With edge1
present, the internal collision seems like a bug. But normally when
Box2D collides two shapes, it views them in isolation.

`b2ChainSegment` provides a mechanism for eliminating ghost
collisions by storing the adjacent *ghost* vertices. Box2D uses these
ghost vertices to prevent internal collisions.

![Ghost Vertices](images/ghost_vertices.svg){html: width=30%}

The Box2D algorithm for dealing with ghost collisions only supports
one-sided collision. The front face is to the right when looking from the first
vertex towards the second vertex. This matches the counter-clockwise winding order
used by polygons.

### Chain segment
Chain segments use a concept called *ghost vertices* that Box2D can use to eliminate ghost
collisions.

```c
b2ChainSegment chainSegment = {0};
chainSegment.ghost1 = (b2Vec2){1.7f, 0.0f};
chainSegment.segment = (b2Segment){{1.0f, 0.25f}, {0.0f, 0.0f}};
chainSegment.ghost2 = (b2Vec2){-1.7f, 0.4f};
```

These ghost vertices must align with vertices of neighboring chain segments, making them
tedious and error-prone to setup.

Chain segments are not created directly. Instead, you can create chains of line
segments. See `b2ChainDef` and `b2CreateChain()`.

## Geometric Queries
You can perform a geometric queries on a single shape.

### Shape Point Test
You can test a point for overlap with a shape. You provide a transform
for the shape and a world point.

```c
b2Vec2 point = {5.0f, 2.0f};
bool hit = b2PointInCapsule(point, &myCapsule);
```

See also `b2PointInCircle()` and `b2PointInPolygon()`.

### Ray Cast
You can cast a ray at a shape to get the point of first intersection and normal vector.

> **Caution**:
> No hit will register if the ray starts inside a convex shape like a circle or polygon. This is
> consistent with Box2D treating convex shapes as solid. 

```c
b2RayCastInput input = {0};
input.origin = (b2Vec2){0.0f, 0.0f};
input.translation = (b2Vec2){1.0f, 0.0f};
input.maxFraction = 1.0f;

b2CastOutput output = b2RayCastPolygon(&input, &myPolygon);
if (output.hit == true)
{
    // do something
}
```

### Shape Cast
You can also cast a shape at another shape. This uses an abstract way of describing the moving shape. It is represented as a point cloud with a radius. This implies a convex shape even if the input data is not convex. The internal algorithm (GJK) will essentially only use the convex portion.

```c
b2ShapeCastInput input = {0};
input.points[0] = (b2Vec2){1.0f, 0.0f};
input.points[1] = (b2Vec2){2.0f, -3.0f};
input.radius = 0.2f;
input.translation = (b2Vec2){1.0f, 0.0f};
input.maxFraction = 1.0f;

b2CastOutput output = b2ShapeCastPolygon(&input, &myPolygon);
if (output.hit == true)
{
    // do something
}
```

Even more generic, you can use `b2ShapeCast()` to linearly cast one point cloud at another point cloud. All shape cast functions use this internally.

### Distance
`b2ShapeDistance()` function can be used to compute the distance between two
shapes. The distance function needs both shapes to be converted into a
`b2DistanceProxy` (which are point clouds with radii). There is also some caching used to warm start the
distance function for repeated calls. This can improve performance when the shapes move by small amounts.

![Distance Function](images/distance.svg)

### Time of Impact
If two shapes are moving fast, they may *tunnel* through each other in a
single time step.

![Tunneling](images/tunneling2.svg){html: width=30%}

The `b2TimeOfImpact()` function is used to determine the time when two moving shapes collide.
This is called the *time of impact* (TOI). The main purpose of `b2TimeOfImpact()` is for
tunnel prevention. Box2D uses this internally to prevent moving objects from tunneling through
static shapes.

The `b2TimeOfImpact()` identifies an initial separating axis and
ensures the shapes do not cross on that axis. This process is repeated
as shapes are moved closer together, until they touch or pass by each other.

The TOI function might miss collisions that are clear at the final positions.
Nevertheless, it is very fast and adequate for tunnel prevention.

![Captured Collision](images/captured_toi.svg){html: width=30%}

![Missed Collision](images/missed_toi.svg){html: width=30%}

It is difficult to put a restriction on the rotation magnitude. There
may be cases where collisions are missed for small rotations. Normally,
these missed rotational collisions should not harm game play. They tend
to be glancing collisions.

The function requires two shapes (converted to `b2DistanceProxy`) and two
`b2Sweep` structures. The sweep structure defines the initial and final
transforms of the shapes.

You can use fixed rotations to perform a *shape cast*. In this case, the
time of impact function will not miss any collisions.

### Contact Manifolds
Box2D has functions to compute contact points for overlapping shapes. If
we consider circle-circle or circle-polygon, we can only get one contact
point and normal. In the case of polygon-polygon we can get two points.
These points share the same normal vector so Box2D groups them into a
manifold structure. The contact solver takes advantage of this to
improve stacking stability.

![Contact Manifold](images/manifolds.svg)

Normally you don't need to compute contact manifolds directly, however
you will likely use the results produced in the simulation.

The `b2Manifold` structure holds a normal vector and up to two contact
points. The contact points store the normal and tangential (friction) impulses
computed in the rigid body simulation.

## Dynamic Tree
`b2DynamicTree` is used by Box2D to organize large numbers of
shapes efficiently. The object does not know directly about shapes. Instead it
operates on axis-aligned bounding boxes (`b2AABB`) with user data integers.

The dynamic tree is a hierarchical AABB tree. Each internal node in the
tree has two children. A leaf node is a single user AABB. The tree uses
rotations to keep the tree balanced, even in the case of degenerate
input.

The tree structure allows for efficient ray casts and region queries.
For example, you may have hundreds of shapes in your scene. You could
perform a ray cast against the scene in a brute force manner by ray
casting each shape. This would be inefficient because it does not take
advantage of shapes being spread out. Instead, you can maintain a
dynamic tree and perform ray casts against the tree. This traverses the
ray through the tree skipping large numbers of shapes.

A region query uses the tree to find all leaf AABBs that overlap a query
AABB. This is faster than a brute force approach because many shapes can
be skipped.

![Ray-cast](images/raycast.svg){html: width=30%}

![Overlap Test](images/overlap_test.svg){html: width=30%}

Normally you will not use the dynamic tree directly. Rather you will go
through the `b2World` functions for ray casts and region queries. If you plan
to instantiate your own dynamic tree, you can learn how to use it by
looking at how Box2D uses it. Also see the `DynamicTree` sample.


================================================
FILE: docs/extra.css
================================================
/*
Doxygen CSS overrides
Adapted from: https://github.com/MaJerle/doxygen-dark-theme
blog-light: #fafafa
blog-dark: #252627
Dark background: #353629;
New light dark background #32363d
Light background: #dfe5f2;
*/

body {
	background: #292a2d;
	background-image: none;
	color: #D8D8D8;
}

#titlearea {
    border-bottom: 1px solid #32363d;
	background-color: #292a2d;
}

div.contents {
    max-width: 1000px;
}

/* this works with doxygen /image */
.image {
	background-color: #CCCCCC;
	border: 10px solid #CCCCCC;
}

/* this kind of works with doxygen markdown */
img.inline {
	background-color: #CCCCCC;
	border: 10px solid #CCCCCC;
	margin: 0px;
}

.caption {
	padding-top: 10px;
	color: black;
}

div.fragment, pre.fragment {
	margin: 20px 0px;
	padding: 10px;
}

blockquote.doxtable {
	border: 1px solid #000000;
	background: #32363d;
    background-color: #bf5f82;
    background-color: #456114;
    margin: 10px 24px 10px 4px;
}

div.toc {
	margin: 0 !important;
	border-radius: 4px !important;
}

div.toc h3 {
	font-size: 150%;
	color: inherit;
}

.contents table.doxtable {
	margin: 0 auto;
}

.fieldtable {
	box-shadow: none !important;
	-webkit-box-shadow: none;
	-moz-box-shadow: none;
}

.memitem,
.memproto,
.memdoc {
	box-shadow: none;
	-webkit-box-shadow: none;
	-moz-box-shadow: none;
	background-image: none;
}

.tablist a:hover,
.tablist li.current a {
	text-shadow: none;
	-moz-text-shadow: none;
	-webkit-text-shadow: none;
}

.textblock h1 {
    border-bottom: 1px solid #32363d;
    border-left: 3px solid #32363d;
    margin: 40px 0px 10px 0px;
    padding-bottom: 10px;
    padding-top: 10px;
    padding-left: 5px;
}

.textblock h1:first-child {
	margin-top: 10px;
}

dl.note,
dl.warning,
dl.todo,
dl.deprecated,
dl.reflist {
	border: 0;
	padding: 0px;
	margin: 4px 0px 4px 0px;
	border-radius: 4px;
}

dl.note dt,
dl.warning dt,
dl.todo dt,
dl.deprecated dt,
dl.reflist dt {
	margin: 0;
	font-size: 14px;
	padding: 2px 4px;

	border: none;
	border-top-left-radius: 0px;
	border-top-right-radius:0px;

	font-weight: bold;
	text-transform: uppercase;
	color: #FFFFFF !important;

	box-shadow: none;
	-webkit-box-shadow: none;
	-moz-box-shadow: none;
	text-shadow: none;
}

dl.note dd,
dl.warning dd,
dl.todo dd,
dl.deprecated dd,
dl.reflist dd {
	margin: 0;
	padding: 4px;
	background: none;

	color: #222222;

	border: 1px solid;
	border-bottom-left-radius: 0px;
	border-bottom-right-radius: 0px;
	border-top: none;

	box-shadow: none;
	-webkit-box-shadow: none;
	-moz-box-shadow: none;
	text-shadow: none;
}

dl.reflist dd {
	margin-bottom: 15px;
}

dl.note dt {
	background-color: #cbc693;
}

dl.warning dt {
	background-color: #bf5f82;
}

dl.todo dt {
	background-color: #82b3c9;
}

dl.deprecated dt {
	background-color: #af8eb5;
}

dl.reflist dt {
	background-color: #cbae82;
}

dl.note dd {
	background-color: #fff9c4;
	border-color: #cbc693;
}

dl.warning dd {
	background-color: #f48fb1;
	border-color: #bf5f82;
}

dl.todo dd {
	background-color: #b3e5fc;
	border-color: #82b3c9;
}

dl.deprecated dd {
	background-color: #e1bee7;
	border-color: #af8eb5;
}

dl.reflist dd {
	background-color: #ffe0b2;
	border-color: #cbae82;
}

#docs_list {
	padding: 0 10px;
}

#docs_list ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

#docs_list ul li {
	display: inline-block;
	border-right: 1px solid #BFBFBF;
}

#docs_list ul li:last-child {
	border-right: none;
}

#docs_list ul li a {
	display: block;
	padding: 8px 13px;
	font-weight: bold;
	font-size: 15px;
}

#docs_list ul li a:hover,
#docs_list ul li a.docs_current {
	text-decoration: underline;
}

.ui-resizable-e {
	width: 3px;
}

.download_url {
	font-weight: bold;
	font-size: 150%;
	line-height: 150%;
}

span.lineno a {
	text-decoration: none;
}

.directory .arrow {
	height: initial;
}

.directory td.entry {
	padding: 3px 6px;
}

.memproto table td {
	font-family: monospace, fixed !important;
}

td.memItemLeft, td.memItemRight {
	font-family: monospace, fixed;
}

.paramname, .paramname em {
	font-style: italic;
}

.memdoc {
	text-shadow: none;
}

.memItem {
	font-family: monospace, fixed;
}

.memItem table {
	font-family: inherit;
}

img.footer {
	height: 22px;
}

.sm-dox {
	background: #dfe5f2 !important;
}

.sm-dox a {
	background: none;
}

div.fragment, pre.fragment {
	border: 1px solid #000000;
	background: #32363d;
}

a, a:link, a:visited {
	color: #67d8ef !important;
}

.highlighted {
	background: none !important;
}

a.highlighted {
	background: none !important;
}

#main-nav {
	border-bottom: 1px solid #32363d;
}

#main-nav .sm-dox {
	background: transparent !important;
}

.sm-dox a {
	text-shadow: none !important;
	background: transparent !important;
}

.sm-dox a:hover {
	background: #282923 !important;
}

.sm-dox {
	text-shadow: none !important;
	box-shadow: none !important;
}

.sm-dox ul {
	border: 1px solid #000000;
	background: #32363d;
}

.directory tr.even {
	background: #36383d;
}

.directory tr.odd {
	background: #292a2d;
}

#MSearchSelectWindow {
	border: 1px solid #000000;
	background: #32363d;
}

a.selectItem {
	padding: 3px;
}

a.SelectItem:hover {
	background: #282923 !important;
}

#MSearchResultsWindow {
	border: 1px solid #000000;
	background: #32363d;
	color: #67d8ef !important;;
}

#nav-tree {
	background: transparent;
}

#nav-tree .selected {
	background-image: none;
	background: #32363d;
}


div.toc {
	background: #32363d;
	border: 1px solid #000000;
}

div.toc h3 {
	font-size: 150%;
	color: inherit;
}

table.doxtable tr:nth-child(even) td {
	background: #32363d;
}

div.header {
	background: transparent;
	border-bottom: 1px solid #32363d;
}

.fieldtable th {
	background: #282923;
	color: inherit;
}

.memdoc {
	border: 1px solid #A8B8D9;
}

.tabs, .tabs2, .tabs3 {
	background: #DDDDDD;
}

.tablist li {
	background: transparent !important;
}

.tablist a {
	background-image: none;
	border-right: 1px solid #999999;

	color: #32363d;
}

.tablist a:hover,
.tablist li.current a {
	text-decoration: none;
	color: #000000;
	background: #CCCCCC;
	background-image: none;
}

#docs_list {
	background: #32363d;
}

#docs_list ul li {
	border-right: 1px solid #BFBFBF;
}

#docs_list ul li a {
	color: #1b1e21;
}

#docs_list ul li a:hover,
#docs_list ul li a.docs_current {
	background: #282923;
}

.ui-resizable-e {
	background: #32363d;
}

div.line {
	background: transparent;
	color: inherit;
}

div.line a {
	text-decoration: underline;
    color: inherit;
}

span.keyword {
	color: #f92472;
	font-style: italic;
}

span.keywordtype {
	color: #67cfc1;
	font-style: italic;
}

span.keywordflow {
	color: #f92472;
	font-style: italic;
}

span.comment {
	color: #74705a;
}

span.preprocessor {
	color: #a6e22b;
}

span.stringliteral {
	color: #e7db74;
}

span.charliteral {
	color: #e7db74;
}

span.vhdldigit { 
	color: #ff00ff;
}

span.vhdlchar { 
	color: #000000;
}

span.vhdlkeyword { 
	color: #700070;
}

span.vhdllogic { 
	color: #ff0000;
}

span.lineno {
	background: transparent;
}

span.lineno a {
	background: transparent;
}

.mdescLeft, .mdescRight, .memItemLeft, .memItemRight,
.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
	background: #32363d;
	color: inherit;
}

.memSeparator {
	border: none;
	background: transparent;
}

h2.groupheader {
	color: #67d8ef;
}

.memtitle {
	background: #32363d !important;
	border-color: #000000;
}

.memitem {
	background: #32363d !important;
	color: inherit;
	text-shadow: none;
}

.memproto {
	background: inherit;
	border-color: #000000;
	color: inherit;
	text-shadow: none;
}

.memproto table td {
	font-family: monospace, fixed !important;
}

td.memItemLeft, td.memItemRight {
	font-family: monospace, fixed;
}

.paramname, .paramname em {
	color: #bf5f82;
}

.memdoc {
	background: inherit;
	border-color: #000000;
}

#nav-path {
	background: transparent;
}

#nav-path ul {
	background: transparent;
	color: inherit;
	border: none;
	border-top: 1px solid #32363d;
}

.navpath li.footer {
	color: inherit;
}

.navpath li.navelem a {
	text-shadow: none;
}

::-webkit-scrollbar {
	width: 10px;
}

::-webkit-scrollbar-track {
	border-radius: 10px;
}

::-webkit-scrollbar-thumb {
	background: #234567;
	border: none;
}

::-webkit-scrollbar-thumb:hover {
	background: #32363d; 
}

h1.glow, h2.glow, h3.glow,
h4.glow, h5.glow, h6.glow {
	text-shadow: 0 0 15px #67d8ef;
}


================================================
FILE: docs/foundation.md
================================================
# Foundations
Box2D provides minimal base functionality for allocation hooks and vector math. The C interface
allows most runtime data and types to be defined internally in the `src` folder.

## Assertions
Box2D will assert on bad input. This includes things like sending in NaN or infinity for values. It will assert if
you use negative values for things that should only be positive, such as density.

Box2D will also assert if an internal bug is detected. For this reason, it is advisable to build Box2D from source.
The Box2D library compiles in about a second on my computer.

You may wish to capture assertions in your application. In this case you can use `b2SetAssertFcn()`. This allows you
to override the debugger break and/or perform your own error handling.

## Allocation
Box2D uses memory efficiently and minimizes per frame allocations by pooling memory. The engine quickly adapts to the
simulation size. After the first step or two of simulation, there should be no further per frame allocations.

As bodies, shapes, and joints are created and destroyed, their memory will be recycled. Internally all this data is stored in contiguous arrays. When an object is destroyed, the array element will be marked as empty. And when an object is created it will use empty slots in the array using an efficient free list.

Once the internal memory pools are initially filled, the only allocations should be for sleeping islands since their data is copied out of the main simulation. Generally, these allocations should be infrequent.

You can provide a custom allocator using `b2SetAllocator()` and you can get the number of bytes allocated using `b2GetByteCount()`.

## Version
The b2Version structure holds the current version so you can query this
at run-time using `b2GetVersion()`.

```c
b2Version version = b2GetVersion();
printf("Box2D version %d.%d.%d\n", version.major, version.minor, version.revision);
```

## Vector Math
Box2D includes a small vector math library including types `b2Vec2`, `b2Rot`, `b2Transform`, and `b2AABB`. This has been
designed to suit the internal needs of Box2D and the interface. All the
members are exposed, so you may use them freely in your application.

The math library is kept simple to make Box2D easy to port and maintain.

## Multithreading {#multi}
Box2D has been highly optimized for multithreading. Multithreading is not required and by default Box2D will run single-threaded. If performance is important for your application, you should consider using the multithreading interface.

Box2D multithreading has been designed to work with your application's task system. Box2D does
not create threads. The Samples application shows how to do this using the open source tasks system [enkiTS](https://github.com/dougbinks/enkiTS).

Multithreading is established for each Box2D world you create and must be hooked up to
the world definition. See `b2TaskCallback()`, `b2EnqueueTaskCallback()`, and `b2FinishTaskCallback()` for more details. Also see `b2WorldDef::workerCount`, `b2WorldDef::enqueueTask`, and `b2WorldDef::finishTask`.

The multithreading design for Box2D is focused on [data parallelism](https://en.wikipedia.org/wiki/Data_parallelism). The idea is to use multiple cores to complete the world simulation as fast as possible. Box2D multithreading is not designed for [task parallelism](https://en.wikipedia.org/wiki/Task_parallelism). Often in games you may have a render thread and an audio thread that do work in isolation from the main thread. Those are examples of task parallelism.

So when you design your game loop, you should let Box2D *go wide* and use multiple cores to finish its work quickly, without other threads trying to interact with the Box2D world.

In a multithreaded environment you must be careful to avoid [race conditions](https://en.wikipedia.org/wiki/Race_condition). Modifying the world while it is simulating will lead to unpredictable behavior and this is never safe. It is also not safe to read data from a Box2D world while it is simulating. Box2D may move data structures to improve cache performance. So it is very likely that you will read garbage data.

> **Caution**:
> Do not perform read or write operations on a Box2D world during `b2World_Step()`

> **Caution**:
> Do not write to the Box2D world from multiple threads

It *is safe* to do ray-casts, shape-casts, and overlap tests from multiple threads outside of `b2World_Step()`. Generally, any read-only operation is safe to do multithreaded outside of `b2World_Step()`. This can be very useful if you have multithreaded game logic.

## Multithreading Multiple Worlds
Some applications may wish to create multiple Box2D worlds and simulate them on different threads. This works fine because Box2D has very limited use of globals.

There are a few caveats:
- You will get a race condition if you create or destroy Box2D worlds from multiple threads. You should use a mutex to guard this.
- If you will simulate multiple Box2D worlds simultaneously, then they should probably not use a task system. Otherwise you're likely to get preemption.
- Any callbacks you hook up to Box2D must be thread-safe, such as memory allocators.
- All of the limitations for single world simulation still apply.


================================================
FILE: docs/hello.md
================================================
# Hello Box2D {#hello}
In the distribution of Box2D is a Hello World unit test written in C. The test
creates a large ground box and a small dynamic box. This code does not
contain any graphics. All you will see is text output in the console of
the box's position over time.

This is a good example of how to get up and running with Box2D.

## Creating a World
Every Box2D program begins with the creation of a world object.
The world is the physics hub that manages memory, objects, and simulation.
The world is represented by an opaque handle called `b2WorldId`.

It is easy to create a Box2D world. First, I create the world definition:

```c
b2WorldDef worldDef = b2DefaultWorldDef();
```

The world definition is a temporary object that you can create on the stack. The function
`b2DefaultWorldDef()` populates the world definition with default values. This is necessary because C does not have constructors and zero initialization is not appropriate for `b2WorldDef`.

Now I configure the world gravity vector. Note that Box2D has no concept of *up* and you may point gravity in any direction you like. Box2D example code uses the positive y-axis as the up direction.

```c
worldDef.gravity = (b2Vec2){0.0f, -10.0f};
```

Now I create the world object.

```c
b2WorldId worldId = b2CreateWorld(&worldDef);
```

The world creation copies all the data it needs out of the world definition, so the world
definition is no longer needed.

So now we have our physics world, let's start adding some stuff to it.

## Creating a Ground Box
Bodies are built using the following steps:
1. Define a body with position, damping, etc.
2. Use the world id to create the body.
3. Define shapes with friction, density, etc.
4. Create shapes on the body.

For step 1 I create the ground body. For this I need a body
definition. With the body definition I specify the initial position of
the ground body.

```c
b2BodyDef groundBodyDef = b2DefaultBodyDef();
groundBodyDef.position = (b2Vec2){0.0f, -10.0f};
```

For step 2 the body definition and the world id are used to create
the ground body. Again, the definition is fully copied and may leave scope after
the body is created. Bodies are static by default. Static bodies don't collide
with other static bodies and are immovable by the simulation.

```c
b2BodyId groundId = b2CreateBody(worldId, &groundBodyDef);
```

Notice that `worldId` is passed by value. Ids are small structures that should
be passed by value.

For step 3 I create a ground polygon. I use the `b2MakeBox()` helper function to
form the ground polygon into a box shape, with the box centered on the
origin of the parent body.

```c
b2Polygon groundBox = b2MakeBox(50.0f, 10.0f);
```

The `b2MakeBox()` function takes the **half-width** and
**half-height** (extents). So in this case the ground box is 100
units wide (x-axis) and 20 units tall (y-axis). Box2D is tuned for
meters, kilograms, and seconds. So you can consider the extents to be in
meters. Box2D generally works best when objects are the size of typical
real world objects. For example, a barrel is about 1 meter tall. Due to
the limitations of floating point arithmetic, using Box2D to model the
movement of glaciers or dust particles might not work well.

I'll finish the ground body in step 4 by creating the shape. For this step
I need to create a shape definition which works fine with the default value.

```c
b2ShapeDef groundShapeDef = b2DefaultShapeDef();
b2CreatePolygonShape(groundId, &groundShapeDef, &groundBox);
```

Box2D does not keep a reference to the shape data. It copies the data into the internal
data structures.

Note that every shape must have a parent body, even shapes that are
static. You may attach multiple shapes to a single parent body.

When you attach a shape, the shape's
coordinates become local to the body. So when the body moves, so does
the shape. A shape's world transform is inherited from the parent
body. A shape does not have a transform independent of the body. So we
don't move a shape around on the body. Moving or modifying a shape that
is on a body is possible with certain functions, but it should not be part
of normal simulation. The reason is simple: a body with
morphing shapes is not a rigid body, but Box2D is a rigid body engine.
Many of the algorithms in Box2D are based on the rigid body model and optimized with
that in mind. If this is violated you may get unexpected behavior.

## Creating a Dynamic Body
I can use the same technique to create a
dynamic body. The main difference, besides dimensions, is that I must
establish the dynamic body's mass properties.

First I create the body using CreateBody. By default bodies are static,
so I should set the `b2BodyType` at creation time to make the body
dynamic. I should also use the body definition to put the body at the
intended position for simulation. Creating a body then moving it afterwards is
very inefficient and may cause lag spikes, especially if many bodies are created at
the origin.

```c
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
bodyDef.position = (b2Vec2){0.0f, 4.0f};
b2BodyId bodyId = b2CreateBody(worldId, &bodyDef);
```

> **Caution**:
> You must set the body type to `b2_dynamicBody` if you want the body to
> move in response to forces (such as gravity).

Next I create and attach a polygon shape using a shape definition.
First I create another box shape:

```c
b2Polygon dynamicBox = b2MakeBox(1.0f, 1.0f);
```

Next I create a shape definition for the box. Notice that I set
density to 1. The default density is 1, so this is unnecessary. Also,
the friction on the surface material is set to 0.3.

```c
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.density = 1.0f;
shapeDef.material.friction = 0.3f;
```

> **Caution**:
> A dynamic body should have at least one shape with a non-zero density.
> Otherwise you will get strange behavior.

Using the shape definition I can now create the shape. This
automatically updates the mass of the body. You can add as many shapes
as you like to a body. Each one contributes to the total mass.

```c
b2CreatePolygonShape(bodyId, &shapeDef, &dynamicBox);
```

That's it for initialization. We are now ready to begin simulating.

## Simulating the World
I have initialized the ground box and a dynamic box. Now we are
ready to set Newton loose to do his thing. I just have a couple more
issues to consider.

Box2D uses a computational algorithm called an integrator. Integrators
simulate the physics equations at discrete points of time. This goes
along with the traditional game loop where we essentially have a flip
book of movement on the screen. So we need to pick a time step for
Box2D. Generally physics engines for games like a time step at least as
fast as 60Hz or 1/60 seconds. You can get away with larger time steps,
but you will have to be more careful about setting up your simulation.
It is also not good for the time step to vary from frame to frame. A
variable time step produces variable results, which makes it difficult
to debug. So don't tie the time step to your frame rate. Without further ado,
here is the time step.

```c
float timeStep = 1.0f / 60.0f;
```

In addition to the integrator, Box2D also uses a larger bit of code
called a constraint solver. The constraint solver solves all the
constraints in the simulation, one at a time. A single constraint can be
solved perfectly. However, when Box2D solves one constraint, it slightly
disrupts other constraints. To get a good solution, Box2D needs to iterate
over all constraints a number of times.

Box2D uses sub-stepping as a means of constraint iteration. It lets the
simulation move forward in time by small amounts and each constraint
gets a chance to react to the changes.

The suggested sub-step count for Box2D is 4. You can tune this number
to your liking, just keep in mind that this has a trade-off between
performance and accuracy. Using fewer sub-steps increases performance
but accuracy suffers. Likewise, using
more sub-steps decreases performance but improves the quality of your
simulation. For this example, I will use 4 sub-steps.

```c
int subStepCount = 4;
```

Note that the time step and the sub-step count are related. As the time step
decreases, the size of the sub-steps also decreases. For example, at 60Hz
time step and 4 sub-steps, the sub-steps operate at 240Hz. With 8 sub-steps
the sub-step is 480Hz.

We are now ready to begin the simulation loop. In your game the
simulation loop can be merged with your game loop. In each pass through
your game loop you call `b2World_Step()`. Just one call is usually enough,
depending on your frame rate and your physics time step. I recommend this article
[Fix Your Timestep!](https://gafferongames.com/post/fix_your_timestep/) to run
your game simulation at a fixed rate.

The Hello World test was designed to be simple, so it has no
graphical output. The code prints out the position and rotation of the
dynamic body. Here is the simulation loop that simulates 90 time steps
for a total of 1.5 seconds of simulated time.

```c
for (int i = 0; i < 90; ++i)
{
	b2World_Step(worldId, timeStep, subStepCount);
    b2Vec2 position = b2Body_GetPosition(bodyId);
    b2Rot rotation = b2Body_GetRotation(bodyId);
    printf("%4.2f %4.2f %4.2f\n", position.x, position.y, b2Rot_GetAngle(rotation));
}
```

Notice that the rotation of the body is returned in a `b2Rot` struct (short for rotation). This
struct holds the rotation in a format that is fast for simulation. You may use `b2Rot_GetAngle`
to get the rotation in radians.

The output shows the box falling and landing on the ground box. Your
output should look like this:

```
0.00 4.00 0.00
0.00 3.99 0.00
0.00 3.98 0.00
...
0.00 1.25 0.00
0.00 1.13 0.00
0.00 1.01 0.00
```

## Cleanup
When you are done with the simulation, you should destroy the world.

```c
b2DestroyWorld(worldId);
```

This efficiently destroys all bodies, shapes, and joints in the simulation.


================================================
FILE: docs/layout.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<doxygenlayout version="1.0">
  <!-- Generated by doxygen 1.10.0 -->
  <!-- Navigation index tabs for HTML output -->
  <navindex>
    <tab type="mainpage" visible="yes" title=""/>
    <tab type="pages" visible="yes" title="" intro=""/>
    <tab type="topics" visible="yes" title="Reference" intro=""/>
    <tab type="modules" visible="yes" title="" intro="">
      <tab type="modulelist" visible="yes" title="" intro=""/>
      <tab type="modulemembers" visible="yes" title="" intro=""/>
    </tab>
    <tab type="namespaces" visible="yes" title="">
      <tab type="namespacelist" visible="yes" title="" intro=""/>
      <tab type="namespacemembers" visible="yes" title="" intro=""/>
    </tab>
    <tab type="concepts" visible="yes" title="">
    </tab>
    <tab type="interfaces" visible="yes" title="">
      <tab type="interfacelist" visible="yes" title="" intro=""/>
      <tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
      <tab type="interfacehierarchy" visible="yes" title="" intro=""/>
    </tab>
    <tab type="classes" visible="yes" title="">
      <tab type="classlist" visible="yes" title="" intro=""/>
      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
      <tab type="hierarchy" visible="yes" title="" intro=""/>
      <tab type="classmembers" visible="yes" title="" intro=""/>
    </tab>
    <tab type="structs" visible="yes" title="">
      <tab type="structlist" visible="yes" title="" intro=""/>
      <tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
    </tab>
    <tab type="exceptions" visible="yes" title="">
      <tab type="exceptionlist" visible="yes" title="" intro=""/>
      <tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
      <tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
    </tab>
    <tab type="files" visible="yes" title="">
      <tab type="filelist" visible="yes" title="" intro=""/>
      <tab type="globals" visible="yes" title="" intro=""/>
    </tab>
    <tab type="examples" visible="yes" title="" intro=""/>
  </navindex>

  <!-- Layout definition for a class page -->
  <class>
    <briefdescription visible="yes"/>
    <includes visible="$SHOW_HEADERFILE"/>
    <inheritancegraph visible="yes"/>
    <collaborationgraph visible="yes"/>
    <memberdecl>
      <nestedclasses visible="yes" title=""/>
      <publictypes title=""/>
      <services title=""/>
      <interfaces title=""/>
      <publicslots title=""/>
      <signals title=""/>
      <publicmethods title=""/>
      <publicstaticmethods title=""/>
      <publicattributes title=""/>
      <publicstaticattributes title=""/>
      <protectedtypes title=""/>
      <protectedslots title=""/>
      <protectedmethods title=""/>
      <protectedstaticmethods title=""/>
      <protectedattributes title=""/>
      <protectedstaticattributes title=""/>
      <packagetypes title=""/>
      <packagemethods title=""/>
      <packagestaticmethods title=""/>
      <packageattributes title=""/>
      <packagestaticattributes title=""/>
      <properties title=""/>
      <events title=""/>
      <privatetypes title=""/>
      <privateslots title=""/>
      <privatemethods title=""/>
      <privatestaticmethods title=""/>
      <privateattributes title=""/>
      <privatestaticattributes title=""/>
      <friends title=""/>
      <related title="" subtitle=""/>
      <membergroups visible="yes"/>
    </memberdecl>
    <detaileddescription title=""/>
    <memberdef>
      <inlineclasses title=""/>
      <typedefs title=""/>
      <enums title=""/>
      <services title=""/>
      <interfaces title=""/>
      <constructors title=""/>
      <functions title=""/>
      <related title=""/>
      <variables title=""/>
      <properties title=""/>
      <events title=""/>
    </memberdef>
    <allmemberslink visible="yes"/>
    <usedfiles visible="$SHOW_USED_FILES"/>
    <authorsection visible="yes"/>
  </class>

  <!-- Layout definition for a namespace page -->
  <namespace>
    <briefdescription visible="yes"/>
    <memberdecl>
      <nestednamespaces visible="yes" title=""/>
      <constantgroups visible="yes" title=""/>
      <interfaces visible="yes" title=""/>
      <classes visible="yes" title=""/>
      <concepts visible="yes" title=""/>
      <structs visible="yes" title=""/>
      <exceptions visible="yes" title=""/>
      <typedefs title=""/>
      <sequences title=""/>
      <dictionaries title=""/>
      <enums title=""/>
      <functions title=""/>
      <variables title=""/>
      <properties title=""/>
      <membergroups visible="yes"/>
    </memberdecl>
    <detaileddescription title=""/>
    <memberdef>
      <inlineclasses title=""/>
      <typedefs title=""/>
      <sequences title=""/>
      <dictionaries title=""/>
      <enums title=""/>
      <functions title=""/>
      <variables title=""/>
      <properties title=""/>
    </memberdef>
    <authorsection visible="yes"/>
  </namespace>

  <!-- Layout definition for a concept page -->
  <concept>
    <briefdescription visible="yes"/>
    <includes visible="$SHOW_HEADERFILE"/>
    <definition visible="yes" title=""/>
    <detaileddescription title=""/>
    <authorsection visible="yes"/>
  </concept>

  <!-- Layout definition for a file page -->
  <file>
    <briefdescription visible="yes"/>
    <includes visible="$SHOW_INCLUDE_FILES"/>
    <includegraph visible="yes"/>
    <includedbygraph visible="yes"/>
    <sourcelink visible="yes"/>
    <memberdecl>
      <interfaces visible="yes" title=""/>
      <classes visible="yes" title=""/>
      <structs visible="yes" title=""/>
      <exceptions visible="yes" title=""/>
      <namespaces visible="yes" title=""/>
      <concepts visible="yes" title=""/>
      <constantgroups visible="yes" title=""/>
      <defines title=""/>
      <typedefs title=""/>
      <sequences title=""/>
      <dictionaries title=""/>
      <enums title=""/>
      <functions title=""/>
      <variables title=""/>
      <properties title=""/>
      <membergroups visible="yes"/>
    </memberdecl>
    <detaileddescription title=""/>
    <memberdef>
      <inlineclasses title=""/>
      <defines title=""/>
      <typedefs title=""/>
      <sequences title=""/>
      <dictionaries title=""/>
      <enums title=""/>
      <functions title=""/>
      <variables title=""/>
      <properties title=""/>
    </memberdef>
    <authorsection/>
  </file>

  <!-- Layout definition for a group page -->
  <group>
    <briefdescription visible="yes"/>
    <groupgraph visible="yes"/>
    <memberdecl>
      <nestedgroups visible="yes" title=""/>
      <modules visible="yes" title=""/>
      <dirs visible="yes" title=""/>
      <files visible="yes" title=""/>
      <namespaces visible="yes" title=""/>
      <concepts visible="yes" title=""/>
      <classes visible="yes" title=""/>
      <defines title=""/>
      <typedefs title=""/>
      <sequences title=""/>
      <dictionaries title=""/>
      <enums title=""/>
      <enumvalues title=""/>
      <functions title=""/>
      <variables title=""/>
      <signals title=""/>
      <publicslots title=""/>
      <protectedslots title=""/>
      <privateslots title=""/>
      <events title=""/>
      <properties title=""/>
      <friends title=""/>
      <membergroups visible="yes"/>
    </memberdecl>
    <detaileddescription title=""/>
    <memberdef>
      <pagedocs/>
      <inlineclasses title=""/>
      <defines title=""/>
      <typedefs title=""/>
      <sequences title=""/>
      <dictionaries title=""/>
      <enums title=""/>
      <enumvalues title=""/>
      <functions title=""/>
      <variables title=""/>
      <signals title=""/>
      <publicslots title=""/>
      <protectedslots title=""/>
      <privateslots title=""/>
      <events title=""/>
      <properties title=""/>
      <friends title=""/>
    </memberdef>
    <authorsection visible="yes"/>
  </group>

  <!-- Layout definition for a C++20 module page -->
  <module>
    <briefdescription visible="yes"/>
    <exportedmodules visible="yes"/>
    <memberdecl>
      <concepts visible="yes" title=""/>
      <classes visible="yes" title=""/>
      <enums title=""/>
      <typedefs title=""/>
      <functions title=""/>
      <variables title=""/>
      <membergroups title=""/>
    </memberdecl>
    <detaileddescription title=""/>
    <memberdecl>
      <files visible="yes"/>
    </memberdecl>
  </module>

  <!-- Layout definition for a directory page -->
  <directory>
    <briefdescription visible="yes"/>
    <directorygraph visible="yes"/>
    <memberdecl>
      <dirs visible="yes"/>
      <files visible="yes"/>
    </memberdecl>
    <detaileddescription title=""/>
  </directory>
</doxygenlayout>


================================================
FILE: docs/loose_ends.md
================================================
# Loose Ends

## User Data
Bodies, shapes, and joints allow you to attach user data
as a `void*`. This is handy when you are examining Box2D data
structures and you want to determine how they relate to the objects in
your game engine.

For example, it is typical to attach an entity pointer to the rigid body
on that entity. This sets up a circular reference. If you have the entity,
you can get the body. If you have the body, you can get the entity.

```c
GameEntity* entity = GameCreateEntity();
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.userData = entity;
entity->bodyId = b2CreateBody(myWorldId, &bodyDef);
```

Here are some examples of cases where you would need the user data:
-   Applying damage to an entity using a collision result.
-   Playing a scripted event if the player is inside an axis-aligned box.
-   Accessing a game structure when Box2D notifies you that a joint is
    going to be destroyed.

Keep in mind that user data is optional and you can put anything in it.
However, you should be consistent. For example, if you want to store an
entity pointer on one body, you should keep an entity pointer on all
bodies. Don't store a `GameEntity` pointer on one body, and a `ParticleSystem`
pointer on another body. Casting a `GameEntity` to a `ParticleSystem` pointer
may lead to a crash.

## Pixels and Coordinate Systems
I recommend using MKS (meters, kilograms, and seconds) units and
radians for angles. You may have trouble working with meters because
your game is expressed in terms of pixels. To deal with this in the
sample I have the whole *game* world in meters and just use an OpenGL
viewport transformation to scale the world into screen space.

You use code like this to scale your graphics.

```c
float lowerX = -25.0f, upperX = 25.0f, lowerY = -5.0f, upperY = 25.0f;
gluOrtho2D(lowerX, upperX, lowerY, upperY);
```

If your game must work in pixel units then you could convert your
length units from pixels to meters when passing values from Box2D.
Likewise you should convert the values received from Box2D from meters
to pixels. This will improve the stability of the physics simulation.

You have to come up with a reasonable conversion factor. I suggest
making this choice based on the size of your characters. Suppose you
have determined to use 50 pixels per meter (because your character is 75
pixels tall). Then you can convert from pixels to meters using these
formulas:

```cpp
xMeters = 0.02f * xPixels;
yMeters = 0.02f * yPixels;
```

In reverse:

```cpp
xPixels = 50.0f * xMeters;
yPixels = 50.0f * yMeters;
```

You should consider using MKS units in your game code and just convert
to pixels when you render. This will simplify your game logic and reduce
the chance for errors since the rendering conversion can be isolated to
a small amount of code.

If you use a conversion factor, you should try tweaking it globally to
make sure nothing breaks. You can also try adjusting it to improve
stability.

If this conversion is not possible, you can set the length units used
by Box2D using `b2SetLengthUnitsPerMeter()`. This is experimental and not
well tested.

## Debug Drawing
You can implement the function pointers in `b2DebugDraw` struct to get detailed
drawing of the Box2D world. Debug draw provides:
- shapes
- joints
- broad-phase axis-aligned bounding boxes (AABBs)
- center of mass
- contact points

This is the preferred method of drawing the Box2D simulation, rather
than accessing the data directly. The reason is that much of the
necessary data is internal and subject to change.

The samples application draws the Box2D world using the `b2DebugDraw`.

## Limitations
Box2D uses several approximations to simulate rigid body physics
efficiently. This brings some limitations.

Here are the current limitations:
1. Extreme mass ratios may cause joint stretching and collision overlap.
2. Box2D uses soft constraints to improve robustness. This can lead to joint and contact flexing.
3. Continuous collision does not handle all situations. For example, general dynamic versus dynamic continuous collision is not handled. [Bullets](#bullets) handle this in a limited way. This is done for performance reasons.
4. Continuous collision does not handle joints. So you may see joint stretching on fast moving objects. Usually the joints recover after a few time steps.
5. Box2D uses the [semi-implicit Euler method](https://en.wikipedia.org/wiki/Semi-implicit_Euler_method) to solve the [equations of motion](https://en.wikipedia.org/wiki/Equations_of_motion). It does not reproduce exactly the parabolic motion of projectiles and has only first-order accuracy. However it is fast and has good stability.
6. Box2D uses the [Gauss-Seidel method](https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method) to solve constraints and achieve real-time performance. You will not get precisely rigid collisions or pixel perfect accuracy. Increasing the sub-step count will improve accuracy.


================================================
FILE: docs/migration.md
================================================
# Migration Guide

> **Caution**:
> This guide only covers the transition from 2.4 to 3.0. Please see the release notes for future version changes.

## Version 2.4 to Version 3.0

Box2D version 3.0 is a full rewrite. You can read some background information [here](https://box2d.org/posts/2023/01/starting-box2d-3.0/).

Here are the highlights that affect the API:
- moved from C++ to C
- identifiers (handles) instead of pointers
- multithreading support
- fewer callbacks
- more features (such as capsules and shape casts)
- new sub-stepping solver (*Soft Step*)
- gear and pulley joint removed (temporarily)

However, the scope of what Box2D does has not changed much. It is still a 2D rigid body engine. It is just faster and more robust (hopefully). And hopefully it is easier to work with and port/wrap for other languages/platforms.

I'm going to describe migration by comparing code snippets between 2.4 and 3.0. These should give you and idea of the sort of transformations you need to make to your code to migrate to v3.0. These snippets are written in C and may need some small adjustments to work with C++.

I'm not going to cover all the details of v3.0 in this guide. That is the job of the manual, the doxygen reference, and the samples.

The surface area of the Box2D is smaller in v3.0 because C++ is not good at hiding details. So hopefully you find the new API easier to work with.

### Should I upgrade to Version 3?
Since the behavior changed from version 2 to version 3, I recommend to only use version 3 for new projects. Version 2 no longer receives updates, but it is already battle tested. Version 3 is good for projects that need high performance.

### Creating a world
Version 2.4:
```cpp
#include "box2d/box2d.h"
b2Vec2 gravity(0.0f, -10.0f);
b2World world(gravity);
```
Version 3.0:
```c
#include "box2d/box2d.h"
b2Vec2 gravity = {0.0f, -10.0f};
b2WorldDef worldDef = b2DefaultWorldDef();
worldDef.gravity = gravity;
b2WorldId worldId = b2CreateWorld(&worldDef);
```
There is now a required world definition. C does not have constructors, so you need to initialize **ALL** structures that you pass to Box2D. Box2D provides an initialization helper for almost all structures. For example `b2DefaultWorldDef()` is used here to initialize `b2WorldDef`. `b2WorldDef` provides many options, but the defaults are good enough to get going.

In Version 3.0, Box2D objects are generally hidden and you only have an identifier. This keeps the API small. So when you create a world you just get a `b2WorldId` which you should treat as an atomic object, like `int` or `float`. It is small and should be passed by value.

In Version 3.0 there are also no destructors, so you must destroy the world.
```c
b2DestroyWorld(worldId);
worldId = b2_nullWorldId;
```
This destroys all bodies, shapes, and joints as well. This is quicker than destroying them individually. Just like pointers, it is good practice to nullify identifiers. Box2D provides null values for all identifiers and also macros such as `B2_IS_NULL` to test if an identifier is null.

### Creating a body
Version 2.4:
```cpp
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(0.0f, 4.0f);
b2Body* body = world.CreateBody(&bodyDef);
```
Version 3.0:
```c
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
bodyDef.position = (b2Vec2){0.0f, 4.0f};
b2BodyId bodyId = b2CreateBody(worldId, &bodyDef);
```
Body creation is very similar in v3.0. In this case there is a definition initialization function `b2DefaultBodyDef()`. This can help save a bit of typing in some cases. In v3.0 I recommend getting comfortable with curly brace initialization for initializing vectors. There are no member functions in C. Notice that the body is created using a loose function and providing the `b2WorldId` as an argument. Basically what you would expect going from C++ to C.

Destroying a body is also similar.
Version 2.4:
```cpp
world.DestroyBody(body);
body = nullptr;
```
Version 3.0:
```c
b2DestroyBody(bodyId);
bodyId = b2_nullBodyId;
```
Notice there is a little magic here in Version 3.0. `b2BodyId` knows what world it comes from. So you do not need to provide `worldId` when destroying the body. Version 3.0 supports up to 128 worlds. This may be increased or be overridden in the future.

Shapes and joints are still destroyed automatically. However, `b2DestructionListener` is gone. This holds to the theme of fewer callbacks. However, you can now use 
`b2Shape_IsValid()` and `b2Joint_IsValid()`.

### Creating a shape
Shape creation has been streamlined in Version 3.0. `b2Fixture` is gone. I feel like it was a confusing concept so I hope you don't miss it.

Version 2.4:
```cpp
b2PolygonShape box;
box.SetAsBox(1.0f, 1.0f);

b2FixtureDef fixtureDef;
fixtureDef.shape = &box;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;

b2Fixture* fixture = body->CreateFixture(&fixtureDef);
```

Version 3.0:
```c
b2Polygon box = b2MakeBox(1.0f, 1.0f);

b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.density = 1.0f;
shapeDef.friction = 0.3f;

b2ShapeId shapeId = b2CreatePolygonShape(bodyId, &shapeDef, &box);
```

So basically v2.4 shapes are no longer shapes, they are *primitives* or *geometry* with no inheritance (of course). This freed the term _shape_ to be used where _fixture_ was used before. In v3.0 the shape definition is generic and there are different functions for creating each shape type, such as `b2CreateCircleShape` or `b2CreateSegmentShape`.

Again notice the structure initialization with `b2DefaultShapeDef()`. Unfortunately we cannot have meaningful definitions with zero initialization. You must initialize your structures.

Another important change for shapes is that the default density in the shape definition is now 1 instead of 0. Static and kinematic bodies will ignore the density. You can now make an entire game without touching the density.

Destroying shapes is straight forward.

Version 2.4:
```cpp
body->DestroyFixture(fixture);
fixture = nullptr;
```

Version 3.0:
```c
b2DestroyShape(shapeId);
shapeId = b2_nullShapeId;
```

### Chains
In Version 2.4 chains are a type of shape. In Version 3.0 they are a separate concept. This leads to significant simplifications internally. In Version 2.4 all shapes had to support the notion of child shapes. This is gone.

Version 2.4:
```cpp
b2Vec2 points[5];
points[0].Set(-8.0f, 6.0f);
points[1].Set(-8.0f, 20.0f);
points[2].Set(8.0f, 20.0f);
points[3].Set(8.0f, 6.0f);
points[4].Set(0.0f, -2.0f);

b2ChainShape chain;
chain.CreateLoop(points, 5);
b2FixtureDef fixtureDef;
fixtureDef.shape = &chain;
b2Fixture* chainFixture = body->CreateFixture(&fixtureDef);
```

Version 3.0:
```c
b2Vec2 points[5] = {
    {-8.0f, 6.0f},
    {-8.0f, 20.0f},
    {8.0f, 20.0f},
    {8.0f, 6.0f},
    {0.0f, -2.0f}
};

b2ChainDef chainDef = b2DefaultChainDef();
chainDef.points = points;
chainDef.count = 5;
chainDef.loop = true;
b2ChainId chainId = b2CreateChain(bodyId, &chainDef);
```

Since chains are their own concept now, they get their own identifier, `b2ChainId`. You can view chains as macro objects, they create many `b2ChainSegment` shapes internally. Normally you don't interact with these. However they are returned from queries. You can use `b2Shape_GetParentChain()` to get the `b2ChainId` for a chain segment that you get from a query.

> DO NOT destroy or modify a `b2ChainSegment` that belongs to a chain shape directly

### Creating a joint
Joints are very similar in v3.0. The lack of C member functions changes initialization.

Version 2.4:
```cpp
b2RevoluteJointDef jointDef;
jointDef.Initialize(ground, body, b2Vec2(-10.0f, 20.5f));
jointDef.motorSpeed = 1.0f;
jointDef.maxMotorTorque = 100.0f;
jointDef.enableMotor = true;
jointDef.lowerAngle = -0.25f * b2_pi;
jointDef.upperAngle = 0.5f * b2_pi;
jointDef.enableLimit = true;:
b2RevolutionJoint* joint = (b2RevoluteJoint*)world->CreateJoint(&jointDef);
```
Version 3.0:
```c
b2Vec2 pivot = {-10.0f, 20.5f};
b2RevoluteJointDef jointDef = b2DefaultRevoluteJointDef();
jointDef.bodyIdA = groundId;
jointDef.bodyIdB = bodyId;
jointDef.localAnchorA = b2Body_GetLocalPoint(jointDef.bodyIdA, pivot);
jointDef.localAnchorB = b2Body_GetLocalPoint(jointDef.bodyIdB, pivot);
jointDef.motorSpeed = 1.0f;
jointDef.maxMotorTorque = 100.0f;
jointDef.enableMotor = true;
jointDef.lowerAngle = -0.25f * b2_pi;
jointDef.upperAngle = 0.5f * b2_pi;
jointDef.enableLimit = true;
b2JointId jointId = b2CreateRevoluteJoint(worldId, &jointDef);
```

Some of the joints have more options now. Check the code comments and samples for details.

The friction joint has been removed since it is a subset of the motor joint.

The pulley and gear joints have been removed. I'm not satisfied with how they work in 2.4 and plan to implement improved versions in the future.

### New solver
There is a new solver that uses sub-stepping called *Soft Step*. Instead of specifying velocity iterations or position iterations, you now specify the number of sub-steps.
```c
void b2World_Step(b2WorldId worldId, float timeStep, int32_t subStepCount);
```
It is recommended to start with 4 sub-steps and adjust as needed. The sub-stepping only computes contact points once per full time step, so contact events are for the full time step.

With a sub-stepping solver you need to think differently about how you interact with bodies. Externally applied impulses or velocity adjustments no longer exist after the first sub-step. So if you try to control the movement of a body by setting the velocity every time step then you may get unexpected results. You will get more predictable results by applying a force and/or torque. Forces and torques are spread across all time steps.

If you want full control over the movement of a body, considering setting the body type to `b2_kinematicBody`. Preferably this is done in the `b2BodyDef`:
```c
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_kinematicBody;
```

### Contact data
In v2.4 `b2ContactListener` provided `BeginContact`, `EndContact`, `PreSolve`, and `PostSolve`. You could also iterate over the contacts associated with a body using `b2Body::GetContactList`. The latter was rarely used due to how continuous collision worked in v2.4 meant that you could miss some contacts using `GetContactList`.

In v3.0 there is a strong emphasis on multithreading. Callbacks in multithreading are problematic for a few reasons:
  * chance of race conditions in user code
  * user code becomes non-deterministic
  * uncertain performance impact

Therefore all callbacks except `PreSolve` have been removed. Instead you can now access all events and contact data after the time step. Version 3.0 no longer uses collision sub-stepping for continuous collision. This means all contacts data are valid at the end of the time step. Just keep in mind that Box2D computes contact points at the beginning of the time step, so the contact points apply to the previous position of the body.

Here is how you access contact data in v3.0:
```c
b2ContactEvents contactEvents = b2World_GetContactEvents(worldId);
```
The contact events structure has begin and end events:
```c 
typedef struct b2ContactEvents
{
	b2ContactBeginTouchEvent* beginEvents;
	b2ContactEndTouchEvent* endEvents;
  b2ContactHitEvent* hitEvents;
	int beginCount;
	int endCount;
  int hitCount;
} b2ContactEvents;
```
You can loop through these events after the time step. These events are in deterministic order, even with multithreading. See the `sample_events.cpp` file for examples.

You may not want Box2D to save all contact events, so you can disable them for a given shape using `enableContactEvents` on `b2ShapeDef`.

If you want to access persistent contacts, you can get the data from bodies or shapes.
```c
b2ContactData contactData[10];
int count = b2Body_GetContactData(bodyId, contactData, 10);
```
```c
b2ContactData contactData[10];
int count = b2Shape_GetContactData(shapeId, contactData, 10);
```
This includes contact data for contacts reported in begin events. This data is also in deterministic order.

Pre-solve contact modification is available using a callback.
```c
typedef bool b2PreSolveFcn(b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Manifold* manifold, void* context);
void b2World_SetPreSolveCallback(b2WorldId worldId, b2PreSolveFcn* fcn, void* context);
```
You can define a pre-solve callback and register that with the world. You can also provide a context variable that will be passed back to your callback. This is **not** enough to get a pre-solve callback. You also need to enable it on your shape using `enablePreSolveEvents` in `b2ShapeDef`. This is false by default.

> Pre-solve callbacks are dangerous. You must avoid race conditions and you must understand that behavior may not be deterministic. This is especially true if you have multiple pre-solve callbacks that are sensitive to order.

### Sensors
In v2.4 sensor events were mixed in with contact events. I have split them up to make user code simpler.
```c
b2SensorEvents sensorEvents = b2World_GetSensorEvents(b2WorldId worldId);
```
Note that contact data on bodies and shapes have no information about sensors. That data only has touching contacts.

Sensor events are available to all shapes on dynamic bodies except chains. You can disable them using `enableSensorEvents` on `b2ShapeDef`.

### Queries
Version 2.4 has `b2World::QueryAABB` and `b2World::RayCast`. This functionality is largely the same in v3.0, but more features have been added such as precise overlap tests and shape casts.

Another new feature is `b2QueryFilter` which allows you to filter raycast results before they reach your callback.
This query filter is tested against `b2Filter` on shapes that the query encounters.

Ray casts now take an origin and translation rather than start and end points. This convention works better with the added shape cast functions.

### World iteration
Iterating over all bodies/shapes/joints/contacts in a world is very inefficient and has been removed from Version 3.0. Instead, you should be using `b2BodyEvents` and `b2ContactEvents`. Events are efficient and data-oriented.

### Library configuration
Version 3.0 offers more library configuration. You can override the allocator and you can intercept assertions by registering global callbacks. These are for expert users and they must be thread safe.
```c
void b2SetAllocator(b2AllocFcn* allocFcn, b2FreeFcn* freeFcn);
void b2SetAssertFcn(b2AssertFcn* assertFcn);
```


================================================
FILE: docs/overview.md
================================================
# Overview
Box2D is a 2D rigid body simulation library for games. Programmers can
use it in their games to make objects move in realistic ways and make
the game world more interactive. From the game engine's point of view,
a physics engine is a system for procedural animation.

Box2D also provides many collision routines that can be used even when
rigid body simulation is not used. There are functions for overlap and
cast queries. There is also a bounding volume hierarchy (dynamic tree)
that can be used for game specific spatial sorting needs.

Box2D is written in portable C17. Most of the types defined in the
engine begin with the b2 prefix. Hopefully this is sufficient to avoid
name clashing with your application.

## Prerequisites
In this manual I'll assume you are familiar with basic physics
concepts, such as mass, force, torque, and impulses. If not, please
first consult Google search and Wikipedia.

Box2D was created as part of a physics tutorial at the Game Developer
Conference. You can get these tutorials from the publications section of
[box2d.org](https://box2d.org/publications/).

Since Box2D is written in C, you are expected to be experienced in C
programming. Box2D should not be your first C programming project. You
should be comfortable with compiling, linking, and debugging.

> **Caution**:
> Box2D should not be your first C project. Please learn C
> programming, compiling, linking, and debugging before working with
> Box2D. There are many resources for this online.

## Scope
This manual covers the majority of the Box2D API. However, not every
aspect is covered. Please look at the Reference section and samples
application included with Box2D to learn more.

This manual is only updated with new releases. The latest version of
Box2D may be out of sync with this manual.

> **Caution**:
> This manual applies to the associated release and not necessarily the
> latest version on the main branch.

## Feedback and Bugs
Please file bugs and feature requests here:
[Box2D Issues](https://github.com/erincatto/box2d/issues)

You can help to ensure your issue gets fixed if you provide sufficient
detail. A testbed example that reproduces the problem is ideal. You can
read about the testbed later in this document.

There is also a [Discord server](https://discord.gg/NKYgCBP) and a
[subreddit](https://reddit.com/r/box2d) for Box2D. You may also use
[GitHub Discussions](https://github.com/erincatto/box2d/discussions).

## Core Concepts
Box2D works with several fundamental concepts and objects. I briefly
define these objects here and more details are given later in this
document.

### rigid body
A chunk of matter that is so strong that the distance between any two
bits of matter on the chunk is constant. They are hard like a diamond.
In the following discussion I use *body* interchangeably with rigid body.

### shape
A shape binds collision geometry to a body and adds material properties such as
density, friction, and restitution. A shape puts collision geometry into the
collision system (broad-phase) so that it can collide with other shapes.

### constraint
A constraint is a physical connection that removes degrees of freedom
from bodies. A 2D body has 3 degrees of freedom (two translation
coordinates and one rotation coordinate). If I take a body and pin it
to the wall (like a pendulum) I have constrained the body to the wall.
At this point the body can only rotate about the pin, so the constraint
has removed 2 degrees of freedom.

### contact constraint
A special constraint designed to prevent penetration of rigid bodies and
to simulate friction and restitution. You do not create contact
constraints; they are created automatically by Box2D.

### joint constraint
This is a constraint used to hold two or more bodies together. Box2D
supports several joint types: revolute, prismatic, distance, and more.
Joints may have limits, motors, and/or springs.

### joint limit
A joint limit restricts the range of motion of a joint. For example, the
human elbow only allows a certain range of angles.

### joint motor
A joint motor drives the motion of the connected bodies according to the
joint's degrees of freedom. For example, you can use a motor to drive
the rotation of an elbow. Motors have a target speed and a maximum force
or torque. The simulation will apply the force or torque required to
achieve the desired speed.

### joint spring
A joint spring has a stiffness and damping. In Box2D spring stiffness is
expressed in terms or Hertz or cycles per second. This lets you configure how
quickly a spring reacts regardless of the body masses. Joint springs also
have a damping ratio to let you specify how quickly the spring will come to
rest.

### world
A physics world is a collection of bodies, shapes, joints, and contacts
that interact together. Box2D supports the creation of multiple worlds which
are completely independent.

### solver
The physics world has a solver that is used to advance time and to
resolve contact and joint constraints. The Box2D solver is a high
performance sequential solver that operates in order N time, where N is
the number of constraints.

### continuous collision
The solver advances bodies in time using discrete time steps. Without
intervention this can lead to tunneling.
![Tunneling Effect](images/tunneling1.svg)

Box2D contains specialized algorithms to deal with tunneling. First, the
collision algorithms can interpolate the motion of two bodies to find
the first time of impact (TOI). Second, speculative collision is used to create
contact constraints between bodies before they touch.

### events
World simulation leads to the creation of events that are available at the end
of the time step:

- body movement events
- contact begin and end events
- sensor begin and end events
- contact hit events

These events allow your application to react to changes in the simulation.

## Modules
Box2D's primary purpose is to provide rigid body simulation. However,
there are math and collision features that may be useful apart from the
rigid body simulation. These are provided in the `include` directory. Anything
in the `include` directory is considered public, while everything in the `src`
directory is consider internal.

Public features are supported and you can get help with these on the Discord
server. Using internal code directly is not supported. However, feel free to
study the code and ask questions. I'm happy to share all the details of how
Box2D works internally.

## Units
Box2D works with floating point numbers and tolerances have to be used
to make Box2D perform well. These tolerances have been tuned to work
well with meters-kilogram-second (MKS) units. In particular, Box2D has
been tuned to work well with moving shapes between 0.1 and 10 meters. So
this means objects between soup cans and buses in size should work well.

Static shapes may be up to 50 meters long without trouble. If you have a
large world, you should split it up into multiple static bodies. This will
improve precision and simulation behavior.

Being a 2D physics engine, it is tempting to use pixels as your units.
Unfortunately this will lead to a poor simulation and possibly weird
behavior. An object of length 200 pixels would be seen by Box2D as the
size of a 45 story building.

> **Caution**: 
> Box2D is tuned for MKS units. Keep the size of moving objects larger than 1cm.
> You'll need to use some scaling system when
> you render your environment and actors. The Box2D samples application
> does this by using an OpenGL viewport transform. Do not use pixel units
> unless you understand the implications.

It is best to think of Box2D bodies as moving billboards upon which you
attach your artwork. The billboard may move in a unit system of meters,
but you can convert that to pixel coordinates with a simple scaling
factor. You can then use those pixel coordinates to place your sprites,
etc. You can also account for flipped coordinate axes.

Another limitation to consider is overall world size. If your world units
become larger than 12 kilometers or so, then the lost precision can affect
stability.

> **Caution**: 
> Box2D works best with world sizes less than 12 kilometers. If you are
> careful with your simulation tuning, this can be pushed up to around 24
> kilometers, which is much larger than most game worlds.

Box2D uses radians for angles. The body rotation is stored a complex number,
so when you access the angle of a body, it will be between \f$-\pi\f$ and \f$\pi\f$ radians.

> **Caution**:
> Box2D uses radians, not degrees.

## Changing the length units
Advanced users may change the length unit by calling `b2SetLengthUnitsPerMeter()`
at application startup. If you keep Box2D in a shared library, you will need
to call this if the shared library is reloaded.

If you change the length units to pixels you will need to decide how many pixels
represent a meter. You will also need to figure out reasonable values for gravity,
density, force, and torque. One of the benefits of using MKS units for physics
simulation is that you can use real world values to get reasonable results.

It is also harder to get support for using Box2D if you change the unit
system, because values are harder to communicate and may become non-intuitive.

## Ids and Definitions
Fast memory management plays a central role in the design of the Box2D
interface. When you create a world, body, shape or joint, you will receive
a handle called an *id*. These ids are opaque and are passed to various functions
to access the underlying data.

These ids provide some safety. If you use an id after it has been freed you will
usually get an assertion. All ids support 64k generations of safety. All ids
also have a corresponding function you can call to check if it is valid.

When you create a world, body, shape, or joint, you need to provide a definition structure.
These definitions contain all the information needed to build the Box2D object. By using
this approach I can prevent construction errors, keep the number of function parameters
small, provide sensible defaults, and reduce the number of accessors.

Here is an example of body creation:

```c
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.position = (b2Vec2){10.0f, 5.0f};
b2BodyId myBodyId = b2CreateBody(myWorldId, &bodyDef);
```

Notice the body definition is initialized by calling `b2DefaultBodyDef()`. This is needed
because C does not have constructors and zero initialization is generally not suitable for the definitions used in Box2D.

Also notice that the body definition is a temporary object that is fully copied into the internal
body data structures. Definitions should usually be created on the stack as temporaries.

This is how a body is destroyed:

```c
b2DestroyBody(myBodyId);
myBodyId = b2_nullBodyId;
```

Notice that the body id is set to null using the constant `b2_nullBodyId`. You should treat
ids as opaque data, however you may zero initialize all Box2D ids and they will be considered
*null*.

Shapes are created in a similar way. For example, here is how a box shape is created:

```c
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.material.friction = 0.42f;
b2Polygon box = b2MakeBox(0.5f, 0.25f);
b2ShapeId myShapeId = b2CreatePolygonShape(myBodyId, &shapeDef, &box);
```

And the shape may be destroyed as follows:

```c
b2DestroyShape(myShapeId);
myShapeId = b2_nullShapeId;
```

For convenience, Box2D will destroy all shapes on a body when the body is destroyed. You don't need to store the shape id.

There are some macros to assist using ids in logical operations.

```c
bool isNull = B2_IS_NULL(myBodyId);
bool isNonNull = B2_IS_NON_NULL(myJointId);
bool areEqual = B2_ID_EQUALS(myShapeIdA, myShapeIdB);
```


================================================
FILE: docs/reading.md
================================================
# Further Reading
- [Erin Catto's Publications](https://box2d.org/publications/)
- [Erin Catto's Blog Posts](https://box2d.org/posts/)
- Collision Detection in Interactive 3D Environments, Gino van den Bergen, 2004
- Real-Time Collision Detection, Christer Ericson, 2005


================================================
FILE: docs/release_notes_v310.md
================================================
# v3.1 Release Notes

## API Changes
- 64-bit filter categories and masks
- 64-bit dynamic tree user data
- Renamed `b2SmoothSegment` to `b2ChainSegment`
- Cast and overlap functions modified for argument consistency
- Contact begin events now provide the manifold
- More consistent functions to make polygons
- Contact events are now disabled by default
- Replaced `b2Timer` with `uint64_t`
- Shape material properties now use `b2SurfaceMaterial`

## New Features
- New character mover features and sample
- Revised sensor system is now independent of body type and sleep
- Rolling resistance and tangent speed
- Friction and restitution mixing callbacks
- World explosions
- World access to the maximum linear speed
- More control over body mass updates
- Filter joint to disable collision between specific bodies
- Bodies can now have names for debugging
- Added `b2Body_SetTargetTransform` for kinematic bodies

## Improvements
- Cross-platform determinism
- Custom SSE2 and Neon for significantly improved performance
- SSE2 is the default instead of AVX2
- Removed SIMDE library dependency
- Faster ray and shape casts
- Faster continuous collision
- Each segment of a chain shape may have a different surface material
- Reduced overhead of restitution when not used
- Implemented atomic platform wrappers eliminating the `experimental:c11atomics` flag

## Bugs Fixes
- Many bug fixes based on user testing
- Fixed missing hit events
- Capsule and polygon manifold fixes
- Fixed missing contact end events
- PreSolve is now called in continuous collision
- Reduced clipping into chain shapes by fast bodies
- Friction and restitution are now remixed in the contact solver every time step
- Body move events are now correctly adjusted for time of impact

## Infrastructure
- Unit test for API coverage
- macOS and Windows samples built in GitHub actions
- CMake install
- imgui and glfw versions are now pinned in FetchContent
- Initial Emscripten support


================================================
FILE: docs/samples.md
================================================
# Samples {#samples}
Once you have conquered the HelloWorld example, you should start looking
at Box2D's samples application. The samples application is a testing framework and demo
environment. Here are some of the features:
- Camera with pan and zoom
- Mouse dragging of dynamic bodies
- Many samples in a tree view
- GUI for selecting samples, parameter tuning, and debug drawing options
- Pause and single step simulation
- Multithreading and performance data

![Box2D Samples](images/samples.png)

The samples application has many examples of Box2D usage in the test cases and the
framework itself. I encourage you to explore and tinker with the samples
as you learn Box2D.

Note: the sample application is written using [GLFW](https://www.glfw.org),
[imgui](https://github.com/ocornut/imgui), and [enkiTS](https://github.com/dougbinks/enkiTS).
The samples app is not part of the Box2D library. The Box2D library is agnostic about rendering.
As shown by the HelloWorld example, you don't need a renderer to use Box2D.


================================================
FILE: docs/simulation.md
================================================
# Simulation
Rigid body simulation is the primary feature of Box2D. It is the most complex part of
Box2D and is the part you will likely interact with the most. Simulation sits on top of
the foundation and collision layers, so you should be somewhat familiar with those by now.

Rigid body simulation contains:
- worlds
- bodies
- shapes
- contacts
- joints
- events

There are many dependencies between these objects so it is difficult to
describe one without referring to another. In the following, you
may see some references to objects that have not been described yet.
Therefore, you may want to quickly skim this section before reading it
closely.

## Ids
Box2D has a C interface. Typically in a C/C++ library when you create an object with a long lifetime
you will keep a pointer (or smart pointer) to the object.

Box2D works differently. Instead of pointers, you are given an *id* when you create an object.
This *id* acts as a [handle](https://en.wikipedia.org/wiki/Handle_(computing)) which helps avoid
problems with [dangling pointers](https://en.wikipedia.org/wiki/Dangling_pointer).

This also allows Box2D to use [data-oriented design](https://en.wikipedia.org/wiki/Data-oriented_design) internally.
This helps to reduce cache misses drastically and also allows for [SIMD](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data) optimizations.

So you will be dealing with `b2WorldId`, `b2BodyId`, etc. These are small opaque structures that you
will pass around by value, just like pointers. Box2D creation functions return an id. Functions
that operate on Box2D objects take ids.

```c
b2BodyId myBodyId = b2CreateBody(myWorldId, &myBodyDef);
```

There are functions to check if an id is valid. Box2D functions will assert if you use an invalid id.
This makes debugging easier than using dangling pointers.

```c
if (b2Body_IsValid(myBodyId) == false)
{
    // oops
}
```

Null ids can be established in a couple ways. You can use predefined constants or zero initialization.
```c
b2BodyId myNullBodyId = b2_nullBodyId;
b2BodyId otherNullBodyId = {0};
```

You can test if an id is null using some helper macros:
```c
if (B2_IS_NULL(myBodyId))
{
    // do something
}
```

```c
if (B2_IS_NON_NULL(myShapeId))
{
    // do something
}
```

## World
The Box2D world contains the bodies and joints. It manages all aspects
of the simulation and allows for asynchronous queries (like AABB queries
and ray-casts). Much of your interactions with Box2D will be with a
world object, using `b2WorldId`.

### World Definition
Worlds are created using a *definition* structure. This is temporary structure that
you can use to configure options for world creation. You **must** initialize the world definition
using `b2DefaultWorldDef()`.

```c
b2WorldDef worldDef = b2DefaultWorldDef();
```

The world definition has lots of options, but for most you will use the defaults. You may want to set the gravity:

```c
worldDef.gravity = (b2Vec2){0.0f, -10.0f};
```

If your game doesn't need sleep, you can get a performance boost by completely disabling sleep:

```c
worldDef.enableSleep = false;
```

You can also configure multithreading to improve performance:

```c
worldDef.workerCount = 4;
worldDef.enqueueTask = myAddTaskFunction;
worldDef.finishTask = myFinishTaskFunction;
worldDef.userTaskContext = &myTaskSystem;
```

Multithreading is not required but it can improve performance substantially. Read more [here](#multi).

### World Lifetime
Creating a world is done using a world definition.

```c
b2WorldId myWorldId = b2CreateWorld(&worldDef);

// ... do stuff ...

b2DestroyWorld(myWorldId);

// Nullify id for safety
myWorldId = b2_nullWorldId;
```

You can create up to 128 worlds. These worlds do not interact and may be simulated in parallel.

When you destroy a world, every body, shape, and joint is also destroyed. This is much faster
than destroying individual objects.

### Simulation
The world is used to drive the simulation. You specify a time step
and a sub-step count. For example:

```c
float timeStep = 1.0f / 60.f;
int32_t subSteps = 4;
b2World_Step(myWorldId, timeStep, subSteps);
```

After the time step you can examine your bodies and joints for
information. Most likely you will grab the position off the bodies so
that you can update your game objects and render them. Or more optimally, you
will use `b2World_GetBodyEvents()`.

You can perform the time step anywhere in your game loop, but you should be aware of the
order of things. For example, you must create bodies before the time
step if you want to get collision results for the new bodies in that
frame.

As I discussed in the [HelloWorld tutorial](#hello), you should use a fixed
time step. By using a larger time step you can improve performance in
low frame rate scenarios. But generally you should use a time steps 1/30 seconds (30Hz) or smaller.
A time step of 1/60 seconds (60Hz) will usually deliver a high quality simulation.

The sub-step count is used to increase accuracy. By sub-stepping the solver
divides up time into small increments and the bodies move by a small amount.
This allows joints and contacts to respond with finer detail. The recommended
sub-step count is 4. However, increasing the sub-step count may improve 
accuracy. For example, long joint chains will stretch less with more sub-steps.

The scissor lift sample shown [here](#samples) works better with more sub-steps
and is configured to use 8 sub-steps. With a primary time step of 1/60 seconds,
the scissor lift is taking sub-steps at 480Hz!

## Rigid Bodies
Rigid bodies, or just *bodies* have position and velocity. You can apply forces, torques,
and impulses to bodies. Bodies can be static, kinematic, or dynamic. Here
are the body type definitions:

### Body types
#b2_staticBody:
A static body does not move under simulation and behaves as if it has infinite mass.
Internally, Box2D stores zero for the mass and the inverse mass. A static body has zero
velocity. Static bodies do not collide with other static or kinematic bodies.

#b2_kinematicBody:
A kinematic body moves under simulation according to its velocity.
Kinematic bodies do not respond to forces. A kinematic body is moved by setting its
velocity. A kinematic body behaves as if it has infinite mass, however,
Box2D stores zero for the mass and the inverse mass. Kinematic bodies do
not collide with other kinematic or static bodies. Generally you should use
a kinematic body if you want a shape to be animated and not affected by
forces or collisions.

#b2_dynamicBody:
A dynamic body is fully simulated and moves according to forces and torques.
A dynamic body can collide with all body types. A dynamic body always has
finite, non-zero mass.

> **Caution**:
> Generally you should not set the transform on bodies after creation.
> Box2D treats this as a teleport and may result in undesirable behavior and/or performance problems.

Bodies carry shapes and moves them around in the world. Bodies are always
rigid bodies in Box2D. That means that two shapes attached to the same rigid body never move
relative to each other and shapes attached to the same body don't collide.

Shapes have collision geometry and density. Normally, bodies acquire
their mass properties from the shapes. However, you can override the
mass properties after a body is constructed.

You usually keep ids to all the bodies you create. This way you can
query the body positions to update the positions of your graphical
entities. You should also keep body ids so you can destroy them
when you are done with them.

### Body Definition
Before a body is created you must create a body definition (`b2BodyDef`).
The body definition holds the data needed to create and initialize a
body correctly.

Because Box2D uses a C API, a function is provided to create a default
body definition.

```c
b2BodyDef myBodyDef = b2DefaultBodyDef();
```

This ensures the body definition is valid and this initialization is **mandatory**.

Box2D copies the data out of the body definition; it does not keep a
pointer to the body definition. This means you can recycle a body
definition to create multiple bodies.

Let's go over some of the key members of the body definition.

### Body Type
As discussed previously, there are three different
body types: static, kinematic, and dynamic. b2_staticBody is the default.
You should establish the body type at creation because changing the body type
later is expensive.

```c
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
```

### Position and Angle
You can initialize the body position and angle in the body definition. This has far
better performance than creating the body at the world origin and then moving the body.

> **Caution**:
> Do not create a body at the origin and then move it. If you create
> several bodies at the origin, then performance will suffer.

A body has two main points of interest. The first point is the body's
origin. Shapes and joints are attached relative to the body's origin.
The second point of interest is the center of mass. The center of mass
is determined from the mass distribution of the attached shapes or is
explicitly set using `b2MassData`. Much of Box2D's internal computations
use the center of mass position. For example the body stores the linear
velocity for the center of mass, not the body origin.

![Body Origin and Center of Mass](images/center_of_mass.svg)

When you are building the body definition, you may not know where the
center of mass is located. Therefore you specify the position of the
body's origin. You may also specify the body's angle in radians. If you later
change the mass properties of the body, then the center of mass may move
on the body, but the origin position and body angle does not change and the attached
shapes and joints do not move.

```c
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.position = (b2Vec2){0.0f, 2.0f};
bodyDef.angle = 0.25f * b2_pi;
```

A rigid body is a frame of reference. You can define shapes and
joints in that frame. Those shapes and joint anchors never move in the
local frame of the body.

### Damping
Damping is used to reduce the world velocity of bodies. Damping is
different than friction because friction only occurs with contact.
Damping is not a replacement for friction and the two effects are
used together.

Damping parameter are non-negative. Normally you will use a
damping value between 0 and 1. I generally do not use linear damping
because it makes bodies look like they are floating.

```c
bodyDef.linearDamping = 0.0f;
bodyDef.angularDamping = 0.1f;
```

Damping is approximated to improve performance. At small damping
values the damping effect is mostly independent of the time step. At
larger damping values, the damping effect will vary with the time step.
This is not an issue if you use a fixed time step (recommended).

Here's some math for the curious. A first-order differential equation for velocity damping is:

\f[
\frac{dv}{dt} + c v = 0
\f]

The solution with initial velocity \f$v_0\f$ is
\f[
v = v_0 e^{-c t}
\f]

Across a single time step \f$h\f$ the velocity evolves like so
\f[
v(t + h) = v_0 e^{-c (t + h)} = v_0 e^{-c t} e^{-c h} = v(t) e^{-c h}
\f]

Using the [Pade approximation](https://en.wikipedia.org/wiki/Pad%C3%A9_table) for the
exponential function gives the update formula:
\f[
v(t + h) \approx \frac{1}{1 + c h} v(t)
\f]

This is the formula used in the Box2D solver.

### Gravity Scale
You can use the gravity scale to adjust the gravity on a single body. Be
careful though, a large gravity magnitude can decrease stability.

```c
// Set the gravity scale to zero so this body will float
bodyDef.gravityScale = 0.0f;
```

### Sleep Parameters
What does sleep mean? Well it is expensive to simulate bodies, so the
less we have to simulate the better. When a body comes to rest we would
like to stop simulating it.

When Box2D determines that a body (or group of bodies) has come to rest,
the body enters a sleep state which has very little CPU overhead. If a
body is awake and collides with a sleeping body, then the sleeping body
wakes up. Bodies will also wake up if a joint or contact attached to
them is destroyed. You can also wake a body manually.

The body definition lets you specify whether a body can sleep and
whether a body is created sleeping.

```c
bodyDef.enableSleep = true;
bodyDef.isAwake = true;
```

The `isAwake` flag is ignored if `enableSleep` is false.

### Fixed Rotation
You may want a rigid body, such as a character, to have a fixed
rotation. Such a body does not rotate, even under load. You can use
the fixed rotation setting to achieve this:

```c
bodyDef.fixedRotation = true;
```

The fixed rotation flag causes the rotational inertia and its inverse to
be set to zero.

### Bullets {#bullets}
Game simulation usually generates a sequence of transforms that are played
at some frame rate. This is called discrete simulation. In discrete
simulation, rigid bodies can move by a large amount in one time step. If
a physics engine doesn't account for the large motion, you may see some
objects incorrectly pass through each other. This effect is called
*tunneling*.

By default, Box2D uses continuous collision detection (CCD) to prevent
dynamic bodies from tunneling through static bodies. This is done by
sweeping shapes from their old position to their new positions. The
engine looks for new collisions during the sweep and computes the time
of impact (TOI) for these collisions. Bodies are moved to their first
TOI at the end of the time step.

Normally CCD is not used between dynamic bodies. This is done to keep
performance reasonable. In some game scenarios you need dynamic bodies
to use CCD. For example, you may want to shoot a high speed bullet at a
stack of dynamic bricks. Without CCD, the bullet might tunnel through
the bricks.

Fast moving objects in Box2D can be configured as *bullets*. Bullets will
perform CCD with all body types, but **not** other bullets. You should decide what
bodies should be bullets based on your game design. If you decide a body
should be treated as a bullet, use the following setting.

```c
bodyDef.isBullet = true;
```

The bullet flag only affects dynamic bodies. I recommend using bullets sparingly.

### Disabling
You may wish a body to be created but not participate in collision or
simulation. This state is similar to sleeping except the body will not be
woken by other bodies and the body's shapes will not collide with anything.
This means the body will not participate in collisions, ray
casts, etc.

You can create a body as disabled and later enable it.

```c
bodyDef.isEnabled = false;

// Later ...
b2Body_Enable(myBodyId);
```

Joints may be connected to disabled bodies. These joints will not be
simulated. You should be careful when you enable a body that its
joints are not distorted.

Note that enabling a body is almost as expensive as creating the body
from scratch. So you should not use body disabling for streaming worlds. Instead, use
creation/destruction for streaming worlds to save memory.

Body disabling is a convenience and is generally not good for performance.

### User Data
User data is a void pointer. This gives you a hook to link your
application objects to bodies. You should be consistent to use the same
object type for all body user data.

```c
bodyDef.userData = &myGameObject;
```

This is useful when you receive results from a query such as a ray-cast
or event and you want to get back to your game object. You can acquire the
use data from a body using `b2Body_GetUserData()`.

### Body Lifetime
Bodies are created and destroyed using a world id. This lets the world create
the body with an efficient allocator and add the body to the world data structure.

```c
b2BodyId myBodyId = b2CreateBody(myWorldId, &bodyDef);

// ... do stuff ...

b2DestroyBody(myBodyId);

// Nullify body id for safety
myBodyId = b2_nullBodyId;
```

Box2D does not keep a reference to the body definition or any of the
data it holds (except user data pointers). So you can create temporary
body definitions and reuse the same body definitions.

Box2D allows you to avoid destroying bodies by destroying the world
directly using `b2DestroyWorld()`, which does all the cleanup work for you.
However, you should be mindful to nullify body ids that you keep in your application.

When you destroy a body, the attached shapes and joints are
automatically destroyed. This has important implications for how you
manage shape and joint ids. You should nullify these ids after destroying
a body.

### Using a Body
After creating a body, there are many operations you can perform on the
body. These include setting mass properties, accessing position and
velocity, applying forces, and transforming points and vectors.

### Mass Data
A body has mass (scalar), center of mass (2-vector), and rotational
inertia (scalar). For static bodies, the mass and rotational inertia are
set to zero. When a body has fixed rotation, its rotational inertia is
zero.

Normally the mass properties of a body are established automatically
when shapes are added to the body. You can also adjust the mass of a
body at run-time. This is usually done when you have special game
scenarios that require altering the mass.

```c
b2MassData myMassData;
myMassData.mass = 10.0f;
myMassData.center = (b2Vec2){0.0f, 0.0f};
myMassData.rotationalInertia = 100.0f;
b2Body_SetMassData(myBodyId, myMassData);
```

After setting a body's mass directly, you may wish to revert to the 
mass determined by the shapes. You can do this with:

```c
b2Body_ApplyMassFromShapes(myBodyId);
```

The body's mass data is available through the following functions:

```c
float mass = b2Body_GetMass(myBodyId);
float inertia = b2Body_GetRotationalInertia(myBodyId);
b2Vec2 localCenter b2Body_GetLocalCenterOfMass(myBodyId);
b2MassData massData = b2Body_GetMassData(myBodyId);
```

### State Information
There are many aspects to the body's state. You can access this state
data through the following functions:

```c
b2Body_SetType(myBodyId, b2_kinematicBody);
b2BodyType bodyType = b2Body_GetType(myBodyId);
b2Body_SetBullet(myBodyId, true);
bool isBullet = b2Body_IsBullet(myBodyId);
b2Body_EnableSleep(myBodyId, false);
bool isSleepEnabled = b2Body_IsSleepingEnabled(myBodyId);
b2Body_SetAwake(myBodyId, true);
bool isAwake = b2Body_IsAwake(myBodyId);
b2Body_Disable(myBodyId);
b2Body_Enable(myBodyId);
bool isEnabled = b2Body_IsEnabled(myBodyId);
b2Body_SetFixedRotation(myBodyId, true);
bool isFixedRotation = b2Body_IsFixedRotation(myBodyId);
```

Please see the comments on these functions for more details.

### Position and Velocity
You can access the position and rotation of a body. This is common when
rendering your associated game object. You can also set the position and angle,
although this is less common since you will normally use Box2D to
simulate movement.

Keep in mind that the Box2D interface uses *radians*.

```c
b2Body_SetTransform(myBodyId, position, rotation);
b2Transform transform = b2Body_GetTransform(myBodyId);
b2Vec2 position = b2Body_GetPosition(myBodyId);
b2Rot rotation = b2Body_GetRotation(myBodyId);
float angleInRadians = b2Rot_GetAngle(rotation);
```

You can access the center of mass position in local and world
coordinates. Much of the internal simulation in Box2D uses the center of
mass. However, you should normally not need to access it. Instead you
will usually work with the body transform. For example, you may have a
body that is square. The body origin might be a corner of the square,
while the center of mass is located at the center of the square.

```c
b2Vec2 worldCenter = b2Body_GetWorldCenterOfMass(myBodyId);
b2Vec2 localCenter = b2Body_GetLocalCenterOfMass(myBodyId);
```

You can access the linear and angular velocity. The linear velocity is
for the center of mass. Therefore, the linear velocity may change if the
mass properties change. Since Box2D uses radians, the angular velocity is
in radians per second.

```c
b2Vec2 linearVelocity = b2Body_GetLinearVelocity(myBodyId);
float angularVelocity = b2Body_GetAngularVelocity(myBodyId);
```

You can drive a body to a specific transform. This is useful for kinematic bodies.

```c
b2Vec2 targetPosition = {42.0f, -100.0f};
b2Rot targetRotation = b2MakeRot(B2_PI);
b2Transform target = {targetPosition, targetRotation};
float timeStep = 1.0f / 60.0f;
b2Body_SetTargetTransform(myBodyId, target, timeStep);
```

### Forces and Impulses
You can apply forces, torques, and impulses to a body. When you apply a
force or an impulse, you can provide a world point where the load is
applied. This often results in a torque about the center of mass.

```c
b2Body_ApplyForce(myBodyId, force, worldPoint, wake);
b2Body_ApplyTorque(myBodyId, torque, wake);
b2Body_ApplyLinearImpulse(myBodyId, linearImpulse, worldPoint, wake);
b2Body_ApplyAngularImpulse(myBodyId, angularImpulse, wake);
```

Applying a force, torque, or impulse optionally wakes the body. If you don't
wake the body and it is asleep, then the force or impulse will be ignored.

You can also apply a force and linear impulse to the center of mass to avoid rotation.

```c
b2Body_ApplyForceToCenter(myBodyId, force, wake);
b2Body_ApplyLinearImpulseToCenter(myBodyId, linearImpulse, wake);
```

> **Caution**:
> Since Box2D uses sub-stepping, you should not apply a steady impulse
> for several frames. Instead you should apply a force which Box2D will
> spread out evenly across the sub-steps, resulting in smoother movement.

### Coordinate Transformations
The body has some utility functions to help you transform points
and vectors between local and world space. If you don't understand
these concepts, I recommend reading \"Essential Mathematics for Games and
Interactive Applications\" by Jim Van Verth and Lars Bishop.

```c
b2Vec2 worldPoint = b2Body_GetWorldPoint(myBodyId, localPoint);
b2Vec2 worldVector = b2Body_GetWorldVector(myBodyId, localVector);
b2Vec2 localPoint = b2Body_GetLocalPoint(myBodyId, worldPoint);
b2Vec2 localVector = b2Body_GetLocalVector(myBodyId, worldVector);
```

### Accessing Shapes and Joints
You can access the shapes on a body. You can get the number of shapes first.

```c
int shapeCount = b2Body_GetShapeCount(myBodyId);
```

If you have bodies with many shapes, you can allocate an array or if you
know the number is limited you can use a fixed size array.

```c
b2ShapeId shapeIds[10];
int returnCount = b2Body_GetShapes(myBodyId, shapeIds, 10);

for (int i = 0; i < returnCount; ++i)
{
    b2ShapeId shapeId = shapeIds[i];

    // do something with shapeId
}
```

You can similarly get an array of the joints on a body.

### Body Events
While you can gather transforms from all your bodies after every time step, this is inefficient.
Many bodies may not have moved because they are sleeping. Also iterating across many bodies
will have lots of cache misses.

Box2D provides `b2BodyEvents` that you can access after every call to `b2World_Step()` to get
an array of body movement events. Since this data is contiguous, it is cache friendly.

```c
b2BodyEvents events = b2World_GetBodyEvents(m_worldId);
for (int i = 0; i < events.moveCount; ++i)
{
    const b2BodyMoveEvent* event = events.moveEvents + i;
    MyGameObject* gameObject = event->userData;
    MoveGameObject(gameObject, event->transform);
    if (event->fellAsleep)
    {
        SleepGameObject(gameObject);
    }
}
```

The body event also indicates if the body fell asleep this time step. This might be useful to
optimize your application.

## Shapes
A body may have zero or more shapes. A body with multiple shapes is sometimes
called a *compound body.*

Shapes hold the following:
- a shape primitive
- density, friction, and restitution
- collision filtering flags
- parent body id
- user data
- sensor flag

These are described in the following sections.

### Shape Lifetime
Shapes are created by initializing a shape definition and a shape primitive.
These are passed to a creation function specific to each shape type.

```c
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.density = 10.0f;
shapeDef.material.friction = 0.7f;

b2Polygon box = b2MakeBox(0.5f, 1.0f);
b2ShapeId myShapeId = b2CreatePolygonShape(myBodyId, &shapeDef, &box);
```

This creates a polygon and attaches it to the body. You do not need to
store the shape id since the shape will automatically be
destroyed when the parent body is destroyed. However, you may wish to store the shape id if you plan
to change properties on it later.

You can create multiple shapes on a single body. They all can contribute
to the mass of the body. These shapes never collide with each other and may overlap.

You can destroy a shape on the parent body. You may do this to model a
breakable object. Otherwise you can just leave the shape alone and let
the body destruction take care of destroying the attached shapes.

```c
b2DestroyShape(myShapeId);
```

Material properties such as density, friction, and restitution are associated with shapes
instead of bodies. Since you can attach multiple shapes to a body, this allows for more
possible setups. For example, you can make a car that is heavier in the back.

### Density
The shape density is used to compute the mass properties of the parent
body. The density can be zero or positive. You should generally use
similar densities for all your shapes. This will improve stacking
stability.

The mass of a body is not adjusted when you set the density. You must
call `b2Body_ApplyMassFromShapes()` for this to occur. Generally you should establish
the shape density in `b2ShapeDef` and avoid modifying it later because this
can be expensive, especially on a compound body.

```c
b2Shape_SetDensity(myShapeId, 5.0f);
b2Body_ApplyMassFromShapes(myBodyId);
```

### Friction
Friction is used to make objects slide along each other realistically.
Box2D supports static and dynamic friction, but uses the same parameter
for both. Box2D attempts to simulate friction accurately and the friction
strength is proportional to the normal force. This is called [Coulomb
friction](https://en.wikipedia.org/wiki/Friction). The friction parameter
is usually set between 0 and 1, but
can be any non-negative value. A friction value of 0 turns off friction
and a value of 1 makes the friction strong. When the friction force is
computed between two shapes, Box2D must combine the friction parameters
of the two parent shapes. This is done with the
[geometric mean](https://en.wikipedia.org/wiki/Geometric_mean):

```c
float mixedFriction = sqrtf(b2Shape_GetFriction(shapeIdA) * b2Shape_GetFriction(shapeIdB));
```

If one shape has zero friction then the mixed friction will be zero.

### Restitution
[Restitution](https://en.wikipedia.org/wiki/Coefficient_of_restitution) is used to make
objects bounce. The restitution value is
usually set to be between 0 and 1. Consider dropping a ball on a table.
A value of zero means the ball won't bounce. This is called an
*inelastic* collision. A value of one means the ball's velocity will be
exactly reflected. This is called a *perfectly elastic* collision.
Restitution is combined using the following formula.

```c
float mixedRestitution = b2MaxFloat(b2Shape_GetRestitution(shapeIdA), b2Shape_GetRestitution(shapeIdB));
```

Restitution is combined this way so that you can have a bouncy super
ball without having a bouncy floor.

When a shape develops multiple contacts, restitution is simulated
approximately. This is because Box2D uses a sequential solver. Box2D
also uses inelastic collisions when the collision velocity is small.
This is done to prevent jitter. See `b2WorldDef::restitutionThreshold`.

### Friction and restitution callbacks
Advanced users can override friction and restitution mixing using b2FrictionCallback
and b2RestitutionCallback. These should be very light weight functions because they
are called frequently. See the API reference for details.

```c
float MyFrictionCallback(float frictionA, int userMaterialIdA, float frictionB, int userMaterialIdB)
{
    if (userMaterialIdA > userMaterialIdB)
    {
        return frictionA;
    }

    return frictionB;
}

b2WorldDef worldDef = b2DefaultWorldDef();
worldDef.frictionCallback = MyFrictionCallback;
```

### Filtering {#filtering}
Collision filtering allows you to efficiently prevent collision between shapes.
For example, say you make a character that rides a bicycle. You want the
bicycle to collide with the terrain and the character to collide with
the terrain, but you don't want the character to collide with the
bicycle (because they must overlap). Box2D supports such collision
filtering using categories, masks, and groups.

Box2D supports 64 collision categories. For each shape you can specify
which category it belongs to. You can also specify what other categories
this shape can collide with. For example, you could specify in a
multiplayer game that players don't collide with each other. Rather
than identifying all the situations where things should not collide, I recommend
identifying all the situations where things should collide. This way you
don't get into situations where you are using 
[double negatives](https://en.wikipedia.org/wiki/Double_negative).
You can specify which things can collide using mask bits. For example:

```c
enum MyCategories
{
    PLAYER = 0x00000002,
    MONSTER = 0x00000004,
};

b2ShapeDef playerShapeDef = b2DefaultShapeDef();
b2ShapeDef monsterShapeDef = b2DefaultShapeDef();
playerShapeDef.filter.categoryBits = PLAYER;
monsterShapeDef.filter.categoryBits = MONSTER;

// Players collide with monsters, but not with other players
playerShapeDef.filter.maskBits = MONSTER;

// Monsters collide with players and other monsters
monsterShapeDef.filter.maskBits = PLAYER | MONSTER;
```

Here is the rule for a collision to occur:

```c
uint64_t catA = shapeA.filter.categoryBits;
uint64_t maskA = shapeA.filter.maskBits;
uint64_t catB = shapeB.filter.categoryBits;
uint64_t maskB = shapeB.filter.maskBits;

if ((catA & maskB) != 0 && (catB & maskA) != 0)
{
    // shapes can collide
}
```

Another filtering feature is *collision group*.
Collision groups let you specify a group index. You can have
all shapes with the same group index always collide (positive index)
or never collide (negative index). Group indices are usually used for
things that are somehow related, like the parts of a bicycle. In the
following example, shape1 and shape2 always collide, but shape3
and shape4 never collide.

```c
shape1Def.filter.groupIndex = 2;
shape2Def.filter.groupIndex = 2;
shape3Def.filter.groupIndex = -8;
shape4Def.filter.groupIndex = -8;
```

Collisions between shapes of different group indices are filtered
according the category and mask bits. If two shapes have the
same non-zero group index, then this overrides the category and mask.
Collision groups have a higher priority than categories and masks.

Note that additional collision filtering occurs automatically in Box2D. Here is a
list:
- A shape on a static body can only collide with a dynamic body.
- A shape on a kinematic body can only collide with a dynamic body.
- Shapes on the same body never collide with each other.
- You can optionally enable/disable collision between bodies connected by a joint.

Sometimes you might need to change collision filtering after a shape
has already been created. You can get and set the `b2Filter` structure on
an existing shape using `b2Shape_GetFilter()` and
`b2Shape_SetFilter()`. Changing the filter is expensive because
it causes contacts to be destroyed.

### Chain Shapes
The chain shape provides an efficient way to connect many line segments together
to construct your static game worlds. Chain shapes automatically
eliminate ghost collisions and provide one-sided collision.

If you don't care about ghost collisions, you can create a bunch of
two-sided segment shapes. The performance is similar.

The simplest way to use chain shapes is to create loops. Simply provide an
array of vertices.

```c
b2Vec2 points[4] = {
    {1.7f, 0.0f},
    {1.0f, 0.25f},
    {0.0f, 0.0f},
    {-1.7f, 0.4f}};

b2ChainDef chainDef = b2DefaultChainDef();
chainDef.points = points;
chainDef.count = 4;

b2ChainId myChainId = b2CreateChain(myBodyId, &chainDef);

// Later ...
b2DestroyChain(myChainId);

// Nullify id for safety
myChainId = b2_nullChainId;
```

The segment normal depends on the winding order. A counter-clockwise winding order orients the normal outwards and a clockwise winding order orients the normal inwards.

![Chain Shape Outwards Loop](images/chain_loop_outwards.svg)

![Chain Shape Inwards Loop](images/chain_loop_inwards.svg)

You may have a scrolling game world and would like to connect several chains together.
You can connect chains together using ghost vertices. To do this you must have the first three or last three points of each chain overlap. See the sample `ChainLink` for details.

![Chain Shape](images/chain_shape.svg)

Self-intersection of chain shapes is not supported. It might work, it
might not. The code that prevents ghost collisions assumes there are no
self-intersections of the chain. Also, very close vertices can cause
problems. Make sure all your points are more than than about a centimeter apart.

![Self Intersection is Bad](images/self_intersect.svg)

Each segment in the chain is created as a `b2ChainSegment` shape on the body. If you have the
shape id for a chain segment shape, you can get the owning chain id. This will return `b2_nullChainId`
if the shape is not a chain segment.

```c
b2ChainId chainId = b2SHape_GetParentChain(myShapeId);
```

You cannot create a chain segment shape directly.

### Sensors
Sometimes game logic needs to know when two shapes overlap yet there
should be no collision response. This is done by using sensors. A sensor
is a shape that detects overlap but does not produce a response.

You can flag any shape as being a sensor. Sensors may be static,
kinematic, or dynamic. Remember that you may have multiple shapes per
body and you can have any mix of sensors and solid shapes. Sensors can also
detect other sensors.

```c
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.isSensor = true;
```

For both sensors and non-sensors, sensor events must also be enabled. There is a
performance cost to generate sensor events, so they are disabled by default.

```c
shapeDef.enableSensorEvents = true;
```

Sensors are processed at the end of the world step and generate begin and end
events without delay. User operations may cause overlaps to begin or end. These
are processed the next time step. Such operations include:
- destroying a body or shape
- changing a shape filter
- disabling or enabling a body
- setting a body transform
- disabling or enabling sensor events on a shape

Sensors do not detect objects that pass through the sensor shape within 
one time step. So sensors do not have continuous collision detection.
If you have fast moving object and/or small sensors then you should use a
ray or shape cast to detect these events.

You can access the current sensor overlaps. Be careful because some shape ids may
be invalid due to a shape being destroyed. Use `b2Shape_IsValid` to ensure an
overlapping shape is still valid.

```cpp
// First determine the required array capacity to hold all the overlapping shape ids.
int capacity = b2Shape_GetSensorCapacity( sensorShapeId );
std::vector<b2ShapeId> overlaps;
overlaps.resize( capacity );

// Now get all overlaps and record the actual count
int count = b2Shape_GetSensorOverlaps( sensorShapeId, overlaps.data(), capacity );
overlaps.resize( count );

for ( int i = 0; i < count; ++i )
{
    b2ShapeId visitorId = overlaps[i];

    // Ensure the visitorId is valid
    if ( b2Shape_IsValid( visitorId ) == false )
    {
        continue;
    }

    // process overlap using game logic
}
```

Sensor overlap can also be determined using events, which are described below.

### Sensor Events
Sensor events are available after every call to `b2World_Step()`.
Sensor events are the best way to get information about sensors overlaps. There are
events for when a shape begins to overlap with a sensor.

```c
b2SensorEvents sensorEvents = b2World_GetSensorEvents(myWorldId);
for (int i = 0; i < sensorEvents.beginCount; ++i)
{
    b2SensorBeginTouchEvent* beginTouch = sensorEvents.beginEvents + i;
    void* myUserData = b2Shape_GetUserData(beginTouch->visitorShapeId);
    // process begin event
}
```

And there are events when a shape stops overlapping with a sensor. Be careful with end
touch events because they may be generated when shapes are destroyed. Test the shape
ids with `b2Shape_IsValid`.

```c
for (int i = 0; i < sensorEvents.endCount; ++i)
{
    b2SensorEndTouchEvent* endTouch = sensorEvents.endEvents + i;
    if (b2Shape_IsValid(endTouch->visitorShapeId))
    {
        void* myUserData = b2Shape_GetUserData(endTouch->visitorShapeId);
        // process end event
    }
}
```

Sensor events should be processed after the world step and before other game logic. This should
help you avoid processing stale data.

Sensor events are only enabled for shapes and sensors if b2ShapeDef::enableSensorEvents is set to true.

> **Note**:
> A shape cannot start or stop being a sensor. Such a feature would break
> sensor events, potentially causing bugs in game logic.

## Contacts
Contacts are internal objects created by Box2D to manage collision between pairs of
shapes. They are fundamental to rigid body simulation in games.

### Terminology
Contacts have a fair bit of terminology that are important to review.

#### contact point
A contact point is a point where two shapes touch. Box2D approximates
contact with a small number of points. Specifically, contact between
two shapes has 0, 1, or 2 points. This is possible because Box2D uses
convex shapes.

#### contact normal
A contact normal is a unit vector that points from one shape to another.
By convention, the normal points from shapeA to shapeB.

#### contact separation
Separation is the opposite of penetration. Separation is negative when
shapes overlap.

#### contact manifold
Contact between two convex polygons may generate up to 2 contact points.
Both of these points use the same normal, so they are grouped into a
contact manifold, which is an approximation of a continuous region of
contact.

#### normal impulse
The normal force is the force applied at a contact point to prevent the
shapes from penetrating. For convenience, Box2D uses impulses. The
normal impulse is just the normal force multiplied by the time step. Since
Box2D uses sub-stepping, this is the sub-step time step.

#### tangent impulse
The tangent force is generated at a contact point to simulate friction.
For convenience, this is stored as an impulse.

#### contact point id
Box2D tries to re-use the contact impulse results from a time step as the
initial guess for the next time step. Box2D uses contact point ids to match
contact points across time steps. The ids contain geometric feature
indices that help to distinguish one contact point from another.

#### speculative contact
When two shapes are close together, Box2D will create up to two contact
points even if the shapes are not touching. This lets Box2D anticipate
collision to improve behavior. Speculative contact points have positive
separation.

### Contact Lifetime
Contacts are created when two shape's AABBs (bounding boxes) begin to overlap. Sometimes
collision filtering will prevent the creation of contacts. Contacts are
destroyed with the AABBs cease to overlap.

So you might gather that there may be contacts created for shapes that
are not touching (just their AABBs). Well, this is correct. It's a
\"chicken or egg\" problem. We don't know if we need a contact object
until one is created to analyze the collision. We could delete the
contact right away if the shapes are not touching, or we can just wait
until the AABBs stop overlapping. Box2D takes the latter approach
because it lets the system cache information to improve performance.

### Contact Data
As mentioned before, the contact is created and destroyed by
Box2D automatically. Contact data is not created by the user. However, you are
able to access the contact data.

You can get contact data from shapes or bodies. The contact data
on a shape is a sub-set of the contact data on a body. The contact
data is only returned for touching contacts. Contacts that are not
touching provide no meaningful information for an application.

Contact data is returned in arrays. So first you can ask a shape or
body how much space you'll need in your array. This number is conservative
and the actual number of contacts you'll receive may be less than
this number, but never more.

```c
int shapeContactCapacity = b2Shape_GetContactCapacity(myShapeId);
int bodyContactCapacity = b2Body_GetContactCapacity(myBodyId);
```

You could allocate array space to get all the contact data in all cases, or you could use a fixed size
array and get a limited number of results.

```c
b2ContactData contactData[10];
int shapeContactCount = b2Shape_GetContactData(myShapeId, contactData, 10);
int bodyContactCount = b2Body_GetContactData(myBodyId, contactData, 10);
```

`b2ContactData` contains the two shape ids and the manifold.

```c
for (int i = 0; i < bodyContactCount; ++i)
{
    b2ContactData* data = contactData + i;
    printf("point count = %d\n", data->manifold.pointCount);
}
```

Getting contact data off shapes and bodies is not the most efficient
way to handle contact data. Instead you should use contact events.

### Contact Events

Contact events are available after each world step. Like sensor events these should be
retrieved and processed before performing other game logic. Otherwise
you may be accessing orphaned/invalid data.

You can access all contact events in a single data structure. This is much more efficient
than using functions like `b2Body_GetContactData()`.

```c
b2ContactEvents contactEvents = b2World_GetContactEvents(myWorldId);
```

None of this data applies to sensors because they are handled separately. All events involve
at least one dynamic body.

There are three kinds of contact events:
1. Begin touch events
2. End touch events
3. Hit events

#### Contact Touch Event
`b2ContactBeginTouchEvent` is recorded when two shapes begin touching. These only
contain the two shape ids.

```c
for (int i = 0; i < contactEvents.beginCount; ++i)
{
    b2ContactBeginTouchEvent* beginEvent = contactEvents.beginEvents + i;
    ShapesStartTouching(beginEvent->shapeIdA, beginEvent->shapeIdB);
}
```

`b2ContactEndTouchEvent` is recorded when two shapes stop touching. These only
contain the two shape ids.



```c
for (int i = 0; i < contactEvents.endCount; ++i)
{
    b2ContactEndTouchEvent* endEvent = contactEvents.endEvents + i;

    // Use b2Shape_IsValid because a shape may have been destroyed
    if (b2Shape_IsValid(endEvent->shapeIdA) && b2Shape_IsValid(endEvent->shapeIdB))
    {
        ShapesStopTouching(endEvent->shapeIdA, endEvent->shapeIdB);
    }
}
```

Similar to `b2SensorEndTouchEvent`, `b2ContactEndTouchEvent` may be generated due to a user operation,
such as destroying a body or shape. These events are included with simulation events after the next `b2World_Step`.

Shapes only generate begin and end touch events if `b2ShapeDef::enableContactEvents` is true.

#### Hit Events
Typically in games you are mainly concerned about getting contact events for when
two shapes collide at a significant speed so you can play a sound and/or particle effect. Hit
events are the answer for this.

```c
for (int i = 0; i < contactEvents.hitCount; ++i)
{
    b2ContactHitEvent* hitEvent = contactEvents.hitEvents + i;
    if (hitEvent->approachSpeed > 10.0f)
    {
        // play sound
    }
}
```

Shapes only generate hit events if `b2ShapeDef::enableHitEvents` is true.
I recommend you only enable this for shapes that need hit events because
it creates some overhead. Box2D also only reports hit events that have an
approach speed larger than `b2WorldDef::hitEventThreshold`.

### Contact Filtering
Often in a game you don't want all objects to collide. For example, you
may want to create a door that only certain characters can pass through.
This is called contact filtering, because some interactions are filtered
out.

Contact filtering is setup on shapes and is covered [here](#filtering).

### Advanced Contact Handling

#### Custom Filtering Callback
For the best performance, use the contact filtering provided by `b2Filter`.
However, in some cases you may need custom filtering. You can do
this by registering a custom filter callback that implements `b2CustomFilterFcn()`.

```c
bool MyCustomFilter(b2ShapeId shapeIdA, b2ShapeId shapeIdB, void* context)
{
    MyGame* myGame = context;
    return myGame->WantsCollision(shapeIdA, shapeIdB);
}

// Elsewhere
b2World_SetCustomFilterCallback(myWorldId, MyCustomFilter, myGame);
```

This function must be [thread-safe](https://en.wikipedia.org/wiki/Thread_safety) and must not read from or write to the Box2D world. Otherwise you will get a [race condition](https://en.wikipedia.org/wiki/Race_condition). 

#### Pre-Solve Callback
This is called after collision detection, but before collision
resolution. This gives you a chance to disable the contact based on the contact geometry. For example, you can implement a one-sided platform using this callback.

The contact will be re-enabled each time through collision processing,
so you will need to disable the contact every time-step. This function must be thread-safe
and must not read from or write to the Box2D world.

```c
bool MyPreSolve(b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Manifold* manifold, void* context)
{
    MyGame* myGame = context;

    if (myGame->IsHittingBelowPlatform(shapeIdA, shapeIdB, manifold))
    {
        return false;
    }

    return true;
}

// Elsewhere
b2World_SetPreSolveCallback(myWorldId, MyPreSolve, myGame);
```

Note this currently does not work with high speed collisions, so you may see a
pause in those situations.

See the `Platformer` sample for more details.

## Joints
Joints are used to constrain bodies to the world or to each other.
Typical examples in games include ragdolls, teeters, and pulleys. Joints
can be combined in many different ways to create interesting motions.

Some joints provide limits so you can control the range of motion. Some
joints provide motors which can be used to drive the joint at a
prescribed speed until a prescribed force/torque is exceeded. And some
joints provide springs with damping.

Joint motors can be used in many ways. You can use motors to control
position by specifying a joint velocity that is proportional to the
difference between the actual and desired position. You can also use
motors to simulate joint friction: set the joint velocity to zero and
provide a small, but significant maximum motor force/torque. Then the
motor will attempt to keep the joint from moving until the load becomes
too strong.

### Joint Definition
Each joint type has an associated joint definition. All
joints are connected between two different bodies. One body may be static.
Joints between static and/or kinematic bodies are allowed, but have no
effect and use some processing time.

If a joint is connected to a disabled body, that joint is effectively disabled.
When the both bodies on a joint become enabled, the joint will automatically
be enabled as well. In other words, you do not need to explicitly enable
or disable a joint.

You can specify user data for any joint type and you can provide a flag
to prevent the attached bodies from colliding with each other. This is
the default behavior and you must set the `collideConnected`
Boolean to allow collision between two connected bodies.

Many joint definitions require that you provide some geometric data.
Often a joint will be defined by anchor points. These are points fixed
in the attached bodies. Box2D requires these points to be specified in
local coordinates. This way the joint can be specified even when the
current body transforms violate the joint constraint. Additionally, some joint
definitions need a reference angle between the bodies.
This may be necessary to constrain rotation correctly.

The rest of the joint definition data depends on the joint type. I
cover these below.

### Joint Lifetime
Joints are created using creation functions supplied for each joint type. They are destroyed
with a shared function. All joint types share a single id type `b2JointId`.

Here's an example of the lifetime of a revolute joint:

```c
b2RevoluteJointDef jointDef = b2DefaultRevoluteJointDef();
jointDef.bodyIdA = myBodyA;
jointDef.bodyIdB = myBodyB;
jointDef.localAnchorA = (b2Vec2){0.0f, 0.0f};
jointDef.localAnchorB = (b2Vec2){1.0f, 2.0f};

b2JointId myJointId = b2CreateRevoluteJoint(myWorldId, &jointDef);

// ... do stuff ...

b2DestroyJoint(myJointId);
myJointId = b2_nullJointId;
```

It is always good to nullify your ids after they are destroyed. 

Joint lifetime is related to body lifetime. Joints cannot exist detached from a body. 
So when a body is destroyed, all joints attached to that body are automatically destroyed.
This means you need to be careful to avoid using joint ids when the attached body was
destroyed. Box2D will assert if you use a dangling joint id.

> **Caution**:
> Joints are destroyed when an attached body is destroyed.

Fortunately you can check if your joint id is valid.

```c
if (b2Joint_IsValid(myJointId) == false)
{
    myJointId = b2_nullJointId;
}
```

This is certainly useful, but should not be overused because if you are creating
and destroying many joints, this may eventually alias to a different joint. All ids have
a limit of 64k generations.

### Using Joints
Many simulations create the joints and don't access them again until
they are destroyed. However, there is a lot of useful data contained in
joints that you can use to create a rich simulation.

First of all, you can get the type, bodies, anchor points, and user data from
a joint.

```c
b2JointType jointType = b2Joint_GetType(myJointId);
b2BodyId bodyIdA = b2Joint_GetBodyA(myJointId);
b2BodyId bodyIdB = b2Joint_GetBodyB(myJointId);
b2Vec2 localAnchorA = b2Joint_GetLocalAnchorA(myJointId);
b2Vec2 localAnchorB = b2Joint_GetLocalAnchorB(myJointId);
void* myUserData = b2Joint_GetUserData(myJointId);
```

All joints have a reaction force and torque. Reaction forces are
related to the [free body diagram](https://en.wikipedia.org/wiki/Free_body_diagram).
The Box2D convention is that the reaction force
is applied to body B at the anchor point. You can use reaction forces to
break joints or trigger other game events. These functions may do some
computations, so don't call them if you don't need the result.

```c
b2Vec2 force = b2Joint_GetConstraintForce(myJointId);
float torque = b2Joint_GetConstraintTorque(myJointId);
```

See the sample `BreakableJoint` for more details.

### Distance Joint
One of the simplest joints is a distance joint which says that the
distance between two points on two bodies must be constant. When you
specify a distance joint the two bodies should already be in place. Then
you specify the two anchor points in local coordinates. The first anchor
point is connected to body A, and the second anchor point is connected
to body B. These points imply the length of the distance constraint.

![Distance Joint](images/distance_joint.svg)

Here is an example of a distance joint definition. In this case I
decided to allow the bodies to collide.

```c
b2DistanceJointDef jointDef = b2DefaultDistanceJointDef();
jointDef.bodyIdA = myBodyIdA;
jointDef.bodyIdB = myBodyIdB;
jointDef.localAnchorA = (b2Vec2){1.0f, -3.0f};
jointDef.localAnchorB = (b2Vec2){0.0f, 0.5f};
b2Vec2 anchorA = b2Body_GetWorldPoint(myBodyIdA, jointDef.localAnchorA);
b2Vec2 anchorB = b2Body_GetWorldPoint(myBodyIdB, jointDef.localAnchorB);
jointDef.length = b2Distance(anchorA, anchorB);
jointDef.collideConnected = true;

b2JointId myJointId = b2CreateDistanceJoint(myWorldId, &jointDef);
```

The distance joint can also be made soft, like a spring-damper
connection. Softness is achieved by enabling the spring and tuning two values in the definition:
Hertz and damping ratio.

```c
jointDef.enableSpring = true;
jointDef.hertz = 2.0f;
jointDef.dampingRatio = 0.5f;
```

The hertz is the frequency of a [harmonic oscillator](https://en.wikipedia.org/wiki/Harmonic_oscillator) (like a
guitar string). Typically the frequency
should be less than a half the frequency of the time step. So if you are using
a 60Hz time step, the frequency of the distance joint should be less than 30Hz.
The reason is related to the [Nyquist frequency](https://en.wikipedia.org/wiki/Nyquist_frequency).

The damping ratio controls how fast the oscillations dissipate. A damping
ratio of one is [critical damping](https://en.wikipedia.org/wiki/Damping) and prevents
oscillation.

It is also possible to define a minimum and maximum length for the distance joint.
You can even motorize the distance joint to adjust its length dynamically.
See `b2DistanceJointDef` and the `DistanceJoint` sample for details.

### Revolute Joint
A revolute joint forces two bodies to share a common anchor point, often
called a hinge point or pivot. The revolute joint has a single degree of freedom:
the relative rotation of the two bodies. This is called the joint angle.

![Revolute Joint](images/revolute_joint.svg)

Like all joints, the anchor points are specified in local coordinates.
However, you can use the body utility functions to simplify this.

```c
b2Vec2 worldPivot = {10.0f, -4.0f};
b2RevoluteJointDef jointDef = b2DefaultRevoluteJointDef();
jointDef.bodyIdA = myBodyIdA;
jointDef.bodyIdB = myBodyIdB;
jointDef.localAnchorA = b2Body_GetLocalPoint(myBodyIdA, worldPivot);
jointDef.localAnchorB = b2Body_GetLocalPoint(myBodyIdB, worldPivot);

b2JointId myJointId = b2CreateRevoluteJoint(myWorldId, &jointDef);
```

The revolute joint angle is positive when bodyB rotates counter-clockwise
about the
anchor point. Like all angles in Box2D, the revolute angle is measured in
radians. By convention the revolute joint angle is zero when the two bodies
have equal angles. You can offset this using `b2RevoluteJointDef::referenceAngle`.

In some cases you might wish to control the joint angle. For this, the
revolute joint can simulate a joint limit and/or a motor.

A joint limit forces the joint angle to remain between a lower and upper
angle. The limit will apply as much torque as needed to make this
happen. The limit range should include zero, otherwise the joint will
lurch when the simulation begins. The lower and upper limit are relative to
the reference angle.

A joint motor allows you to specify the joint speed. The speed can be negative or
positive. A motor can have infinite force, but this is usually not desirable. Recall the eternal
question:

> *What happens when an irresistible force meets an immovable object?*

I can tell you it's not pretty. So you can provide a maximum torque for
the joint motor. The joint motor will maintain the specified speed
unless the required torque exceeds the specified maximum. When the
maximum torque is exceeded, the joint will slow down and can even
reverse.

You can use a joint motor to simulate joint friction. Just set the joint
speed to zero, and set the maximum torque to some small, but significant
value. The motor will try to prevent the joint from rotating, but will
yield to a significant load.

Here's a revision of the revolute joint definition above; this time the
joint has a limit and a motor enabled. The motor is setup to simulate
joint friction.

```c
b2Vec2 worldPivot = {10.0f, -4.0f};
b2RevoluteJointDef jointDef = b2DefaultRevoluteJointDef();
jointDef.bodyIdA = myBodyIdA;
jointDef.bodyIdB = myBodyIdB;
jointDef.localAnchorA = b2Body_GetLocalPoint(myBodyIdA, worldPivot);
jointDef.localAnchorB = b2Body_GetLocalPoint(myBodyIdB, worldPivot);
jointDef.lowerAngle = -0.5f * b2_pi; // -90 degrees
jointDef.upperAngle = 0.25f * b2_pi; // 45 degrees
jointDef.enableLimit = true;
jointDef.maxMotorTorque = 10.0f;
jointDef.motorSpeed = 0.0f;
jointDef.enableMotor = true;
```
You can access a revolute joint's angle, speed, and motor torque.

```c
float angleInRadians = b2RevoluteJoint_GetAngle(myJointId);
float speed = b2RevoluteJoint_GetMotorSpeed(myJointId);
float currentTorque = b2RevoluteJoint_GetMotorTorque(myJointId);
```

You also update the motor parameters each step.

```c
b2RevoluteJoint_SetMotorSpeed(myJointId, 20.0f);
b2RevoluteJoint_SetMaxMotorTorque(myJointId, 100.0f);
```

Joint motors have some interesting abilities. You can update the joint
speed every time step so you can make the joint move back-and-forth like
a sine-wave or according to whatever function you want.

```c
// ... Game Loop Begin ...

b2RevoluteJoint_SetMotorSpeed(myJointId, cosf(0.5f * time));

// ... Game Loop End ...
```

You can also use joint motors to track a desired joint angle. For example:

```c
// ... Game Loop Begin ...

float angleError = b2RevoluteJoint_GetAngle(myJointId) - angleTarget;
float gain = 0.1f;
b2RevoluteJoint_SetMotorSpeed(myJointId, -gain * angleError);

// ... Game Loop End ...
```

Generally your gain parameter should not be too large. Otherwise your
joint may become unstable.

### Prismatic Joint
A prismatic joint allows for relative translation of two bodies along a
local axis. A prismatic joint prevents relative rotation. Therefore,
a prismatic joint has a single degree of freedom.

![Prismatic Joint](images/prismatic_joint.svg)

The prismatic joint definition is similar to the revolute joint
description; just substitute translation for angle and force for torque.
Using this analogy provides an example prismatic joint definition with a
joint limit and a friction motor:

```c
b2Vec2 worldPivot = {10.0f, -4.0f};
b2Vec2 worldAxis = {1.0f, 0.0f};
b2PrismaticJointDef jointDef = b2DefaultPrismaticJointDef();
jointDef.bodyIdA = myBodyIdA;
jointDef.bodyIdB = myBodyIdB;
jointDef.localAnchorA = b2Body_GetLocalPoint(myBodyIdA, worldPivot);
jointDef.localAnchorB = b2Body_GetLocalPoint(myBodyIdB, worldPivot);
jointDef.localAxisA = b2Body_GetLocalVector(myBodyIdA, worldAxis);
jointDef.lowerTranslation = -5.0f;
jointDef.upperTranslation = 2.5f;
jointDef.enableLimit = true;
jointDef.maxMotorForce = 1.0f;
jointDef.motorSpeed = 0.0f;
jointDef.enableMotor = true;
```

The revolute joint has an implicit axis coming out of the screen. The
prismatic joint needs an explicit axis parallel to the screen. This axis
is fixed in body A.

The prismatic joint translation is zero when the anchor points overlap. I recommend
to have the prismatic anchor points close to the center of mass of the two bodies.
This will improve joint stiffness.

Using a prismatic joint is similar to using a revolute joint. Here are
the relevant member functions:

```c
float PrismaticJoint::GetJointTranslation() const;
float PrismaticJoint::GetJointSpeed() const;
float PrismaticJoint::GetMotorForce() const;
void PrismaticJoint::SetMotorSpeed(float speed);
void PrismaticJoint::SetMotorForce(float force);
```

### Mouse Joint
The mouse joint is used in the samples to manipulate bodies with the
mouse. It attempts to drive a point on a body towards the current
position of the cursor. There is no restriction on rotation.

The mouse joint definition has a target point, maximum force, Hertz,
and damping ratio. The target point initially coincides with the body's
anchor point. The maximum force is used to prevent violent reactions
when multiple dynamic bodies interact. You can make this as large as you
like. The frequency and damping ratio are used to create a spring/damper
effect similar to the distance joint.

### Weld Joint
The weld joint attempts to constrain all relative motion between two
bodies. See the `Cantilever` sample to see how the weld joint
behaves.

It is tempting to use the weld joint to define breakable structures.
However, the Box2D solver is approximate so the joints can be soft in some
cases regardless of the joint settings. So chains of bodies connected by weld
joints may flex.

See the `ContactEvent` sample for an example of how to merge and split bodies
without using the weld joint.

### Motor Joint
A motor joint lets you control the motion of a body by specifying target
position and rotation offsets. You can set the maximum motor force and
torque that will be applied to reach the target position and rotation.
If the body is blocked, it will stop and the contact forces will be
proportional the maximum motor force and torque. See `b2MotorJointDef` and
the `MotorJoint` sample for details.

### Wheel Joint
The wheel joint restricts a point on bodyB to a line on bodyA. The wheel
joint also provides a suspension spring and a motor. See the `Driving` sample
for details.

![Wheel Joint](images/wheel_joint.svg)

The wheel joint is designed specifically for vehicles. It provides a translation
and rotation. The translation has a spring and damper to simulate the vehicle
suspension. The rotation allows the wheel to rotate. You can specify an rotational
motor to drive the wheel and to apply braking. See `b2WheelJointDef` and the `Drive`
sample for details.

You may also use the wheel joint where you want free rotation and translation along
an axis. See the `ScissorLift` sample for details.

## Spatial Queries {#spatial}
Spatial queries allow you to inspect the world geometrically. There are overlap queries,
ray-casts, and shape-casts. These allow you to do things like:
- find a treasure chest near the player
- shoot a laser beam and destroy all asteroids in the path
- throw a grenade that is represented as a circle moving along a parabolic path

### Overlap Queries
Sometimes you want to determine all the shapes in a region. The world has a fast
log(N) method for this using the broad-phase data structure. Box2D provides these
overlap tests:
- axis-aligned bound box (AABB) overlap
- shape proxy overlap

#### Query Filtering
A basic understanding of query filtering is needed before considering the specific queries.
Shape versus shape filtering was discussed [here](#filtering). A similar setup is used
for queries. This lets your queries only consider certain categories of shapes, it also
lets your shapes ignore certain queries.

Just like shapes, queries themselves can have a category. For example, you can have a `CAMERA`
or `PROJECTILE` category.

```c
enum MyCategories
{
    STATIC = 0x00000001,
    PLAYER = 0x00000002,
    MONSTER = 0x00000004,
    WINDOW = 0x00000008,
    CAMERA = 0x00000010,
    PROJECTILE = 0x00000020,
};

// Grenades collide with the static world, monsters, and windows but
// not players or other projectiles.
b2QueryFilter grenadeFilter;
grenadeFilter.categoryBits = PROJECTILE;
grenadeFilter.maskBits = STATIC | MONSTER | WINDOW;

// The view collides with the static world, monsters, and players.
b2QueryFilter viewFilter;
viewFilter.categoryBits = CAMERA;
viewFilter.maskBits = STATIC | PLAYER | MONSTER;
```

If you want to query everything you can use `b2DefaultQueryFilter()`;

#### AABB Overlap
You provide an AABB in world coordinates and an
implementation of `b2OverlapResultFcn()`. The world calls your function with each
shape whose AABB overlaps the query AABB. Return true to continue the
query, otherwise return false. For example, the following code finds all
the shapes that potentially intersect a specified AABB and wakes up
all of the associated bodies.

```c
bool MyOverlapCallback(b2ShapeId shapeId, void* context)
{
    b2BodyId bodyId = b2Shape_GetBody(shapeId);
    b2Body_SetAwake(bodyId, true);

    // Return true to continue the query.
    return true;
}

// Elsewhere ...
MyOverlapCallback callback;
b2AABB aabb;
aabb.lowerBound = (b2Vec2){-1.0f, -1.0f};
aabb.upperBound = (b2Vec2){1.0f, 1.0f};
b2QueryFilter filter = b2DefaultQueryFilter();
b2World_OverlapAABB(myWorldId, aabb, filter, MyOverlapCallback, &myGame);
```

Do not make any assumptions about the order of the callback. The order shapes
are returned to your callback may seem arbitrary.

#### Shape Overlap
The AABB overlap is very fast but not very accurate because it only considers
the shape bounding box. If you want an accurate overlap test, you can use a shape
overlap query.

The overlap function uses a `b2ShapeProxy` which is an abstract shape consisting
of some points and a radius. You can think of it as a cloud of circles that has been
_shrink wrapped_. This can represent a point, a circle, a line segment, a capsule, a polygon,
a rounded rectangle, and so on. The helper function `b2MakeProxy` takes an array of points
and a radius.

In this example, I'm creating a shape proxy from a circle and then calling `b2World_OverlapShape()`.
This takes a `b2OverlapResultFcn()` to receive results and control the search progress.

```c
b2Circle circle = {b2Vec2_zero, 0.2f};
b2ShapeProxy proxy = b2MakeProxy(&circle.center, 1, circle.radius);
b2World_OverlapShape(myWorldId, &proxy, grenadeFilter, MyOverlapCallback, &myGame);
```

### Ray-casts
You can use ray-casts to do line-of-sight checks, fire guns, etc. You
perform a ray-cast by implementing the `b2CastResultFcn()` callback
function and providing the
origin point and translation. The world calls your function with each shape
hit by the ray. Your callback is provided with the shape, the point of
intersection, the unit normal vector, and the fractional distance along
the ray. You cannot make any assumptions about the order of the points
sent to the callback. The callback may receive points that are further away
before receiving points that are closer.

You control the continuation of the ray-cast by returning a fraction.
Returning a fraction of zero indicates the ray-cast should be
terminated. A fraction of one indicates the ray-cast should continue as
if no 
Download .txt
gitextract___deiibx/

├── .clang-format
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── issue_template.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── benchmark/
│   ├── CMakeLists.txt
│   ├── amd7950x_avx2/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── amd7950x_float/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── amd7950x_sse2/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   ├── tumbler.csv
│   │   └── washer.csv
│   ├── m2air_float/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── m2air_neon/
│   │   ├── joint_grid.csv
│   │   ├── large_pyramid.csv
│   │   ├── many_pyramids.csv
│   │   ├── rain.csv
│   │   ├── smash.csv
│   │   ├── spinner.csv
│   │   └── tumbler.csv
│   ├── main.c
│   └── n100_sse2/
│       ├── joint_grid.csv
│       ├── large_pyramid.csv
│       ├── many_pyramids.csv
│       ├── rain.csv
│       ├── smash.csv
│       ├── spinner.csv
│       └── tumbler.csv
├── build.sh
├── build_emscripten.sh
├── create_sln.bat
├── deploy_docs.sh
├── docs/
│   ├── CMakeLists.txt
│   ├── FAQ.md
│   ├── character.md
│   ├── collision.md
│   ├── extra.css
│   ├── foundation.md
│   ├── hello.md
│   ├── layout.xml
│   ├── loose_ends.md
│   ├── migration.md
│   ├── overview.md
│   ├── reading.md
│   ├── release_notes_v310.md
│   ├── samples.md
│   └── simulation.md
├── extern/
│   ├── glad/
│   │   ├── include/
│   │   │   ├── KHR/
│   │   │   │   └── khrplatform.h
│   │   │   └── glad/
│   │   │       └── glad.h
│   │   └── src/
│   │       └── glad.c
│   └── jsmn/
│       └── jsmn.h
├── include/
│   └── box2d/
│       ├── base.h
│       ├── box2d.h
│       ├── collision.h
│       ├── id.h
│       ├── math_functions.h
│       └── types.h
├── samples/
│   ├── CMakeLists.txt
│   ├── car.cpp
│   ├── car.h
│   ├── container.c
│   ├── container.h
│   ├── data/
│   │   ├── background.fs
│   │   ├── background.vs
│   │   ├── circle.fs
│   │   ├── circle.vs
│   │   ├── font.fs
│   │   ├── font.vs
│   │   ├── line.fs
│   │   ├── line.vs
│   │   ├── point.fs
│   │   ├── point.vs
│   │   ├── solid_capsule.fs
│   │   ├── solid_capsule.vs
│   │   ├── solid_circle.fs
│   │   ├── solid_circle.vs
│   │   ├── solid_polygon.fs
│   │   └── solid_polygon.vs
│   ├── donut.cpp
│   ├── donut.h
│   ├── doohickey.cpp
│   ├── doohickey.h
│   ├── draw.c
│   ├── draw.h
│   ├── main.cpp
│   ├── sample.cpp
│   ├── sample.h
│   ├── sample_benchmark.cpp
│   ├── sample_bodies.cpp
│   ├── sample_character.cpp
│   ├── sample_collision.cpp
│   ├── sample_continuous.cpp
│   ├── sample_determinism.cpp
│   ├── sample_events.cpp
│   ├── sample_geometry.cpp
│   ├── sample_issues.cpp
│   ├── sample_joints.cpp
│   ├── sample_robustness.cpp
│   ├── sample_shapes.cpp
│   ├── sample_stacking.cpp
│   ├── sample_world.cpp
│   ├── shader.c
│   ├── shader.h
│   ├── stb_image_write.h
│   └── stb_truetype.h
├── shared/
│   ├── CMakeLists.txt
│   ├── benchmarks.c
│   ├── benchmarks.h
│   ├── determinism.c
│   ├── determinism.h
│   ├── human.c
│   ├── human.h
│   ├── random.c
│   └── random.h
├── src/
│   ├── CMakeLists.txt
│   ├── aabb.c
│   ├── aabb.h
│   ├── arena_allocator.c
│   ├── arena_allocator.h
│   ├── array.c
│   ├── array.h
│   ├── atomic.h
│   ├── bitset.c
│   ├── bitset.h
│   ├── body.c
│   ├── body.h
│   ├── box2d.natvis
│   ├── broad_phase.c
│   ├── broad_phase.h
│   ├── constants.h
│   ├── constraint_graph.c
│   ├── constraint_graph.h
│   ├── contact.c
│   ├── contact.h
│   ├── contact_solver.c
│   ├── contact_solver.h
│   ├── core.c
│   ├── core.h
│   ├── ctz.h
│   ├── distance.c
│   ├── distance_joint.c
│   ├── dynamic_tree.c
│   ├── geometry.c
│   ├── hull.c
│   ├── id_pool.c
│   ├── id_pool.h
│   ├── island.c
│   ├── island.h
│   ├── joint.c
│   ├── joint.h
│   ├── manifold.c
│   ├── math_functions.c
│   ├── motor_joint.c
│   ├── mover.c
│   ├── physics_world.c
│   ├── physics_world.h
│   ├── prismatic_joint.c
│   ├── revolute_joint.c
│   ├── sensor.c
│   ├── sensor.h
│   ├── shape.c
│   ├── shape.h
│   ├── solver.c
│   ├── solver.h
│   ├── solver_set.c
│   ├── solver_set.h
│   ├── table.c
│   ├── table.h
│   ├── timer.c
│   ├── types.c
│   ├── weld_joint.c
│   └── wheel_joint.c
└── test/
    ├── CMakeLists.txt
    ├── main.c
    ├── test_bitset.c
    ├── test_collision.c
    ├── test_determinism.c
    ├── test_distance.c
    ├── test_dynamic_tree.c
    ├── test_id.c
    ├── test_macros.h
    ├── test_math.c
    ├── test_shape.c
    ├── test_table.c
    └── test_world.c
Download .txt
Showing preview only (212K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2423 symbols across 107 files)

FILE: benchmark/main.c
  type Benchmark (line 34) | typedef struct Benchmark
  type TaskData (line 45) | typedef struct TaskData
  function GetNumberOfCores (line 56) | int GetNumberOfCores()
  function ExecuteRangeTask (line 73) | void ExecuteRangeTask( uint32_t start, uint32_t end, uint32_t threadInde...
  type enkiParamsTaskSet (line 90) | struct enkiParamsTaskSet
  function FinishTask (line 111) | static void FinishTask( void* userTask, void* userContext )
  function MinProfile (line 119) | static void MinProfile( b2Profile* p1, const b2Profile* p2 )
  function main (line 148) | int main( int argc, char** argv )

FILE: extern/glad/include/KHR/khrplatform.h
  type khronos_int32_t (line 150) | typedef int32_t                 khronos_int32_t;
  type khronos_uint32_t (line 151) | typedef uint32_t                khronos_uint32_t;
  type khronos_int64_t (line 152) | typedef int64_t                 khronos_int64_t;
  type khronos_uint64_t (line 153) | typedef uint64_t                khronos_uint64_t;
  type khronos_int32_t (line 177) | typedef int32_t                 khronos_int32_t;
  type khronos_uint32_t (line 178) | typedef uint32_t                khronos_uint32_t;
  type khronos_int64_t (line 179) | typedef int64_t                 khronos_int64_t;
  type khronos_uint64_t (line 180) | typedef uint64_t                khronos_uint64_t;
  type __int32 (line 189) | typedef __int32                 khronos_int32_t;
  type khronos_uint32_t (line 190) | typedef unsigned __int32        khronos_uint32_t;
  type __int64 (line 191) | typedef __int64                 khronos_int64_t;
  type khronos_uint64_t (line 192) | typedef unsigned __int64        khronos_uint64_t;
  type khronos_int32_t (line 201) | typedef int                     khronos_int32_t;
  type khronos_uint32_t (line 202) | typedef unsigned int            khronos_uint32_t;
  type khronos_int64_t (line 204) | typedef long int                khronos_int64_t;
  type khronos_uint64_t (line 205) | typedef unsigned long int       khronos_uint64_t;
  type khronos_int64_t (line 207) | typedef long long int           khronos_int64_t;
  type khronos_uint64_t (line 208) | typedef unsigned long long int  khronos_uint64_t;
  type khronos_int32_t (line 218) | typedef int                     khronos_int32_t;
  type khronos_uint32_t (line 219) | typedef unsigned int            khronos_uint32_t;
  type khronos_int32_t (line 229) | typedef int32_t                 khronos_int32_t;
  type khronos_uint32_t (line 230) | typedef uint32_t                khronos_uint32_t;
  type khronos_int64_t (line 231) | typedef int64_t                 khronos_int64_t;
  type khronos_uint64_t (line 232) | typedef uint64_t                khronos_uint64_t;
  type khronos_int8_t (line 242) | typedef signed   char          khronos_int8_t;
  type khronos_uint8_t (line 243) | typedef unsigned char          khronos_uint8_t;
  type khronos_int16_t (line 244) | typedef signed   short int     khronos_int16_t;
  type khronos_uint16_t (line 245) | typedef unsigned short int     khronos_uint16_t;
  type khronos_intptr_t (line 253) | typedef intptr_t               khronos_intptr_t;
  type khronos_uintptr_t (line 254) | typedef uintptr_t              khronos_uintptr_t;
  type khronos_intptr_t (line 256) | typedef signed   long long int khronos_intptr_t;
  type khronos_uintptr_t (line 257) | typedef unsigned long long int khronos_uintptr_t;
  type khronos_intptr_t (line 259) | typedef signed   long  int     khronos_intptr_t;
  type khronos_uintptr_t (line 260) | typedef unsigned long  int     khronos_uintptr_t;
  type khronos_ssize_t (line 264) | typedef signed   long long int khronos_ssize_t;
  type khronos_usize_t (line 265) | typedef unsigned long long int khronos_usize_t;
  type khronos_ssize_t (line 267) | typedef signed   long  int     khronos_ssize_t;
  type khronos_usize_t (line 268) | typedef unsigned long  int     khronos_usize_t;
  type khronos_float_t (line 275) | typedef          float         khronos_float_t;
  type khronos_uint64_t (line 288) | typedef khronos_uint64_t       khronos_utime_nanoseconds_t;
  type khronos_int64_t (line 289) | typedef khronos_int64_t        khronos_stime_nanoseconds_t;
  type khronos_boolean_enum_t (line 305) | typedef enum {

FILE: extern/glad/include/glad/glad.h
  type gladGLversionStruct (line 50) | struct gladGLversionStruct {
  type GLenum (line 90) | typedef unsigned int GLenum;
  type GLboolean (line 91) | typedef unsigned char GLboolean;
  type GLbitfield (line 92) | typedef unsigned int GLbitfield;
  type GLvoid (line 93) | typedef void GLvoid;
  type khronos_int8_t (line 94) | typedef khronos_int8_t GLbyte;
  type khronos_uint8_t (line 95) | typedef khronos_uint8_t GLubyte;
  type khronos_int16_t (line 96) | typedef khronos_int16_t GLshort;
  type khronos_uint16_t (line 97) | typedef khronos_uint16_t GLushort;
  type GLint (line 98) | typedef int GLint;
  type GLuint (line 99) | typedef unsigned int GLuint;
  type khronos_int32_t (line 100) | typedef khronos_int32_t GLclampx;
  type GLsizei (line 101) | typedef int GLsizei;
  type khronos_float_t (line 102) | typedef khronos_float_t GLfloat;
  type khronos_float_t (line 103) | typedef khronos_float_t GLclampf;
  type GLdouble (line 104) | typedef double GLdouble;
  type GLclampd (line 105) | typedef double GLclampd;
  type GLchar (line 108) | typedef char GLchar;
  type GLcharARB (line 109) | typedef char GLcharARB;
  type GLhandleARB (line 113) | typedef unsigned int GLhandleARB;
  type khronos_uint16_t (line 115) | typedef khronos_uint16_t GLhalf;
  type khronos_uint16_t (line 116) | typedef khronos_uint16_t GLhalfARB;
  type khronos_int32_t (line 117) | typedef khronos_int32_t GLfixed;
  type khronos_intptr_t (line 118) | typedef khronos_intptr_t GLintptr;
  type khronos_intptr_t (line 119) | typedef khronos_intptr_t GLintptrARB;
  type khronos_ssize_t (line 120) | typedef khronos_ssize_t GLsizeiptr;
  type khronos_ssize_t (line 121) | typedef khronos_ssize_t GLsizeiptrARB;
  type khronos_int64_t (line 122) | typedef khronos_int64_t GLint64;
  type khronos_int64_t (line 123) | typedef khronos_int64_t GLint64EXT;
  type khronos_uint64_t (line 124) | typedef khronos_uint64_t GLuint64;
  type khronos_uint64_t (line 125) | typedef khronos_uint64_t GLuint64EXT;
  type __GLsync (line 126) | struct __GLsync
  type _cl_context (line 127) | struct _cl_context
  type _cl_event (line 128) | struct _cl_event
  type GLhalfNV (line 133) | typedef unsigned short GLhalfNV;
  type GLintptr (line 134) | typedef GLintptr GLvdpauSurfaceNV;
  type GLubyte (line 2064) | typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name);
  type GLuint (line 2941) | typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, co...
  type GLubyte (line 3803) | typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLu...
  type const (line 4242) | typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint p...
  type const (line 4245) | typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC)(GLuint program, G...
  type const (line 4668) | typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint progr...
  type const (line 4677) | typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint pro...
  type const (line 4680) | typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuin...

FILE: extern/glad/src/glad.c
  function open_gl (line 56) | static
  function close_gl (line 71) | static
  function open_gl (line 87) | static
  function close_gl (line 118) | static
  function gladLoadGL (line 148) | int gladLoadGL(void) {
  type gladGLversionStruct (line 159) | struct gladGLversionStruct
  function get_exts (line 172) | static int get_exts(void) {
  function free_exts (line 206) | static void free_exts(void) {
  function has_ext (line 217) | static int has_ext(const char *ext) {
  function load_GL_VERSION_1_0 (line 1325) | static void load_GL_VERSION_1_0(GLADloadproc load) {
  function load_GL_VERSION_1_1 (line 1634) | static void load_GL_VERSION_1_1(GLADloadproc load) {
  function load_GL_VERSION_1_2 (line 1667) | static void load_GL_VERSION_1_2(GLADloadproc load) {
  function load_GL_VERSION_1_3 (line 1674) | static void load_GL_VERSION_1_3(GLADloadproc load) {
  function load_GL_VERSION_1_4 (line 1723) | static void load_GL_VERSION_1_4(GLADloadproc load) {
  function load_GL_VERSION_1_5 (line 1773) | static void load_GL_VERSION_1_5(GLADloadproc load) {
  function load_GL_VERSION_2_0 (line 1795) | static void load_GL_VERSION_2_0(GLADloadproc load) {
  function load_GL_VERSION_2_1 (line 1891) | static void load_GL_VERSION_2_1(GLADloadproc load) {
  function load_GL_VERSION_3_0 (line 1900) | static void load_GL_VERSION_3_0(GLADloadproc load) {
  function load_GL_VERSION_3_1 (line 1987) | static void load_GL_VERSION_3_1(GLADloadproc load) {
  function load_GL_VERSION_3_2 (line 2005) | static void load_GL_VERSION_3_2(GLADloadproc load) {
  function load_GL_VERSION_3_3 (line 2027) | static void load_GL_VERSION_3_3(GLADloadproc load) {
  function load_GL_VERSION_4_0 (line 2088) | static void load_GL_VERSION_4_0(GLADloadproc load) {
  function load_GL_VERSION_4_1 (line 2137) | static void load_GL_VERSION_4_1(GLADloadproc load) {
  function load_GL_VERSION_4_2 (line 2229) | static void load_GL_VERSION_4_2(GLADloadproc load) {
  function load_GL_VERSION_4_3 (line 2244) | static void load_GL_VERSION_4_3(GLADloadproc load) {
  function load_GL_VERSION_4_4 (line 2291) | static void load_GL_VERSION_4_4(GLADloadproc load) {
  function load_GL_VERSION_4_5 (line 2303) | static void load_GL_VERSION_4_5(GLADloadproc load) {
  function load_GL_VERSION_4_6 (line 2428) | static void load_GL_VERSION_4_6(GLADloadproc load) {
  function find_extensionsGL (line 2435) | static int find_extensionsGL(void) {
  function find_coreGL (line 2442) | static void find_coreGL(void) {
  function gladLoadGLLoader (line 2503) | int gladLoadGLLoader(GLADloadproc load) {

FILE: extern/jsmn/jsmn.h
  type jsmntype_t (line 46) | typedef enum {
  type jsmnerr (line 54) | enum jsmnerr {
  type jsmntok_t (line 69) | typedef struct jsmntok {
  type jsmn_parser (line 83) | typedef struct jsmn_parser {
  function jsmntok_t (line 106) | static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens,
  function jsmn_fill_token (line 124) | static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type,
  function jsmn_parse_primitive (line 135) | static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
  function jsmn_parse_string (line 193) | static int jsmn_parse_string(jsmn_parser *parser, const char *js,
  function JSMN_API (line 268) | JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_...
  function JSMN_API (line 459) | JSMN_API void jsmn_init(jsmn_parser *parser) {

FILE: include/box2d/base.h
  type b2Version (line 79) | typedef struct b2Version

FILE: include/box2d/collision.h
  type b2SimplexCache (line 11) | typedef struct b2SimplexCache b2SimplexCache;
  type b2Hull (line 12) | typedef struct b2Hull b2Hull;
  type b2RayCastInput (line 28) | typedef struct b2RayCastInput
  type b2ShapeProxy (line 42) | typedef struct b2ShapeProxy
  type b2ShapeCastInput (line 57) | typedef struct b2ShapeCastInput
  type b2CastOutput (line 73) | typedef struct b2CastOutput
  type b2MassData (line 92) | typedef struct b2MassData
  type b2Circle (line 105) | typedef struct b2Circle
  type b2Capsule (line 116) | typedef struct b2Capsule
  type b2Polygon (line 134) | typedef struct b2Polygon
  type b2Segment (line 153) | typedef struct b2Segment
  type b2ChainSegment (line 165) | typedef struct b2ChainSegment
  type b2Hull (line 285) | typedef struct b2Hull
  type b2SegmentDistanceResult (line 323) | typedef struct b2SegmentDistanceResult
  type b2SimplexCache (line 348) | typedef struct b2SimplexCache
  type b2DistanceInput (line 363) | typedef struct b2DistanceInput
  type b2DistanceOutput (line 382) | typedef struct b2DistanceOutput
  type b2SimplexVertex (line 393) | typedef struct b2SimplexVertex
  type b2Simplex (line 404) | typedef struct b2Simplex
  type b2ShapeCastPairInput (line 417) | typedef struct b2ShapeCastPairInput
  type b2Sweep (line 441) | typedef struct b2Sweep
  type b2TOIInput (line 454) | typedef struct b2TOIInput
  type b2TOIState (line 464) | typedef enum b2TOIState
  type b2TOIOutput (line 474) | typedef struct b2TOIOutput
  type b2ManifoldPoint (line 508) | typedef struct b2ManifoldPoint
  type b2Manifold (line 550) | typedef struct b2Manifold
  type b2DynamicTree (line 633) | typedef struct b2DynamicTree
  type b2TreeStats (line 670) | typedef struct b2TreeStats
  type b2PlaneResult (line 801) | typedef struct b2PlaneResult
  type b2CollisionPlane (line 815) | typedef struct b2CollisionPlane
  type b2PlaneSolverResult (line 832) | typedef struct b2PlaneSolverResult

FILE: include/box2d/id.h
  type b2WorldId (line 37) | typedef struct b2WorldId
  type b2BodyId (line 44) | typedef struct b2BodyId
  type b2ShapeId (line 52) | typedef struct b2ShapeId
  type b2ChainId (line 60) | typedef struct b2ChainId
  type b2JointId (line 68) | typedef struct b2JointId
  type b2ContactId (line 76) | typedef struct b2ContactId
  function B2_ID_INLINE (line 111) | B2_ID_INLINE uint32_t b2StoreWorldId( b2WorldId id )
  function B2_ID_INLINE (line 117) | B2_ID_INLINE b2WorldId b2LoadWorldId( uint32_t x )
  function B2_ID_INLINE (line 124) | B2_ID_INLINE uint64_t b2StoreBodyId( b2BodyId id )
  function B2_ID_INLINE (line 130) | B2_ID_INLINE b2BodyId b2LoadBodyId( uint64_t x )
  function B2_ID_INLINE (line 137) | B2_ID_INLINE uint64_t b2StoreShapeId( b2ShapeId id )
  function B2_ID_INLINE (line 143) | B2_ID_INLINE b2ShapeId b2LoadShapeId( uint64_t x )
  function B2_ID_INLINE (line 150) | B2_ID_INLINE uint64_t b2StoreChainId( b2ChainId id )
  function B2_ID_INLINE (line 156) | B2_ID_INLINE b2ChainId b2LoadChainId( uint64_t x )
  function B2_ID_INLINE (line 163) | B2_ID_INLINE uint64_t b2StoreJointId( b2JointId id )
  function B2_ID_INLINE (line 169) | B2_ID_INLINE b2JointId b2LoadJointId( uint64_t x )
  function B2_ID_INLINE (line 176) | B2_ID_INLINE void b2StoreContactId( b2ContactId id, uint32_t values[3] )
  function B2_ID_INLINE (line 184) | B2_ID_INLINE b2ContactId b2LoadContactId( uint32_t values[3] )

FILE: include/box2d/math_functions.h
  type b2Vec2 (line 20) | typedef struct b2Vec2
  type b2CosSin (line 28) | typedef struct b2CosSin
  type b2Rot (line 37) | typedef struct b2Rot
  type b2Transform (line 44) | typedef struct b2Transform
  type b2Mat22 (line 51) | typedef struct b2Mat22
  type b2AABB (line 58) | typedef struct b2AABB
  type b2Plane (line 65) | typedef struct b2Plane
  function B2_INLINE (line 105) | B2_INLINE int b2MinInt( int a, int b )
  function B2_INLINE (line 111) | B2_INLINE int b2MaxInt( int a, int b )
  function B2_INLINE (line 117) | B2_INLINE int b2AbsInt( int a )
  function B2_INLINE (line 123) | B2_INLINE int b2ClampInt( int a, int lower, int upper )
  function B2_INLINE (line 129) | B2_INLINE float b2MinFloat( float a, float b )
  function B2_INLINE (line 135) | B2_INLINE float b2MaxFloat( float a, float b )
  function B2_INLINE (line 141) | B2_INLINE float b2AbsFloat( float a )
  function B2_INLINE (line 147) | B2_INLINE float b2ClampFloat( float a, float lower, float upper )
  function B2_INLINE (line 163) | B2_INLINE float b2Dot( b2Vec2 a, b2Vec2 b )
  function B2_INLINE (line 169) | B2_INLINE float b2Cross( b2Vec2 a, b2Vec2 b )
  function B2_INLINE (line 181) | B2_INLINE b2Vec2 b2CrossSV( float s, b2Vec2 v )
  function B2_INLINE (line 187) | B2_INLINE b2Vec2 b2LeftPerp( b2Vec2 v )
  function B2_INLINE (line 211) | B2_INLINE b2Vec2 b2Neg( b2Vec2 a )
  function B2_INLINE (line 218) | B2_INLINE b2Vec2 b2Lerp( b2Vec2 a, b2Vec2 b, float t )
  function B2_INLINE (line 248) | B2_INLINE b2Vec2 b2Abs( b2Vec2 a )
  function B2_INLINE (line 257) | B2_INLINE b2Vec2 b2Min( b2Vec2 a, b2Vec2 b )
  function B2_INLINE (line 266) | B2_INLINE b2Vec2 b2Max( b2Vec2 a, b2Vec2 b )
  function B2_INLINE (line 275) | B2_INLINE b2Vec2 b2Clamp( b2Vec2 v, b2Vec2 a, b2Vec2 b )
  function B2_INLINE (line 284) | B2_INLINE float b2Length( b2Vec2 v )
  function B2_INLINE (line 290) | B2_INLINE float b2Distance( b2Vec2 a, b2Vec2 b )
  function B2_INLINE (line 313) | B2_INLINE bool b2IsNormalized( b2Vec2 a )
  function B2_INLINE (line 335) | B2_INLINE b2Rot b2NormalizeRot( b2Rot q )
  function B2_INLINE (line 346) | B2_INLINE b2Rot b2IntegrateRotation( b2Rot q1, float deltaAngle )
  function B2_INLINE (line 360) | B2_INLINE float b2LengthSquared( b2Vec2 v )
  function B2_INLINE (line 366) | B2_INLINE float b2DistanceSquared( b2Vec2 a, b2Vec2 b )
  function B2_INLINE (line 390) | B2_INLINE bool b2IsNormalizedRot( b2Rot q )
  function B2_INLINE (line 398) | B2_INLINE b2Rot b2InvertRot( b2Rot a )
  function B2_INLINE (line 409) | B2_INLINE b2Rot b2NLerp( b2Rot q1, b2Rot q2, float t )
  function B2_INLINE (line 427) | B2_INLINE float b2ComputeAngularVelocity( b2Rot q1, b2Rot q2, float inv_h )
  function B2_INLINE (line 444) | B2_INLINE float b2Rot_GetAngle( b2Rot q )
  function B2_INLINE (line 450) | B2_INLINE b2Vec2 b2Rot_GetXAxis( b2Rot q )
  function B2_INLINE (line 457) | B2_INLINE b2Vec2 b2Rot_GetYAxis( b2Rot q )
  function B2_INLINE (line 464) | B2_INLINE b2Rot b2MulRot( b2Rot q, b2Rot r )
  function B2_INLINE (line 478) | B2_INLINE b2Rot b2InvMulRot( b2Rot a, b2Rot b )
  function B2_INLINE (line 491) | B2_INLINE float b2RelativeAngle( b2Rot a, b2Rot b )
  function B2_INLINE (line 501) | B2_INLINE float b2UnwindAngle( float radians )
  function B2_INLINE (line 508) | B2_INLINE b2Vec2 b2RotateVector( b2Rot q, b2Vec2 v )
  function b2Vec2 (line 751) | inline b2Vec2 operator*( float a, b2Vec2 b )
  function b2Vec2 (line 757) | inline b2Vec2 operator*( b2Vec2 a, float b )

FILE: include/box2d/types.h
  type b2RayResult (line 67) | typedef struct b2RayResult
  type b2WorldDef (line 81) | typedef struct b2WorldDef
  type b2BodyType (line 155) | typedef enum b2BodyType
  type b2MotionLocks (line 171) | typedef struct b2MotionLocks
  type b2BodyDef (line 188) | typedef struct b2BodyDef
  type b2Filter (line 276) | typedef struct b2Filter
  type b2QueryFilter (line 318) | typedef struct b2QueryFilter
  type b2ShapeType (line 334) | typedef enum b2ShapeType
  type b2SurfaceMaterial (line 357) | typedef struct b2SurfaceMaterial
  type b2ShapeDef (line 389) | typedef struct b2ShapeDef
  type b2ChainDef (line 460) | typedef struct b2ChainDef
  type b2Profile (line 498) | typedef struct b2Profile
  type b2Counters (line 526) | typedef struct b2Counters
  type b2JointType (line 547) | typedef enum b2JointType
  type b2JointDef (line 562) | typedef struct b2JointDef
  type b2DistanceJointDef (line 603) | typedef struct b2DistanceJointDef
  type b2MotorJointDef (line 656) | typedef struct b2MotorJointDef
  type b2FilterJointDef (line 702) | typedef struct b2FilterJointDef
  type b2PrismaticJointDef (line 719) | typedef struct b2PrismaticJointDef
  type b2RevoluteJointDef (line 766) | typedef struct b2RevoluteJointDef
  type b2WeldJointDef (line 815) | typedef struct b2WeldJointDef
  type b2WheelJointDef (line 844) | typedef struct b2WheelJointDef
  type b2ExplosionDef (line 887) | typedef struct b2ExplosionDef
  type b2SensorBeginTouchEvent (line 929) | typedef struct b2SensorBeginTouchEvent
  type b2SensorEndTouchEvent (line 942) | typedef struct b2SensorEndTouchEvent
  type b2SensorEvents (line 959) | typedef struct b2SensorEvents
  type b2ContactBeginTouchEvent (line 975) | typedef struct b2ContactBeginTouchEvent
  type b2ContactEndTouchEvent (line 992) | typedef struct b2ContactEndTouchEvent
  type b2ContactHitEvent (line 1012) | typedef struct b2ContactHitEvent
  type b2ContactEvents (line 1040) | typedef struct b2ContactEvents
  type b2BodyMoveEvent (line 1071) | typedef struct b2BodyMoveEvent
  type b2BodyEvents (line 1082) | typedef struct b2BodyEvents
  type b2JointEvent (line 1093) | typedef struct b2JointEvent
  type b2JointEvents (line 1105) | typedef struct b2JointEvents
  type b2ContactData (line 1117) | typedef struct b2ContactData
  type b2HexColor (line 1189) | typedef enum b2HexColor
  type b2DebugDraw (line 1342) | typedef struct b2DebugDraw

FILE: samples/car.h
  function class (line 8) | class Car
  function class (line 29) | class Truck

FILE: samples/donut.h
  function class (line 8) | class Donut

FILE: samples/doohickey.h
  function class (line 8) | class Doohickey

FILE: samples/draw.c
  type RGBA8 (line 43) | typedef struct
  function RGBA8 (line 48) | static inline RGBA8 MakeRGBA8( b2HexColor c, float alpha )
  function Camera (line 58) | Camera GetDefaultCamera( void )
  function ResetView (line 68) | void ResetView( Camera* camera )
  function b2Vec2 (line 74) | b2Vec2 ConvertScreenToWorld( Camera* camera, b2Vec2 screenPoint )
  function b2Vec2 (line 91) | b2Vec2 ConvertWorldToScreen( Camera* camera, b2Vec2 worldPoint )
  function BuildProjectionMatrix (line 112) | static void BuildProjectionMatrix( Camera* camera, float* m, float zBias )
  function MakeOrthographicMatrix (line 143) | static void MakeOrthographicMatrix( float* m, float left, float right, f...
  function b2AABB (line 166) | b2AABB GetViewBounds( Camera* camera )
  type FontVertex (line 180) | typedef struct
  type Font (line 199) | typedef struct
  function Font (line 210) | Font CreateFont( const char* trueTypeFile, float fontSize )
  function DestroyFont (line 282) | void DestroyFont( Font* font )
  function AddText (line 302) | void AddText( Font* font, float x, float y, b2HexColor color, const char...
  function FlushText (line 342) | void FlushText( Font* font, Camera* camera )
  type Background (line 397) | typedef struct
  function Background (line 407) | Background CreateBackground()
  function DestroyBackground (line 439) | void DestroyBackground( Background* background )
  function RenderBackground (line 456) | void RenderBackground( Background* background, Camera* camera )
  type PointData (line 481) | typedef struct
  type PointRender (line 492) | typedef struct
  function PointRender (line 501) | PointRender CreatePointDrawData()
  function DestroyPointDrawData (line 539) | void DestroyPointDrawData( PointRender* render )
  function AddPoint (line 557) | void AddPoint( PointRender* render, b2Vec2 v, float size, b2HexColor c )
  function FlushPoints (line 563) | void FlushPoints( PointRender* render, Camera* camera )
  type VertexData (line 605) | typedef struct
  type LineRender (line 615) | typedef struct
  function LineRender (line 624) | LineRender CreateLineRender()
  function DestroyLineRender (line 660) | void DestroyLineRender( LineRender* render )
  function AddLine (line 678) | void AddLine( LineRender* render, b2Vec2 p1, b2Vec2 p2, b2HexColor c )
  function FlushLines (line 685) | void FlushLines( LineRender* render, Camera* camera )
  type CircleData (line 734) | typedef struct
  type CircleRender (line 745) | typedef struct
  function CircleRender (line 755) | CircleRender CreateCircles()
  function DestroyCircles (line 807) | void DestroyCircles( CircleRender* render )
  function AddCircle (line 825) | void AddCircle( CircleRender* render, b2Vec2 center, float radius, b2Hex...
  function FlushCircles (line 831) | void FlushCircles( CircleRender* render, Camera* camera )
  type SolidCircle (line 876) | typedef struct
  type SolidCircles (line 892) | typedef struct
  function SolidCircles (line 902) | SolidCircles CreateSolidCircles()
  function DestroySolidCircles (line 955) | void DestroySolidCircles( SolidCircles* render )
  function AddSolidCircle (line 973) | void AddSolidCircle( SolidCircles* render, b2Transform transform, float ...
  function FlushSolidCircles (line 979) | void FlushSolidCircles( SolidCircles* render, Camera* camera )
  type Capsule (line 1024) | typedef struct
  type Capsules (line 1039) | typedef struct
  function Capsules (line 1049) | Capsules CreateCapsules()
  function DestroyCapsules (line 1104) | void DestroyCapsules( Capsules* render )
  function AddCapsule (line 1122) | void AddCapsule( Capsules* render, b2Vec2 p1, b2Vec2 p2, float radius, b...
  function FlushCapsules (line 1143) | void FlushCapsules( Capsules* render, Camera* camera )
  type Polygon (line 1188) | typedef struct
  type Polygons (line 1206) | typedef struct
  function Polygons (line 1216) | Polygons CreatePolygons()
  function DestroyPolygons (line 1288) | void DestroyPolygons( Polygons* render )
  function AddPolygon (line 1306) | void AddPolygon( Polygons* render, b2Transform transform, const b2Vec2* ...
  function FlushPolygons (line 1325) | void FlushPolygons( Polygons* render, Camera* camera )
  type Draw (line 1369) | typedef struct Draw
  function Draw (line 1381) | Draw* CreateDraw( void )
  function DestroyDraw (line 1396) | void DestroyDraw( Draw* draw )
  function DrawPoint (line 1409) | void DrawPoint( Draw* draw, b2Vec2 p, float size, b2HexColor color )
  function DrawLine (line 1414) | void DrawLine( Draw* draw, b2Vec2 p1, b2Vec2 p2, b2HexColor color )
  function DrawCircle (line 1419) | void DrawCircle( Draw* draw, b2Vec2 center, float radius, b2HexColor col...
  function DrawSolidCircle (line 1424) | void DrawSolidCircle( Draw* draw, b2Transform transform, float radius, b...
  function DrawSolidCapsule (line 1429) | void DrawSolidCapsule( Draw* draw, b2Vec2 p1, b2Vec2 p2, float radius, b...
  function DrawPolygon (line 1434) | void DrawPolygon( Draw* draw, const b2Vec2* vertices, int vertexCount, b...
  function DrawSolidPolygon (line 1445) | void DrawSolidPolygon( Draw* draw, b2Transform transform, const b2Vec2* ...
  function DrawTransform (line 1451) | void DrawTransform( Draw* draw, b2Transform transform, float scale )
  function DrawBounds (line 1462) | void DrawBounds( Draw* draw, b2AABB aabb, b2HexColor color )
  function DrawScreenString (line 1475) | void DrawScreenString( Draw* draw, float x, float y, b2HexColor color, c...
  function DrawWorldString (line 1487) | void DrawWorldString( Draw* draw, Camera* camera, b2Vec2 p, b2HexColor c...
  function FlushDraw (line 1501) | void FlushDraw( Draw* draw, Camera* camera )
  function DrawBackground (line 1514) | void DrawBackground( Draw* draw, Camera* camera )

FILE: samples/draw.h
  type Camera (line 8) | typedef struct Camera
  type Draw (line 16) | typedef struct Draw Draw;

FILE: samples/main.cpp
  function MyAllocHook (line 42) | static int MyAllocHook( int allocType, void* userData, size_t size, int ...
  function IsPowerOfTwo (line 62) | inline bool IsPowerOfTwo( int32_t x )
  function FreeFcn (line 84) | void FreeFcn( void* mem, unsigned int size )
  function AssertFcn (line 95) | int AssertFcn( const char* condition, const char* fileName, int lineNumb...
  function glfwErrorCallback (line 101) | void glfwErrorCallback( int error, const char* description )
  function CompareSamples (line 106) | static int CompareSamples( const void* a, const void* b )
  function SortSamples (line 120) | static void SortSamples()
  function RestartSample (line 125) | static void RestartSample()
  function CreateUI (line 134) | static void CreateUI( GLFWwindow* window, const char* glslVersion )
  function DestroyUI (line 181) | static void DestroyUI()
  function ResizeWindowCallback (line 188) | static void ResizeWindowCallback( GLFWwindow*, int width, int height )
  function KeyCallback (line 194) | static void KeyCallback( GLFWwindow* window, int key, int scancode, int ...
  function CharCallback (line 310) | static void CharCallback( GLFWwindow* window, unsigned int c )
  function MouseButtonCallback (line 315) | static void MouseButtonCallback( GLFWwindow* window, int button, int act...
  function MouseMotionCallback (line 357) | static void MouseMotionCallback( GLFWwindow* window, double xd, double yd )
  function ScrollCallback (line 375) | static void ScrollCallback( GLFWwindow* window, double dx, double dy )
  function UpdateUI (line 393) | static void UpdateUI()
  function main (line 545) | int main( int, char** )

FILE: samples/sample.cpp
  function ReadFile (line 28) | static bool ReadFile( char*& data, int& size, const char* filename )
  function jsoneq (line 65) | static int jsoneq( const char* json, jsmntok_t* tok, const char* s )
  function DrawPolygonFcn (line 75) | void DrawPolygonFcn( const b2Vec2* vertices, int vertexCount, b2HexColor...
  function DrawSolidPolygonFcn (line 81) | void DrawSolidPolygonFcn( b2Transform transform, const b2Vec2* vertices,...
  function DrawCircleFcn (line 88) | void DrawCircleFcn( b2Vec2 center, float radius, b2HexColor color, void*...
  function DrawSolidCircleFcn (line 94) | void DrawSolidCircleFcn( b2Transform transform, float radius, b2HexColor...
  function DrawSolidCapsuleFcn (line 100) | void DrawSolidCapsuleFcn( b2Vec2 p1, b2Vec2 p2, float radius, b2HexColor...
  function DrawLineFcn (line 106) | void DrawLineFcn( b2Vec2 p1, b2Vec2 p2, b2HexColor color, void* context )
  function DrawTransformFcn (line 112) | void DrawTransformFcn( b2Transform transform, void* context )
  function DrawPointFcn (line 118) | void DrawPointFcn( b2Vec2 p, float size, b2HexColor color, void* context )
  function DrawStringFcn (line 124) | void DrawStringFcn( b2Vec2 p, const char* s, b2HexColor color, void* con...
  class SampleTask (line 207) | class SampleTask : public enki::ITaskSet
    method SampleTask (line 210) | SampleTask() = default;
    method ExecuteRange (line 212) | void ExecuteRange( enki::TaskSetPartition range, uint32_t threadIndex ...
  function FinishTask (line 244) | static void FinishTask( void* taskPtr, void* userContext )
  function TestMathCpp (line 254) | static void TestMathCpp()
  type QueryContext (line 352) | struct QueryContext
  function QueryCallback (line 358) | bool QueryCallback( b2ShapeId shapeId, void* context )
  function RegisterSample (line 849) | int RegisterSample( const char* category, const char* name, SampleCreate...

FILE: samples/sample.h
  function namespace (line 12) | namespace enki
  type ImFont (line 17) | struct ImFont
  type SampleContext (line 19) | struct SampleContext
  function class (line 50) | class Sample
  type Sample (line 114) | typedef Sample* SampleCreateFcn( SampleContext* context );
  type SampleEntry (line 118) | struct SampleEntry

FILE: samples/sample_benchmark.cpp
  class BenchmarkBarrel (line 38) | class BenchmarkBarrel : public Sample
    type ShapeType (line 41) | enum ShapeType
    method BenchmarkBarrel (line 56) | explicit BenchmarkBarrel( SampleContext* context )
    method CreateScene (line 118) | void CreateScene()
    method UpdateGui (line 311) | void UpdateGui() override
    method Sample (line 336) | static Sample* Create( SampleContext* context )
  class BenchmarkBarrel24 (line 352) | class BenchmarkBarrel24 : public Sample
    method BenchmarkBarrel24 (line 355) | explicit BenchmarkBarrel24( SampleContext* context )
    method Sample (line 427) | static Sample* Create( SampleContext* context )
  class BenchmarkTumbler (line 435) | class BenchmarkTumbler : public Sample
    method BenchmarkTumbler (line 438) | explicit BenchmarkTumbler( SampleContext* context )
    method Sample (line 450) | static Sample* Create( SampleContext* context )
  class BenchmarkWasher (line 458) | class BenchmarkWasher : public Sample
    method BenchmarkWasher (line 461) | explicit BenchmarkWasher( SampleContext* context )
    method Sample (line 473) | static Sample* Create( SampleContext* context )
  class BenchmarkManyTumblers (line 482) | class BenchmarkManyTumblers : public Sample
    method BenchmarkManyTumblers (line 485) | explicit BenchmarkManyTumblers( SampleContext* context )
    method CreateTumbler (line 521) | void CreateTumbler( b2Vec2 position, int index )
    method CreateScene (line 544) | void CreateScene()
    method UpdateGui (line 593) | void UpdateGui() override
    method Step (line 624) | void Step() override
    method Sample (line 649) | static Sample* Create( SampleContext* context )
  class BenchmarkLargePyramid (line 672) | class BenchmarkLargePyramid : public Sample
    method BenchmarkLargePyramid (line 675) | explicit BenchmarkLargePyramid( SampleContext* context )
    method Sample (line 688) | static Sample* Create( SampleContext* context )
  class BenchmarkManyPyramids (line 696) | class BenchmarkManyPyramids : public Sample
    method BenchmarkManyPyramids (line 699) | explicit BenchmarkManyPyramids( SampleContext* context )
    method Sample (line 712) | static Sample* Create( SampleContext* context )
  class BenchmarkCreateDestroy (line 720) | class BenchmarkCreateDestroy : public Sample
    method BenchmarkCreateDestroy (line 729) | explicit BenchmarkCreateDestroy( SampleContext* context )
    method CreateScene (line 760) | void CreateScene()
    method Step (line 817) | void Step() override
    method Sample (line 836) | static Sample* Create( SampleContext* context )
  class BenchmarkSleep (line 851) | class BenchmarkSleep : public Sample
    method BenchmarkSleep (line 860) | explicit BenchmarkSleep( SampleContext* context )
    method Step (line 924) | void Step() override
    method Sample (line 953) | static Sample* Create( SampleContext* context )
  class BenchmarkJointGrid (line 968) | class BenchmarkJointGrid : public Sample
    method BenchmarkJointGrid (line 971) | explicit BenchmarkJointGrid( SampleContext* context )
    method Sample (line 984) | static Sample* Create( SampleContext* context )
  class BenchmarkSmash (line 992) | class BenchmarkSmash : public Sample
    method BenchmarkSmash (line 995) | explicit BenchmarkSmash( SampleContext* context )
    method Sample (line 1007) | static Sample* Create( SampleContext* context )
  class BenchmarkCompound (line 1015) | class BenchmarkCompound : public Sample
    method BenchmarkCompound (line 1018) | explicit BenchmarkCompound( SampleContext* context )
    method Sample (line 1107) | static Sample* Create( SampleContext* context )
  class BenchmarkKinematic (line 1115) | class BenchmarkKinematic : public Sample
    method BenchmarkKinematic (line 1118) | explicit BenchmarkKinematic( SampleContext* context )
    method Sample (line 1163) | static Sample* Create( SampleContext* context )
  type QueryType (line 1171) | enum QueryType
  class BenchmarkCast (line 1178) | class BenchmarkCast : public Sample
    method BenchmarkCast (line 1181) | explicit BenchmarkCast( SampleContext* context )
    method BuildScene (line 1222) | void BuildScene()
    method UpdateGui (line 1294) | void UpdateGui() override
    type CastResult (line 1368) | struct CastResult
    method CastCallback (line 1375) | static float CastCallback( b2ShapeId shapeId, b2Vec2 point, b2Vec2 nor...
    type OverlapResult (line 1384) | struct OverlapResult
    method OverlapCallback (line 1390) | static bool OverlapCallback( b2ShapeId shapeId, void* context )
    method Step (line 1403) | void Step() override
    method Sample (line 1542) | static Sample* Create( SampleContext* context )
  class BenchmarkSpinner (line 1566) | class BenchmarkSpinner : public Sample
    method BenchmarkSpinner (line 1569) | explicit BenchmarkSpinner( SampleContext* context )
    method Step (line 1584) | void Step() override
    method Sample (line 1599) | static Sample* Create( SampleContext* context )
  class BenchmarkRain (line 1607) | class BenchmarkRain : public Sample
    method BenchmarkRain (line 1610) | explicit BenchmarkRain( SampleContext* context )
    method Step (line 1625) | void Step() override
    method Sample (line 1640) | static Sample* Create( SampleContext* context )
  class BenchmarkShapeDistance (line 1648) | class BenchmarkShapeDistance : public Sample
    method BenchmarkShapeDistance (line 1651) | explicit BenchmarkShapeDistance( SampleContext* context )
    method UpdateGui (line 1712) | void UpdateGui() override
    method Step (line 1725) | void Step() override
    method Sample (line 1772) | static Sample* Create( SampleContext* context )
  type ShapeUserData (line 1790) | struct ShapeUserData
  class BenchmarkSensor (line 1796) | class BenchmarkSensor : public Sample
    method BenchmarkSensor (line 1799) | explicit BenchmarkSensor( SampleContext* context )
    method CreateRow (line 1877) | void CreateRow( float y )
    method Step (line 1901) | void Step() override
    method Filter (line 1972) | bool Filter( b2ShapeId idA, b2ShapeId idB )
    method FilterFcn (line 1992) | static bool FilterFcn( b2ShapeId idA, b2ShapeId idB, void* context )
    method Sample (line 1998) | static Sample* Create( SampleContext* context )
  class BenchmarkCapacity (line 2019) | class BenchmarkCapacity : public Sample
    method BenchmarkCapacity (line 2022) | explicit BenchmarkCapacity( SampleContext* context )
    method Step (line 2048) | void Step() override
    method Sample (line 2099) | static Sample* Create( SampleContext* context )

FILE: samples/sample_bodies.cpp
  class BodyType (line 11) | class BodyType : public Sample
    method BodyType (line 14) | explicit BodyType( SampleContext* context )
    method UpdateGui (line 202) | void UpdateGui() override
    method Step (line 265) | void Step() override
    method Sample (line 283) | static Sample* Create( SampleContext* context )
  function FrictionCallback (line 301) | float FrictionCallback( float, uint64_t, float, uint64_t )
  function RestitutionCallback (line 306) | float RestitutionCallback( float, uint64_t, float, uint64_t )
  class Weeble (line 311) | class Weeble : public Sample
    method Weeble (line 314) | explicit Weeble( SampleContext* context )
    method UpdateGui (line 366) | void UpdateGui() override
    method Step (line 395) | void Step() override
    method Sample (line 413) | static Sample* Create( SampleContext* context )
  class Sleep (line 426) | class Sleep : public Sample
    method Sleep (line 429) | explicit Sleep( SampleContext* context )
    method ToggleInvoker (line 551) | void ToggleInvoker()
    method UpdateGui (line 571) | void UpdateGui() override
    method Step (line 618) | void Step() override
    method Sample (line 663) | static Sample* Create( SampleContext* context )
  class BadBody (line 677) | class BadBody : public Sample
    method BadBody (line 680) | explicit BadBody( SampleContext* context )
    method Step (line 733) | void Step() override
    method Sample (line 744) | static Sample* Create( SampleContext* context )
  class Pivot (line 755) | class Pivot : public Sample
    method Pivot (line 758) | explicit Pivot( SampleContext* context )
    method Step (line 802) | void Step() override
    method Sample (line 814) | static Sample* Create( SampleContext* context )
  class Kinematic (line 826) | class Kinematic : public Sample
    method Kinematic (line 829) | explicit Kinematic( SampleContext* context )
    method Step (line 855) | void Step() override
    method Sample (line 884) | static Sample* Create( SampleContext* context )
  class MixedLocks (line 897) | class MixedLocks : public Sample
    method MixedLocks (line 900) | explicit MixedLocks( SampleContext* context )
    method Sample (line 998) | static Sample* Create( SampleContext* context )
  class SetVelocity (line 1006) | class SetVelocity : public Sample
    method SetVelocity (line 1009) | explicit SetVelocity( SampleContext* context )
    method Step (line 1040) | void Step() override
    method Sample (line 1050) | static Sample* Create( SampleContext* context )
  class WakeTouching (line 1060) | class WakeTouching : public Sample
    method WakeTouching (line 1063) | explicit WakeTouching( SampleContext* context )
    method UpdateGui (line 1100) | void UpdateGui() override
    method Sample (line 1117) | static Sample* Create( SampleContext* context )

FILE: samples/sample_character.cpp
  type ShapeUserData (line 13) | struct ShapeUserData
  type CollisionBits (line 19) | enum CollisionBits : uint64_t
  type PogoShape (line 29) | enum PogoShape
  type CastResult (line 36) | struct CastResult
  function CastCallback (line 45) | static float CastCallback( b2ShapeId shapeId, b2Vec2 point, b2Vec2 norma...
  class Mover (line 56) | class Mover : public Sample
    method Mover (line 59) | explicit Mover( SampleContext* context )
    method SolveMove (line 231) | void SolveMove( float timeStep, float throttle )
    method UpdateGui (line 410) | void UpdateGui() override
    method PlaneResultFcn (line 448) | static bool PlaneResultFcn( b2ShapeId shapeId, const b2PlaneResult* pl...
    method Kick (line 472) | static bool Kick( b2ShapeId shapeId, void* context )
    method Keyboard (line 491) | void Keyboard( int key ) override
    method Step (line 506) | void Step() override
    method Sample (line 594) | static Sample* Create( SampleContext* context )
  type MoverMode (line 636) | enum MoverMode
  class Mover2 (line 643) | class Mover2 : public Sample
    method Mover (line 646) | explicit Mover( SampleContext* context )
    method UpdateFloorData (line 823) | void UpdateFloorData(float timeStep)
    method SetMode (line 898) | void SetMode(MoverMode mode)
    method ComputeVelocity (line 930) | void ComputeVelocity( float timeStep, bool keepNormalVelocity )
    method UpdateFalling (line 1071) | void UpdateFalling(float timeStep)
    method UpdateWalking (line 1096) | void UpdateWalking( float timeStep )
    method SolveMove (line 1121) | void SolveMove( float timeStep, float throttle )
    method UpdateGui (line 1359) | void UpdateGui() override
    method PlaneResultFcn (line 1390) | static bool PlaneResultFcn( b2ShapeId shapeId, const b2PlaneResult* pl...
    method Kick (line 1414) | static bool Kick( b2ShapeId shapeId, void* context )
    method Keyboard (line 1433) | void Keyboard( int key ) override
    method Step (line 1448) | void Step() override
    method Sample (line 1536) | static Sample* Create( SampleContext* context )

FILE: samples/sample_collision.cpp
  class ShapeDistance (line 17) | class ShapeDistance : public Sample
    type ShapeType (line 20) | enum ShapeType
    method ShapeDistance (line 28) | explicit ShapeDistance( SampleContext* context )
    method b2ShapeProxy (line 76) | b2ShapeProxy MakeProxy( ShapeType type, float radius )
    method DrawShape (line 117) | void DrawShape( ShapeType type, b2Transform transform, float radius, b...
    method UpdateGui (line 164) | void UpdateGui() override
    method MouseDown (line 229) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 248) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 257) | void MouseMove( b2Vec2 p ) override
    method b2Vec2 (line 271) | static b2Vec2 Weight2( float a1, b2Vec2 w1, float a2, b2Vec2 w2 )
    method b2Vec2 (line 276) | static b2Vec2 Weight3( float a1, b2Vec2 w1, float a2, b2Vec2 w2, float...
    method ComputeSimplexWitnessPoints (line 281) | void ComputeSimplexWitnessPoints( b2Vec2* a, b2Vec2* b, const b2Simple...
    method Step (line 310) | void Step() override
    method Sample (line 400) | static Sample* Create( SampleContext* context )
  type UpdateType (line 440) | enum UpdateType
  type Proxy (line 447) | struct Proxy
  class DynamicTree (line 464) | class DynamicTree : public Sample
    method DynamicTree (line 467) | explicit DynamicTree( SampleContext* context )
    method BuildTree (line 509) | void BuildTree()
    method UpdateGui (line 573) | void UpdateGui() override
    method MouseDown (line 650) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 669) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 678) | void MouseMove( b2Vec2 p ) override
    method Step (line 683) | void Step() override
    method Sample (line 826) | static Sample* Create( SampleContext* context )
  function QueryCallback (line 854) | static bool QueryCallback( int proxyId, uint64_t userData, void* context )
  function RayCallback (line 863) | static float RayCallback( const b2RayCastInput* input, int proxyId, uint...
  class RayCast (line 874) | class RayCast : public Sample
    method RayCast (line 877) | explicit RayCast( SampleContext* context )
    method UpdateGui (line 913) | void UpdateGui() override
    method MouseDown (line 955) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 979) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 989) | void MouseMove( b2Vec2 p ) override
    method DrawRay (line 1008) | void DrawRay( const b2CastOutput* output )
    method Step (line 1049) | void Step() override
    method Sample (line 1173) | static Sample* Create( SampleContext* context )
  type ShapeUserData (line 1204) | struct ShapeUserData
  type CastContext (line 1211) | struct CastContext
  function RayCastClosestCallback (line 1220) | static float RayCastClosestCallback( b2ShapeId shapeId, b2Vec2 point, b2...
  function RayCastAnyCallback (line 1248) | static float RayCastAnyCallback( b2ShapeId shapeId, b2Vec2 point, b2Vec2...
  function RayCastMultipleCallback (line 1278) | static float RayCastMultipleCallback( b2ShapeId shapeId, b2Vec2 point, b...
  function RayCastSortedCallback (line 1312) | static float RayCastSortedCallback( b2ShapeId shapeId, b2Vec2 point, b2V...
  class CastWorld (line 1372) | class CastWorld : public Sample
    type Mode (line 1375) | enum Mode
    type CastType (line 1383) | enum CastType
    method CastWorld (line 1396) | explicit CastWorld( SampleContext* context )
    method Create (line 1464) | void Create( int index )
    method CreateN (line 1538) | void CreateN( int index, int count )
    method DestroyBody (line 1546) | void DestroyBody()
    method MouseDown (line 1559) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 1578) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 1587) | void MouseMove( b2Vec2 p ) override
    method UpdateGui (line 1600) | void UpdateGui() override
    method Step (line 1677) | void Step() override
    method Sample (line 1846) | static Sample* Create( SampleContext* context )
  class OverlapWorld (line 1880) | class OverlapWorld : public Sample
    method OverlapResultFcn (line 1896) | static bool OverlapResultFcn( b2ShapeId shapeId, void* context )
    method OverlapWorld (line 1918) | explicit OverlapWorld( SampleContext* context )
    method Create (line 1977) | void Create( int index )
    method CreateN (line 2023) | void CreateN( int index, int count )
    method DestroyBody (line 2031) | void DestroyBody()
    method MouseDown (line 2044) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 2062) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 2071) | void MouseMove( b2Vec2 p ) override
    method UpdateGui (line 2084) | void UpdateGui() override
    method Step (line 2149) | void Step() override
    method Sample (line 2214) | static Sample* Create( SampleContext* context )
  class Manifold (line 2248) | class Manifold : public Sample
    method Manifold (line 2251) | explicit Manifold( SampleContext* context )
    method UpdateGui (line 2289) | void UpdateGui() override
    method MouseDown (line 2334) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 2353) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 2362) | void MouseMove( b2Vec2 p ) override
    method DrawManifold (line 2377) | void DrawManifold( const b2Manifold* manifold, b2Vec2 origin1, b2Vec2 ...
    method Step (line 2419) | void Step() override
    method Sample (line 2882) | static Sample* Create( SampleContext* context )
  class SmoothManifold (line 2913) | class SmoothManifold : public Sample
    type ShapeType (line 2916) | enum ShapeType
    method SmoothManifold (line 2922) | explicit SmoothManifold( SampleContext* context )
    method UpdateGui (line 3010) | void UpdateGui() override
    method MouseDown (line 3055) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 3074) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 3083) | void MouseMove( b2Vec2 p ) override
    method DrawManifold (line 3098) | void DrawManifold( const b2Manifold* manifold )
    method Step (line 3133) | void Step() override
    method Sample (line 3180) | static Sample* Create( SampleContext* context )
  class ShapeCast (line 3207) | class ShapeCast : public Sample
    type ShapeType (line 3210) | enum ShapeType
    method ShapeCast (line 3218) | explicit ShapeCast( SampleContext* context )
    method b2ShapeProxy (line 3301) | b2ShapeProxy MakeProxy( ShapeType type, float radius ) const
    method DrawShape (line 3342) | void DrawShape( ShapeType type, b2Transform transform, float radius, b...
    method MouseDown (line 3389) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 3420) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 3430) | void MouseMove( b2Vec2 p ) override
    method UpdateGui (line 3448) | void UpdateGui() override
    method Step (line 3500) | void Step() override
    method Sample (line 3573) | static Sample* Create( SampleContext* context )
  class TimeOfImpact (line 3608) | class TimeOfImpact : public Sample
    method TimeOfImpact (line 3611) | explicit TimeOfImpact( SampleContext* context )
    method Sample (line 3622) | static Sample* Create( SampleContext* context )
    method Step (line 3627) | void Step() override

FILE: samples/sample_continuous.cpp
  class BounceHouse (line 18) | class BounceHouse : public Sample
    type ShapeType (line 21) | enum ShapeType
    type HitEvent (line 28) | struct HitEvent
    method BounceHouse (line 35) | explicit BounceHouse( SampleContext* context )
    method Launch (line 77) | void Launch()
    method UpdateGui (line 120) | void UpdateGui() override
    method Step (line 145) | void Step() override
    method Sample (line 184) | static Sample* Create( SampleContext* context )
  class BounceHumans (line 197) | class BounceHumans : public Sample
    method BounceHumans (line 200) | explicit BounceHumans( SampleContext* context )
    method Step (line 238) | void Step() override
    method Sample (line 267) | static Sample* Create( SampleContext* context )
  class ChainDrop (line 280) | class ChainDrop : public Sample
    method ChainDrop (line 283) | explicit ChainDrop( SampleContext* context )
    method Launch (line 315) | void Launch()
    method UpdateGui (line 343) | void UpdateGui() override
    method Sample (line 363) | static Sample* Create( SampleContext* context )
  class ChainSlide (line 376) | class ChainSlide : public Sample
    method ChainSlide (line 379) | explicit ChainSlide( SampleContext* context )
    method Step (line 446) | void Step() override
    method Sample (line 453) | static Sample* Create( SampleContext* context )
  class SegmentSlide (line 461) | class SegmentSlide : public Sample
    method SegmentSlide (line 464) | explicit SegmentSlide( SampleContext* context )
    method Step (line 501) | void Step() override
    method Sample (line 508) | static Sample* Create( SampleContext* context )
  class SkinnyBox (line 516) | class SkinnyBox : public Sample
    method SkinnyBox (line 519) | explicit SkinnyBox( SampleContext* context )
    method Launch (line 551) | void Launch()
    method UpdateGui (line 600) | void UpdateGui() override
    method Step (line 621) | void Step() override
    method Sample (line 631) | static Sample* Create( SampleContext* context )
  class GhostBumps (line 647) | class GhostBumps : public Sample
    type ShapeType (line 650) | enum ShapeType
    method GhostBumps (line 657) | explicit GhostBumps( SampleContext* context )
    method CreateScene (line 679) | void CreateScene()
    method Launch (line 834) | void Launch()
    method UpdateGui (line 870) | void UpdateGui() override
    method Sample (line 924) | static Sample* Create( SampleContext* context )
  class SpeculativeFallback (line 943) | class SpeculativeFallback : public Sample
    method SpeculativeFallback (line 946) | explicit SpeculativeFallback( SampleContext* context )
    method Sample (line 984) | static Sample* Create( SampleContext* context )
  class SpeculativeSliver (line 992) | class SpeculativeSliver : public Sample
    method SpeculativeSliver (line 995) | explicit SpeculativeSliver( SampleContext* context )
    method Sample (line 1028) | static Sample* Create( SampleContext* context )
  class SpeculativeGhost (line 1037) | class SpeculativeGhost : public Sample
    method SpeculativeGhost (line 1040) | explicit SpeculativeGhost( SampleContext* context )
    method Sample (line 1077) | static Sample* Create( SampleContext* context )
  class PixelImperfect (line 1086) | class PixelImperfect : public Sample
    method PixelImperfect (line 1089) | explicit PixelImperfect( SampleContext* context )
    method Step (line 1130) | void Step() override
    method Sample (line 1142) | static Sample* Create( SampleContext* context )
  class RestitutionThreshold (line 1152) | class RestitutionThreshold : public Sample
    method RestitutionThreshold (line 1155) | explicit RestitutionThreshold( SampleContext* context )
    method Step (line 1200) | void Step() override
    method Sample (line 1212) | static Sample* Create( SampleContext* context )
  class Drop (line 1222) | class Drop : public Sample
    method Drop (line 1225) | explicit Drop( SampleContext* context )
    method Clear (line 1266) | void Clear()
    method CreateGround1 (line 1281) | void CreateGround1()
    method CreateGround2 (line 1302) | void CreateGround2()
    method CreateGround3 (line 1330) | void CreateGround3()
    method Scene1 (line 1354) | void Scene1()
    method Scene2 (line 1375) | void Scene2()
    method Scene3 (line 1398) | void Scene3()
    method Scene4 (line 1413) | void Scene4()
    method Keyboard (line 1456) | void Keyboard( int key ) override
    method Step (line 1497) | void Step() override
    method Sample (line 1544) | static Sample* Create( SampleContext* context )
  class Pinball (line 1562) | class Pinball : public Sample
    method Pinball (line 1565) | explicit Pinball( SampleContext* context )
    method Step (line 1700) | void Step() override
    method Sample (line 1716) | static Sample* Create( SampleContext* context )
  class Wedge (line 1730) | class Wedge : public Sample
    method Wedge (line 1733) | explicit Wedge( SampleContext* context )
    method Sample (line 1768) | static Sample* Create( SampleContext* context )

FILE: samples/sample_determinism.cpp
  class FallingHinges (line 17) | class FallingHinges : public Sample
    method FallingHinges (line 21) | explicit FallingHinges( SampleContext* context )
    method Step (line 39) | void Step() override
    method Sample (line 53) | static Sample* Create( SampleContext* context )

FILE: samples/sample_events.cpp
  class SensorFunnel (line 18) | class SensorFunnel : public Sample
    method SensorFunnel (line 28) | explicit SensorFunnel( SampleContext* context )
    method CreateElement (line 161) | void CreateElement()
    method DestroyElement (line 201) | void DestroyElement( int index )
    method Clear (line 217) | void Clear()
    method UpdateGui (line 237) | void UpdateGui() override
    method Step (line 261) | void Step() override
    method Sample (line 327) | static Sample* Create( SampleContext* context )
  class SensorBookend (line 342) | class SensorBookend : public Sample
    method SensorBookend (line 345) | explicit SensorBookend( SampleContext* context )
    method CreateSensor1 (line 378) | void CreateSensor1()
    method CreateSensor2 (line 393) | void CreateSensor2()
    method CreateVisitor (line 414) | void CreateVisitor()
    method UpdateGui (line 429) | void UpdateGui() override
    method Step (line 559) | void Step() override
    method Sample (line 657) | static Sample* Create( SampleContext* context )
  class FootSensor (line 678) | class FootSensor : public Sample
    type CollisionBits (line 681) | enum CollisionBits
    method FootSensor (line 690) | explicit FootSensor( SampleContext* context )
    method Step (line 746) | void Step() override
    method Sample (line 800) | static Sample* Create( SampleContext* context )
  type BodyUserData (line 813) | struct BodyUserData
  class ContactEvent (line 818) | class ContactEvent : public Sample
    method ContactEvent (line 826) | explicit ContactEvent( SampleContext* context )
    method SpawnDebris (line 878) | void SpawnDebris()
    method UpdateGui (line 929) | void UpdateGui() override
    method Step (line 943) | void Step() override
    method Sample (line 1215) | static Sample* Create( SampleContext* context )
  class Platform (line 1232) | class Platform : public Sample
    method Platform (line 1235) | explicit Platform( SampleContext* context )
    method PreSolveStatic (line 1312) | static bool PreSolveStatic( b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2...
    method PreSolve (line 1321) | bool PreSolve( b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Vec2 point, b...
    method UpdateGui (line 1350) | void UpdateGui() override
    method Step (line 1365) | void Step() override
    method Sample (line 1448) | static Sample* Create( SampleContext* context )
  class BodyMove (line 1466) | class BodyMove : public Sample
    method BodyMove (line 1474) | explicit BodyMove( SampleContext* context )
    method CreateBodies (line 1516) | void CreateBodies()
    method UpdateGui (line 1560) | void UpdateGui() override
    method Step (line 1584) | void Step() override
    method Sample (line 1639) | static Sample* Create( SampleContext* context )
  class SensorTypes (line 1655) | class SensorTypes : public Sample
    type CollisionBits (line 1658) | enum CollisionBits
    method SensorTypes (line 1667) | explicit SensorTypes( SampleContext* context )
    method PrintOverlaps (line 1769) | void PrintOverlaps( b2ShapeId sensorShapeId, const char* prefix )
    method Step (line 1804) | void Step() override
    method Sample (line 1834) | static Sample* Create( SampleContext* context )
  class JointEvent (line 1851) | class JointEvent : public Sample
    method JointEvent (line 1859) | explicit JointEvent( SampleContext* context )
    method Step (line 2049) | void Step() override
    method Sample (line 2070) | static Sample* Create( SampleContext* context )
  class PersistentContact (line 2080) | class PersistentContact : public Sample
    method PersistentContact (line 2083) | explicit PersistentContact( SampleContext* context )
    method Step (line 2132) | void Step() override
    method Sample (line 2172) | static Sample* Create( SampleContext* context )
  class SensorHits (line 2182) | class SensorHits : public Sample
    method SensorHits (line 2185) | explicit SensorHits( SampleContext* context )
    method Launch (line 2283) | void Launch()
    method UpdateGui (line 2310) | void UpdateGui() override
    method CollectTransforms (line 2329) | void CollectTransforms( b2ShapeId sensorShapeId )
    method Step (line 2343) | void Step() override
    method Sample (line 2389) | static Sample* Create( SampleContext* context )
  class ProjectileEvent (line 2417) | class ProjectileEvent : public Sample
    method ProjectileEvent (line 2420) | explicit ProjectileEvent( SampleContext* context )
    method FireProjectile (line 2472) | void FireProjectile()
    method MouseDown (line 2493) | void MouseDown( b2Vec2 p, int button, int mods ) override
    method MouseUp (line 2505) | void MouseUp( b2Vec2, int button ) override
    method MouseMove (line 2517) | void MouseMove( b2Vec2 p ) override
    method Step (line 2525) | void Step() override
    method Sample (line 2567) | static Sample* Create( SampleContext* context )
  class CircleImpulse (line 2581) | class CircleImpulse : public Sample
    type Event (line 2584) | struct Event
    method CircleImpulse (line 2591) | explicit CircleImpulse( SampleContext* context )
    method Spawn (line 2620) | void Spawn()
    method UpdateGui (line 2656) | void UpdateGui() override
    method Step (line 2678) | void Step() override
    method Sample (line 2713) | static Sample* Create( SampleContext* context )

FILE: samples/sample_geometry.cpp
  class ConvexHull (line 12) | class ConvexHull : public Sample
    method ConvexHull (line 20) | explicit ConvexHull( SampleContext* context )
    method Generate (line 35) | void Generate()
    method Keyboard (line 91) | void Keyboard( int key ) override
    method Step (line 112) | void Step() override
    method Sample (line 202) | static Sample* Create( SampleContext* context )

FILE: samples/sample_issues.cpp
  type PhysicsHitQueryResult2D (line 7) | struct PhysicsHitQueryResult2D
  type CastContext_Single (line 18) | struct CastContext_Single
  function b2CastResult_Closest (line 26) | static float b2CastResult_Closest( b2ShapeId shapeId, b2Vec2 point, b2Ve...
  function b2ShapeProxy (line 44) | static b2ShapeProxy TransformShapeProxy( const b2Transform& t, const b2S...
  class ShapeCastChain (line 59) | class ShapeCastChain : public Sample
    method ShapeCastChain (line 62) | explicit ShapeCastChain( SampleContext* context )
    method Step (line 118) | void Step() override
    method ShapeCastSingle (line 205) | bool ShapeCastSingle( PhysicsHitQueryResult2D& outResult, b2Vec2 start...
    method Sample (line 227) | static Sample* Create( SampleContext* context )
  class BadSteiner (line 242) | class BadSteiner : public Sample
    method BadSteiner (line 245) | explicit BadSteiner( SampleContext* context )
    method Sample (line 283) | static Sample* Create( SampleContext* context )
  class DisableCrash (line 291) | class DisableCrash : public Sample
    method DisableCrash (line 294) | explicit DisableCrash( SampleContext* context )
    method UpdateGui (line 341) | void UpdateGui() override
    method Sample (line 366) | static Sample* Create( SampleContext* context )
  class Crash01 (line 378) | class Crash01 : public Sample
    method Crash01 (line 381) | explicit Crash01( SampleContext* context )
    method UpdateGui (line 460) | void UpdateGui() override
    method Sample (line 502) | static Sample* Create( SampleContext* context )
  class StaticVsBulletBug (line 515) | class StaticVsBulletBug : public Sample
    method StaticVsBulletBug (line 518) | explicit StaticVsBulletBug( SampleContext* context )
    method Sample (line 569) | static Sample* Create( SampleContext* context )
  class UnstablePrismaticJoints (line 579) | class UnstablePrismaticJoints : public Sample
    method UnstablePrismaticJoints (line 582) | explicit UnstablePrismaticJoints( SampleContext* context )
    method Sample (line 665) | static Sample* Create( SampleContext* context )
  class UnstableWindmill (line 674) | class UnstableWindmill : public Sample
    method UnstableWindmill (line 677) | explicit UnstableWindmill( SampleContext* context )
    method Sample (line 750) | static Sample* Create( SampleContext* context )

FILE: samples/sample_joints.cpp
  class DistanceJoint (line 19) | class DistanceJoint : public Sample
    method DistanceJoint (line 27) | explicit DistanceJoint( SampleContext* context )
    method CreateScene (line 61) | void CreateScene( int newCount )
    method UpdateGui (line 118) | void UpdateGui() override
    method Sample (line 225) | static Sample* Create( SampleContext* context )
  class MotorJoint (line 250) | class MotorJoint : public Sample
    method MotorJoint (line 253) | explicit MotorJoint( SampleContext* context )
    method UpdateGui (line 338) | void UpdateGui() override
    method Step (line 369) | void Step() override
    method Sample (line 406) | static Sample* Create( SampleContext* context )
  class TopDownFriction (line 423) | class TopDownFriction : public Sample
    method TopDownFriction (line 426) | explicit TopDownFriction( SampleContext* context )
    method UpdateGui (line 509) | void UpdateGui() override
    method Sample (line 533) | static Sample* Create( SampleContext* context )
  class FilterJoint (line 543) | class FilterJoint : public Sample
    method FilterJoint (line 546) | explicit FilterJoint( SampleContext* context )
    method Sample (line 586) | static Sample* Create( SampleContext* context )
  class RevoluteJoint (line 594) | class RevoluteJoint : public Sample
    method RevoluteJoint (line 597) | explicit RevoluteJoint( SampleContext* context )
    method UpdateGui (line 705) | void UpdateGui() override
    method Step (line 771) | void Step() override
    method Sample (line 785) | static Sample* Create( SampleContext* context )
  class PrismaticJoint (line 805) | class PrismaticJoint : public Sample
    method PrismaticJoint (line 808) | explicit PrismaticJoint( SampleContext* context )
    method UpdateGui (line 867) | void UpdateGui() override
    method Step (line 933) | void Step() override
    method Sample (line 947) | static Sample* Create( SampleContext* context )
  class WheelJoint (line 965) | class WheelJoint : public Sample
    method WheelJoint (line 968) | explicit WheelJoint( SampleContext* context )
    method UpdateGui (line 1021) | void UpdateGui() override
    method Step (line 1074) | void Step() override
    method Sample (line 1082) | static Sample* Create( SampleContext* context )
  class Bridge (line 1100) | class Bridge : public Sample
    method Bridge (line 1103) | explicit Bridge( SampleContext* context )
    method UpdateGui (line 1205) | void UpdateGui() override
    method Sample (line 1262) | static Sample* Create( SampleContext* context )
  class BallAndChain (line 1279) | class BallAndChain : public Sample
    method BallAndChain (line 1282) | explicit BallAndChain( SampleContext* context )
    method UpdateGui (line 1359) | void UpdateGui() override
    method Sample (line 1380) | static Sample* Create( SampleContext* context )
  class Cantilever (line 1394) | class Cantilever : public Sample
    method Cantilever (line 1402) | explicit Cantilever( SampleContext* context )
    method UpdateGui (line 1465) | void UpdateGui() override
    method Step (line 1527) | void Step() override
    method Sample (line 1535) | static Sample* Create( SampleContext* context )
  class MotionLocks (line 1554) | class MotionLocks : public Sample
    method MotionLocks (line 1562) | explicit MotionLocks( SampleContext* context )
    method UpdateGui (line 1731) | void UpdateGui() override
    method Sample (line 1775) | static Sample* Create( SampleContext* context )
  class BreakableJoint (line 1787) | class BreakableJoint : public Sample
    method BreakableJoint (line 1795) | explicit BreakableJoint( SampleContext* context )
    method UpdateGui (line 1964) | void UpdateGui() override
    method Step (line 1984) | void Step() override
    method Sample (line 2009) | static Sample* Create( SampleContext* context )
  class JointSeparation (line 2021) | class JointSeparation : public Sample
    method JointSeparation (line 2029) | explicit JointSeparation( SampleContext* context )
    method UpdateGui (line 2171) | void UpdateGui() override
    method Step (line 2216) | void Step() override
    method Sample (line 2235) | static Sample* Create( SampleContext* context )
  class UserConstraint (line 2250) | class UserConstraint : public Sample
    method UserConstraint (line 2253) | explicit UserConstraint( SampleContext* context )
    method Step (line 2279) | void Step() override
    method Sample (line 2360) | static Sample* Create( SampleContext* context )
  class Driving (line 2372) | class Driving : public Sample
    method Driving (line 2375) | explicit Driving( SampleContext* context )
    method UpdateGui (line 2550) | void UpdateGui() override
    method Step (line 2584) | void Step() override
    method Sample (line 2616) | static Sample* Create( SampleContext* context )
  class Ragdoll (line 2632) | class Ragdoll : public Sample
    method Ragdoll (line 2635) | explicit Ragdoll( SampleContext* context )
    method Spawn (line 2666) | void Spawn()
    method UpdateGui (line 2673) | void UpdateGui() override
    method Sample (line 2707) | static Sample* Create( SampleContext* context )
  class SoftBody (line 2720) | class SoftBody : public Sample
    method SoftBody (line 2723) | explicit SoftBody( SampleContext* context )
    method Sample (line 2743) | static Sample* Create( SampleContext* context )
  class DoohickeyFarm (line 2753) | class DoohickeyFarm : public Sample
    method DoohickeyFarm (line 2756) | explicit DoohickeyFarm( SampleContext* context )
    method Step (line 2786) | void Step() override
    method Sample (line 2791) | static Sample* Create( SampleContext* context )
  class ScissorLift (line 2799) | class ScissorLift : public Sample
    method ScissorLift (line 2802) | explicit ScissorLift( SampleContext* context )
    method UpdateGui (line 2972) | void UpdateGui() override
    method Step (line 3002) | void Step() override
    method Sample (line 3007) | static Sample* Create( SampleContext* context )
  class GearLift (line 3020) | class GearLift : public Sample
    method GearLift (line 3023) | explicit GearLift( SampleContext* context )
    method UpdateGui (line 3285) | void UpdateGui() override
    method Step (line 3315) | void Step() override
    method Sample (line 3334) | static Sample* Create( SampleContext* context )
  class Door (line 3348) | class Door : public Sample
    method Door (line 3351) | explicit Door( SampleContext* context )
    method UpdateGui (line 3409) | void UpdateGui() override
    method Step (line 3445) | void Step() override
    method Sample (line 3458) | static Sample* Create( SampleContext* context )
  class ScaleRagdoll (line 3474) | class ScaleRagdoll : public Sample
    method ScaleRagdoll (line 3477) | explicit ScaleRagdoll( SampleContext* context )
    method Spawn (line 3502) | void Spawn()
    method UpdateGui (line 3512) | void UpdateGui() override
    method Sample (line 3531) | static Sample* Create( SampleContext* context )

FILE: samples/sample_robustness.cpp
  class HighMassRatio1 (line 13) | class HighMassRatio1 : public Sample
    method HighMassRatio1 (line 16) | explicit HighMassRatio1( SampleContext* context )
    method Sample (line 67) | static Sample* Create( SampleContext* context )
  class HighMassRatio2 (line 76) | class HighMassRatio2 : public Sample
    method HighMassRatio2 (line 79) | explicit HighMassRatio2( SampleContext* context )
    method Sample (line 125) | static Sample* Create( SampleContext* context )
  class HighMassRatio3 (line 134) | class HighMassRatio3 : public Sample
    method HighMassRatio3 (line 137) | explicit HighMassRatio3( SampleContext* context )
    method Sample (line 185) | static Sample* Create( SampleContext* context )
  class OverlapRecovery (line 193) | class OverlapRecovery : public Sample
    method OverlapRecovery (line 196) | explicit OverlapRecovery( SampleContext* context )
    method CreateScene (line 228) | void CreateScene()
    method UpdateGui (line 271) | void UpdateGui() override
    method Sample (line 299) | static Sample* Create( SampleContext* context )
  class TinyPyramid (line 316) | class TinyPyramid : public Sample
    method TinyPyramid (line 319) | explicit TinyPyramid( SampleContext* context )
    method Step (line 363) | void Step() override
    method Sample (line 369) | static Sample* Create( SampleContext* context )
  class Cart (line 382) | class Cart : public Sample
    method Cart (line 385) | explicit Cart( SampleContext* context )
    method CreateScene (line 424) | void CreateScene()
    method UpdateGui (line 488) | void UpdateGui() override
    method Sample (line 532) | static Sample* Create( SampleContext* context )
  class MultiplePrismatic (line 553) | class MultiplePrismatic : public Sample
    method MultiplePrismatic (line 556) | explicit MultiplePrismatic( SampleContext* context )
    method Sample (line 603) | static Sample* Create( SampleContext* context )

FILE: samples/sample_shapes.cpp
  class ChainShape (line 19) | class ChainShape : public Sample
    type ShapeType (line 22) | enum ShapeType
    method ChainShape (line 29) | explicit ChainShape( SampleContext* context )
    method CreateScene (line 53) | void CreateScene()
    method Launch (line 129) | void Launch()
    method UpdateGui (line 167) | void UpdateGui() override
    method Step (line 203) | void Step() override
    method Sample (line 213) | static Sample* Create( SampleContext* context )
  class CompoundShapes (line 231) | class CompoundShapes : public Sample
    method CompoundShapes (line 234) | explicit CompoundShapes( SampleContext* context )
    method Spawn (line 340) | void Spawn()
    method UpdateGui (line 397) | void UpdateGui() override
    method Step (line 416) | void Step() override
    method Sample (line 436) | static Sample* Create( SampleContext* context )
  class ShapeFilter (line 450) | class ShapeFilter : public Sample
    type CollisionBits (line 453) | enum CollisionBits
    method ShapeFilter (line 463) | explicit ShapeFilter( SampleContext* context )
    method UpdateGui (line 515) | void UpdateGui() override
    method Step (line 633) | void Step() override
    method Sample (line 647) | static Sample* Create( SampleContext* context )
  class CustomFilter (line 664) | class CustomFilter : public Sample
    method CustomFilter (line 672) | explicit CustomFilter( SampleContext* context )
    method Step (line 712) | void Step() override
    method ShouldCollide (line 725) | bool ShouldCollide( b2ShapeId shapeIdA, b2ShapeId shapeIdB )
    method CustomFilterStatic (line 741) | static bool CustomFilterStatic( b2ShapeId shapeIdA, b2ShapeId shapeIdB...
    method Sample (line 747) | static Sample* Create( SampleContext* context )
  class Restitution (line 759) | class Restitution : public Sample
    type ShapeType (line 762) | enum ShapeType
    method Restitution (line 768) | explicit Restitution( SampleContext* context )
    method CreateBodies (line 792) | void CreateBodies()
    method UpdateGui (line 840) | void UpdateGui() override
    method Sample (line 866) | static Sample* Create( SampleContext* context )
  class Friction (line 879) | class Friction : public Sample
    method Friction (line 882) | explicit Friction( SampleContext* context )
    method Sample (line 938) | static Sample* Create( SampleContext* context )
  class RollingResistance (line 946) | class RollingResistance : public Sample
    method RollingResistance (line 949) | explicit RollingResistance( SampleContext* context )
    method CreateScene (line 963) | void CreateScene()
    method Keyboard (line 988) | void Keyboard( int key ) override
    method Step (line 1016) | void Step() override
    method Sample (line 1026) | static Sample* Create( SampleContext* context )
  class ConveyorBelt (line 1037) | class ConveyorBelt : public Sample
    method ConveyorBelt (line 1040) | explicit ConveyorBelt( SampleContext* context )
    method Sample (line 1088) | static Sample* Create( SampleContext* context )
  class TangentSpeed (line 1096) | class TangentSpeed : public Sample
    method TangentSpeed (line 1099) | explicit TangentSpeed( SampleContext* context )
    method b2BodyId (line 1161) | b2BodyId DropBall()
    method Reset (line 1177) | void Reset()
    method UpdateGui (line 1188) | void UpdateGui() override
    method Step (line 1211) | void Step() override
    method Sample (line 1222) | static Sample* Create( SampleContext* context )
  class ModifyGeometry (line 1237) | class ModifyGeometry : public Sample
    method ModifyGeometry (line 1240) | explicit ModifyGeometry( SampleContext* context )
    method UpdateShape (line 1280) | void UpdateShape()
    method UpdateGui (line 1313) | void UpdateGui() override
    method Step (line 1372) | void Step() override
    method Sample (line 1377) | static Sample* Create( SampleContext* context )
  class ChainLink (line 1398) | class ChainLink : public Sample
    method ChainLink (line 1401) | explicit ChainLink( SampleContext* context )
    method Step (line 1463) | void Step() override
    method Sample (line 1470) | static Sample* Create( SampleContext* context )
  class RoundedShapes (line 1478) | class RoundedShapes : public Sample
    method RoundedShapes (line 1481) | explicit RoundedShapes( SampleContext* context )
    method Sample (line 1540) | static Sample* Create( SampleContext* context )
  class EllipseShape (line 1548) | class EllipseShape : public Sample
    method EllipseShape (line 1551) | explicit EllipseShape( SampleContext* context )
    method Sample (line 1605) | static Sample* Create( SampleContext* context )
  class OffsetShapes (line 1613) | class OffsetShapes : public Sample
    method OffsetShapes (line 1616) | explicit OffsetShapes( SampleContext* context )
    method Step (line 1656) | void Step() override
    method Sample (line 1663) | static Sample* Create( SampleContext* context )
  class Explosion (line 1672) | class Explosion : public Sample
    method Explosion (line 1675) | explicit Explosion( SampleContext* context )
    method UpdateGui (line 1724) | void UpdateGui() override
    method Step (line 1750) | void Step() override
    method Sample (line 1774) | static Sample* Create( SampleContext* context )
  class RecreateStatic (line 1789) | class RecreateStatic : public Sample
    method RecreateStatic (line 1792) | explicit RecreateStatic( SampleContext* context )
    method Step (line 1813) | void Step() override
    method Sample (line 1836) | static Sample* Create( SampleContext* context )
  class BoxRestitution (line 1846) | class BoxRestitution : public Sample
    method BoxRestitution (line 1849) | explicit BoxRestitution( SampleContext* context )
    method Sample (line 1902) | static Sample* Create( SampleContext* context )
  class Wind (line 1912) | class Wind : public Sample
    type ShapeType (line 1915) | enum ShapeType
    method Wind (line 1922) | explicit Wind( SampleContext* context )
    method CreateScene (line 1947) | void CreateScene()
    method UpdateGui (line 2006) | void UpdateGui() override
    method Step (line 2036) | void Step() override
    method Sample (line 2063) | static Sample* Create( SampleContext* context )

FILE: samples/sample_stacking.cpp
  class SingleBox (line 15) | class SingleBox : public Sample
    method SingleBox (line 18) | explicit SingleBox( SampleContext* context )
    method Step (line 47) | void Step() override
    method Sample (line 57) | static Sample* Create( SampleContext* context )
  class TiltedStack (line 67) | class TiltedStack : public Sample
    method TiltedStack (line 70) | explicit TiltedStack( SampleContext* context )
    method Sample (line 125) | static Sample* Create( SampleContext* context )
  class VerticalStack (line 143) | class VerticalStack : public Sample
    type ShapeType (line 153) | enum ShapeType
    method VerticalStack (line 159) | explicit VerticalStack( SampleContext* context )
    method CreateStacks (line 201) | void CreateStacks()
    method DestroyBody (line 265) | void DestroyBody()
    method DestroyBullets (line 283) | void DestroyBullets()
    method FireBullets (line 297) | void FireBullets()
    method UpdateGui (line 329) | void UpdateGui() override
    method Sample (line 380) | static Sample* Create( SampleContext* context )
  class CircleStack (line 397) | class CircleStack : public Sample
    type Event (line 400) | struct Event
    method CircleStack (line 405) | explicit CircleStack( SampleContext* context )
    method Step (line 459) | void Step() override
    method Sample (line 485) | static Sample* Create( SampleContext* context )
  class CapsuleStack (line 495) | class CapsuleStack : public Sample
    type Event (line 498) | struct Event
    method CapsuleStack (line 503) | explicit CapsuleStack( SampleContext* context )
    method Sample (line 548) | static Sample* Create( SampleContext* context )
  class Cliff (line 556) | class Cliff : public Sample
    method Cliff (line 559) | explicit Cliff( SampleContext* context )
    method CreateBodies (line 597) | void CreateBodies()
    method UpdateGui (line 676) | void UpdateGui() override
    method Sample (line 694) | static Sample* Create( SampleContext* context )
  class Arch (line 705) | class Arch : public Sample
    method Arch (line 708) | explicit Arch( SampleContext* context )
    method Sample (line 795) | static Sample* Create( SampleContext* context )
  class DoubleDomino (line 803) | class DoubleDomino : public Sample
    method DoubleDomino (line 806) | explicit DoubleDomino( SampleContext* context )
    method Sample (line 848) | static Sample* Create( SampleContext* context )
  class Confined (line 856) | class Confined : public Sample
    method Confined (line 859) | explicit Confined( SampleContext* context )
    method Sample (line 914) | static Sample* Create( SampleContext* context )
  class CardHouse (line 929) | class CardHouse : public Sample
    method CardHouse (line 932) | explicit CardHouse( SampleContext* context )
    method Sample (line 997) | static Sample* Create( SampleContext* context )

FILE: samples/sample_world.cpp
  class LargeWorld (line 16) | class LargeWorld : public Sample
    method LargeWorld (line 19) | explicit LargeWorld( SampleContext* context )
    method UpdateGui (line 144) | void UpdateGui() override
    method Step (line 166) | void Step() override
    method Sample (line 227) | static Sample* Create( SampleContext* context )

FILE: samples/shader.c
  function DumpInfoGL (line 23) | void DumpInfoGL()
  function CheckOpenGL (line 43) | void CheckOpenGL()
  function PrintLogGL (line 53) | void PrintLogGL( uint32_t object )
  function GLuint (line 85) | static GLuint sCreateShaderFromString( const char* source, GLenum type )
  function CreateProgramFromStrings (line 107) | uint32_t CreateProgramFromStrings( const char* vertexString, const char*...
  function GLuint (line 142) | static GLuint sCreateShaderFromFile( const char* filename, GLenum type )
  function CreateProgramFromFiles (line 181) | uint32_t CreateProgramFromFiles( const char* vertexPath, const char* fra...

FILE: samples/stb_image_write.h
  function STBIWDEF (line 262) | STBIWDEF void stbi_flip_vertically_on_write(int flag)
  type stbi__write_context (line 267) | typedef struct
  function stbi__start_write_callbacks (line 276) | static void stbi__start_write_callbacks(stbi__write_context *s, stbi_wri...
  function stbi__stdio_write (line 284) | static void stbi__stdio_write(void *context, void *data, int size)
  function STBIWDEF (line 298) | STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen,...
  function FILE (line 304) | static FILE *stbiw__fopen(char const *filename, char const *mode)
  function stbi__start_write_file (line 332) | static int stbi__start_write_file(stbi__write_context *s, const char *fi...
  function stbi__end_write_file (line 339) | static void stbi__end_write_file(stbi__write_context *s)
  type stbiw_uint32 (line 346) | typedef unsigned int stbiw_uint32;
  function stbiw__writefv (line 349) | static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_l...
  function stbiw__writef (line 378) | static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
  function stbiw__write_flush (line 386) | static void stbiw__write_flush(stbi__write_context *s)
  function stbiw__putc (line 394) | static void stbiw__putc(stbi__write_context *s, unsigned char c)
  function stbiw__write1 (line 399) | static void stbiw__write1(stbi__write_context *s, unsigned char a)
  function stbiw__write3 (line 406) | static void stbiw__write3(stbi__write_context *s, unsigned char a, unsig...
  function stbiw__write_pixel (line 418) | static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int ...
  function stbiw__write_pixels (line 451) | static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int...
  function stbiw__outfile (line 478) | static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir,...
  function stbi_write_bmp_core (line 492) | static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int...
  function STBIWDEF (line 512) | STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context...
  function STBIWDEF (line 520) | STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp...
  function stbi_write_tga_core (line 532) | static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int...
  function STBIWDEF (line 611) | STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context...
  function STBIWDEF (line 619) | STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp...
  function stbiw__linear_to_rgbe (line 639) | static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
  function stbiw__write_run_data (line 656) | static void stbiw__write_run_data(stbi__write_context *s, int length, un...
  function stbiw__write_dump_data (line 664) | static void stbiw__write_dump_data(stbi__write_context *s, int length, u...
  function stbiw__write_hdr_scanline (line 672) | static void stbiw__write_hdr_scanline(stbi__write_context *s, int width,...
  function stbi_write_hdr_core (line 761) | static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int...
  function STBIWDEF (line 787) | STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context...
  function STBIWDEF (line 794) | STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp...
  function stbiw__zlib_bitrev (line 849) | static int stbiw__zlib_bitrev(int code, int codebits)
  function stbiw__zlib_countm (line 859) | static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *...
  function stbiw__zhash (line 867) | static unsigned int stbiw__zhash(unsigned char *data)
  function stbiw__crc32 (line 1024) | static unsigned int stbiw__crc32(unsigned char *buffer, int len)
  function stbiw__wpcrc (line 1077) | static void stbiw__wpcrc(unsigned char **data, int len)
  function stbiw__paeth (line 1083) | static unsigned char stbiw__paeth(int a, int b, int c)
  function stbiw__encode_png_line (line 1092) | static void stbiw__encode_png_line(unsigned char *pixels, int stride_byt...
  function STBIWDEF (line 1215) | STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp...
  function STBIWDEF (line 1231) | STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context...
  function stbiw__jpg_writeBits (line 1253) | static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, i...
  function stbiw__jpg_DCT (line 1270) | static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3...
  function stbiw__jpg_calcBits (line 1318) | static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) {
  function stbiw__jpg_processDU (line 1328) | static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int...
  function stbi_write_jpg_core (line 1398) | static int stbi_write_jpg_core(stbi__write_context *s, int width, int he...
  function STBIWDEF (line 1607) | STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context...
  function STBIWDEF (line 1616) | STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp...

FILE: samples/stb_truetype.h
  function my_stbtt_initfont (line 287) | void my_stbtt_initfont(void)
  function my_stbtt_print (line 299) | void my_stbtt_print(float x, float y, char *text)
  function main (line 334) | int main(int argc, char **argv)
  function main (line 375) | int main(int arg, char **argv)
  type stbtt_uint8 (line 428) | typedef unsigned char   stbtt_uint8;
  type stbtt_int8 (line 429) | typedef signed   char   stbtt_int8;
  type stbtt_uint16 (line 430) | typedef unsigned short  stbtt_uint16;
  type stbtt_int16 (line 431) | typedef signed   short  stbtt_int16;
  type stbtt_uint32 (line 432) | typedef unsigned int    stbtt_uint32;
  type stbtt_int32 (line 433) | typedef signed   int    stbtt_int32;
  type stbtt__buf (line 513) | typedef struct
  type stbtt_bakedchar (line 527) | typedef struct
  type stbtt_aligned_quad (line 543) | typedef struct
  type stbtt_packedchar (line 575) | typedef struct
  type stbtt_pack_context (line 582) | typedef struct stbtt_pack_context stbtt_pack_context;
  type stbtt_fontinfo (line 583) | typedef struct stbtt_fontinfo stbtt_fontinfo;
  type stbrp_rect (line 585) | typedef struct stbrp_rect stbrp_rect;
  type stbtt_pack_range (line 619) | typedef struct
  type stbtt_pack_context (line 678) | struct stbtt_pack_context {
  type stbtt_fontinfo (line 713) | struct stbtt_fontinfo
  type stbtt_kerningentry (line 804) | typedef struct stbtt_kerningentry
  type stbtt_vertex (line 835) | typedef struct
  type stbtt__bitmap (line 924) | typedef struct
  function stbtt_uint8 (line 1133) | static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b)
  function stbtt_uint8 (line 1140) | static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b)
  function stbtt__buf_seek (line 1147) | static void stbtt__buf_seek(stbtt__buf *b, int o)
  function stbtt__buf_skip (line 1153) | static void stbtt__buf_skip(stbtt__buf *b, int o)
  function stbtt_uint32 (line 1158) | static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n)
  function stbtt__buf (line 1168) | static stbtt__buf stbtt__new_buf(const void *p, size_t size)
  function stbtt__buf (line 1181) | static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s)
  function stbtt__buf (line 1190) | static stbtt__buf stbtt__cff_get_index(stbtt__buf *b)
  function stbtt_uint32 (line 1204) | static stbtt_uint32 stbtt__cff_int(stbtt__buf *b)
  function stbtt__cff_skip_operand (line 1216) | static void stbtt__cff_skip_operand(stbtt__buf *b) {
  function stbtt__buf (line 1231) | static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key)
  function stbtt__dict_get_ints (line 1246) | static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, s...
  function stbtt__cff_index_count (line 1254) | static int stbtt__cff_index_count(stbtt__buf *b)
  function stbtt__buf (line 1260) | static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
  function stbtt_uint16 (line 1286) | static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; }
  function stbtt_int16 (line 1287) | static stbtt_int16 ttSHORT(stbtt_uint8 *p)   { return p[0]*256 + p[1]; }
  function stbtt_uint32 (line 1288) | static stbtt_uint32 ttULONG(stbtt_uint8 *p)  { return (p[0]<<24) + (p[1]...
  function stbtt_int32 (line 1289) | static stbtt_int32 ttLONG(stbtt_uint8 *p)    { return (p[0]<<24) + (p[1]...
  function stbtt__isfont (line 1294) | static int stbtt__isfont(stbtt_uint8 *font)
  function stbtt_uint32 (line 1306) | static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fo...
  function stbtt_GetFontOffsetForIndex_internal (line 1319) | static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_coll...
  function stbtt_GetNumberOfFonts_internal (line 1338) | static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection)
  function stbtt__buf (line 1354) | static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
  function stbtt__get_svg (line 1368) | static int stbtt__get_svg(stbtt_fontinfo *info)
  function stbtt_InitFont_internal (line 1383) | static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *...
  function STBTT_DEF (line 1496) | STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unico...
  function STBTT_DEF (line 1589) | STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int un...
  function stbtt_setvertex (line 1594) | static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int...
  function stbtt__GetGlyfOffset (line 1603) | static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_in...
  function STBTT_DEF (line 1625) | STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_in...
  function STBTT_DEF (line 1641) | STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int code...
  function STBTT_DEF (line 1646) | STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_i...
  function stbtt__close_shape (line 1658) | static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, ...
  function stbtt__GetGlyphShapeTT (line 1674) | static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_...
  type stbtt__csctx (line 1897) | typedef struct
  function stbtt__track_vertex (line 1911) | static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_in...
  function stbtt__csctx_v (line 1920) | static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int3...
  function stbtt__csctx_close_shape (line 1936) | static void stbtt__csctx_close_shape(stbtt__csctx *ctx)
  function stbtt__csctx_rmove_to (line 1942) | static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy)
  function stbtt__csctx_rline_to (line 1950) | static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy)
  function stbtt__csctx_rccurve_to (line 1957) | static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float ...
  function stbtt__buf (line 1968) | static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n)
  function stbtt__buf (line 1982) | static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info,...
  function stbtt__run_charstring (line 2010) | static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_i...
  function stbtt__GetGlyphShapeT2 (line 2269) | static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_...
  function stbtt__GetGlyphInfoT2 (line 2286) | static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_i...
  function STBTT_DEF (line 2297) | STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_...
  function STBTT_DEF (line 2305) | STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int gl...
  function STBTT_DEF (line 2317) | STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo *info)
  function STBTT_DEF (line 2332) | STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_ke...
  function stbtt__GetGlyphKernInfoAdvance (line 2359) | static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, in...
  function stbtt_int32 (line 2389) | static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, i...
  function stbtt_int32 (line 2447) | static stbtt_int32  stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int...
  function stbtt_int32 (line 2496) | static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *...
  function STBTT_DEF (line 2610) | STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int...
  function STBTT_DEF (line 2622) | STBTT_DEF int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info,...
  function STBTT_DEF (line 2629) | STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, in...
  function STBTT_DEF (line 2634) | STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *as...
  function STBTT_DEF (line 2641) | STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int ...
  function STBTT_DEF (line 2652) | STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int ...
  function STBTT_DEF (line 2660) | STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, fl...
  function STBTT_DEF (line 2666) | STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *in...
  function STBTT_DEF (line 2672) | STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
  function STBTT_DEF (line 2677) | STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl)
  function STBTT_DEF (line 2694) | STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, cons...
  function STBTT_DEF (line 2711) | STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unic...
  function STBTT_DEF (line 2721) | STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *fon...
  function STBTT_DEF (line 2739) | STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int g...
  function STBTT_DEF (line 2744) | STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo ...
  function STBTT_DEF (line 2749) | STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, i...
  type stbtt__hheap_chunk (line 2758) | typedef struct stbtt__hheap_chunk
  type stbtt__hheap (line 2763) | typedef struct stbtt__hheap
  function stbtt__hheap_free (line 2791) | static void stbtt__hheap_free(stbtt__hheap *hh, void *p)
  function stbtt__hheap_cleanup (line 2797) | static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata)
  type stbtt__edge (line 2807) | typedef struct stbtt__edge {
  type stbtt__active_edge (line 2813) | typedef struct stbtt__active_edge
  function stbtt__active_edge (line 2835) | static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__ed...
  function stbtt__active_edge (line 2857) | static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__ed...
  function stbtt__fill_active_edges (line 2882) | static void stbtt__fill_active_edges(unsigned char *scanline, int len, s...
  function stbtt__rasterize_sorted_edges (line 2924) | static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__...
  function stbtt__handle_clipped_edge (line 3028) | static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__ac...
  function stbtt__sized_trapezoid_area (line 3065) | static float stbtt__sized_trapezoid_area(float height, float top_width, ...
  function stbtt__position_trapezoid_area (line 3072) | static float stbtt__position_trapezoid_area(float height, float tx0, flo...
  function stbtt__sized_triangle_area (line 3077) | static float stbtt__sized_triangle_area(float height, float width)
  function stbtt__fill_active_edges_new (line 3082) | static void stbtt__fill_active_edges_new(float *scanline, float *scanlin...
  function stbtt__rasterize_sorted_edges (line 3297) | static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__...
  function stbtt__sort_edges_ins_sort (line 3399) | static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
  function stbtt__sort_edges_quicksort (line 3417) | static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
  function stbtt__sort_edges (line 3479) | static void stbtt__sort_edges(stbtt__edge *p, int n)
  type stbtt__point (line 3485) | typedef struct
  function stbtt__rasterize (line 3490) | static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, i...
  function stbtt__add_point (line 3547) | static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
  function stbtt__tesselate_curve (line 3555) | static int stbtt__tesselate_curve(stbtt__point *points, int *num_points,...
  function stbtt__tesselate_cubic (line 3575) | static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points...
  function stbtt__point (line 3618) | static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num...
  function STBTT_DEF (line 3695) | STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_...
  function STBTT_DEF (line 3708) | STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
  function STBTT_DEF (line 3758) | STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info,...
  function STBTT_DEF (line 3777) | STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigne...
  function STBTT_DEF (line 3787) | STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fo...
  function STBTT_DEF (line 3792) | STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *i...
  function STBTT_DEF (line 3802) | STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, uns...
  function stbtt_BakeFontBitmap_internal (line 3813) | static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset...
  function STBTT_DEF (line 3859) | STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int p...
  type stbrp_coord (line 3887) | typedef int stbrp_coord;
  type stbrp_context (line 3900) | typedef struct
  type stbrp_node (line 3906) | typedef struct
  type stbrp_rect (line 3911) | struct stbrp_rect
  function stbrp_init_target (line 3917) | static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_...
  function stbrp_pack_rects (line 3928) | static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int ...
  function STBTT_DEF (line 3957) | STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pi...
  function STBTT_DEF (line 3989) | STBTT_DEF void stbtt_PackEnd  (stbtt_pack_context *spc)
  function STBTT_DEF (line 3995) | STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsign...
  function STBTT_DEF (line 4005) | STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *sp...
  function stbtt__h_prefilter (line 4012) | static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int ...
  function stbtt__v_prefilter (line 4074) | static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int ...
  function stbtt__oversample_shift (line 4136) | static float stbtt__oversample_shift(int oversample)
  function STBTT_DEF (line 4149) | STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, c...
  function STBTT_DEF (line 4184) | STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontin...
  function STBTT_DEF (line 4208) | STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *sp...
  function STBTT_DEF (line 4297) | STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, st...
  function STBTT_DEF (line 4302) | STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsign...
  function STBTT_DEF (line 4338) | STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigne...
  function STBTT_DEF (line 4350) | STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata...
  function STBTT_DEF (line 4363) | STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int...
  function stbtt__ray_intersect_bezier (line 4398) | static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], floa...
  function equal (line 4462) | static int equal(float *a, float *b)
  function stbtt__compute_crossings_x (line 4467) | static int stbtt__compute_crossings_x(float x, float y, int nverts, stbt...
  function stbtt__cuberoot (line 4535) | static float stbtt__cuberoot( float x )
  function stbtt__solve_cubic (line 4544) | static int stbtt__solve_cubic(float a, float b, float c, float* r)
  function STBTT_DEF (line 4767) | STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
  function stbtt_int32 (line 4778) | static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint...
  function stbtt_CompareUTF8toUTF16_bigendian_internal (line 4817) | static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len...
  function STBTT_DEF (line 4824) | STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font...
  function stbtt__matchpair (line 4845) | static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint...
  function stbtt__matches (line 4892) | static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_ui...
  function stbtt_FindMatchingFont_internal (line 4921) | static int stbtt_FindMatchingFont_internal(unsigned char *font_collectio...
  function STBTT_DEF (line 4937) | STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,
  function STBTT_DEF (line 4944) | STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int...
  function STBTT_DEF (line 4949) | STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
  function STBTT_DEF (line 4954) | STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *...
  function STBTT_DEF (line 4959) | STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, cons...
  function STBTT_DEF (line 4964) | STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len...

FILE: shared/benchmarks.c
  function CreateJointGrid (line 20) | void CreateJointGrid( b2WorldId worldId )
  function CreateLargePyramid (line 89) | void CreateLargePyramid( b2WorldId worldId )
  function CreateSmallPyramid (line 133) | static void CreateSmallPyramid( b2WorldId worldId, int baseCount, float ...
  function CreateManyPyramids (line 157) | void CreateManyPyramids( b2WorldId worldId )
  type RainConstants (line 198) | enum RainConstants
  type RainConstants (line 205) | enum RainConstants
  type Group (line 213) | typedef struct Group
  type RainData (line 218) | typedef struct RainData
  function CreateRain (line 229) | void CreateRain( b2WorldId worldId )
  function CreateGroup (line 267) | void CreateGroup( b2WorldId worldId, int rowIndex, int columnIndex )
  function DestroyGroup (line 293) | void DestroyGroup( int rowIndex, int columnIndex )
  function StepRain (line 305) | float StepRain( b2WorldId worldId, int stepCount )
  type SpinnerData (line 337) | typedef struct
  function CreateSpinner (line 344) | void CreateSpinner( b2WorldId worldId )
  function StepSpinner (line 444) | float StepSpinner( b2WorldId worldId, int stepCount )
  function CreateSmash (line 452) | void CreateSmash( b2WorldId worldId )
  function CreateTumbler (line 494) | void CreateTumbler( b2WorldId worldId )
  function CreateWasher (line 561) | void CreateWasher( b2WorldId worldId )

FILE: shared/determinism.c
  function FallingHingeData (line 11) | FallingHingeData CreateFallingHinges( b2WorldId worldId )
  function UpdateFallingHinges (line 107) | bool UpdateFallingHinges( b2WorldId worldId, FallingHingeData* data )
  function DestroyFallingHinges (line 134) | void DestroyFallingHinges( FallingHingeData* data )

FILE: shared/determinism.h
  type FallingHingeData (line 14) | typedef struct FallingHingeData

FILE: shared/human.c
  function CreateHuman (line 13) | void CreateHuman( Human* human, b2WorldId worldId, b2Vec2 position, floa...
  function DestroyHuman (line 512) | void DestroyHuman( Human* human )
  function Human_SetVelocity (line 541) | void Human_SetVelocity( Human* human, b2Vec2 velocity )
  function Human_ApplyRandomAngularImpulse (line 556) | void Human_ApplyRandomAngularImpulse( Human* human, float magnitude )
  function Human_SetJointFrictionTorque (line 563) | void Human_SetJointFrictionTorque( Human* human, float torque )
  function Human_SetJointSpringHertz (line 584) | void Human_SetJointSpringHertz( Human* human, float hertz )
  function Human_SetJointDampingRatio (line 604) | void Human_SetJointDampingRatio( Human* human, float dampingRatio )
  function Human_EnableSensorEvents (line 613) | void Human_EnableSensorEvents( Human* human, bool enable )
  function Human_SetScale (line 626) | void Human_SetScale( Human* human, float scale )

FILE: shared/human.h
  type BoneId (line 8) | typedef enum BoneId
  type Bone (line 24) | typedef struct Bone
  type Human (line 33) | typedef struct Human

FILE: shared/random.c
  function b2Polygon (line 8) | b2Polygon RandomPolygon( float extent )

FILE: shared/random.h
  function B2_INLINE (line 27) | B2_INLINE int RandomInt()
  function B2_INLINE (line 41) | B2_INLINE int RandomIntRange( int lo, int hi )
  function B2_INLINE (line 47) | B2_INLINE float RandomFloat()
  function B2_INLINE (line 56) | B2_INLINE float RandomFloatRange( float lo, float hi )
  function B2_INLINE (line 65) | B2_INLINE b2Vec2 RandomVec2( float lo, float hi )
  function B2_INLINE (line 74) | B2_INLINE b2Rot RandomRot( void )

FILE: src/aabb.c
  function b2IsValidAABB (line 10) | bool b2IsValidAABB( b2AABB a )
  function b2CastOutput (line 19) | b2CastOutput b2AABB_RayCast( b2AABB a, b2Vec2 p1, b2Vec2 p2 )

FILE: src/aabb.h
  function b2Perimeter (line 12) | static inline float b2Perimeter( b2AABB a )
  function b2EnlargeAABB (line 21) | static inline bool b2EnlargeAABB( b2AABB* a, b2AABB b )

FILE: src/arena_allocator.c
  function b2ArenaAllocator (line 14) | b2ArenaAllocator b2CreateArenaAllocator( int capacity )
  function b2DestroyArenaAllocator (line 27) | void b2DestroyArenaAllocator( b2ArenaAllocator* allocator )
  function b2FreeArenaItem (line 68) | void b2FreeArenaItem( b2ArenaAllocator* alloc, void* mem )
  function b2GrowArena (line 86) | void b2GrowArena( b2ArenaAllocator* alloc )
  function b2GetArenaCapacity (line 99) | int b2GetArenaCapacity( b2ArenaAllocator* alloc )
  function b2GetArenaAllocation (line 104) | int b2GetArenaAllocation( b2ArenaAllocator* alloc )
  function b2GetMaxArenaAllocation (line 109) | int b2GetMaxArenaAllocation( b2ArenaAllocator* alloc )

FILE: src/arena_allocator.h
  type b2ArenaEntry (line 12) | typedef struct b2ArenaEntry
  type b2ArenaAllocator (line 25) | typedef struct b2ArenaAllocator

FILE: src/atomic.h
  function b2AtomicStoreInt (line 15) | static inline void b2AtomicStoreInt( b2AtomicInt* a, int value )
  function b2AtomicLoadInt (line 26) | static inline int b2AtomicLoadInt( b2AtomicInt* a )
  function b2AtomicFetchAddInt (line 37) | static inline int b2AtomicFetchAddInt( b2AtomicInt* a, int increment )
  function b2AtomicCompareExchangeInt (line 48) | static inline bool b2AtomicCompareExchangeInt( b2AtomicInt* a, int expec...
  function b2AtomicStoreU32 (line 60) | static inline void b2AtomicStoreU32( b2AtomicU32* a, uint32_t value )
  function b2AtomicLoadU32 (line 71) | static inline uint32_t b2AtomicLoadU32( b2AtomicU32* a )

FILE: src/bitset.c
  function b2BitSet (line 8) | b2BitSet b2CreateBitSet( uint32_t bitCapacity )
  function b2DestroyBitSet (line 19) | void b2DestroyBitSet( b2BitSet* bitSet )
  function b2SetBitCountAndClear (line 27) | void b2SetBitCountAndClear( b2BitSet* bitSet, uint32_t bitCount )
  function b2GrowBitSet (line 41) | void b2GrowBitSet( b2BitSet* bitSet, uint32_t blockCount )
  function b2InPlaceUnion (line 59) | void b2InPlaceUnion( b2BitSet* B2_RESTRICT setA, const b2BitSet* B2_REST...

FILE: src/bitset.h
  type b2BitSet (line 12) | typedef struct b2BitSet
  function b2SetBit (line 26) | static inline void b2SetBit( b2BitSet* bitSet, uint32_t bitIndex )
  function b2SetBitGrow (line 33) | static inline void b2SetBitGrow( b2BitSet* bitSet, uint32_t bitIndex )
  function b2ClearBit (line 43) | static inline void b2ClearBit( b2BitSet* bitSet, uint32_t bitIndex )
  function b2GetBit (line 53) | static inline bool b2GetBit( const b2BitSet* bitSet, uint32_t bitIndex )
  function b2GetBitSetBytes (line 63) | static inline int b2GetBitSetBytes( b2BitSet* bitSet )

FILE: src/body.c
  function b2LimitVelocity (line 28) | static void b2LimitVelocity( b2BodyState* state, float maxLinearSpeed )
  function b2Body (line 38) | b2Body* b2GetBodyFullId( b2World* world, b2BodyId bodyId )
  function b2Transform (line 46) | b2Transform b2GetBodyTransformQuick( b2World* world, b2Body* body )
  function b2Transform (line 53) | b2Transform b2GetBodyTransform( b2World* world, int bodyId )
  function b2BodyId (line 60) | b2BodyId b2MakeBodyId( b2World* world, int bodyId )
  function b2BodySim (line 66) | b2BodySim* b2GetBodySim( b2World* world, b2Body* body )
  function b2BodyState (line 73) | b2BodyState* b2GetBodyState( b2World* world, b2Body* body )
  function b2CreateIslandForBody (line 84) | static void b2CreateIslandForBody( b2World* world, int setIndex, b2Body*...
  function b2RemoveBodyFromIsland (line 99) | static void b2RemoveBodyFromIsland( b2World* world, b2Body* body )
  function b2DestroyBodyContacts (line 160) | static void b2DestroyBodyContacts( b2World* world, b2Body* body, bool wa...
  function b2BodyId (line 177) | b2BodyId b2CreateBody( b2WorldId worldId, const b2BodyDef* def )
  function b2WakeBody (line 338) | bool b2WakeBody( b2World* world, b2Body* body )
  function b2DestroyBody (line 350) | void b2DestroyBody( b2BodyId bodyId )
  function b2Body_GetContactCapacity (line 453) | int b2Body_GetContactCapacity( b2BodyId bodyId )
  function b2Body_GetContactData (line 467) | int b2Body_GetContactData( b2BodyId bodyId, b2ContactData* contactData, ...
  function b2AABB (line 510) | b2AABB b2Body_ComputeAABB( b2BodyId bodyId )
  function b2UpdateBodyMassData (line 536) | void b2UpdateBodyMassData( b2World* world, b2Body* body )
  function b2Vec2 (line 670) | b2Vec2 b2Body_GetPosition( b2BodyId bodyId )
  function b2Rot (line 678) | b2Rot b2Body_GetRotation( b2BodyId bodyId )
  function b2Transform (line 686) | b2Transform b2Body_GetTransform( b2BodyId bodyId )
  function b2Vec2 (line 693) | b2Vec2 b2Body_GetLocalPoint( b2BodyId bodyId, b2Vec2 worldPoint )
  function b2Vec2 (line 701) | b2Vec2 b2Body_GetWorldPoint( b2BodyId bodyId, b2Vec2 localPoint )
  function b2Vec2 (line 709) | b2Vec2 b2Body_GetLocalVector( b2BodyId bodyId, b2Vec2 worldVector )
  function b2Vec2 (line 717) | b2Vec2 b2Body_GetWorldVector( b2BodyId bodyId, b2Vec2 localVector )
  function b2Body_SetTransform (line 725) | void b2Body_SetTransform( b2BodyId bodyId, b2Vec2 position, b2Rot rotati...
  function b2Vec2 (line 780) | b2Vec2 b2Body_GetLinearVelocity( b2BodyId bodyId )
  function b2Body_GetAngularVelocity (line 792) | float b2Body_GetAngularVelocity( b2BodyId bodyId )
  function b2Body_SetLinearVelocity (line 804) | void b2Body_SetLinearVelocity( b2BodyId bodyId, b2Vec2 linearVelocity )
  function b2Body_SetAngularVelocity (line 828) | void b2Body_SetAngularVelocity( b2BodyId bodyId, float angularVelocity )
  function b2Body_SetTargetTransform (line 852) | void b2Body_SetTargetTransform( b2BodyId bodyId, b2Transform target, flo...
  function b2Vec2 (line 908) | b2Vec2 b2Body_GetLocalPointVelocity( b2BodyId bodyId, b2Vec2 localPoint )
  function b2Vec2 (line 926) | b2Vec2 b2Body_GetWorldPointVelocity( b2BodyId bodyId, b2Vec2 worldPoint )
  function b2Body_ApplyForce (line 944) | void b2Body_ApplyForce( b2BodyId bodyId, b2Vec2 force, b2Vec2 point, boo...
  function b2Body_ApplyForceToCenter (line 967) | void b2Body_ApplyForceToCenter( b2BodyId bodyId, b2Vec2 force, bool wake )
  function b2Body_ApplyTorque (line 989) | void b2Body_ApplyTorque( b2BodyId bodyId, float torque, bool wake )
  function b2Body_ClearForces (line 1011) | void b2Body_ClearForces( b2BodyId bodyId )
  function b2Body_ApplyLinearImpulse (line 1020) | void b2Body_ApplyLinearImpulse( b2BodyId bodyId, b2Vec2 impulse, b2Vec2 ...
  function b2Body_ApplyLinearImpulseToCenter (line 1048) | void b2Body_ApplyLinearImpulseToCenter( b2BodyId bodyId, b2Vec2 impulse,...
  function b2Body_ApplyAngularImpulse (line 1075) | void b2Body_ApplyAngularImpulse( b2BodyId bodyId, float impulse, bool wa...
  function b2BodyType (line 1102) | b2BodyType b2Body_GetType( b2BodyId bodyId )
  function b2Body_SetType (line 1136) | void b2Body_SetType( b2BodyId bodyId, b2BodyType type )
  function b2Body_SetName (line 1325) | void b2Body_SetName( b2BodyId bodyId, const char* name )
  function b2Body_SetUserData (line 1358) | void b2Body_SetUserData( b2BodyId bodyId, void* userData )
  function b2Body_GetMass (line 1372) | float b2Body_GetMass( b2BodyId bodyId )
  function b2Body_GetRotationalInertia (line 1379) | float b2Body_GetRotationalInertia( b2BodyId bodyId )
  function b2Vec2 (line 1386) | b2Vec2 b2Body_GetLocalCenterOfMass( b2BodyId bodyId )
  function b2Vec2 (line 1394) | b2Vec2 b2Body_GetWorldCenterOfMass( b2BodyId bodyId )
  function b2Body_SetMassData (line 1402) | void b2Body_SetMassData( b2BodyId bodyId, b2MassData massData )
  function b2MassData (line 1429) | b2MassData b2Body_GetMassData( b2BodyId bodyId )
  function b2Body_ApplyMassFromShapes (line 1438) | void b2Body_ApplyMassFromShapes( b2BodyId bodyId )
  function b2Body_SetLinearDamping (line 1450) | void b2Body_SetLinearDamping( b2BodyId bodyId, float linearDamping )
  function b2Body_GetLinearDamping (line 1465) | float b2Body_GetLinearDamping( b2BodyId bodyId )
  function b2Body_SetAngularDamping (line 1473) | void b2Body_SetAngularDamping( b2BodyId bodyId, float angularDamping )
  function b2Body_GetAngularDamping (line 1488) | float b2Body_GetAngularDamping( b2BodyId bodyId )
  function b2Body_SetGravityScale (line 1496) | void b2Body_SetGravityScale( b2BodyId bodyId, float gravityScale )
  function b2Body_GetGravityScale (line 1512) | float b2Body_GetGravityScale( b2BodyId bodyId )
  function b2Body_IsAwake (line 1521) | bool b2Body_IsAwake( b2BodyId bodyId )
  function b2Body_SetAwake (line 1528) | void b2Body_SetAwake( b2BodyId bodyId, bool awake )
  function b2Body_WakeTouching (line 1555) | void b2Body_WakeTouching(b2BodyId bodyId)
  function b2Body_IsEnabled (line 1585) | bool b2Body_IsEnabled( b2BodyId bodyId )
  function b2Body_IsSleepEnabled (line 1592) | bool b2Body_IsSleepEnabled( b2BodyId bodyId )
  function b2Body_SetSleepThreshold (line 1599) | void b2Body_SetSleepThreshold( b2BodyId bodyId, float sleepThreshold )
  function b2Body_GetSleepThreshold (line 1606) | float b2Body_GetSleepThreshold( b2BodyId bodyId )
  function b2Body_EnableSleep (line 1613) | void b2Body_EnableSleep( b2BodyId bodyId, bool enableSleep )
  function b2Body_Disable (line 1632) | void b2Body_Disable( b2BodyId bodyId )
  function b2Body_Enable (line 1702) | void b2Body_Enable( b2BodyId bodyId )
  function b2Body_SetMotionLocks (line 1792) | void b2Body_SetMotionLocks( b2BodyId bodyId, b2MotionLocks locks )
  function b2MotionLocks (line 1839) | b2MotionLocks b2Body_GetMotionLocks( b2BodyId bodyId )
  function b2Body_SetBullet (line 1851) | void b2Body_SetBullet( b2BodyId bodyId, bool flag )
  function b2Body_IsBullet (line 1872) | bool b2Body_IsBullet( b2BodyId bodyId )
  function b2Body_EnableContactEvents (line 1880) | void b2Body_EnableContactEvents( b2BodyId bodyId, bool flag )
  function b2Body_EnableHitEvents (line 1893) | void b2Body_EnableHitEvents( b2BodyId bodyId, bool flag )
  function b2WorldId (line 1906) | b2WorldId b2Body_GetWorld( b2BodyId bodyId )
  function b2Body_GetShapeCount (line 1912) | int b2Body_GetShapeCount( b2BodyId bodyId )
  function b2Body_GetShapes (line 1919) | int b2Body_GetShapes( b2BodyId bodyId, b2ShapeId* shapeArray, int capaci...
  function b2Body_GetJointCount (line 1938) | int b2Body_GetJointCount( b2BodyId bodyId )
  function b2Body_GetJoints (line 1945) | int b2Body_GetJoints( b2BodyId bodyId, b2JointId* jointArray, int capaci...
  function b2ShouldBodiesCollide (line 1969) | bool b2ShouldBodiesCollide( b2World* world, b2Body* bodyA, b2Body* bodyB )

FILE: src/body.h
  type b2World (line 14) | typedef struct b2World b2World;
  type b2BodyFlags (line 16) | enum b2BodyFlags
  type b2Body (line 60) | typedef struct b2Body
  type b2BodyState (line 148) | typedef struct b2BodyState
  type b2BodySim (line 170) | typedef struct b2BodySim
  function b2Sweep (line 224) | static inline b2Sweep b2MakeSweep( const b2BodySim* bodySim )

FILE: src/broad_phase.c
  function b2CreateBroadPhase (line 27) | void b2CreateBroadPhase( b2BroadPhase* bp )
  function b2DestroyBroadPhase (line 51) | void b2DestroyBroadPhase( b2BroadPhase* bp )
  function b2UnBufferMove (line 71) | static inline void b2UnBufferMove( b2BroadPhase* bp, int proxyKey )
  function b2BroadPhase_CreateProxy (line 91) | int b2BroadPhase_CreateProxy( b2BroadPhase* bp, b2BodyType proxyType, b2...
  function b2BroadPhase_DestroyProxy (line 104) | void b2BroadPhase_DestroyProxy( b2BroadPhase* bp, int proxyKey )
  function b2BroadPhase_MoveProxy (line 116) | void b2BroadPhase_MoveProxy( b2BroadPhase* bp, int proxyKey, b2AABB aabb )
  function b2BroadPhase_EnlargeProxy (line 125) | void b2BroadPhase_EnlargeProxy( b2BroadPhase* bp, int proxyKey, b2AABB a...
  type b2MovePair (line 137) | typedef struct b2MovePair
  type b2MoveResult (line 145) | typedef struct b2MoveResult
  type b2QueryPairContext (line 150) | typedef struct b2QueryPairContext
  function b2PairQueryCallback (line 160) | static bool b2PairQueryCallback( int proxyId, uint64_t userData, void* c...
  function b2FindPairsTask (line 314) | static void b2FindPairsTask( int startIndex, int endIndex, uint32_t thre...
  function b2UpdateBroadPhasePairs (line 382) | void b2UpdateBroadPhasePairs( b2World* world )
  function b2BroadPhase_TestOverlap (line 482) | bool b2BroadPhase_TestOverlap( const b2BroadPhase* bp, int proxyKeyA, in...
  function b2BroadPhase_RebuildTrees (line 494) | void b2BroadPhase_RebuildTrees( b2BroadPhase* bp )
  function b2BroadPhase_GetShapeIndex (line 500) | int b2BroadPhase_GetShapeIndex( b2BroadPhase* bp, int proxyKey )
  function b2ValidateBroadphase (line 508) | void b2ValidateBroadphase( const b2BroadPhase* bp )
  function b2ValidateNoEnlarged (line 516) | void b2ValidateNoEnlarged( const b2BroadPhase* bp )

FILE: src/broad_phase.h
  type b2Shape (line 12) | typedef struct b2Shape b2Shape;
  type b2MovePair (line 13) | typedef struct b2MovePair b2MovePair;
  type b2MoveResult (line 14) | typedef struct b2MoveResult b2MoveResult;
  type b2ArenaAllocator (line 15) | typedef struct b2ArenaAllocator b2ArenaAllocator;
  type b2World (line 16) | typedef struct b2World b2World;
  type b2BroadPhase (line 26) | typedef struct b2BroadPhase
  function b2BufferMove (line 74) | static inline void b2BufferMove( b2BroadPhase* bp, int queryProxy )

FILE: src/constants.h
  type b2TreeNodeFlags (line 50) | enum b2TreeNodeFlags

FILE: src/constraint_graph.c
  function b2CreateGraph (line 29) | void b2CreateGraph( b2ConstraintGraph* graph, int bodyCapacity )
  function b2DestroyGraph (line 49) | void b2DestroyGraph( b2ConstraintGraph* graph )
  function b2AddContactToGraph (line 67) | void b2AddContactToGraph( b2World* world, b2ContactSim* contactSim, b2Co...
  function b2RemoveContactFromGraph (line 185) | void b2RemoveContactFromGraph( b2World* world, int bodyIdA, int bodyIdB,...
  function b2AssignJointColor (line 215) | static int b2AssignJointColor( b2ConstraintGraph* graph, int bodyIdA, in...
  function b2JointSim (line 273) | b2JointSim* b2CreateJointInGraph( b2World* world, b2Joint* joint )
  function b2AddJointToGraph (line 292) | void b2AddJointToGraph( b2World* world, b2JointSim* jointSim, b2Joint* j...
  function b2RemoveJointFromGraph (line 298) | void b2RemoveJointFromGraph( b2World* world, int bodyIdA, int bodyIdB, i...

FILE: src/constraint_graph.h
  type b2Body (line 12) | typedef struct b2Body b2Body;
  type b2ContactSim (line 13) | typedef struct b2ContactSim b2ContactSim;
  type b2Contact (line 14) | typedef struct b2Contact b2Contact;
  type b2ContactConstraint (line 15) | typedef struct b2ContactConstraint b2ContactConstraint;
  type b2ContactConstraintSIMD (line 16) | typedef struct b2ContactConstraintSIMD b2ContactConstraintSIMD;
  type b2JointSim (line 17) | typedef struct b2JointSim b2JointSim;
  type b2Joint (line 18) | typedef struct b2Joint b2Joint;
  type b2StepContext (line 19) | typedef struct b2StepContext b2StepContext;
  type b2World (line 20) | typedef struct b2World b2World;
  type b2GraphColor (line 30) | typedef struct b2GraphColor
  type b2ConstraintGraph (line 54) | typedef struct b2ConstraintGraph

FILE: src/contact.c
  function b2Contact (line 57) | static b2Contact* b2GetContactFullId( b2World* world, b2ContactId contac...
  function b2ContactData (line 65) | b2ContactData b2Contact_GetData( b2ContactId contactId )
  type b2Manifold (line 93) | typedef b2Manifold b2ManifoldFcn( const b2Shape* shapeA, b2Transform xfA...
  type b2ContactRegister (line 96) | struct b2ContactRegister
  type b2ContactRegister (line 102) | struct b2ContactRegister
  function b2Manifold (line 105) | static b2Manifold b2CircleManifold( const b2Shape* shapeA, b2Transform x...
  function b2Manifold (line 112) | static b2Manifold b2CapsuleAndCircleManifold( const b2Shape* shapeA, b2T...
  function b2Manifold (line 119) | static b2Manifold b2CapsuleManifold( const b2Shape* shapeA, b2Transform ...
  function b2Manifold (line 126) | static b2Manifold b2PolygonAndCircleManifold( const b2Shape* shapeA, b2T...
  function b2Manifold (line 133) | static b2Manifold b2PolygonAndCapsuleManifold( const b2Shape* shapeA, b2...
  function b2Manifold (line 140) | static b2Manifold b2PolygonManifold( const b2Shape* shapeA, b2Transform ...
  function b2Manifold (line 147) | static b2Manifold b2SegmentAndCircleManifold( const b2Shape* shapeA, b2T...
  function b2Manifold (line 154) | static b2Manifold b2SegmentAndCapsuleManifold( const b2Shape* shapeA, b2...
  function b2Manifold (line 161) | static b2Manifold b2SegmentAndPolygonManifold( const b2Shape* shapeA, b2...
  function b2Manifold (line 168) | static b2Manifold b2ChainSegmentAndCircleManifold( const b2Shape* shapeA...
  function b2Manifold (line 175) | static b2Manifold b2ChainSegmentAndCapsuleManifold( const b2Shape* shape...
  function b2Manifold (line 181) | static b2Manifold b2ChainSegmentAndPolygonManifold( const b2Shape* shape...
  function b2AddType (line 187) | static void b2AddType( b2ManifoldFcn* fcn, b2ShapeType type1, b2ShapeTyp...
  function b2InitializeContactRegisters (line 202) | void b2InitializeContactRegisters( void )
  function b2CreateContact (line 222) | void b2CreateContact( b2World* world, b2Shape* shapeA, b2Shape* shapeB )
  function b2DestroyContact (line 376) | void b2DestroyContact( b2World* world, b2Contact* contact, bool wakeBodi...
  function b2ContactSim (line 507) | b2ContactSim* b2GetContactSim( b2World* world, b2Contact* contact )
  function b2UpdateContact (line 523) | bool b2UpdateContact( b2World* world, b2ContactSim* contactSim, b2Shape*...

FILE: src/contact.h
  type b2Shape (line 12) | typedef struct b2Shape b2Shape;
  type b2World (line 13) | typedef struct b2World b2World;
  type b2ContactFlags (line 15) | enum b2ContactFlags
  type b2ContactEdge (line 32) | typedef struct b2ContactEdge
  type b2Contact (line 41) | typedef struct b2Contact
  type b2ContactSimFlags (line 75) | enum b2ContactSimFlags
  type b2ContactSim (line 99) | typedef struct b2ContactSim

FILE: src/contact_solver.c
  function b2PrepareOverflowContacts (line 24) | void b2PrepareOverflowContacts( b2StepContext* context )
  function b2WarmStartOverflowContacts (line 160) | void b2WarmStartOverflowContacts( b2StepContext* context )
  function b2SolveOverflowContacts (line 237) | void b2SolveOverflowContacts( b2StepContext* context, bool useBias )
  function b2ApplyOverflowRestitution (line 402) | void b2ApplyOverflowRestitution( b2StepContext* context )
  function b2StoreOverflowImpulses (line 507) | void b2StoreOverflowImpulses( b2StepContext* context )
  type __m256 (line 543) | typedef __m256 b2FloatW;
  type float32x4_t (line 550) | typedef float32x4_t b2FloatW;
  type __m128 (line 557) | typedef __m128 b2FloatW;
  type b2FloatW (line 562) | typedef struct b2FloatW
  type b2Vec2W (line 570) | typedef struct b2Vec2W
  type b2RotW (line 576) | typedef struct b2RotW
  function b2FloatW (line 583) | static inline b2FloatW b2ZeroW( void )
  function b2FloatW (line 588) | static inline b2FloatW b2SplatW( float scalar )
  function b2FloatW (line 593) | static inline b2FloatW b2AddW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 598) | static inline b2FloatW b2SubW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 603) | static inline b2FloatW b2MulW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 608) | static inline b2FloatW b2MulAddW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 615) | static inline b2FloatW b2MulSubW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 621) | static inline b2FloatW b2MinW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 626) | static inline b2FloatW b2MaxW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 632) | static inline b2FloatW b2SymClampW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 638) | static inline b2FloatW b2OrW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 643) | static inline b2FloatW b2GreaterThanW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 648) | static inline b2FloatW b2EqualsW( b2FloatW a, b2FloatW b )
  function b2AllZeroW (line 653) | static inline bool b2AllZeroW( b2FloatW a )
  function b2FloatW (line 667) | static inline b2FloatW b2BlendW( b2FloatW a, b2FloatW b, b2FloatW mask )
  function b2FloatW (line 674) | static inline b2FloatW b2ZeroW( void )
  function b2FloatW (line 679) | static inline b2FloatW b2SplatW( float scalar )
  function b2FloatW (line 684) | static inline b2FloatW b2SetW( float a, float b, float c, float d )
  function b2FloatW (line 690) | static inline b2FloatW b2AddW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 695) | static inline b2FloatW b2SubW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 700) | static inline b2FloatW b2MulW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 705) | static inline b2FloatW b2MulAddW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 710) | static inline b2FloatW b2MulSubW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 715) | static inline b2FloatW b2MinW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 720) | static inline b2FloatW b2MaxW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 726) | static inline b2FloatW b2SymClampW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 732) | static inline b2FloatW b2OrW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 737) | static inline b2FloatW b2GreaterThanW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 742) | static inline b2FloatW b2EqualsW( b2FloatW a, b2FloatW b )
  function b2AllZeroW (line 747) | static inline bool b2AllZeroW( b2FloatW a )
  function b2FloatW (line 767) | static inline b2FloatW b2BlendW( b2FloatW a, b2FloatW b, b2FloatW mask )
  function b2FloatW (line 773) | static inline b2FloatW b2LoadW( const float32_t* data )
  function b2StoreW (line 778) | static inline void b2StoreW( float32_t* data, b2FloatW a )
  function b2FloatW (line 783) | static inline b2FloatW b2UnpackLoW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 795) | static inline b2FloatW b2UnpackHiW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 809) | static inline b2FloatW b2ZeroW( void )
  function b2FloatW (line 814) | static inline b2FloatW b2SplatW( float scalar )
  function b2FloatW (line 819) | static inline b2FloatW b2SetW( float a, float b, float c, float d )
  function b2FloatW (line 824) | static inline b2FloatW b2AddW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 829) | static inline b2FloatW b2SubW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 834) | static inline b2FloatW b2MulW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 839) | static inline b2FloatW b2MulAddW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 844) | static inline b2FloatW b2MulSubW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 849) | static inline b2FloatW b2MinW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 854) | static inline b2FloatW b2MaxW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 860) | static inline b2FloatW b2SymClampW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 871) | static inline b2FloatW b2OrW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 876) | static inline b2FloatW b2GreaterThanW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 881) | static inline b2FloatW b2EqualsW( b2FloatW a, b2FloatW b )
  function b2AllZeroW (line 886) | static inline bool b2AllZeroW( b2FloatW a )
  function b2FloatW (line 900) | static inline b2FloatW b2BlendW( b2FloatW a, b2FloatW b, b2FloatW mask )
  function b2FloatW (line 905) | static inline b2FloatW b2LoadW( const float* data )
  function b2StoreW (line 910) | static inline void b2StoreW( float* data, b2FloatW a )
  function b2FloatW (line 915) | static inline b2FloatW b2UnpackLoW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 920) | static inline b2FloatW b2UnpackHiW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 927) | static inline b2FloatW b2ZeroW( void )
  function b2FloatW (line 932) | static inline b2FloatW b2SplatW( float scalar )
  function b2FloatW (line 937) | static inline b2FloatW b2AddW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 942) | static inline b2FloatW b2SubW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 947) | static inline b2FloatW b2MulW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 952) | static inline b2FloatW b2MulAddW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 957) | static inline b2FloatW b2MulSubW( b2FloatW a, b2FloatW b, b2FloatW c )
  function b2FloatW (line 962) | static inline b2FloatW b2MinW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 972) | static inline b2FloatW b2MaxW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 983) | static inline b2FloatW b2SymClampW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 993) | static inline b2FloatW b2OrW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 1003) | static inline b2FloatW b2GreaterThanW( b2FloatW a, b2FloatW b )
  function b2FloatW (line 1013) | static inline b2FloatW b2EqualsW( b2FloatW a, b2FloatW b )
  function b2AllZeroW (line 1023) | static inline bool b2AllZeroW( b2FloatW a )
  function b2FloatW (line 1029) | static inline b2FloatW b2BlendW( b2FloatW a, b2FloatW b, b2FloatW mask )
  function b2FloatW (line 1041) | static inline b2FloatW b2DotW( b2Vec2W a, b2Vec2W b )
  function b2FloatW (line 1046) | static inline b2FloatW b2CrossW( b2Vec2W a, b2Vec2W b )
  function b2Vec2W (line 1051) | static inline b2Vec2W b2RotateVectorW( b2RotW q, b2Vec2W v )
  type b2ContactConstraintSIMD (line 1061) | typedef struct b2ContactConstraintSIMD
  function b2GetContactConstraintSIMDByteCount (line 1093) | int b2GetContactConstraintSIMDByteCount( void )
  type b2BodyStateW (line 1099) | typedef struct b2BodyStateW
  function b2BodyStateW (line 1112) | static b2BodyStateW b2GatherBodies( const b2BodyState* B2_RESTRICT state...
  function b2ScatterBodies (line 1157) | static void b2ScatterBodies( b2BodyState* B2_RESTRICT states, int* B2_RE...
  function b2BodyStateW (line 1203) | static b2BodyStateW b2GatherBodies( const b2BodyState* B2_RESTRICT state...
  function b2ScatterBodies (line 1257) | static void b2ScatterBodies( b2BodyState* B2_RESTRICT states, int* B2_RE...
  function b2BodyStateW (line 1309) | static b2BodyStateW b2GatherBodies( const b2BodyState* B2_RESTRICT state...
  function b2ScatterBodies (line 1361) | static void b2ScatterBodies( b2BodyState* B2_RESTRICT states, int* B2_RE...
  function b2BodyStateW (line 1436) | static b2BodyStateW b2GatherBodies( const b2BodyState* B2_RESTRICT state...
  function b2ScatterBodies (line 1459) | static void b2ScatterBodies( b2BodyState* B2_RESTRICT states, int* B2_RE...
  function b2PrepareContactsTask (line 1496) | void b2PrepareContactsTask( int startIndex, int endIndex, b2StepContext*...
  function b2WarmStartContactsTask (line 1749) | void b2WarmStartContactsTask( int startIndex, int endIndex, b2StepContex...
  function b2SolveContactsTask (line 1811) | void b2SolveContactsTask( int startIndex, int endIndex, b2StepContext* c...
  function b2ApplyRestitutionTask (line 2051) | void b2ApplyRestitutionTask( int startIndex, int endIndex, b2StepContext...
  function b2StoreImpulsesTask (line 2164) | void b2StoreImpulsesTask( int startIndex, int endIndex, b2StepContext* c...

FILE: src/contact_solver.h
  type b2ContactSim (line 8) | typedef struct b2ContactSim b2ContactSim;
  type b2ContactConstraintPoint (line 10) | typedef struct b2ContactConstraintPoint
  type b2ContactConstraint (line 22) | typedef struct b2ContactConstraint

FILE: src/core.c
  function b2SetLengthUnitsPerMeter (line 38) | void b2SetLengthUnitsPerMeter( float lengthUnits )
  function b2GetLengthUnitsPerMeter (line 44) | float b2GetLengthUnitsPerMeter( void )
  function b2DefaultAssertFcn (line 49) | static int b2DefaultAssertFcn( const char* condition, const char* fileNa...
  function b2SetAssertFcn (line 59) | void b2SetAssertFcn( b2AssertFcn* assertFcn )
  function b2InternalAssertFcn (line 66) | int b2InternalAssertFcn( const char* condition, const char* fileName, in...
  function b2DefaultLogFcn (line 72) | static void b2DefaultLogFcn( const char* message )
  function b2SetLogFcn (line 79) | void b2SetLogFcn( b2LogFcn* logFcn )
  function b2Log (line 85) | void b2Log( const char* format, ... )
  function b2Version (line 95) | b2Version b2GetVersion( void )
  function b2SetAllocator (line 109) | void b2SetAllocator( b2AllocFcn* allocFcn, b2FreeFcn* freeFcn )
  function b2Free (line 164) | void b2Free( void* mem, int size )
  function b2GetByteCount (line 201) | int b2GetByteCount( void )

FILE: src/core.h
  type b2AtomicInt (line 133) | typedef struct b2AtomicInt
  type b2AtomicU32 (line 138) | typedef struct b2AtomicU32
  type b2Mutex (line 155) | typedef struct b2Mutex b2Mutex;

FILE: src/ctz.h
  function b2CTZ32 (line 15) | static inline uint32_t b2CTZ32( uint32_t block )
  function b2CLZ32 (line 23) | static inline uint32_t b2CLZ32( uint32_t value )
  function b2CTZ64 (line 49) | static inline uint32_t b2CTZ64( uint64_t block )
  function b2PopCount64 (line 71) | static inline int b2PopCount64( uint64_t block )
  function b2CTZ32 (line 77) | static inline uint32_t b2CTZ32( uint32_t block )
  function b2CLZ32 (line 82) | static inline uint32_t b2CLZ32( uint32_t value )
  function b2CTZ64 (line 87) | static inline uint32_t b2CTZ64( uint64_t block )
  function b2PopCount64 (line 92) | static inline int b2PopCount64( uint64_t block )
  function b2IsPowerOf2 (line 98) | static inline bool b2IsPowerOf2( int x )
  function b2BoundingPowerOf2 (line 103) | static inline int b2BoundingPowerOf2( int x )
  function b2RoundUpPowerOf2 (line 113) | static inline int b2RoundUpPowerOf2( int x )

FILE: src/distance.c
  function b2Transform (line 14) | b2Transform b2GetSweepTransform( const b2Sweep* sweep, float time )
  function b2SegmentDistanceResult (line 33) | b2SegmentDistanceResult b2SegmentDistance( b2Vec2 p1, b2Vec2 q1, b2Vec2 ...
  function b2ShapeProxy (line 108) | b2ShapeProxy b2MakeProxy( const b2Vec2* points, int count, float radius )
  function b2ShapeProxy (line 121) | b2ShapeProxy b2MakeOffsetProxy( const b2Vec2* points, int count, float r...
  function b2Vec2 (line 138) | static inline b2Vec2 b2Weight2( float a1, b2Vec2 w1, float a2, b2Vec2 w2 )
  function b2Vec2 (line 143) | static inline b2Vec2 b2Weight3( float a1, b2Vec2 w1, float a2, b2Vec2 w2...
  function b2FindSupport (line 148) | static inline int b2FindSupport( const b2ShapeProxy* proxy, b2Vec2 direc...
  function b2Simplex (line 168) | static b2Simplex b2MakeSimplexFromCache( const b2SimplexCache* cache, co...
  function b2MakeSimplexCache (line 206) | static void b2MakeSimplexCache( b2SimplexCache* cache, const b2Simplex* ...
  function b2ComputeWitnessPoints (line 217) | static void b2ComputeWitnessPoints( const b2Simplex* s, b2Vec2* a, b2Vec...
  function b2Vec2 (line 271) | static b2Vec2 b2SolveSimplex2( b2Simplex* s )
  function b2Vec2 (line 306) | static b2Vec2 b2SolveSimplex3( b2Simplex* s )
  function b2DistanceOutput (line 421) | b2DistanceOutput b2ShapeDistance( const b2DistanceInput* input, b2Simple...
  function b2CastOutput (line 608) | b2CastOutput b2ShapeCast( const b2ShapeCastPairInput* input )
  function b2Vec2 (line 701) | static inline b2Vec2 b2ComputeSimplexClosestPoint( const b2Simplex* s )
  type b2ShapeCastData (line 716) | typedef struct b2ShapeCastData
  function b2CastOutput (line 739) | b2CastOutput b2ShapeCastMerged( const b2ShapeCastPairInput* input, b2Sha...
  type b2SeparationType (line 925) | typedef enum b2SeparationType
  type b2SeparationFunction (line 932) | typedef struct b2SeparationFunction
  function b2SeparationFunction (line 942) | static b2SeparationFunction b2MakeSeparationFunction( const b2SimplexCac...
  function b2FindMinSeparation (line 1019) | static float b2FindMinSeparation( const b2SeparationFunction* f, int* in...
  function b2EvaluateSeparation (line 1087) | static float b2EvaluateSeparation( const b2SeparationFunction* f, int in...
  function b2TOIOutput (line 1138) | b2TOIOutput b2TimeOfImpact( const b2TOIInput* input )

FILE: src/distance_joint.c
  function b2DistanceJoint_SetLength (line 18) | void b2DistanceJoint_SetLength( b2JointId jointId, float length )
  function b2DistanceJoint_GetLength (line 29) | float b2DistanceJoint_GetLength( b2JointId jointId )
  function b2DistanceJoint_EnableLimit (line 36) | void b2DistanceJoint_EnableLimit( b2JointId jointId, bool enableLimit )
  function b2DistanceJoint_IsLimitEnabled (line 43) | bool b2DistanceJoint_IsLimitEnabled( b2JointId jointId )
  function b2DistanceJoint_SetLengthRange (line 49) | void b2DistanceJoint_SetLengthRange( b2JointId jointId, float minLength,...
  function b2DistanceJoint_GetMinLength (line 63) | float b2DistanceJoint_GetMinLength( b2JointId jointId )
  function b2DistanceJoint_GetMaxLength (line 70) | float b2DistanceJoint_GetMaxLength( b2JointId jointId )
  function b2DistanceJoint_GetCurrentLength (line 77) | float b2DistanceJoint_GetCurrentLength( b2JointId jointId )
  function b2DistanceJoint_EnableSpring (line 98) | void b2DistanceJoint_EnableSpring( b2JointId jointId, bool enableSpring )
  function b2DistanceJoint_IsSpringEnabled (line 104) | bool b2DistanceJoint_IsSpringEnabled( b2JointId jointId )
  function b2DistanceJoint_SetSpringForceRange (line 110) | void b2DistanceJoint_SetSpringForceRange( b2JointId jointId, float lower...
  function b2DistanceJoint_GetSpringForceRange (line 118) | void b2DistanceJoint_GetSpringForceRange( b2JointId jointId, float* lowe...
  function b2DistanceJoint_SetSpringHertz (line 125) | void b2DistanceJoint_SetSpringHertz( b2JointId jointId, float hertz )
  function b2DistanceJoint_SetSpringDampingRatio (line 131) | void b2DistanceJoint_SetSpringDampingRatio( b2JointId jointId, float dam...
  function b2DistanceJoint_GetSpringHertz (line 137) | float b2DistanceJoint_GetSpringHertz( b2JointId jointId )
  function b2DistanceJoint_GetSpringDampingRatio (line 144) | float b2DistanceJoint_GetSpringDampingRatio( b2JointId jointId )
  function b2DistanceJoint_EnableMotor (line 151) | void b2DistanceJoint_EnableMotor( b2JointId jointId, bool enableMotor )
  function b2DistanceJoint_IsMotorEnabled (line 161) | bool b2DistanceJoint_IsMotorEnabled( b2JointId jointId )
  function b2DistanceJoint_SetMotorSpeed (line 167) | void b2DistanceJoint_SetMotorSpeed( b2JointId jointId, float motorSpeed )
  function b2DistanceJoint_GetMotorSpeed (line 173) | float b2DistanceJoint_GetMotorSpeed( b2JointId jointId )
  function b2DistanceJoint_GetMotorForce (line 179) | float b2DistanceJoint_GetMotorForce( b2JointId jointId )
  function b2DistanceJoint_SetMaxMotorForce (line 186) | void b2DistanceJoint_SetMaxMotorForce( b2JointId jointId, float force )
  function b2DistanceJoint_GetMaxMotorForce (line 192) | float b2DistanceJoint_GetMaxMotorForce( b2JointId jointId )
  function b2Vec2 (line 198) | b2Vec2 b2GetDistanceJointForce( b2World* world, b2JointSim* base )
  function b2PrepareDistanceJoint (line 228) | void b2PrepareDistanceJoint( b2JointSim* base, b2StepContext* context )
  function b2WarmStartDistanceJoint (line 293) | void b2WarmStartDistanceJoint( b2JointSim* base, b2StepContext* context )
  function b2SolveDistanceJoint (line 332) | void b2SolveDistanceJoint( b2JointSim* base, b2StepContext* context, boo...
  function Dump (line 523) | void b2DistanceJoint::Dump()
  function b2DrawDistanceJoint (line 543) | void b2DrawDistanceJoint( b2DebugDraw* draw, b2JointSim* base, b2Transfo...

FILE: src/dynamic_tree.c
  type b2TreeNode (line 19) | typedef struct b2TreeNode
  function b2IsLeaf (line 65) | static bool b2IsLeaf( const b2TreeNode* node )
  function b2IsAllocated (line 70) | static bool b2IsAllocated( const b2TreeNode* node )
  function b2MaxUInt16 (line 75) | static uint16_t b2MaxUInt16( uint16_t a, uint16_t b )
  function b2DynamicTree (line 80) | b2DynamicTree b2DynamicTree_Create( void )
  function b2DynamicTree_Destroy (line 114) | void b2DynamicTree_Destroy( b2DynamicTree* tree )
  function b2AllocateNode (line 126) | static int b2AllocateNode( b2DynamicTree* tree )
  function b2FreeNode (line 164) | static void b2FreeNode( b2DynamicTree* tree, int nodeId )
  function b2FindBestSibling (line 191) | static int b2FindBestSibling( const b2DynamicTree* tree, b2AABB boxD )
  type b2RotateType (line 331) | enum b2RotateType
  function b2RotateNodes (line 342) | static void b2RotateNodes( b2DynamicTree* tree, int iA )
  function b2InsertLeaf (line 629) | static void b2InsertLeaf( b2DynamicTree* tree, int leaf, bool shouldRota...
  function b2RemoveLeaf (line 702) | static void b2RemoveLeaf( b2DynamicTree* tree, int leaf )
  function b2DynamicTree_CreateProxy (line 771) | int b2DynamicTree_CreateProxy( b2DynamicTree* tree, b2AABB aabb, uint64_...
  function b2DynamicTree_DestroyProxy (line 795) | void b2DynamicTree_DestroyProxy( b2DynamicTree* tree, int proxyId )
  function b2DynamicTree_GetProxyCount (line 807) | int b2DynamicTree_GetProxyCount( const b2DynamicTree* tree )
  function b2DynamicTree_MoveProxy (line 812) | void b2DynamicTree_MoveProxy( b2DynamicTree* tree, int proxyId, b2AABB a...
  function b2DynamicTree_EnlargeProxy (line 828) | void b2DynamicTree_EnlargeProxy( b2DynamicTree* tree, int proxyId, b2AAB...
  function b2DynamicTree_SetCategoryBits (line 869) | void b2DynamicTree_SetCategoryBits( b2DynamicTree* tree, int proxyId, ui...
  function b2DynamicTree_GetCategoryBits (line 894) | uint64_t b2DynamicTree_GetCategoryBits( b2DynamicTree* tree, int proxyId )
  function b2DynamicTree_GetHeight (line 900) | int b2DynamicTree_GetHeight( const b2DynamicTree* tree )
  function b2DynamicTree_GetAreaRatio (line 910) | float b2DynamicTree_GetAreaRatio( const b2DynamicTree* tree )
  function b2AABB (line 935) | b2AABB b2DynamicTree_GetRootBounds( const b2DynamicTree* tree )
  function b2ComputeHeight (line 948) | static int b2ComputeHeight( const b2DynamicTree* tree, int nodeId )
  function b2ValidateStructure (line 963) | static void b2ValidateStructure( const b2DynamicTree* tree, int index )
  function b2ValidateMetrics (line 1003) | static void b2ValidateMetrics( const b2DynamicTree* tree, int index )
  function b2DynamicTree_Validate (line 1047) | void b2DynamicTree_Validate( const b2DynamicTree* tree )
  function b2DynamicTree_ValidateNoEnlarged (line 1077) | void b2DynamicTree_ValidateNoEnlarged( const b2DynamicTree* tree )
  function b2DynamicTree_GetByteCount (line 1095) | int b2DynamicTree_GetByteCount( const b2DynamicTree* tree )
  function b2DynamicTree_GetUserData (line 1103) | uint64_t b2DynamicTree_GetUserData( const b2DynamicTree* tree, int proxy...
  function b2AABB (line 1109) | b2AABB b2DynamicTree_GetAABB( const b2DynamicTree* tree, int proxyId )
  function b2TreeStats (line 1115) | b2TreeStats b2DynamicTree_Query( const b2DynamicTree* tree, b2AABB aabb,...
  function b2TreeStats (line 1167) | b2TreeStats b2DynamicTree_QueryAll( const b2DynamicTree* tree, b2AABB aa...
  function b2TreeStats (line 1218) | b2TreeStats b2DynamicTree_RayCast( const b2DynamicTree* tree, const b2Ra...
  function b2TreeStats (line 1338) | b2TreeStats b2DynamicTree_ShapeCast( const b2DynamicTree* tree, const b2...
  function b2PartitionMid (line 1472) | static int b2PartitionMid( int* indices, b2Vec2* centers, int count )
  type b2TreeBin (line 1584) | typedef struct b2TreeBin
  type b2TreePlane (line 1590) | typedef struct b2TreePlane
  function b2PartitionSAH (line 1600) | static int b2PartitionSAH( int* indices, int* binIndices, b2AABB* boxes,...
  type b2RebuildItem (line 1750) | struct b2RebuildItem
  function b2BuildTree (line 1762) | static int b2BuildTree( b2DynamicTree* tree, int leafCount )
  function b2DynamicTree_Rebuild (line 1918) | int b2DynamicTree_Rebuild( b2DynamicTree* tree, bool fullBuild )

FILE: src/geometry.c
  function b2IsValidRay (line 15) | bool b2IsValidRay( const b2RayCastInput* input )
  function b2Vec2 (line 22) | static b2Vec2 b2ComputePolygonCentroid( const b2Vec2* vertices, int count )
  function b2Polygon (line 56) | b2Polygon b2MakePolygon( const b2Hull* hull, float radius )
  function b2Polygon (line 91) | b2Polygon b2MakeOffsetPolygon( const b2Hull* hull, b2Vec2 position, b2Ro...
  function b2Polygon (line 96) | b2Polygon b2MakeOffsetRoundedPolygon( const b2Hull* hull, b2Vec2 positio...
  function b2Polygon (line 133) | b2Polygon b2MakeSquare( float halfWidth )
  function b2Polygon (line 138) | b2Polygon b2MakeBox( float halfWidth, float halfHeight )
  function b2Polygon (line 158) | b2Polygon b2MakeRoundedBox( float halfWidth, float halfHeight, float rad...
  function b2Polygon (line 166) | b2Polygon b2MakeOffsetBox( float halfWidth, float halfHeight, b2Vec2 cen...
  function b2Polygon (line 185) | b2Polygon b2MakeOffsetRoundedBox( float halfWidth, float halfHeight, b2V...
  function b2Polygon (line 205) | b2Polygon b2TransformPolygon( b2Transform transform, const b2Polygon* po...
  function b2MassData (line 220) | b2MassData b2ComputeCircleMass( const b2Circle* shape, float density )
  function b2MassData (line 234) | b2MassData b2ComputeCapsuleMass( const b2Capsule* shape, float density )
  function b2MassData (line 273) | b2MassData b2ComputePolygonMass( const b2Polygon* shape, float density )
  function b2AABB (line 401) | b2AABB b2ComputeCircleAABB( const b2Circle* shape, b2Transform xf )
  function b2AABB (line 410) | b2AABB b2ComputeCapsuleAABB( const b2Capsule* shape, b2Transform xf )
  function b2AABB (line 423) | b2AABB b2ComputePolygonAABB( const b2Polygon* shape, b2Transform xf )
  function b2AABB (line 444) | b2AABB b2ComputeSegmentAABB( const b2Segment* shape, b2Transform xf )
  function b2PointInCircle (line 456) | bool b2PointInCircle( const b2Circle* shape, b2Vec2 point )
  function b2PointInCapsule (line 462) | bool b2PointInCapsule( const b2Capsule* shape, b2Vec2 point )
  function b2PointInPolygon (line 489) | bool b2PointInPolygon( const b2Polygon* shape, b2Vec2 point )
  function b2CastOutput (line 506) | b2CastOutput b2RayCastCircle( const b2Circle* shape, const b2RayCastInpu...
  function b2CastOutput (line 582) | b2CastOutput b2RayCastCapsule( const b2Capsule* shape, const b2RayCastIn...
  function b2CastOutput (line 718) | b2CastOutput b2RayCastSegment( const b2Segment* shape, const b2RayCastIn...
  function b2CastOutput (line 799) | b2CastOutput b2RayCastPolygon( const b2Polygon* shape, const b2RayCastIn...
  function b2CastOutput (line 893) | b2CastOutput b2ShapeCastCircle( const b2Circle* shape, const b2ShapeCast...
  function b2CastOutput (line 908) | b2CastOutput b2ShapeCastCapsule( const b2Capsule* shape, const b2ShapeCa...
  function b2CastOutput (line 923) | b2CastOutput b2ShapeCastSegment( const b2Segment* shape, const b2ShapeCa...
  function b2CastOutput (line 938) | b2CastOutput b2ShapeCastPolygon( const b2Polygon* shape, const b2ShapeCa...
  function b2PlaneResult (line 953) | b2PlaneResult b2CollideMoverAndCircle( const b2Capsule* mover, const b2C...
  function b2PlaneResult (line 980) | b2PlaneResult b2CollideMoverAndCapsule( const b2Capsule* mover, const b2...
  function b2PlaneResult (line 1007) | b2PlaneResult b2CollideMoverAndPolygon( const b2Capsule* mover, const b2...
  function b2PlaneResult (line 1034) | b2PlaneResult b2CollideMoverAndSegment( const b2Capsule* mover, const b2...

FILE: src/hull.c
  function b2Hull (line 13) | static b2Hull b2RecurseHull( b2Vec2 p1, b2Vec2 p2, b2Vec2* ps, int count )
  function b2Hull (line 87) | b2Hull b2ComputeHull( const b2Vec2* points, int count )
  function b2ValidateHull (line 273) | bool b2ValidateHull( const b2Hull* hull )

FILE: src/id_pool.c
  function b2IdPool (line 6) | b2IdPool b2CreateIdPool( void )
  function b2DestroyIdPool (line 13) | void b2DestroyIdPool( b2IdPool* pool )
  function b2AllocId (line 19) | int b2AllocId( b2IdPool* pool )
  function b2FreeId (line 33) | void b2FreeId( b2IdPool* pool, int id )
  function b2ValidateFreeId (line 42) | void b2ValidateFreeId( b2IdPool* pool, int id )
  function b2ValidateUsedId (line 56) | void b2ValidateUsedId( b2IdPool* pool, int id )
  function b2ValidateFreeId (line 70) | void b2ValidateFreeId( b2IdPool* pool, int id )
  function b2ValidateUsedId (line 75) | void b2ValidateUsedId( b2IdPool* pool, int id )

FILE: src/id_pool.h
  type b2IdPool (line 8) | typedef struct b2IdPool
  function b2GetIdCount (line 22) | static inline int b2GetIdCount( b2IdPool* pool )
  function b2GetIdCapacity (line 27) | static inline int b2GetIdCapacity( b2IdPool* pool )
  function b2GetIdBytes (line 32) | static inline int b2GetIdBytes( b2IdPool* pool )

FILE: src/island.c
  function b2Island (line 18) | b2Island* b2CreateIsland( b2World* world, int setIndex )
  function b2DestroyIsland (line 57) | void b2DestroyIsland( b2World* world, int islandId )
  function b2MergeIslands (line 85) | static int b2MergeIslands( b2World* world, int islandIdA, int islandIdB )
  function b2AddContactToIsland (line 236) | static void b2AddContactToIsland( b2World* world, int islandId, b2Contac...
  function b2LinkContact (line 264) | void b2LinkContact( b2World* world, b2Contact* contact )
  function b2UnlinkContact (line 305) | void b2UnlinkContact( b2World* world, b2Contact* contact )
  function b2AddJointToIsland (line 348) | static void b2AddJointToIsland( b2World* world, int islandId, b2Joint* j...
  function b2LinkJoint (line 375) | void b2LinkJoint( b2World* world, b2Joint* joint )
  function b2UnlinkJoint (line 403) | void b2UnlinkJoint( b2World* world, b2Joint* joint )
  function b2SplitIsland (line 454) | void b2SplitIsland( b2World* world, int baseId )
  function b2SplitIslandTask (line 691) | void b2SplitIslandTask( int startIndex, int endIndex, uint32_t threadInd...
  function b2ValidateIsland (line 709) | void b2ValidateIsland( b2World* world, int islandId )
  function b2ValidateIsland (line 819) | void b2ValidateIsland( b2World* world, int islandId )

FILE: src/island.h
  type b2Contact (line 11) | typedef struct b2Contact b2Contact;
  type b2Joint (line 12) | typedef struct b2Joint b2Joint;
  type b2World (line 13) | typedef struct b2World b2World;
  type b2Island (line 27) | typedef struct b2Island
  type b2IslandSim (line 57) | typedef struct b2IslandSim

FILE: src/joint.c
  function b2JointDef (line 26) | static b2JointDef b2DefaultJointDef( void )
  function b2DistanceJointDef (line 39) | b2DistanceJointDef b2DefaultDistanceJointDef( void )
  function b2MotorJointDef (line 51) | b2MotorJointDef b2DefaultMotorJointDef( void )
  function b2FilterJointDef (line 59) | b2FilterJointDef b2DefaultFilterJointDef( void )
  function b2PrismaticJointDef (line 67) | b2PrismaticJointDef b2DefaultPrismaticJointDef( void )
  function b2RevoluteJointDef (line 75) | b2RevoluteJointDef b2DefaultRevoluteJointDef( void )
  function b2WeldJointDef (line 83) | b2WeldJointDef b2DefaultWeldJointDef( void )
  function b2WheelJointDef (line 91) | b2WheelJointDef b2DefaultWheelJointDef( void )
  function b2ExplosionDef (line 102) | b2ExplosionDef b2DefaultExplosionDef( void )
  function b2Joint (line 109) | b2Joint* b2GetJointFullId( b2World* world, b2JointId jointId )
  function b2JointSim (line 117) | b2JointSim* b2GetJointSim( b2World* world, b2Joint* joint )
  function b2JointSim (line 130) | b2JointSim* b2GetJointSimCheckType( b2JointId jointId, b2JointType type )
  function b2DestroyContactsBetweenBodies (line 148) | static void b2DestroyContactsBetweenBodies( b2World* world, b2Body* body...
  type b2JointPair (line 188) | typedef struct b2JointPair
  function b2JointPair (line 194) | static b2JointPair b2CreateJoint( b2World* world, const b2JointDef* def,...
  function b2JointId (line 384) | b2JointId b2CreateDistanceJoint( b2WorldId worldId, const b2DistanceJoin...
  function b2JointId (line 426) | b2JointId b2CreateMotorJoint( b2WorldId worldId, const b2MotorJointDef* ...
  function b2JointId (line 457) | b2JointId b2CreateFilterJoint( b2WorldId worldId, const b2FilterJointDef...
  function b2JointId (line 477) | b2JointId b2CreatePrismaticJoint( b2WorldId worldId, const b2PrismaticJo...
  function b2JointId (line 511) | b2JointId b2CreateRevoluteJoint( b2WorldId worldId, const b2RevoluteJoin...
  function b2JointId (line 549) | b2JointId b2CreateWeldJoint( b2WorldId worldId, const b2WeldJointDef* def )
  function b2JointId (line 578) | b2JointId b2CreateWheelJoint( b2WorldId worldId, const b2WheelJointDef* ...
  function b2DestroyJointInternal (line 616) | void b2DestroyJointInternal( b2World* world, b2Joint* joint, bool wakeBo...
  function b2DestroyJoint (line 723) | void b2DestroyJoint( b2JointId jointId, bool wakeAttached )
  function b2JointType (line 738) | b2JointType b2Joint_GetType( b2JointId jointId )
  function b2BodyId (line 745) | b2BodyId b2Joint_GetBodyA( b2JointId jointId )
  function b2BodyId (line 752) | b2BodyId b2Joint_GetBodyB( b2JointId jointId )
  function b2WorldId (line 759) | b2WorldId b2Joint_GetWorld( b2JointId jointId )
  function b2Joint_SetLocalFrameA (line 765) | void b2Joint_SetLocalFrameA( b2JointId jointId, b2Transform localFrame )
  function b2Transform (line 775) | b2Transform b2Joint_GetLocalFrameA( b2JointId jointId )
  function b2Joint_SetLocalFrameB (line 783) | void b2Joint_SetLocalFrameB( b2JointId jointId, b2Transform localFrame )
  function b2Transform (line 793) | b2Transform b2Joint_GetLocalFrameB( b2JointId jointId )
  function b2Joint_SetCollideConnected (line 801) | void b2Joint_SetCollideConnected( b2JointId jointId, bool shouldCollide )
  function b2Joint_GetCollideConnected (line 846) | bool b2Joint_GetCollideConnected( b2JointId jointId )
  function b2Joint_SetUserData (line 853) | void b2Joint_SetUserData( b2JointId jointId, void* userData )
  function b2Joint_WakeBodies (line 867) | void b2Joint_WakeBodies( b2JointId jointId )
  function b2GetJointReaction (line 883) | void b2GetJointReaction( b2JointSim* sim, float invTimeStep, float* forc...
  function b2Vec2 (line 950) | static b2Vec2 b2GetJointConstraintForce( b2World* world, b2Joint* joint )
  function b2GetJointConstraintTorque (line 983) | static float b2GetJointConstraintTorque( b2World* world, b2Joint* joint )
  function b2Vec2 (line 1016) | b2Vec2 b2Joint_GetConstraintForce( b2JointId jointId )
  function b2Joint_GetConstraintTorque (line 1023) | float b2Joint_GetConstraintTorque( b2JointId jointId )
  function b2Joint_GetLinearSeparation (line 1030) | float b2Joint_GetLinearSeparation( b2JointId jointId )
  function b2Joint_GetAngularSeparation (line 1148) | float b2Joint_GetAngularSeparation( b2JointId jointId )
  function b2Joint_SetConstraintTuning (line 1214) | void b2Joint_SetConstraintTuning( b2JointId jointId, float hertz, float ...
  function b2Joint_GetConstraintTuning (line 1226) | void b2Joint_GetConstraintTuning( b2JointId jointId, float* hertz, float...
  function b2Joint_SetForceThreshold (line 1235) | void b2Joint_SetForceThreshold( b2JointId jointId, float threshold )
  function b2Joint_GetForceThreshold (line 1245) | float b2Joint_GetForceThreshold( b2JointId jointId )
  function b2Joint_SetTorqueThreshold (line 1253) | void b2Joint_SetTorqueThreshold( b2JointId jointId, float threshold )
  function b2Joint_GetTorqueThreshold (line 1263) | float b2Joint_GetTorqueThreshold( b2JointId jointId )
  function b2PrepareJoint (line 1271) | void b2PrepareJoint( b2JointSim* joint, b2StepContext* context )
  function b2WarmStartJoint (line 1311) | void b2WarmStartJoint( b2JointSim* joint, b2StepContext* context )
  function b2SolveJoint (line 1347) | void b2SolveJoint( b2JointSim* joint, b2StepContext* context, bool useBi...
  function b2PrepareOverflowJoints (line 1383) | void b2PrepareOverflowJoints( b2StepContext* context )
  function b2WarmStartOverflowJoints (line 1400) | void b2WarmStartOverflowJoints( b2StepContext* context )
  function b2SolveOverflowJoints (line 1417) | void b2SolveOverflowJoints( b2StepContext* context, bool useBias )
  function b2DrawJoint (line 1434) | void b2DrawJoint( b2DebugDraw* draw, b2World* world, b2Joint* joint )

FILE: src/joint.h
  type b2DebugDraw (line 10) | typedef struct b2DebugDraw b2DebugDraw;
  type b2StepContext (line 11) | typedef struct b2StepContext b2StepContext;
  type b2World (line 12) | typedef struct b2World b2World;
  type b2JointEdge (line 19) | typedef struct b2JointEdge
  type b2Joint (line 27) | typedef struct b2Joint
  type b2DistanceJoint (line 62) | typedef struct b2DistanceJoint
  type b2MotorJoint (line 93) | typedef struct b2MotorJoint
  type b2PrismaticJoint (line 123) | typedef struct b2PrismaticJoint
  type b2RevoluteJoint (line 150) | typedef struct b2RevoluteJoint
  type b2WeldJoint (line 178) | typedef struct b2WeldJoint
  type b2WheelJoint (line 198) | typedef struct b2WheelJoint
  type b2JointSim (line 229) | typedef struct b2JointSim

FILE: src/manifold.c
  function b2Polygon (line 16) | static b2Polygon b2MakeCapsule( b2Vec2 p1, b2Vec2 p2, float radius )
  function b2Manifold (line 40) | b2Manifold b2CollideCircles( const b2Circle* circleA, b2Transform xfA, c...
  function b2Manifold (line 77) | b2Manifold b2CollideCapsuleAndCircle( const b2Capsule* capsuleA, b2Trans...
  function b2Manifold (line 141) | b2Manifold b2CollidePolygonAndCircle( const b2Polygon* polygonA, b2Trans...
  function b2Manifold (line 261) | b2Manifold b2CollideCapsules( const b2Capsule* capsuleA, b2Transform xfA...
  function b2Manifold (line 532) | b2Manifold b2CollideSegmentAndCapsule( const b2Segment* segmentA, b2Tran...
  function b2Manifold (line 538) | b2Manifold b2CollidePolygonAndCapsule( const b2Polygon* polygonA, b2Tran...
  function b2Manifold (line 545) | static b2Manifold b2ClipPolygons( const b2Polygon* polyA, const b2Polygo...
  function b2FindMaxSeparation (line 680) | static float b2FindMaxSeparation( int* edgeIndex, const b2Polygon* poly1...
  function b2Manifold (line 736) | b2Manifold b2CollidePolygons( const b2Polygon* polygonA, b2Transform xfA...
  function b2Manifold (line 1077) | b2Manifold b2CollideSegmentAndCircle( const b2Segment* segmentA, b2Trans...
  function b2Manifold (line 1083) | b2Manifold b2CollideSegmentAndPolygon( const b2Segment* segmentA, b2Tran...
  function b2Manifold (line 1089) | b2Manifold b2CollideChainSegmentAndCircle( const b2ChainSegment* segment...
  function b2Manifold (line 1177) | b2Manifold b2CollideChainSegmentAndCapsule( const b2ChainSegment* segmen...
  function b2Manifold (line 1184) | static b2Manifold b2ClipSegments( b2Vec2 a1, b2Vec2 a2, b2Vec2 b1, b2Vec...
  type b2NormalType (line 1256) | enum b2NormalType
  type b2ChainSegmentParams (line 1268) | struct b2ChainSegmentParams
  function b2ClassifyNormal (line 1279) | static enum b2NormalType b2ClassifyNormal( struct b2ChainSegmentParams p...
  function b2Manifold (line 1319) | b2Manifold b2CollideChainSegmentAndPolygon( const b2ChainSegment* segmen...

FILE: src/math_functions.c
  function b2IsValidFloat (line 10) | bool b2IsValidFloat( float a )
  function b2IsValidVec2 (line 25) | bool b2IsValidVec2( b2Vec2 v )
  function b2IsValidRotation (line 40) | bool b2IsValidRotation( b2Rot q )
  function b2IsValidTransform (line 55) | bool b2IsValidTransform(b2Transform t)
  function b2IsValidPlane (line 65) | bool b2IsValidPlane( b2Plane a )
  function b2Atan2 (line 71) | float b2Atan2( float y, float x )
  function b2CosSin (line 117) | b2CosSin b2ComputeCosSin( float radians )
  function b2Rot (line 160) | b2Rot b2ComputeRotationBetweenUnitVectors(b2Vec2 v1, b2Vec2 v2)

FILE: src/motor_joint.c
  function b2MotorJoint_SetLinearVelocity (line 14) | void b2MotorJoint_SetLinearVelocity( b2JointId jointId, b2Vec2 velocity )
  function b2Vec2 (line 20) | b2Vec2 b2MotorJoint_GetLinearVelocity( b2JointId jointId )
  function b2MotorJoint_SetAngularVelocity (line 26) | void b2MotorJoint_SetAngularVelocity( b2JointId jointId, float velocity )
  function b2MotorJoint_GetAngularVelocity (line 32) | float b2MotorJoint_GetAngularVelocity( b2JointId jointId )
  function b2MotorJoint_SetMaxVelocityTorque (line 38) | void b2MotorJoint_SetMaxVelocityTorque( b2JointId jointId, float maxTorq...
  function b2MotorJoint_GetMaxVelocityTorque (line 44) | float b2MotorJoint_GetMaxVelocityTorque( b2JointId jointId )
  function b2MotorJoint_SetMaxVelocityForce (line 50) | void b2MotorJoint_SetMaxVelocityForce( b2JointId jointId, float maxForce )
  function b2MotorJoint_GetMaxVelocityForce (line 56) | float b2MotorJoint_GetMaxVelocityForce( b2JointId jointId )
  function b2MotorJoint_SetLinearHertz (line 62) | void b2MotorJoint_SetLinearHertz( b2JointId jointId, float hertz )
  function b2MotorJoint_GetLinearHertz (line 68) | float b2MotorJoint_GetLinearHertz( b2JointId jointId )
  function b2MotorJoint_SetLinearDampingRatio (line 74) | void b2MotorJoint_SetLinearDampingRatio( b2JointId jointId, float damping )
  function b2MotorJoint_GetLinearDampingRatio (line 80) | float b2MotorJoint_GetLinearDampingRatio( b2JointId jointId )
  function b2MotorJoint_SetAngularHertz (line 86) | void b2MotorJoint_SetAngularHertz( b2JointId jointId, float hertz )
  function b2MotorJoint_GetAngularHertz (line 92) | float b2MotorJoint_GetAngularHertz( b2JointId jointId )
  function b2MotorJoint_SetAngularDampingRatio (line 98) | void b2MotorJoint_SetAngularDampingRatio( b2JointId jointId, float dampi...
  function b2MotorJoint_GetAngularDampingRatio (line 104) | float b2MotorJoint_GetAngularDampingRatio( b2JointId jointId )
  function b2MotorJoint_SetMaxSpringForce (line 110) | void b2MotorJoint_SetMaxSpringForce( b2JointId jointId, float maxForce )
  function b2MotorJoint_GetMaxSpringForce (line 116) | float b2MotorJoint_GetMaxSpringForce( b2JointId jointId )
  function b2MotorJoint_SetMaxSpringTorque (line 122) | void b2MotorJoint_SetMaxSpringTorque( b2JointId jointId, float maxTorque )
  function b2MotorJoint_GetMaxSpringTorque (line 128) | float b2MotorJoint_GetMaxSpringTorque( b2JointId jointId )
  function b2Vec2 (line 134) | b2Vec2 b2GetMotorJointForce( b2World* world, b2JointSim* base )
  function b2GetMotorJointTorque (line 140) | float b2GetMotorJointTorque( b2World* world, b2JointSim* base )
  function b2PrepareMotorJoint (line 159) | void b2PrepareMotorJoint( b2JointSim* base, b2StepContext* context )
  function b2WarmStartMotorJoint (line 231) | void b2WarmStartMotorJoint( b2JointSim* base, b2StepContext* context )
  function b2SolveMotorJoint (line 267) | void b2SolveMotorJoint( b2JointSim* base, b2StepContext* context )
  function b2DumpMotorJoint (line 419) | void b2DumpMotorJoint()

FILE: src/mover.c
  function b2PlaneSolverResult (line 8) | b2PlaneSolverResult b2SolvePlanes( b2Vec2 targetDelta, b2CollisionPlane*...
  function b2Vec2 (line 57) | b2Vec2 b2ClipVector( b2Vec2 vector, const b2CollisionPlane* planes, int ...

FILE: src/physics_world.c
  function b2World (line 45) | b2World* b2GetWorldFromId( b2WorldId id )
  function b2World (line 54) | b2World* b2GetWorld( int index )
  function b2World (line 62) | b2World* b2GetWorldLocked( int index )
  function b2DefaultFinishTaskFcn (line 83) | static void b2DefaultFinishTaskFcn( void* userTask, void* userContext )
  function b2DefaultFrictionCallback (line 88) | static float b2DefaultFrictionCallback( float frictionA, uint64_t materi...
  function b2DefaultRestitutionCallback (line 94) | static float b2DefaultRestitutionCallback( float restitutionA, uint64_t ...
  function b2WorldId (line 100) | b2WorldId b2CreateWorld( const b2WorldDef* def )
  function b2DestroyWorld (line 267) | void b2DestroyWorld( b2WorldId worldId )
  function b2CollideTask (line 365) | static void b2CollideTask( int startIndex, int endIndex, uint32_t thread...
  function b2UpdateTreesTask (line 455) | static void b2UpdateTreesTask( int startIndex, int endIndex, uint32_t th...
  function b2AddNonTouchingContact (line 469) | static void b2AddNonTouchingContact( b2World* world, b2Contact* contact,...
  function b2RemoveNonTouchingContact (line 480) | static void b2RemoveNonTouchingContact( b2World* world, int setIndex, in...
  function b2Collide (line 496) | static void b2Collide( b2StepContext* context )
  function b2World_Step (line 709) | void b2World_Step( b2WorldId worldId, float timeStep, int subStepCount )
  function b2DrawShape (line 831) | static void b2DrawShape( b2DebugDraw* draw, b2Shape* shape, b2Transform ...
  type DrawContext (line 884) | struct DrawContext
  function DrawQueryCallback (line 890) | static bool DrawQueryCallback( int proxyId, uint64_t userData, void* con...
  function b2World_Draw (line 982) | void b2World_Draw( b2WorldId worldId, b2DebugDraw* draw )
  function b2BodyEvents (line 1219) | b2BodyEvents b2World_GetBodyEvents( b2WorldId worldId )
  function b2SensorEvents (line 1233) | b2SensorEvents b2World_GetSensorEvents( b2WorldId worldId )
  function b2ContactEvents (line 1257) | b2ContactEvents b2World_GetContactEvents( b2WorldId worldId )
  function b2JointEvents (line 1285) | b2JointEvents b2World_GetJointEvents( b2WorldId worldId )
  function b2World_IsValid (line 1299) | bool b2World_IsValid( b2WorldId id )
  function b2Body_IsValid (line 1317) | bool b2Body_IsValid( b2BodyId id )
  function b2Shape_IsValid (line 1356) | bool b2Shape_IsValid( b2ShapeId id )
  function b2Chain_IsValid (line 1388) | bool b2Chain_IsValid( b2ChainId id )
  function b2Joint_IsValid (line 1420) | bool b2Joint_IsValid( b2JointId id )
  function b2Contact_IsValid (line 1452) | bool b2Contact_IsValid( b2ContactId id )
  function b2World_EnableSleeping (line 1484) | void b2World_EnableSleeping( b2WorldId worldId, bool flag )
  function b2World_IsSleepingEnabled (line 1514) | bool b2World_IsSleepingEnabled( b2WorldId worldId )
  function b2World_EnableWarmStarting (line 1520) | void b2World_EnableWarmStarting( b2WorldId worldId, bool flag )
  function b2World_IsWarmStartingEnabled (line 1532) | bool b2World_IsWarmStartingEnabled( b2WorldId worldId )
  function b2World_GetAwakeBodyCount (line 1538) | int b2World_GetAwakeBodyCount( b2WorldId worldId )
  function b2World_EnableContinuous (line 1545) | void b2World_EnableContinuous( b2WorldId worldId, bool flag )
  function b2World_IsContinuousEnabled (line 1557) | bool b2World_IsContinuousEnabled( b2WorldId worldId )
  function b2World_SetRestitutionThreshold (line 1563) | void b2World_SetRestitutionThreshold( b2WorldId worldId, float value )
  function b2World_GetRestitutionThreshold (line 1575) | float b2World_GetRestitutionThreshold( b2WorldId worldId )
  function b2World_SetHitEventThreshold (line 1581) | void b2World_SetHitEventThreshold( b2WorldId worldId, float value )
  function b2World_GetHitEventThreshold (line 1593) | float b2World_GetHitEventThreshold( b2WorldId worldId )
  function b2World_SetContactTuning (line 1599) | void b2World_SetContactTuning( b2WorldId worldId, float hertz, float dam...
  function b2World_SetMaximumLinearSpeed (line 1613) | void b2World_SetMaximumLinearSpeed( b2WorldId worldId, float maximumLine...
  function b2World_GetMaximumLinearSpeed (line 1627) | float b2World_GetMaximumLinearSpeed( b2WorldId worldId )
  function b2Profile (line 1633) | b2Profile b2World_GetProfile( b2WorldId worldId )
  function b2Counters (line 1639) | b2Counters b2World_GetCounters( b2WorldId worldId )
  function b2World_SetUserData (line 1667) | void b2World_SetUserData( b2WorldId worldId, void* userData )
  function b2World_SetFrictionCallback (line 1679) | void b2World_SetFrictionCallback( b2WorldId worldId, b2FrictionCallback*...
  function b2World_SetRestitutionCallback (line 1697) | void b2World_SetRestitutionCallback( b2WorldId worldId, b2RestitutionCal...
  function b2World_DumpMemoryStats (line 1715) | void b2World_DumpMemoryStats( b2WorldId worldId )
  type WorldQueryContext (line 1816) | typedef struct WorldQueryContext
  function TreeQueryCallback (line 1824) | static bool TreeQueryCallback( int proxyId, uint64_t userData, void* con...
  function b2TreeStats (line 1845) | b2TreeStats b2World_OverlapAABB( b2WorldId worldId, b2AABB aabb, b2Query...
  type WorldOverlapContext (line 1872) | typedef struct WorldOverlapContext
  function TreeOverlapCallback (line 1881) | static bool TreeOverlapCallback( int proxyId, uint64_t userData, void* c...
  function b2TreeStats (line 1921) | b2TreeStats b2World_OverlapShape( b2WorldId worldId, const b2ShapeProxy*...
  type WorldRayCastContext (line 1950) | typedef struct WorldRayCastContext
  function RayCastCallback (line 1959) | static float RayCastCallback( const b2RayCastInput* input, int proxyId, ...
  function b2TreeStats (line 1996) | b2TreeStats b2World_CastRay( b2WorldId worldId, b2Vec2 origin, b2Vec2 tr...
  function b2RayCastClosestFcn (line 2034) | static float b2RayCastClosestFcn( b2ShapeId shapeId, b2Vec2 point, b2Vec...
  function b2RayResult (line 2051) | b2RayResult b2World_CastRayClosest( b2WorldId worldId, b2Vec2 origin, b2...
  function ShapeCastCallback (line 2086) | static float ShapeCastCallback( const b2ShapeCastInput* input, int proxy...
  function b2TreeStats (line 2124) | b2TreeStats b2World_CastShape( b2WorldId worldId, const b2ShapeProxy* pr...
  type b2CharacterCallbackContext (line 2163) | typedef struct b2MoverContext
  type WorldMoverCastContext (line 2172) | typedef struct WorldMoverCastContext
  function MoverCastCallback (line 2179) | static float MoverCastCallback( const b2ShapeCastInput* input, int proxy...
  function b2World_CastMover (line 2208) | float b2World_CastMover( b2WorldId worldId, const b2Capsule* mover, b2Ve...
  type WorldMoverContext (line 2246) | typedef struct WorldMoverContext
  function TreeCollideCallback (line 2255) | static bool TreeCollideCallback( int proxyId, uint64_t userData, void* c...
  function b2World_CollideMover (line 2287) | void b2World_CollideMover( b2WorldId worldId, const b2Capsule* mover, b2...
  function b2World_Dump (line 2314) | void b2World_Dump()
  function b2World_SetCustomFilterCallback (line 2379) | void b2World_SetCustomFilterCallback( b2WorldId worldId, b2CustomFilterF...
  function b2World_SetPreSolveCallback (line 2386) | void b2World_SetPreSolveCallback( b2WorldId worldId, b2PreSolveFcn* fcn,...
  function b2World_SetGravity (line 2393) | void b2World_SetGravity( b2WorldId worldId, b2Vec2 gravity )
  function b2Vec2 (line 2399) | b2Vec2 b2World_GetGravity( b2WorldId worldId )
  type ExplosionContext (line 2405) | struct ExplosionContext
  function ExplosionCallback (line 2414) | static bool ExplosionCallback( int proxyId, uint64_t userData, void* con...
  function b2World_Explode (line 2492) | void b2World_Explode( b2WorldId worldId, const b2ExplosionDef* explosion...
  function b2World_RebuildStaticTree (line 2523) | void b2World_RebuildStaticTree( b2WorldId worldId )
  function b2World_EnableSpeculative (line 2536) | void b2World_EnableSpeculative( b2WorldId worldId, bool flag )
  function b2ValidateConnectivity (line 2544) | void b2ValidateConnectivity( b2World* world )
  function b2ValidateSolverSets (line 2631) | void b2ValidateSolverSets( b2World* world )
  function b2ValidateContacts (line 2967) | void b2ValidateContacts( b2World* world )
  function b2ValidateConnectivity (line 3028) | void b2ValidateConnectivity( b2World* world )
  function b2ValidateSolverSets (line 3033) | void b2ValidateSolverSets( b2World* world )
  function b2ValidateContacts (line 3038) | void b2ValidateContacts( b2World* world )

FILE: src/physics_world.h
  type b2TaskContext (line 16) | typedef struct b2TaskContext
  type b2World (line 42) | typedef struct b2World

FILE: src/prismatic_joint.c
  function b2PrismaticJoint_EnableSpring (line 16) | void b2PrismaticJoint_EnableSpring( b2JointId jointId, bool enableSpring )
  function b2PrismaticJoint_IsSpringEnabled (line 26) | bool b2PrismaticJoint_IsSpringEnabled( b2JointId jointId )
  function b2PrismaticJoint_SetSpringHertz (line 32) | void b2PrismaticJoint_SetSpringHertz( b2JointId jointId, float hertz )
  function b2PrismaticJoint_GetSpringHertz (line 38) | float b2PrismaticJoint_GetSpringHertz( b2JointId jointId )
  function b2PrismaticJoint_SetSpringDampingRatio (line 44) | void b2PrismaticJoint_SetSpringDampingRatio( b2JointId jointId, float da...
  function b2PrismaticJoint_GetSpringDampingRatio (line 50) | float b2PrismaticJoint_GetSpringDampingRatio( b2JointId jointId )
  function b2PrismaticJoint_SetTargetTranslation (line 56) | void b2PrismaticJoint_SetTargetTranslation( b2JointId jointId, float tra...
  function b2PrismaticJoint_GetTargetTranslation (line 62) | float b2PrismaticJoint_GetTargetTranslation( b2JointId jointId )
  function b2PrismaticJoint_EnableLimit (line 68) | void b2PrismaticJoint_EnableLimit( b2JointId jointId, bool enableLimit )
  function b2PrismaticJoint_IsLimitEnabled (line 79) | bool b2PrismaticJoint_IsLimitEnabled( b2JointId jointId )
  function b2PrismaticJoint_GetLowerLimit (line 85) | float b2PrismaticJoint_GetLowerLimit( b2JointId jointId )
  function b2PrismaticJoint_GetUpperLimit (line 91) | float b2PrismaticJoint_GetUpperLimit( b2JointId jointId )
  function b2PrismaticJoint_SetLimits (line 97) | void b2PrismaticJoint_SetLimits( b2JointId jointId, float lower, float u...
  function b2PrismaticJoint_EnableMotor (line 111) | void b2PrismaticJoint_EnableMotor( b2JointId jointId, bool enableMotor )
  function b2PrismaticJoint_IsMotorEnabled (line 121) | bool b2PrismaticJoint_IsMotorEnabled( b2JointId jointId )
  function b2PrismaticJoint_SetMotorSpeed (line 127) | void b2PrismaticJoint_SetMotorSpeed( b2JointId jointId, float motorSpeed )
  function b2PrismaticJoint_GetMotorSpeed (line 133) | float b2PrismaticJoint_GetMotorSpeed( b2JointId jointId )
  function b2PrismaticJoint_GetMotorForce (line 139) | float b2PrismaticJoint_GetMotorForce( b2JointId jointId )
  function b2PrismaticJoint_SetMaxMotorForce (line 146) | void b2PrismaticJoint_SetMaxMotorForce( b2JointId jointId, float force )
  function b2PrismaticJoint_GetMaxMotorForce (line 152) | float b2PrismaticJoint_GetMaxMotorForce( b2JointId jointId )
  function b2PrismaticJoint_GetTranslation (line 158) | float b2PrismaticJoint_GetTranslation( b2JointId jointId )
  function b2PrismaticJoint_GetSpeed (line 174) | float b2PrismaticJoint_GetSpeed( b2JointId jointId )
  function b2Vec2 (line 211) | b2Vec2 b2GetPrismaticJointForce( b2World* world, b2JointSim* base )
  function b2GetPrismaticJointTorque (line 230) | float b2GetPrismaticJointTorque( b2World* world, b2JointSim* base )
  function b2PreparePrismaticJoint (line 280) | void b2PreparePrismaticJoint( b2JointSim* base, b2StepContext* context )
  function b2WarmStartPrismaticJoint (line 338) | void b2WarmStartPrismaticJoint( b2JointSim* base, b2StepContext* context )
  function b2SolvePrismaticJoint (line 392) | void b2SolvePrismaticJoint( b2JointSim* base, b2StepContext* context, bo...
  function Dump (line 654) | void b2PrismaticJoint::Dump()
  function b2DrawPrismaticJoint (line 676) | void b2DrawPrismaticJoint( b2DebugDraw* draw, b2JointSim* base, b2Transf...

FILE: src/revolute_joint.c
  function b2RevoluteJoint_EnableSpring (line 34) | void b2RevoluteJoint_EnableSpring( b2JointId jointId, bool enableSpring )
  function b2RevoluteJoint_IsSpringEnabled (line 44) | bool b2RevoluteJoint_IsSpringEnabled( b2JointId jointId )
  function b2RevoluteJoint_SetSpringHertz (line 50) | void b2RevoluteJoint_SetSpringHertz( b2JointId jointId, float hertz )
  function b2RevoluteJoint_GetSpringHertz (line 56) | float b2RevoluteJoint_GetSpringHertz( b2JointId jointId )
  function b2RevoluteJoint_SetSpringDampingRatio (line 62) | void b2RevoluteJoint_SetSpringDampingRatio( b2JointId jointId, float dam...
  function b2RevoluteJoint_GetSpringDampingRatio (line 68) | float b2RevoluteJoint_GetSpringDampingRatio( b2JointId jointId )
  function b2RevoluteJoint_SetTargetAngle (line 74) | void b2RevoluteJoint_SetTargetAngle( b2JointId jointId, float angle )
  function b2RevoluteJoint_GetTargetAngle (line 80) | float b2RevoluteJoint_GetTargetAngle( b2JointId jointId )
  function b2RevoluteJoint_GetAngle (line 86) | float b2RevoluteJoint_GetAngle( b2JointId jointId )
  function b2RevoluteJoint_EnableLimit (line 99) | void b2RevoluteJoint_EnableLimit( b2JointId jointId, bool enableLimit )
  function b2RevoluteJoint_IsLimitEnabled (line 110) | bool b2RevoluteJoint_IsLimitEnabled( b2JointId jointId )
  function b2RevoluteJoint_GetLowerLimit (line 116) | float b2RevoluteJoint_GetLowerLimit( b2JointId jointId )
  function b2RevoluteJoint_GetUpperLimit (line 122) | float b2RevoluteJoint_GetUpperLimit( b2JointId jointId )
  function b2RevoluteJoint_SetLimits (line 128) | void b2RevoluteJoint_SetLimits( b2JointId jointId, float lower, float up...
  function b2RevoluteJoint_EnableMotor (line 144) | void b2RevoluteJoint_EnableMotor( b2JointId jointId, bool enableMotor )
  function b2RevoluteJoint_IsMotorEnabled (line 154) | bool b2RevoluteJoint_IsMotorEnabled( b2JointId jointId )
  function b2RevoluteJoint_SetMotorSpeed (line 160) | void b2RevoluteJoint_SetMotorSpeed( b2JointId jointId, float motorSpeed )
  function b2RevoluteJoint_GetMotorSpeed (line 166) | float b2RevoluteJoint_GetMotorSpeed( b2JointId jointId )
  function b2RevoluteJoint_GetMotorTorque (line 172) | float b2RevoluteJoint_GetMotorTorque( b2JointId jointId )
  function b2RevoluteJoint_SetMaxMotorTorque (line 179) | void b2RevoluteJoint_SetMaxMotorTorque( b2JointId jointId, float torque )
  function b2RevoluteJoint_GetMaxMotorTorque (line 185) | float b2RevoluteJoint_GetMaxMotorTorque( b2JointId jointId )
  function b2Vec2 (line 191) | b2Vec2 b2GetRevoluteJointForce( b2World* world, b2JointSim* base )
  function b2GetRevoluteJointTorque (line 197) | float b2GetRevoluteJointTorque( b2World* world, b2JointSim* base )
  function b2PrepareRevoluteJoint (line 204) | void b2PrepareRevoluteJoint( b2JointSim* base, b2StepContext* context )
  function b2WarmStartRevoluteJoint (line 270) | void b2WarmStartRevoluteJoint( b2JointSim* base, b2StepContext* context )
  function b2SolveRevoluteJoint (line 304) | void b2SolveRevoluteJoint( b2JointSim* base, b2StepContext* context, boo...
  function Dump (line 490) | void b2RevoluteJoint::Dump()
  function b2DrawRevoluteJoint (line 512) | void b2DrawRevoluteJoint( b2DebugDraw* draw, b2JointSim* base, b2Transfo...

FILE: src/sensor.c
  type b2SensorQueryContext (line 24) | struct b2SensorQueryContext
  function b2SensorQueryCallback (line 49) | static bool b2SensorQueryCallback( int proxyId, uint64_t userData, void*...
  function b2CompareVisitors (line 127) | static int b2CompareVisitors( const void* a, const void* b )
  function b2SensorTask (line 140) | static void b2SensorTask( int startIndex, int endIndex, uint32_t threadI...
  function b2OverlapSensors (line 245) | void b2OverlapSensors( b2World* world )
  function b2DestroySensor (line 383) | void b2DestroySensor( b2World* world, b2Shape* sensorShape )

FILE: src/sensor.h
  type b2Shape (line 9) | typedef struct b2Shape b2Shape;
  type b2World (line 10) | typedef struct b2World b2World;
  type b2SensorHit (line 13) | typedef struct b2SensorHit
  type b2Visitor (line 19) | typedef struct b2Visitor
  type b2Sensor (line 25) | typedef struct b2Sensor
  type b2SensorTaskContext (line 34) | typedef struct b2SensorTaskContext

FILE: src/shape.c
  function b2Shape (line 21) | static b2Shape* b2GetShape( b2World* world, b2ShapeId shapeId )
  function b2ChainShape (line 29) | static b2ChainShape* b2GetChainShape( b2World* world, b2ChainId chainId )
  function b2UpdateShapeAABBs (line 37) | static void b2UpdateShapeAABBs( b2Shape* shape, b2Transform transform, b...
  function b2Shape (line 60) | static b2Shape* b2CreateShapeInternal( b2World* world, b2Body* body, b2T...
  function b2ShapeId (line 161) | static b2ShapeId b2CreateShape( b2BodyId bodyId, const b2ShapeDef* def, ...
  function b2ShapeId (line 196) | b2ShapeId b2CreateCircleShape( b2BodyId bodyId, const b2ShapeDef* def, c...
  function b2ShapeId (line 201) | b2ShapeId b2CreateCapsuleShape( b2BodyId bodyId, const b2ShapeDef* def, ...
  function b2ShapeId (line 212) | b2ShapeId b2CreatePolygonShape( b2BodyId bodyId, const b2ShapeDef* def, ...
  function b2ShapeId (line 218) | b2ShapeId b2CreateSegmentShape( b2BodyId bodyId, const b2ShapeDef* def, ...
  function b2DestroyShapeInternal (line 231) | static void b2DestroyShapeInternal( b2World* world, b2Shape* shape, b2Bo...
  function b2DestroyShape (line 320) | void b2DestroyShape( b2ShapeId shapeId, bool updateBodyMass )
  function b2ChainId (line 341) | b2ChainId b2CreateChain( b2BodyId bodyId, const b2ChainDef* def )
  function b2FreeChainData (line 481) | void b2FreeChainData( b2ChainShape* chain )
  function b2DestroyChain (line 490) | void b2DestroyChain( b2ChainId chainId )
  function b2WorldId (line 541) | b2WorldId b2Chain_GetWorld( b2ChainId chainId )
  function b2Chain_GetSegmentCount (line 547) | int b2Chain_GetSegmentCount( b2ChainId chainId )
  function b2Chain_GetSegments (line 559) | int b2Chain_GetSegments( b2ChainId chainId, b2ShapeId* segmentArray, int...
  function b2AABB (line 580) | b2AABB b2ComputeShapeAABB( const b2Shape* shape, b2Transform xf )
  function b2Vec2 (line 603) | b2Vec2 b2GetShapeCentroid( const b2Shape* shape )
  function b2GetShapePerimeter (line 623) | float b2GetShapePerimeter( const b2Shape* shape )
  function b2GetShapeProjectedPerimeter (line 658) | float b2GetShapeProjectedPerimeter( const b2Shape* shape, b2Vec2 line )
  function b2MassData (line 709) | b2MassData b2ComputeShapeMass( const b2Shape* shape )
  function b2ShapeExtent (line 724) | b2ShapeExtent b2ComputeShapeExtent( const b2Shape* shape, b2Vec2 localCe...
  function b2CastOutput (line 794) | b2CastOutput b2RayCastShape( const b2RayCastInput* input, const b2Shape*...
  function b2CastOutput (line 827) | b2CastOutput b2ShapeCastShape( const b2ShapeCastInput* input, const b2Sh...
  function b2PlaneResult (line 891) | b2PlaneResult b2CollideMover( const b2Capsule* mover, const b2Shape* sha...
  function b2CreateShapeProxy (line 929) | void b2CreateShapeProxy( b2Shape* shape, b2BroadPhase* bp, b2BodyType ty...
  function b2DestroyShapeProxy (line 941) | void b2DestroyShapeProxy( b2Shape* shape, b2BroadPhase* bp )
  function b2ShapeProxy (line 950) | b2ShapeProxy b2MakeShapeDistanceProxy( const b2Shape* shape )
  function b2BodyId (line 973) | b2BodyId b2Shape_GetBody( b2ShapeId shapeId )
  function b2WorldId (line 980) | b2WorldId b2Shape_GetWorld( b2ShapeId shapeId )
  function b2Shape_SetUserData (line 986) | void b2Shape_SetUserData( b2ShapeId shapeId, void* userData )
  function b2Shape_IsSensor (line 1000) | bool b2Shape_IsSensor( b2ShapeId shapeId )
  function b2Shape_TestPoint (line 1007) | bool b2Shape_TestPoint( b2ShapeId shapeId, b2Vec2 point )
  function b2CastOutput (line 1032) | b2CastOutput b2Shape_RayCast( b2ShapeId shapeId, const b2RayCastInput* i...
  function b2Shape_SetDensity (line 1083) | void b2Shape_SetDensity( b2ShapeId shapeId, float density, bool updateBo...
  function b2Shape_GetDensity (line 1109) | float b2Shape_GetDensity( b2ShapeId shapeId )
  function b2Shape_SetFriction (line 1116) | void b2Shape_SetFriction( b2ShapeId shapeId, float friction )
  function b2Shape_GetFriction (line 1131) | float b2Shape_GetFriction( b2ShapeId shapeId )
  function b2Shape_SetRestitution (line 1138) | void b2Shape_SetRestitution( b2ShapeId shapeId, float restitution )
  function b2Shape_GetRestitution (line 1153) | float b2Shape_GetRestitution( b2ShapeId shapeId )
  function b2Shape_SetUserMaterial (line 1160) | void b2Shape_SetUserMaterial( b2ShapeId shapeId, uint64_t material )
  function b2Shape_GetUserMaterial (line 1173) | uint64_t b2Shape_GetUserMaterial( b2ShapeId shapeId )
  function b2SurfaceMaterial (line 1180) | b2SurfaceMaterial b2Shape_GetSurfaceMaterial( b2ShapeId shapeId )
  function b2Shape_SetSurfaceMaterial (line 1187) | void b2Shape_SetSurfaceMaterial( b2ShapeId shapeId, const b2SurfaceMater...
  function b2Filter (line 1194) | b2Filter b2Shape_GetFilter( b2ShapeId shapeId )
  function b2ResetProxy (line 1201) | static void b2ResetProxy( b2World* world, b2Shape* shape, bool wakeBodie...
  function b2Shape_SetFilter (line 1251) | void b2Shape_SetFilter( b2ShapeId shapeId, b2Filter filter )
  function b2Shape_EnableSensorEvents (line 1279) | void b2Shape_EnableSensorEvents( b2ShapeId shapeId, bool flag )
  function b2Shape_AreSensorEventsEnabled (line 1291) | bool b2Shape_AreSensorEventsEnabled( b2ShapeId shapeId )
  function b2Shape_EnableContactEvents (line 1298) | void b2Shape_EnableContactEvents( b2ShapeId shapeId, bool flag )
  function b2Shape_AreContactEventsEnabled (line 1310) | bool b2Shape_AreContactEventsEnabled( b2ShapeId shapeId )
  function b2Shape_EnablePreSolveEvents (line 1317) | void b2Shape_EnablePreSolveEvents( b2ShapeId shapeId, bool flag )
  function b2Shape_ArePreSolveEventsEnabled (line 1329) | bool b2Shape_ArePreSolveEventsEnabled( b2ShapeId shapeId )
  function b2Shape_EnableHitEvents (line 1336) | void b2Shape_EnableHitEvents( b2ShapeId shapeId, bool flag )
  function b2Shape_AreHitEventsEnabled (line 1348) | bool b2Shape_AreHitEventsEnabled( b2ShapeId shapeId )
  function b2ShapeType (line 1355) | b2ShapeType b2Shape_GetType( b2ShapeId shapeId )
  function b2Circle (line 1362) | b2Circle b2Shape_GetCircle( b2ShapeId shapeId )
  function b2Segment (line 1370) | b2Segment b2Shape_GetSegment( b2ShapeId shapeId )
  function b2ChainSegment (line 1378) | b2ChainSegment b2Shape_GetChainSegment( b2ShapeId shapeId )
  function b2Capsule (line 1386) | b2Capsule b2Shape_GetCapsule( b2ShapeId shapeId )
  function b2Polygon (line 1394) | b2Polygon b2Shape_GetPolygon( b2ShapeId shapeId )
  function b2Shape_SetCircle (line 1402) | void b2Shape_SetCircle( b2ShapeId shapeId, const b2Circle* circle )
  function b2Shape_SetCapsule (line 1420) | void b2Shape_SetCapsule( b2ShapeId shapeId, const b2Capsule* capsule )
  function b2Shape_SetSegment (line 1444) | void b2Shape_SetSegment( b2ShapeId shapeId, const b2Segment* segment )
  function b2Shape_SetPolygon (line 1462) | void b2Shape_SetPolygon( b2ShapeId shapeId, const b2Polygon* polygon )
  function b2ChainId (line 1480) | b2ChainId b2Shape_GetParentChain( b2ShapeId shapeId )
  function b2Chain_GetSurfaceMaterialCount (line 1498) | int b2Chain_GetSurfaceMaterialCount( b2ChainId chainId )
  function b2Chain_SetSurfaceMaterial (line 1505) | void b2Chain_SetSurfaceMaterial( b2ChainId chainId, const b2SurfaceMater...
  function b2SurfaceMaterial (line 1537) | b2SurfaceMaterial b2Chain_GetSurfaceMaterial( b2ChainId chainId, int seg...
  function b2Shape_GetContactCapacity (line 1545) | int b2Shape_GetContactCapacity( b2ShapeId shapeId )
  function b2Shape_GetContactData (line 1565) | int b2Shape_GetContactData( b2ShapeId shapeId, b2ContactData* contactDat...
  function b2Shape_GetSensorCapacity (line 1613) | int b2Shape_GetSensorCapacity( b2ShapeId shapeId )
  function b2Shape_GetSensorData (line 1631) | int b2Shape_GetSensorData( b2ShapeId shapeId, b2ShapeId* visitorIds, int...
  function b2AABB (line 1663) | b2AABB b2Shape_GetAABB( b2ShapeId shapeId )
  function b2MassData (line 1675) | b2MassData b2Shape_ComputeMassData( b2ShapeId shapeId )
  function b2Vec2 (line 1687) | b2Vec2 b2Shape_GetClosestPoint( b2ShapeId shapeId, b2Vec2 target )
  function b2Shape_ApplyWind (line 1716) | void b2Shape_ApplyWind( b2ShapeId shapeId, b2Vec2 wind, float drag, floa...

FILE: src/shape.h
  type b2BroadPhase (line 10) | typedef struct b2BroadPhase b2BroadPhase;
  type b2World (line 11) | typedef struct b2World b2World;
  type b2Shape (line 13) | typedef struct b2Shape
  type b2ChainShape (line 50) | typedef struct b2ChainShape
  type b2ShapeExtent (line 62) | typedef struct b2ShapeExtent
  type b2SensorOverlaps (line 75) | typedef struct
  function b2GetShapeRadius (line 103) | static inline float b2GetShapeRadius( const b2Shape* shape )
  function b2ShouldShapesCollide (line 118) | static inline bool b2ShouldShapesCollide( b2Filter filterA, b2Filter fil...
  function b2ShouldQueryCollide (line 128) | static inline bool b2ShouldQueryCollide( b2Filter shapeFilter, b2QueryFi...

FILE: src/solver.c
  function b2Pause (line 32) | static inline void b2Pause( void )
  function b2Pause (line 37) | static inline void b2Pause( void )
  function b2Pause (line 42) | static inline void b2Pause( void )
  function b2Pause (line 47) | static inline void b2Pause( void )
  function b2Pause (line 52) | static inline void b2Pause( void )
  type b2WorkerContext (line 57) | typedef struct b2WorkerContext
  function b2IntegrateVelocitiesTask (line 65) | static void b2IntegrateVelocitiesTask( int startIndex, int endIndex, b2S...
  function b2PrepareJointsTask (line 146) | static void b2PrepareJointsTask( int startIndex, int endIndex, b2StepCon...
  function b2WarmStartJointsTask (line 161) | static void b2WarmStartJointsTask( int startIndex, int endIndex, b2StepC...
  function b2SolveJointsTask (line 179) | static void b2SolveJointsTask( int startIndex, int endIndex, b2StepConte...
  function b2IntegratePositionsTask (line 214) | static void b2IntegratePositionsTask( int startIndex, int endIndex, b2St...
  type b2ContinuousContext (line 251) | struct b2ContinuousContext
  function b2ContinuousQueryCallback (line 267) | static bool b2ContinuousQueryCallback( int proxyId, uint64_t userData, v...
  function b2SolveContinuous (line 467) | static void b2SolveContinuous( b2World* world, int bodySimIndex, b2TaskC...
  function b2FinalizeBodiesTask (line 630) | static void b2FinalizeBodiesTask( int startIndex, int endIndex, uint32_t...
  function b2ExecuteBlock (line 859) | static void b2ExecuteBlock( b2SolverStage* stage, b2StepContext* context...
  function GetWorkerStartIndex (line 930) | static inline int GetWorkerStartIndex( int workerIndex, int blockCount, ...
  function b2ExecuteStage (line 942) | static void b2ExecuteStage( b2SolverStage* stage, b2StepContext* context...
  function b2ExecuteMainStage (line 1003) | static void b2ExecuteMainStage( b2SolverStage* stage, b2StepContext* con...
  function b2SolverTask (line 1038) | static void b2SolverTask( int startIndex, int endIndex, uint32_t threadI...
  function b2BulletBodyTask (line 1272) | static void b2BulletBodyTask( int startIndex, int endIndex, uint32_t thr...
  function b2Solve (line 1301) | void b2Solve( b2World* world, b2StepContext* stepContext )

FILE: src/solver.h
  type b2BodySim (line 13) | typedef struct b2BodySim b2BodySim;
  type b2BodyState (line 14) | typedef struct b2BodyState b2BodyState;
  type b2ContactSim (line 15) | typedef struct b2ContactSim b2ContactSim;
  type b2JointSim (line 16) | typedef struct b2JointSim b2JointSim;
  type b2World (line 17) | typedef struct b2World b2World;
  type b2Softness (line 19) | typedef struct b2Softness
  type b2SolverStageType (line 26) | typedef enum b2SolverStageType
  type b2SolverBlockType (line 39) | typedef enum b2SolverBlockType
  type b2SolverBlock (line 53) | typedef struct b2SolverBlock
  type b2SolverStage (line 64) | typedef struct b2SolverStage
  type b2StepContext (line 75) | typedef struct b2StepContext
  function b2Softness (line 140) | static inline b2Softness b2MakeSoft( float hertz, float zeta, float h )

FILE: src/solver_set.c
  function b2DestroySolverSet (line 18) | void b2DestroySolverSet( b2World* world, int setIndex )
  function b2WakeSolverSet (line 37) | void b2WakeSolverSet( b2World* world, int setIndex )
  function b2TrySleepIsland (line 155) | void b2TrySleepIsland( b2World* world, int islandId )
  function b2MergeSolverSets (line 426) | void b2MergeSolverSets( b2World* world, int setId1, int setId2 )
  function b2TransferBody (line 520) | void b2TransferBody( b2World* world, b2SolverSet* targetSet, b2SolverSet...
  function b2TransferJoint (line 564) | void b2TransferJoint( b2World* world, b2SolverSet* targetSet, b2SolverSe...

FILE: src/solver_set.h
  type b2Body (line 8) | typedef struct b2Body b2Body;
  type b2Joint (line 9) | typedef struct b2Joint b2Joint;
  type b2World (line 10) | typedef struct b2World b2World;
  type b2SolverSetType (line 13) | enum b2SolverSetType
  type b2SolverSet (line 38) | typedef struct b2SolverSet

FILE: src/table.c
  function b2HashSet (line 19) | b2HashSet b2CreateSet( int capacity )
  function b2DestroySet (line 40) | void b2DestroySet( b2HashSet* set )
  function b2ClearSet (line 48) | void b2ClearSet( b2HashSet* set )
  function b2KeyHash (line 70) | static uint64_t b2KeyHash( uint64_t key )
  function b2KeyHash (line 78) | static uint64_t b2KeyHash( uint64_t key )
  function b2FindSlot (line 91) | static int b2FindSlot( const b2HashSet* set, uint64_t key, uint64_t hash )
  function b2AddKeyHaveCapacity (line 111) | static void b2AddKeyHaveCapacity( b2HashSet* set, uint64_t key, uint64_t...
  function b2GrowTable (line 121) | static void b2GrowTable( b2HashSet* set )
  function b2ContainsKey (line 154) | bool b2ContainsKey( const b2HashSet* set, uint64_t key )
  function b2GetHashSetBytes (line 163) | int b2GetHashSetBytes( b2HashSet* set )
  function b2AddKey (line 168) | bool b2AddKey( b2HashSet* set, uint64_t key )
  function b2RemoveKey (line 194) | bool b2RemoveKey( b2HashSet* set, uint64_t key )
  function b2CountSetBits (line 258) | int b2CountSetBits( b2BitSet* bitSet )

FILE: src/table.h
  type b2SetItem (line 11) | typedef struct b2SetItem
  type b2HashSet (line 23) | typedef struct b2HashSet
  function b2GetSetCount (line 45) | static inline int b2GetSetCount( b2HashSet* set )
  function b2GetSetCapacity (line 50) | static inline int b2GetSetCapacity( b2HashSet* set )

FILE: src/timer.c
  function b2GetTicks (line 20) | uint64_t b2GetTicks( void )
  function b2GetMilliseconds (line 27) | float b2GetMilliseconds( uint64_t ticks )
  function b2GetMillisecondsAndReset (line 45) | float b2GetMillisecondsAndReset( uint64_t* ticks )
  function b2Yield (line 65) | void b2Yield( void )
  type b2Mutex (line 70) | typedef struct b2Mutex
  function b2Mutex (line 75) | b2Mutex* b2CreateMutex( void )
  function b2DestroyMutex (line 82) | void b2DestroyMutex( b2Mutex* m )
  function b2LockMutex (line 89) | void b2LockMutex( b2Mutex* m )
  function b2UnlockMutex (line 94) | void b2UnlockMutex( b2Mutex* m )
  function b2GetTicks (line 104) | uint64_t b2GetTicks( void )
  function b2GetMilliseconds (line 111) | float b2GetMilliseconds( uint64_t ticks )
  function b2GetMillisecondsAndReset (line 117) | float b2GetMillisecondsAndReset( uint64_t* ticks )
  function b2Yield (line 125) | void b2Yield( void )
  type b2Mutex (line 131) | typedef struct b2Mutex
  function b2Mutex (line 136) | b2Mutex* b2CreateMutex( void )
  function b2DestroyMutex (line 143) | void b2DestroyMutex( b2Mutex* m )
  function b2LockMutex (line 150) | void b2LockMutex( b2Mutex* m )
  function b2UnlockMutex (line 155) | void b2UnlockMutex( b2Mutex* m )
  function b2GetTicks (line 168) | uint64_t b2GetTicks( void )
  function b2GetMilliseconds (line 173) | float b2GetMilliseconds( uint64_t ticks )
  function b2GetMillisecondsAndReset (line 188) | float b2GetMillisecondsAndReset( uint64_t* ticks )
  function b2Yield (line 205) | void b2Yield( void )
  type b2Mutex (line 211) | typedef struct b2Mutex
  function b2Mutex (line 216) | b2Mutex* b2CreateMutex( void )
  function b2DestroyMutex (line 223) | void b2DestroyMutex( b2Mutex* m )
  function b2LockMutex (line 230) | void b2LockMutex( b2Mutex* m )
  function b2UnlockMutex (line 235) | void b2UnlockMutex( b2Mutex* m )
  function b2GetTicks (line 242) | uint64_t b2GetTicks( void )
  function b2GetMilliseconds (line 247) | float b2GetMilliseconds( uint64_t ticks )
  function b2GetMillisecondsAndReset (line 253) | fl
Condensed preview — 212 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,012K chars).
[
  {
    "path": ".clang-format",
    "chars": 1134,
    "preview": "# Reference: https://clang.llvm.org/docs/ClangFormatStyleOptions.html\n# VS 2026 uses 20.1.8\n# https://releases.llvm.org/"
  },
  {
    "path": ".gitattributes",
    "chars": 94,
    "preview": "* text=auto\n\n*.c text\n*.cpp text\n*.h text\n*.md text\n*.txt text\n*.sh text eol=lf\n\n*.ttf binary\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 610,
    "preview": "# These are supported funding model platforms\n\ngithub: [erincatto]\npatreon: Box2D\nopen_collective: # Replace with a sing"
  },
  {
    "path": ".github/issue_template.md",
    "chars": 194,
    "preview": "Make sure these boxes are checked before submitting your issue - thank you!\n\n- [ ] Ask for help on [discord](https://dis"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 104,
    "preview": "Pull requests for core Box2D code are generally not accepted. Please consider filing an issue instead.\n\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 5109,
    "preview": "name: CI Build\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\nenv:\n  BUILD_TYPE: Debug\n\njob"
  },
  {
    "path": ".gitignore",
    "chars": 96,
    "preview": "build/\nimgui.ini\nsettings.ini\n.vscode/\n.vs/\n.cap\n.DS_Store\nCMakeUserPresets.json\n.cache/\n.idea/\n"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 4864,
    "preview": "cmake_minimum_required(VERSION 3.22)\ninclude(FetchContent)\ninclude(CMakeDependentOption)\n\nproject(box2d\n\tVERSION 3.2.0\n"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2022 Erin Catto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 3382,
    "preview": "![Box2D Logo](https://box2d.org/images/logo.svg)\n\n# Build Status\n[![Build Status](https://github.com/erincatto/box2d/act"
  },
  {
    "path": "benchmark/CMakeLists.txt",
    "chars": 490,
    "preview": "# Box2D benchmark app\n\nset(BOX2D_BENCHMARK_FILES\n\tmain.c\n)\nadd_executable(benchmark ${BOX2D_BENCHMARK_FILES})\n\nset_targe"
  },
  {
    "path": "benchmark/amd7950x_avx2/joint_grid.csv",
    "chars": 87,
    "preview": "threads,ms\n1,3174.52\n2,1795.2\n3,1217.45\n4,996.27\n5,857.203\n6,763.975\n7,696.29\n8,648.49\n"
  },
  {
    "path": "benchmark/amd7950x_avx2/large_pyramid.csv",
    "chars": 91,
    "preview": "threads,ms\n1,1951.88\n2,1026.26\n3,721.553\n4,563.934\n5,473.542\n6,415.048\n7,367.646\n8,362.217\n"
  },
  {
    "path": "benchmark/amd7950x_avx2/many_pyramids.csv",
    "chars": 91,
    "preview": "threads,ms\n1,3312.37\n2,1674.87\n3,1116.48\n4,859.268\n5,691.412\n6,594.236\n7,513.412\n8,462.289\n"
  },
  {
    "path": "benchmark/amd7950x_avx2/rain.csv",
    "chars": 90,
    "preview": "threads,ms\n1,8415.32\n2,4830.51\n3,3684.98\n4,3008.05\n5,2568.19\n6,2275.1\n7,2054.01\n8,1896.27\n"
  },
  {
    "path": "benchmark/amd7950x_avx2/smash.csv",
    "chars": 91,
    "preview": "threads,ms\n1,1946.15\n2,1212.81\n3,937.648\n4,786.533\n5,699.338\n6,636.796\n7,597.153\n8,564.691\n"
  },
  {
    "path": "benchmark/amd7950x_avx2/spinner.csv",
    "chars": 90,
    "preview": "threads,ms\n1,5145.33\n2,3090.7\n3,2362.34\n4,1890.21\n5,1643.82\n6,1473.02\n7,1339.32\n8,1256.21\n"
  },
  {
    "path": "benchmark/amd7950x_avx2/tumbler.csv",
    "chars": 91,
    "preview": "threads,ms\n1,2035.14\n2,1273.93\n3,961.824\n4,790.221\n5,679.686\n6,609.556\n7,561.948\n8,531.353\n"
  },
  {
    "path": "benchmark/amd7950x_float/joint_grid.csv",
    "chars": 90,
    "preview": "threads,ms\n1,3070.3\n2,1743.41\n3,1190.54\n4,973.725\n5,839.892\n6,749.347\n7,684.411\n8,639.372\n"
  },
  {
    "path": "benchmark/amd7950x_float/large_pyramid.csv",
    "chars": 91,
    "preview": "threads,ms\n1,4324.94\n2,2218.25\n3,1489.84\n4,1132.51\n5,935.469\n6,818.171\n7,722.364\n8,658.744\n"
  },
  {
    "path": "benchmark/amd7950x_float/many_pyramids.csv",
    "chars": 91,
    "preview": "threads,ms\n1,6803.92\n2,3421.51\n3,2310.75\n4,1766.54\n5,1424.53\n6,1213.28\n7,1043.65\n8,915.268\n"
  },
  {
    "path": "benchmark/amd7950x_float/rain.csv",
    "chars": 90,
    "preview": "threads,ms\n1,10023.3\n2,5685.88\n3,4189.81\n4,3390.77\n5,2873.75\n6,2522.69\n7,2275.75\n8,2098.4\n"
  },
  {
    "path": "benchmark/amd7950x_float/smash.csv",
    "chars": 91,
    "preview": "threads,ms\n1,2660.24\n2,1604.04\n3,1208.81\n4,997.755\n5,871.282\n6,791.138\n7,731.148\n8,687.379\n"
  },
  {
    "path": "benchmark/amd7950x_float/spinner.csv",
    "chars": 89,
    "preview": "threads,ms\n1,8296.22\n2,4821.7\n3,3555.21\n4,2816.7\n5,2427.56\n6,2162.31\n7,2007.07\n8,1896.91\n"
  },
  {
    "path": "benchmark/amd7950x_float/tumbler.csv",
    "chars": 90,
    "preview": "threads,ms\n1,3327.12\n2,1933.37\n3,1436.84\n4,1169.7\n5,1014.31\n6,907.688\n7,840.671\n8,786.672\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/joint_grid.csv",
    "chars": 90,
    "preview": "threads,ms\n1,2901.74\n2,1679.24\n3,1138.81\n4,930.556\n5,802.79\n6,719.061\n7,653.555\n8,609.054\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/large_pyramid.csv",
    "chars": 90,
    "preview": "threads,ms\n1,2234.69\n2,1198.39\n3,821.019\n4,636.813\n5,533.46\n6,476.708\n7,422.339\n8,384.637\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/many_pyramids.csv",
    "chars": 91,
    "preview": "threads,ms\n1,3718.08\n2,1861.18\n3,1279.77\n4,968.623\n5,781.502\n6,667.149\n7,572.954\n8,511.755\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/rain.csv",
    "chars": 88,
    "preview": "threads,ms\n1,10450.7\n2,6050.77\n3,4647.11\n4,3631.8\n5,3096.74\n6,2735.92\n7,2460.2\n8,2256.3\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/smash.csv",
    "chars": 91,
    "preview": "threads,ms\n1,1998.87\n2,1206.23\n3,894.774\n4,732.413\n5,636.455\n6,571.134\n7,527.128\n8,493.411\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/spinner.csv",
    "chars": 91,
    "preview": "threads,ms\n1,5416.19\n2,3229.11\n3,2377.87\n4,1903.65\n5,1630.79\n6,1448.68\n7,1324.58\n8,1237.05\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/tumbler.csv",
    "chars": 89,
    "preview": "threads,ms\n1,2338.19\n2,1413.12\n3,1081.55\n4,883.9\n5,769.756\n6,696.251\n7,647.607\n8,612.832\n"
  },
  {
    "path": "benchmark/amd7950x_sse2/washer.csv",
    "chars": 90,
    "preview": "threads,ms\n1,7934.7\n2,4531.48\n3,3218.58\n4,2523.46\n5,2100.84\n6,1842.67\n7,1638.05\n8,1529.17\n"
  },
  {
    "path": "benchmark/m2air_float/joint_grid.csv",
    "chars": 51,
    "preview": "threads,ms\n1,2367.43\n2,1449.57\n3,999.678\n4,838.636\n"
  },
  {
    "path": "benchmark/m2air_float/large_pyramid.csv",
    "chars": 50,
    "preview": "threads,ms\n1,2317.53\n2,1252.4\n3,891.763\n4,694.968\n"
  },
  {
    "path": "benchmark/m2air_float/many_pyramids.csv",
    "chars": 49,
    "preview": "threads,ms\n1,3559.49\n2,1888.42\n3,1357.7\n4,1085.2\n"
  },
  {
    "path": "benchmark/m2air_float/rain.csv",
    "chars": 51,
    "preview": "threads,ms\n1,7119.67\n2,4144.16\n3,3192.93\n4,2623.99\n"
  },
  {
    "path": "benchmark/m2air_float/smash.csv",
    "chars": 50,
    "preview": "threads,ms\n1,1757.78\n2,1079.8\n3,849.502\n4,709.022\n"
  },
  {
    "path": "benchmark/m2air_float/spinner.csv",
    "chars": 51,
    "preview": "threads,ms\n1,5434.23\n2,3244.67\n3,2462.03\n4,1998.78\n"
  },
  {
    "path": "benchmark/m2air_float/tumbler.csv",
    "chars": 49,
    "preview": "threads,ms\n1,2094.15\n2,1270.1\n3,1020.63\n4,835.34\n"
  },
  {
    "path": "benchmark/m2air_neon/joint_grid.csv",
    "chars": 50,
    "preview": "threads,ms\n1,2377.18\n2,1444.78\n3,998.22\n4,837.361\n"
  },
  {
    "path": "benchmark/m2air_neon/large_pyramid.csv",
    "chars": 51,
    "preview": "threads,ms\n1,1600.72\n2,880.846\n3,632.579\n4,502.146\n"
  },
  {
    "path": "benchmark/m2air_neon/many_pyramids.csv",
    "chars": 51,
    "preview": "threads,ms\n1,2455.91\n2,1329.33\n3,984.499\n4,820.902\n"
  },
  {
    "path": "benchmark/m2air_neon/rain.csv",
    "chars": 51,
    "preview": "threads,ms\n1,6834.98\n2,4020.86\n3,3123.64\n4,2574.69\n"
  },
  {
    "path": "benchmark/m2air_neon/smash.csv",
    "chars": 50,
    "preview": "threads,ms\n1,1595.13\n2,1005.41\n3,798.89\n4,670.542\n"
  },
  {
    "path": "benchmark/m2air_neon/spinner.csv",
    "chars": 51,
    "preview": "threads,ms\n1,4715.34\n2,2939.07\n3,2264.93\n4,1855.98\n"
  },
  {
    "path": "benchmark/m2air_neon/tumbler.csv",
    "chars": 51,
    "preview": "threads,ms\n1,1804.16\n2,1150.51\n3,945.004\n4,777.227\n"
  },
  {
    "path": "benchmark/main.c",
    "chars": 11360,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "benchmark/n100_sse2/joint_grid.csv",
    "chars": 52,
    "preview": "threads,fps\n1,75.5947\n2,123.228\n3,160.379\n4,181.545\n"
  },
  {
    "path": "benchmark/n100_sse2/large_pyramid.csv",
    "chars": 52,
    "preview": "threads,fps\n1,127.236\n2,226.291\n3,297.628\n4,345.526\n"
  },
  {
    "path": "benchmark/n100_sse2/many_pyramids.csv",
    "chars": 52,
    "preview": "threads,fps\n1,30.8828\n2,55.0462\n3,69.5406\n4,77.7339\n"
  },
  {
    "path": "benchmark/n100_sse2/rain.csv",
    "chars": 50,
    "preview": "threads,fps\n1,72.2901\n2,118.753\n3,142.61\n4,162.35\n"
  },
  {
    "path": "benchmark/n100_sse2/smash.csv",
    "chars": 52,
    "preview": "threads,fps\n1,86.2381\n2,132.306\n3,160.725\n4,181.842\n"
  },
  {
    "path": "benchmark/n100_sse2/spinner.csv",
    "chars": 52,
    "preview": "threads,fps\n1,156.855\n2,258.638\n3,303.717\n4,358.492\n"
  },
  {
    "path": "benchmark/n100_sse2/tumbler.csv",
    "chars": 52,
    "preview": "threads,fps\n1,199.492\n2,313.012\n3,381.983\n4,441.825\n"
  },
  {
    "path": "build.sh",
    "chars": 302,
    "preview": "#!/usr/bin/env bash\n\n# Use this to build box2d on any system with a bash shell\nrm -rf build\nmkdir build\ncd build\n\n# I ha"
  },
  {
    "path": "build_emscripten.sh",
    "chars": 257,
    "preview": "#!/usr/bin/env bash\n\n# source emsdk_env.sh\n\n# Use this to build box2d on any system with a bash shell\nrm -rf build\nmkdir"
  },
  {
    "path": "create_sln.bat",
    "chars": 105,
    "preview": "rem Use this batch file to build box2d for Visual Studio\nrmdir /s /q build\nmkdir build\ncd build\ncmake ..\n"
  },
  {
    "path": "deploy_docs.sh",
    "chars": 112,
    "preview": "#!/usr/bin/env bash\n\n# Copies documentation to blog\ncp -R build/docs/html/. ../box2d_blog/public/documentation/\n"
  },
  {
    "path": "docs/CMakeLists.txt",
    "chars": 1968,
    "preview": "find_package(Doxygen REQUIRED dot)\n\nset(DOXYGEN_PROJECT_NAME \"Box2D\")\nset(DOXYGEN_GENERATE_HTML YES)\nset(DOXYGEN_USE_MAT"
  },
  {
    "path": "docs/FAQ.md",
    "chars": 7463,
    "preview": "# FAQ\n\n## What is Box2D?\nBox2D is a feature rich 2D rigid body physics engine, written in C17 by Erin Catto. It has been"
  },
  {
    "path": "docs/character.md",
    "chars": 3264,
    "preview": "# Character mover\n\n> **Caution**:\n> The character mover feature is new to version 3.1 and should be considered experimen"
  },
  {
    "path": "docs/collision.md",
    "chars": 12660,
    "preview": "# Collision\nBox2D provides geometric types and functions. These include:\n- primitives: circles, capsules, segments, and "
  },
  {
    "path": "docs/extra.css",
    "chars": 8274,
    "preview": "/*\nDoxygen CSS overrides\nAdapted from: https://github.com/MaJerle/doxygen-dark-theme\nblog-light: #fafafa\nblog-dark: #252"
  },
  {
    "path": "docs/foundation.md",
    "chars": 5248,
    "preview": "# Foundations\nBox2D provides minimal base functionality for allocation hooks and vector math. The C interface\nallows mos"
  },
  {
    "path": "docs/hello.md",
    "chars": 9949,
    "preview": "# Hello Box2D {#hello}\nIn the distribution of Box2D is a Hello World unit test written in C. The test\ncreates a large gr"
  },
  {
    "path": "docs/layout.xml",
    "chars": 8724,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doxygenlayout version=\"1.0\">\n  <!-- Generated by doxygen 1.10.0 -->\n  <!-- Navig"
  },
  {
    "path": "docs/loose_ends.md",
    "chars": 4944,
    "preview": "# Loose Ends\n\n## User Data\nBodies, shapes, and joints allow you to attach user data\nas a `void*`. This is handy when you"
  },
  {
    "path": "docs/migration.md",
    "chars": 14464,
    "preview": "# Migration Guide\n\n> **Caution**:\n> This guide only covers the transition from 2.4 to 3.0. Please see the release notes "
  },
  {
    "path": "docs/overview.md",
    "chars": 11739,
    "preview": "# Overview\nBox2D is a 2D rigid body simulation library for games. Programmers can\nuse it in their games to make objects "
  },
  {
    "path": "docs/reading.md",
    "chars": 271,
    "preview": "# Further Reading\n- [Erin Catto's Publications](https://box2d.org/publications/)\n- [Erin Catto's Blog Posts](https://box"
  },
  {
    "path": "docs/release_notes_v310.md",
    "chars": 1961,
    "preview": "# v3.1 Release Notes\n\n## API Changes\n- 64-bit filter categories and masks\n- 64-bit dynamic tree user data\n- Renamed `b2S"
  },
  {
    "path": "docs/samples.md",
    "chars": 1023,
    "preview": "# Samples {#samples}\nOnce you have conquered the HelloWorld example, you should start looking\nat Box2D's samples applica"
  },
  {
    "path": "docs/simulation.md",
    "chars": 74907,
    "preview": "# Simulation\nRigid body simulation is the primary feature of Box2D. It is the most complex part of\nBox2D and is the part"
  },
  {
    "path": "extern/glad/include/KHR/khrplatform.h",
    "chars": 11131,
    "preview": "#ifndef __khrplatform_h_\n#define __khrplatform_h_\n\n/*\n** Copyright (c) 2008-2018 The Khronos Group Inc.\n**\n** Permission"
  },
  {
    "path": "extern/glad/include/glad/glad.h",
    "chars": 283844,
    "preview": "/*\n\n    OpenGL loader generated by glad 0.1.34 on Sat Jul  8 18:48:45 2023.\n\n    Language/Generator: C/C++\n    Specifica"
  },
  {
    "path": "extern/glad/src/glad.c",
    "chars": 152452,
    "preview": "/*\n\n    OpenGL loader generated by glad 0.1.34 on Sat Jul  8 18:48:45 2023.\n\n    Language/Generator: C/C++\n    Specifica"
  },
  {
    "path": "extern/jsmn/jsmn.h",
    "chars": 12145,
    "preview": "/*\n * MIT License\n *\n * Copyright (c) 2010 Serge Zaitsev\n *\n * Permission is hereby granted, free of charge, to any pers"
  },
  {
    "path": "include/box2d/base.h",
    "chars": 4496,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include <stdint.h>\n\n// clang-"
  },
  {
    "path": "include/box2d/box2d.h",
    "chars": 56721,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"base.h\"\n#include \"co"
  },
  {
    "path": "include/box2d/collision.h",
    "chars": 31976,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"base.h\"\n#include \"ma"
  },
  {
    "path": "include/box2d/id.h",
    "chars": 5290,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include <stdint.h>\n\n// Note: "
  },
  {
    "path": "include/box2d/math_functions.h",
    "chars": 20264,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"base.h\"\n\n#include <f"
  },
  {
    "path": "include/box2d/types.h",
    "chars": 47664,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"base.h\"\n#include \"co"
  },
  {
    "path": "samples/CMakeLists.txt",
    "chars": 3358,
    "preview": "# Box2D samples app\n\n# glad for OpenGL API\nset(GLAD_DIR ${CMAKE_SOURCE_DIR}/extern/glad)\n\nadd_library(\n\tglad STATIC\n\t${G"
  },
  {
    "path": "samples/car.cpp",
    "chars": 9294,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"car.h\"\n\n#include \"box2d/box2d.h\"\n#"
  },
  {
    "path": "samples/car.h",
    "chars": 1064,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/types.h\"\n\nclas"
  },
  {
    "path": "samples/container.c",
    "chars": 489,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "samples/container.h",
    "chars": 11669,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#define NULL_INDEX -1\n\n// Arra"
  },
  {
    "path": "samples/data/background.fs",
    "chars": 711,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nout vec4 FragColor;\n\nuniform f"
  },
  {
    "path": "samples/data/background.vs",
    "chars": 199,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n#version 330\n\nlayout(location = 0) in vec2 v_"
  },
  {
    "path": "samples/data/circle.fs",
    "chars": 417,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nin vec2 f_position;\nin vec4 f_"
  },
  {
    "path": "samples/data/circle.vs",
    "chars": 765,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nuniform mat4 projectionMatrix;"
  },
  {
    "path": "samples/data/font.fs",
    "chars": 256,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330 core\n\nin vec4 color;\nin vec2 uv"
  },
  {
    "path": "samples/data/font.vs",
    "chars": 378,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330 core\n\nlayout (location = 0) in "
  },
  {
    "path": "samples/data/line.fs",
    "chars": 165,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nin vec4 f_color;\nout vec4 colo"
  },
  {
    "path": "samples/data/line.vs",
    "chars": 330,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nuniform mat4 projectionMatrix;"
  },
  {
    "path": "samples/data/point.fs",
    "chars": 165,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nin vec4 f_color;\nout vec4 colo"
  },
  {
    "path": "samples/data/point.vs",
    "chars": 386,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nuniform mat4 projectionMatrix;"
  },
  {
    "path": "samples/data/solid_capsule.fs",
    "chars": 1630,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nin vec2 f_position;\nin vec4 f_"
  },
  {
    "path": "samples/data/solid_capsule.vs",
    "chars": 1253,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nuniform mat4 projectionMatrix;"
  },
  {
    "path": "samples/data/solid_circle.fs",
    "chars": 1397,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nin vec2 f_position;\nin vec4 f_"
  },
  {
    "path": "samples/data/solid_circle.vs",
    "chars": 961,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nuniform mat4 projectionMatrix;"
  },
  {
    "path": "samples/data/solid_polygon.fs",
    "chars": 2509,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nin vec2 f_position;\nin vec2 f_"
  },
  {
    "path": "samples/data/solid_polygon.vs",
    "chars": 2336,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#version 330\n\nuniform mat4 projectionMatrix;"
  },
  {
    "path": "samples/donut.cpp",
    "chars": 2445,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"donut.h\"\n\n#include \"box2d/box2d.h\""
  },
  {
    "path": "samples/donut.h",
    "chars": 408,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/types.h\"\n\nclas"
  },
  {
    "path": "samples/doohickey.cpp",
    "chars": 3078,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"doohickey.h\"\n\n#include \"box2d/box2"
  },
  {
    "path": "samples/doohickey.h",
    "chars": 414,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/types.h\"\n\nclas"
  },
  {
    "path": "samples/draw.c",
    "chars": 40396,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "samples/draw.h",
    "chars": 1670,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/types.h\"\n\ntype"
  },
  {
    "path": "samples/main.cpp",
    "chars": 19972,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER )\n#ifndef _CRT_SECURE_"
  },
  {
    "path": "samples/sample.cpp",
    "chars": 24734,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "samples/sample.h",
    "chars": 2568,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/id.h\"\n#include"
  },
  {
    "path": "samples/sample_benchmark.cpp",
    "chars": 52002,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"benchmarks.h\"\n#include \"draw.h\"\n#i"
  },
  {
    "path": "samples/sample_bodies.cpp",
    "chars": 31091,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"sample.h\"\n\n#incl"
  },
  {
    "path": "samples/sample_character.cpp",
    "chars": 44768,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"sample.h\"\n\n#incl"
  },
  {
    "path": "samples/sample_collision.cpp",
    "chars": 99645,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"random.h\"\n#inclu"
  },
  {
    "path": "samples/sample_continuous.cpp",
    "chars": 46033,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"human.h\"\n#includ"
  },
  {
    "path": "samples/sample_determinism.cpp",
    "chars": 1522,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"determinism.h\"\n#include \"sample.h\""
  },
  {
    "path": "samples/sample_events.cpp",
    "chars": 71901,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"donut.h\"\n#include \"draw.h\"\n#includ"
  },
  {
    "path": "samples/sample_geometry.cpp",
    "chars": 4261,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"random.h\"\n#inclu"
  },
  {
    "path": "samples/sample_issues.cpp",
    "chars": 21530,
    "preview": "#include \"GLFW/glfw3.h\"\n#include \"imgui.h\"\n#include \"sample.h\"\n\n#include \"box2d/box2d.h\"\n\nstruct PhysicsHitQueryResult2D"
  },
  {
    "path": "samples/sample_joints.cpp",
    "chars": 101501,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"car.h\"\n#include \"donut.h\"\n#include"
  },
  {
    "path": "samples/sample_robustness.cpp",
    "chars": 16668,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"sample.h\"\n\n#incl"
  },
  {
    "path": "samples/sample_shapes.cpp",
    "chars": 54878,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"random.h\"\n#inclu"
  },
  {
    "path": "samples/sample_stacking.cpp",
    "chars": 25457,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"draw.h\"\n#include \"random.h\"\n#inclu"
  },
  {
    "path": "samples/sample_world.cpp",
    "chars": 6084,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"car.h\"\n#include \"donut.h\"\n#include"
  },
  {
    "path": "samples/shader.c",
    "chars": 4726,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "samples/shader.h",
    "chars": 432,
    "preview": "// SPDX-FileCopyrightText: 2024 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include <stdint.h>\n\n#ifdef __"
  },
  {
    "path": "samples/stb_image_write.h",
    "chars": 71238,
    "preview": "/* stb_image_write - v1.16 - public domain - http://nothings.org/stb\n   writes out PNG/BMP/TGA/JPEG/HDR images to C stdi"
  },
  {
    "path": "samples/stb_truetype.h",
    "chars": 199192,
    "preview": "// stb_truetype.h - v1.26 - public domain\n// authored from 2009-2021 by Sean Barrett / RAD Game Tools\n//\n// ============"
  },
  {
    "path": "shared/CMakeLists.txt",
    "chars": 604,
    "preview": "# Box2D code shared by samples, benchmarks, and unit tests\n\nset(BOX2D_SHARED_FILES\n\tbenchmarks.c\n\tbenchmarks.h\n\tdetermin"
  },
  {
    "path": "shared/benchmarks.c",
    "chars": 16715,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"benchmarks.h\"\n\n#include \"human.h\"\n"
  },
  {
    "path": "shared/benchmarks.h",
    "chars": 744,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n#pragma once\n\n#include \"box2d/id.h\"\n\n#include"
  },
  {
    "path": "shared/determinism.c",
    "chars": 3221,
    "preview": "// SPDX-FileCopyrightText: 2022 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"determinism.h\"\n\n#include \"box2d/bo"
  },
  {
    "path": "shared/determinism.h",
    "chars": 525,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n#pragma once\n\n#include \"box2d/id.h\"\n\n#include"
  },
  {
    "path": "shared/human.c",
    "chars": 22343,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"human.h\"\n\n#include \"random.h\"\n\n#in"
  },
  {
    "path": "shared/human.h",
    "chars": 1403,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/types.h\"\n\ntype"
  },
  {
    "path": "shared/random.c",
    "chars": 487,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"random.h\"\n\nuint32_t g_randomSeed ="
  },
  {
    "path": "shared/random.h",
    "chars": 1621,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/collision.h\"\n#"
  },
  {
    "path": "src/CMakeLists.txt",
    "chars": 5182,
    "preview": "include(GNUInstallDirs)\n\nset(BOX2D_SOURCE_FILES\n\taabb.c\n\taabb.h\n\tarena_allocator.c\n\tarena_allocator.h\n\tarray.c\n\tarray.h\n"
  },
  {
    "path": "src/aabb.c",
    "chars": 2258,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"aabb.h\"\n\n#include \"box2d/math_func"
  },
  {
    "path": "src/aabb.h",
    "chars": 990,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/types.h\"\n\n// R"
  },
  {
    "path": "src/arena_allocator.c",
    "chars": 2576,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"arena_allocator.h\"\n\n#include \"arra"
  },
  {
    "path": "src/arena_allocator.h",
    "chars": 1310,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n\n#include <"
  },
  {
    "path": "src/array.c",
    "chars": 147,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"array.h\"\n\n#include <stddef.h>\n\nB2_"
  },
  {
    "path": "src/array.h",
    "chars": 17678,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"core.h\"\n\n// Macro ge"
  },
  {
    "path": "src/atomic.h",
    "chars": 2180,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"core.h\"\n\n#include <s"
  },
  {
    "path": "src/bitset.c",
    "chars": 2019,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"bitset.h\"\n\n#include <string.h>\n\nb2"
  },
  {
    "path": "src/bitset.h",
    "chars": 1722,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"core.h\"\n\n#include <s"
  },
  {
    "path": "src/body.c",
    "chars": 54403,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"body.h\"\n\n#include \"aabb.h\"\n#includ"
  },
  {
    "path": "src/body.h",
    "chars": 6791,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n\n#include \""
  },
  {
    "path": "src/box2d.natvis",
    "chars": 1337,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<AutoVisualizer xmlns=\"http://schemas.microsoft.com/vstudio/debugger/natvis/2010\""
  },
  {
    "path": "src/broad_phase.c",
    "chars": 14386,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "src/broad_phase.h",
    "chars": 2980,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n#include \"t"
  },
  {
    "path": "src/constants.h",
    "chars": 2161,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\nextern float b2_lengthUnitsPer"
  },
  {
    "path": "src/constraint_graph.c",
    "chars": 10699,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"constraint_graph.h\"\n\n#include \"arr"
  },
  {
    "path": "src/constraint_graph.h",
    "chars": 2520,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n#include \"b"
  },
  {
    "path": "src/contact.c",
    "chars": 23442,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"contact.h\"\n\n#include \"array.h\"\n#in"
  },
  {
    "path": "src/contact.h",
    "chars": 3530,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n#include \"c"
  },
  {
    "path": "src/contact_solver.c",
    "chars": 75153,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"contact_solver.h\"\n\n#include \"body."
  },
  {
    "path": "src/contact_solver.h",
    "chars": 1724,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"solver.h\"\n\ntypedef s"
  },
  {
    "path": "src/core.c",
    "chars": 4017,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"core.h\"\n\n#include \"box2d/math_func"
  },
  {
    "path": "src/core.h",
    "chars": 4048,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"box2d/base.h\"\n\n// cl"
  },
  {
    "path": "src/ctz.h",
    "chars": 2113,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include <stdbool.h>\n#include "
  },
  {
    "path": "src/distance.c",
    "chars": 37355,
    "preview": "\n// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"constants.h\"\n#include \"core.h\"\n\n#"
  },
  {
    "path": "src/distance_joint.c",
    "chars": 19111,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "src/dynamic_tree.c",
    "chars": 51343,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"aabb.h\"\n#include \"constants.h\"\n#in"
  },
  {
    "path": "src/geometry.c",
    "chars": 28638,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"constants.h\"\n#include \"shape.h\"\n\n#"
  },
  {
    "path": "src/hull.c",
    "chars": 6908,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"constants.h\"\n#include \"core.h\"\n\n#i"
  },
  {
    "path": "src/id_pool.c",
    "chars": 1320,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"id_pool.h\"\n\nb2IdPool b2CreateIdPoo"
  },
  {
    "path": "src/id_pool.h",
    "chars": 721,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n\ntypedef st"
  },
  {
    "path": "src/island.c",
    "chars": 23561,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"island.h\"\n\n#include \"body.h\"\n#incl"
  },
  {
    "path": "src/island.h",
    "chars": 2452,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n\n#include <"
  },
  {
    "path": "src/joint.c",
    "chars": 41640,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"joint.h\"\n\n#include \"body.h\"\n#inclu"
  },
  {
    "path": "src/joint.h",
    "chars": 8682,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n#pragma once\n\n#include \"array.h\"\n#include \"so"
  },
  {
    "path": "src/manifold.c",
    "chars": 47178,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"constants.h\"\n#include \"core.h\"\n\n#i"
  },
  {
    "path": "src/math_functions.c",
    "chars": 3257,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"box2d/math_functions.h\"\n\n#include "
  },
  {
    "path": "src/motor_joint.c",
    "chars": 14513,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"body.h\"\n#include \"core.h\"\n#include"
  },
  {
    "path": "src/mover.c",
    "chars": 1668,
    "preview": "// SPDX-FileCopyrightText: 2025 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"constants.h\"\n\n#include \"box2d/coll"
  },
  {
    "path": "src/physics_world.c",
    "chars": 86965,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "src/physics_world.h",
    "chars": 6135,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n#include \"b"
  },
  {
    "path": "src/prismatic_joint.c",
    "chars": 23665,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"body.h\"\n#include \"core.h\"\n#include"
  },
  {
    "path": "src/revolute_joint.c",
    "chars": 18681,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#if defined( _MSC_VER ) && !defined( _CRT_SE"
  },
  {
    "path": "src/sensor.c",
    "chars": 12226,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"sensor.h\"\n\n#include \"array.h\"\n#inc"
  },
  {
    "path": "src/sensor.h",
    "chars": 942,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n#include \"b"
  },
  {
    "path": "src/shape.c",
    "chars": 51424,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"shape.h\"\n\n#include \"body.h\"\n#inclu"
  },
  {
    "path": "src/shape.h",
    "chars": 3842,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n\n#include \""
  },
  {
    "path": "src/solver.c",
    "chars": 70901,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"solver.h\"\n\n#include \"arena_allocat"
  },
  {
    "path": "src/solver.h",
    "chars": 4513,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"core.h\"\n\n#include \"b"
  },
  {
    "path": "src/solver_set.c",
    "chars": 20971,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"solver_set.h\"\n\n#include \"body.h\"\n#"
  },
  {
    "path": "src/solver_set.h",
    "chars": 2933,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include \"array.h\"\n\ntypedef st"
  },
  {
    "path": "src/table.c",
    "chars": 5832,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"table.h\"\n\n#include \"atomic.h\"\n#inc"
  },
  {
    "path": "src/table.h",
    "chars": 1296,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#pragma once\n\n#include <stdbool.h>\n#include "
  },
  {
    "path": "src/timer.c",
    "chars": 5141,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"core.h\"\n\n#include \"box2d/base.h\"\n\n"
  },
  {
    "path": "src/types.c",
    "chars": 4134,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"box2d/types.h\"\n\n#include \"constant"
  },
  {
    "path": "src/weld_joint.c",
    "chars": 14875,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"body.h\"\n#include \"core.h\"\n#include"
  },
  {
    "path": "src/wheel_joint.c",
    "chars": 18481,
    "preview": "// SPDX-FileCopyrightText: 2023 Erin Catto\n// SPDX-License-Identifier: MIT\n\n#include \"body.h\"\n#include \"core.h\"\n#include"
  },
  {
    "path": "test/CMakeLists.txt",
    "chars": 778,
    "preview": "# Box2D unit test app\n\nset(BOX2D_TEST_FILES\n    main.c\n    test_bitset.c\n    test_collision.c\n    test_determinism.c\n   "
  }
]

// ... and 12 more files (download for full content)

About this extraction

This page contains the full source code of the erincatto/box2d GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 212 files (2.7 MB), approximately 712.3k tokens, and a symbol index with 2423 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!