Jolt Physics Documentation
repository·master·Indexed 27 days ago
https://github.com/jrouwe/joltphysicsA high-performance, multi-core optimized rigid body physics and collision detection library designed for modern games and VR applications. It features a deterministic simulation, concurrent access to physics data, and support for a wide range of platforms including Windows, Linux, Android, macOS, iOS, and WebAssembly. The library is written in C++17 and supports various CPU instruction sets such as SSE, AVX, and NEON.
What's inside Jolt Physics
- Jolt Physics is a multi-core friendly rigid body physics and collision detection library designed for games and VR applications. It emphasizes concurrent access to physics data, allowing for background loading/unloading of bodies and parallel collision queries (both broadphase and narrowphase) without locking the main simulation update. The simulation is deterministic, making it suitable for replicating physics states to remote clients.
Understand the Physics Simulation Step
masterThe
PhysicsSystem::Updatecall executes a job graph to advance the simulation. Key stages include:- Broad Phase Update: Refits AABBs and swaps the new tree with the old one.
- Step Listeners: Calls
PhysicsStepListener::OnStepfor registered listeners. - Apply Gravity: Parallel jobs apply gravity and damping to active bodies.
- Build Islands: Recreates islands from scratch every step by processing non-contact constraints. If a constraint connects an active and non-active body, the non-active body is woken up.
- Find Collisions: Performs broad and narrow phase checks. Uses GJK and EPA algorithms to determine contact points and creates contact manifolds. This stage uses a lock-free contact cache.
- Setup Velocity Constraints: Calculates Jacobians and effective masses for non-contact constraints.
- Finalize Islands: Finalizes simulation islands so they can be simulated separately in subsequent jobs.
Understand Body types and Motion Properties
masterBodies in Jolt are objects with attached collision shapes. They are categorized by
EMotionType:- static: Not moving or simulating. To save space, static bodies do not have
MotionPropertiesunlessBodyCreationSettings::mAllowDynamicOrKinematicis enabled (allowing them to become dynamic later). - dynamic: Moved by forces.
- kinematic: Moved by velocities only.
Moving bodies (dynamic and kinematic) utilize a
MotionPropertiesobject to track movement information.- static: Not moving or simulating. To save space, static bodies do not have
Understand Body Sleeping Logic
masterTo optimize performance, Jolt puts bodies to sleep when they move very little.
Mechanism:
- The engine tracks three bounding spheres based on the two largest axes of the shape's local space bounding box and the center of mass (all in world space).
- If these bounding spheres expand beyond a certain size, the timer resets.
- If the spheres remain stable for a specific duration, the body is considered non-moving and is put to sleep.
Understand the Physics Simulation Step
masterThe
PhysicsSystem::Updateuses aJobSystemto distribute work across multiple CPUs. It employs a Sequential Impulse solver with warm starting.Each physics step can be divided into multiple collision steps. For example, running at 60 Hz with 2 collision steps results in the following sequence:
- Collision (1/120s)
- Integration (1/120s)
- Collision (1/120s)
- Integration (1/120s)
The system is generally stable when running at 60 Hz with 1 collision step.
Explore Jolt Physics feature categories in Samples
masterThe Samples application demonstrates several core physics capabilities:
- Vehicles: Demonstrates
VehicleConstraintusing ray- or shape casts for engine, gearbox, differential, and suspension simulation. - Rig (Ragdolls): Shows ragdoll creation and control via keyframing or motors (including kinematic ragdolls and skeleton mapping).
- Soft Body: Simulates cloth and soft balls, including contact listeners, bend constraints (distance and dihedral angle), and skin constraints for skinned meshes.
- Character: Demonstrates humanoid character simulation using a capsule (movement, sliding, crouching, jumping).
- Water: Shows buoyancy and friction simulation for various shapes.
- Constraints: Demonstrates various connection types like Path, Swing-Twist, Gear, Rack and Pinion, and Pulley constraints.
- General: Covers friction, restitution, damping, gravity modification, continuous collision detection (CCD), and multithreaded island simulation.
- Shapes & Scaled Shapes: Demonstrates supported shapes and runtime scaling (Uniform, Non-uniform, Mirrored, Inside out).
- Vehicles: Demonstrates
Manage the Body lifecycle via BodyInterface
masterBodies must be managed through the
BodyInterface. You cannot use standard C++newordeletefor bodies.Lifecycle steps:
BodyInterface::CreateBody: Construct and initialize aBodyobject.BodyInterface::AddBody: Add the body to thePhysicsSystemto participate in simulation.BodyInterface::RemoveBody: Remove the body from the simulation.BodyInterface::DestroyBody: Deinitialize and destruct theBody. Note: This does not automatically remove the body from thePhysicsSystemfirst.
Batch Operations (Recommended): Always use batching functions when adding many bodies to avoid inefficient broadphase updates or internal node exhaustion:
BodyInterface::AddBodiesPrepare: Prepares bodies (can be done on a background thread).BodyInterface::AddBodiesFinalize: Atomically adds all prepared bodies to the system.BodyInterface::AddBodiesAbort: Cancels a pending batch addition.BodyInterface::RemoveBodies: Batch removes multiple bodies.
If you must add bodies one by one, call
PhysicsSystem::OptimizeBroadPhaseto rebuild the tree.Follow Jolt Physics coordinate and unit conventions
masterTo ensure simulation stability and accuracy, follow these conventions:
- Coordinate System: Right-handed, Y-up. To use a different up-axis, use
PhysicsSystem::SetGravityand wrap shapes likeHeightFieldShapein aRotatedTranslatedShape. Specify the new up-axis forVehicleConstraintandCharacterBaseSettings. - Math: Uses column-major vectors and matrices. Transformation formula:
TransformedPoint = Matrix * Point. - Units (SI):
- Dynamic Objects: Length [0.1, 10] m, Speed [0, 500] m/s, Gravity [0, 10] m/s².
- Static Objects: Length [0.1, 2000] m.
- If using different units, scale objects before passing them to the simulation.
- Coordinate System: Right-handed, Y-up. To use a different up-axis, use
Breaking API Changes in v5.5.0
masterThe following breaking changes were introduced in version 5.5.0:
- CPU Architecture Bits:
JPH_CPU_ADDRESS_BITShas been renamed toJPH_CPU_ARCH_BITSto clarify that it refers to the architecture bits rather than the pointer size. - Bounds Querying:
BroadPhaseQuery::GetBoundshas been added, andPhysicsSystem::GetBoundsis now deprecated.
- CPU Architecture Bits:
Enable Cross-Platform Determinism
masterBy default, Jolt is deterministic on the same binary/platform. To achieve cross-platform determinism (e.g., between Windows, Linux, and ARM), you must enable the
CROSS_PLATFORM_DETERMINISTICoption in CMake. This incurs an approximately 8% performance penalty.Requirements for Cross-Platform Determinism:
- Use the same source code and the same defines (e.g., do not mix
JPH_DOUBLE_PRECISIONacross platforms). - Compile with Precise floating-point mode:
- Clang:
-ffp-model=preciseand-ffp-contract=off - MSVC:
/fp:precise
- Clang:
- Ensure consistent FPU state: Floating point rounding should be set to 'nearest', and Denormals-Are-Zero (DAZ) and Flush-To-Zero (FTZ) flags must be set consistently.
- Avoid standard library functions that vary by platform. Use Jolt's replacements:
- Use
Jolt::Sin,Jolt::Cos, etc., instead ofstd::sin,std::cos. - Use
Jolt::QuickSortinstead ofstd::sort. - Use
Jolt::BinaryHeapPush/Popinstead ofstd::push_heap/pop_heap. - Use
Jolt::Hashinstead ofstd::hash.
- Use
Non-deterministic elements to watch out for:
- Broadphase queries (
BroadPhaseQuery): Results may vary because the broadphase is modified across multiple threads. To get deterministic results, use a customCollisionCollectorthat validates hits againstBody::GetWorldSpaceBoundsand ensures consistent result ordering. - Narrowphase queries (
NarrowPhaseQuery): Results are consistent, but the order of received results may change. - Listeners:
BodyActivationListener,PhysicsStepListener,SoftBodyContactListener, andContactListenerare called from multiple threads; callback order is not guaranteed. PhysicsSystem::GetActiveBodies: Returns bodies in a non-deterministic order.
- Use the same source code and the same defines (e.g., do not mix
Manage Sleeping Bodies
masterJolt Physics uses 'islands' to group dynamic bodies in contact or connected by constraints. To conserve CPU, entire islands are put to sleep when all bodies in them come to rest.
Key Behaviors
- Waking Up: Sleeping bodies wake up automatically when contacted by non-sleeping objects. You can also wake them explicitly using
BodyInterface::ActivateBody. - Removing Bodies: Removing a body from the world does not automatically wake up surrounding bodies. To wake them, call
BodyInterface::ActivateBodiesInAABoxusing the bounding box of the removed body. - Velocity and Waking: Using
Body::SetLinearVelocitywill not wake a body. You must useBodyInterface::SetLinearVelocityinstead.
Configuration
Adjust the definition of a body 'at rest' via
PhysicsSettings:PhysicsSettings::mTimeBeforeSleepPhysicsSettings::mPointVelocitySleepThreshold
- Waking Up: Sleeping bodies wake up automatically when contacted by non-sleeping objects. You can also wake them explicitly using
Breaking API Changes in v5.6.0
masterThe following breaking changes were introduced in version 5.6.0:
- Friction Model: The friction model has changed, which may slightly alter simulation results over time.
EstimateCollisionResponsenow returns 2 linear and 1 angular friction impulse instead of per-contact point friction impulses. - Character Virtual Renaming:
CharacterVirtual::Contactis nowCharacterContact.CharacterVirtual::ContactKeyis nowCharacterContactKey.CharacterContactListenernow receives a fullCharacterContactobject. When replacing the oldinContactNormalparameter, use-inContact.mContactNormal.
- Soft Body Contact Callbacks: Contacts for bodies with motion quality
LinearCastvs a soft body are now properly reported throughSoftBodyContactListenerinstead of the regularContactListener. - HeightFieldShape Serialization (SBS): Support for
HeightFieldShapeSettings::mBitsPerSample > 8was added. This adds 1 byte to the binary serialization format, making it incompatible with previous versions. - GPU Compute Shader Support: New interfaces for running compute shaders on DX12, Vulkan, and Metal are available.
- To disable these, set
JPH_USE_DX12,JPH_USE_VK, orJPH_USE_MTLtoOFF. - macOS Requirement: To build on macOS, you must have
dxcandspirv-crossinstalled (e.g., via the Vulkan SDK).
- To disable these, set
- Friction Model: The friction model has changed, which may slightly alter simulation results over time.