๐ Jolt Physics: A “High-Performance Physics Engine” in Modern C++
Have you encountered the following problem while developing 3D games, simulation systems, or virtual reality applications:
“I need a fast, stable, and easy-to-use physics engine to handle collisions, gravity, and rigid body motion, but Bullet is too complex, and ODE has limited functionality. What should I do?”
Today, we will introduce an open-source C++ physics library that has gained significant popularity in the gaming community in recent years โ Jolt Physics.
๐ What is Jolt Physics?
Jolt Physics is an open-source, high-performance, multi-threading friendly 3D rigid body physics engine designed for modern games and real-time applications.
It was developed by Jorrit Rouwe, initially for commercial projects at Remedy Entertainment (the developers of “Control” and “Quantum Break”), and was open-sourced in 2020, quickly becoming a popular choice among game developers.
Project address: https://github.com/jrouwe/JoltPhysics
Official documentation: https://jrouwe.github.io/JoltPhysics/
โ Core Features
| Feature | Description |
|---|---|
| โก Extreme Performance | Highly optimized, supports SIMD (SSE/AVX), suitable for real-time simulations at 60+ frames per second |
| ๐งต Multi-threading Support | Built-in task system for parallel processing of collision detection and physics updates |
| ๐ฆ Modular Design | Include only the parts you need, resulting in a small footprint |
| ๐ฎ Game Friendly | Supports triggers, character controllers, vehicles, joint constraints, etc. |
| ๐งฉ Easy Integration | Pure C++, no external dependencies (optional integration with Convex Decomposition) |
| ๐ MIT License | Free for commercial projects |
๐ ๏ธ Installation and Configuration (Ubuntu/Linux Example)
1. Clone the Source Code
git clone https://github.com/jrouwe/JoltPhysics.git
cd JoltPhysics
2. Build (Using CMake)
mkdir build && cd build
cmake ..
make -j$(nproc)
After building, you will get a static library libJoltPhysics.a.
๐ก First Example: Let a Box Fall Freely
Let’s write the simplest program: create a ground and a box, allowing the box to fall freely under gravity.
โ Project Structure
jolt_demo/
โโโ JoltPhysics/ # Header files and library
โโโ main.cpp
โโโ libJoltPhysics.a
โ
main.cpp Code
#include <Jolt/Jolt.h>
#include <Jolt/RegisterTypes.h>
// Physics components
#include <Jolt/Core/Factory.h>
#include <Jolt/Core/TempAllocator.h>
#include <Jolt/Core/JobSystem.h>
#include <Jolt/Physics/PhysicsSettings.h>
#include <Jolt/Physics/PhysicsSystem.h>
#include <Jolt/Physics/Body/BodyCreationSettings.h>
#include <Jolt/Physics/Collision/Shape/BoxShape.h>
#include <iostream>
#include <thread>
using namespace JPH;
int main() {
// 1. Initialize Jolt
RegisterDefaultAllocator();
Factory::sInstance = new Factory();
TempAllocator allocator(10 * 1024 * 1024); // 10MB temporary memory
// 2. Create the physics system
PhysicsSystem physicsSystem;
physicsSystem.Init();
// 3. Create a ground (infinite plane)
BodyInterface &bodyInterface = physicsSystem.GetBodyInterface();
BodyCreationSettings groundSettings(new StaticPlaneShape(Vec3::sAxisY(), 0.0f), // Plane normal Y, height 0
RVec3::sZero(), // Position
Quat::sIdentity(), // Rotation
EMotionType::Static, // Static object
Layers::NON_MOVING); // Layer
BodyID groundID = bodyInterface.CreateAndAddBody(groundSettings, EActivation::DontActivate);
// 4. Create a box (0.5m edge length)
BodyCreationSettings boxSettings(new BoxShape(Vec3(0.25f, 0.25f, 0.25f)), // Half-length, width, height
RVec3(0, 5, 0), // Initial position (x=0, y=5, z=0)
Quat::sIdentity(), // No rotation
EMotionType::Dynamic, // Dynamic object (affected by physics)
Layers::MOVING); // Layer
BodyID boxID = bodyInterface.CreateAndAddBody(boxSettings, EActivation::Activate);
// 5. Simulation loop (1/60 seconds per frame)
const float timeStep = 1.0f / 60.0f;
for (int i = 0; i < 60; ++i) {
// Update physics (multi-threaded)
physicsSystem.Update(timeStep, 1, &allocator, nullptr);
// Get box position
RVec3 position = bodyInterface.GetPosition(boxID);
std::cout << "t=" << i*timeStep << "s, y = " << position.GetY() << " m" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(16)); // Simulate 60 FPS
}
// 6. Cleanup
delete Factory::sInstance;
return 0;
}
โ Compile Command
g++ main.cpp \
-I./JoltPhysics/Include \
-L. -lJoltPhysics \
-lpthread -lstdc++ -o jolt_demo
๐จ๏ธ Output Example
t=0s, y = 5 m
t=0.0167s, y = 4.986 m
t=0.0333s, y = 4.968 m
...
t=0.983s, y = 0.000 m
๐ Success! The box falls freely from a height of 5 meters and finally “crashes” to the ground.
๐ Code Analysis
| Code Snippet | Description |
|---|---|
RegisterDefaultAllocator() |
Initializes memory management |
PhysicsSystem::Init() |
Initializes the physics world (including gravity) |
StaticPlaneShape |
Creates an infinite ground |
BoxShape |
Creates a box shape |
EMotionType::Dynamic |
Indicates that the object will move and is affected by gravity |
physicsSystem.Update() |
Advances one frame of physics simulation (automatically handles collisions, gravity, etc.) |
๐งฉ Going Further: Adding Collision Callbacks
Do you want to know when the box lands? You can use a Contact Listener.
class MyContactListener : public ContactListener {
public:
virtual ValidateResult OnContactValidate(const Body &inBody1, const Body &inBody2,
RVec3Arg inBaseOffset, const CollideShapeResult &inResult) override {
std::cout << "Collision may occur!" << std::endl;
return ValidateResult::AcceptAllContactsForThisBodyPair;
}
virtual void OnContactAdded(const Body &inBody1, const Body &inBody2,
const ContactManifold &inManifold, ContactSettings &ioSettings) override {
std::cout << "Collision occurred!" << std::endl;
}
};
// Register listener after Init
physicsSystem.SetContactListener(new MyContactListener());
๐ Supported Core Features
| Feature | Description |
|---|---|
| ๐ฆ Rigid Body Dynamics | Gravity, velocity, acceleration, collisions |
| ๐ Joint System | Hinges, sliders, spherical, springs, etc. |
| ๐ค Character Controller | For player or NPC movement |
| ๐ Vehicle Support | Complete vehicle physics model |
| ๐งฑ Convex Hull and Mesh | Supports complex shapes (requires preprocessing) |
| ๐ง Multi-threading | Built-in Job System, automatically parallel |
๐ฎ Real-World Applications
- “Control”: The birthplace of Jolt
- Indie Game Development: Integration with Godot and custom engines
- Robot Simulation: A lightweight alternative to Bullet
- VR/AR Applications: Low-latency physics feedback
โ Why Choose Jolt Physics?
| Comparison Item | Jolt Physics | Bullet |
|---|---|---|
| Performance | โก Extremely fast (SIMD + multi-threading) | Fast |
| Ease of Use | โ Simple API | Complex, heavy historical baggage |
| Documentation | ๐ Excellent (includes examples) | Average |
| Community | Growing actively | Very active |
| Commercial Use | โ MIT License | โ |
๐ฌ Many developers say: “Once I used Jolt, I never want to go back to Bullet.”
โ Summary
Jolt Physics is the “rising star” of modern C++ physics engines, it:
โก Fast
๐งฉ Simple
๐ฎ Powerful
๐ Free