Introduction
Atlas Engine provides a comprehensive physics system through the Bezel abstraction layer, which is powered by Jolt Physics - a high-performance, multi-threaded physics engine.
Bezel provides a backend-agnostic interface for rigid bodies, colliders, joint constraints, and vehicle simulation. When BEZEL_NATIVE is not defined, this implementation is backed by Jolt Physics.
Architecture
The physics system consists of several layers:
atlas/physics.h - High-level physics components for the Atlas engine
bezel/bezel.h - Backend-agnostic physics abstraction layer
Jolt Physics - Underlying physics engine implementation
Core Components
PhysicsWorld
The PhysicsWorld manages the entire physics simulation:
bezel ::PhysicsWorld world;
world . init ();
// Set global gravity
world . setGravity ({ 0.0 f , - 9.81 f , 0.0 f });
// Update simulation
world . update (deltaTime);
Rigidbody Component
The Rigidbody component binds physics to a GameObject:
auto rb = std :: make_shared < Rigidbody >();
rb -> setMotionType ( MotionType ::Dynamic);
rb -> setMass ( 5.0 f );
rb -> addBoxCollider ({ 0.5 f , 0.5 f , 0.5 f });
rb -> setFriction ( 0.8 f );
// Optional tagging for filtered queries
rb -> addTag ( "Player" );
Motion Types
Rigidbodies can have three motion types:
enum class MotionType {
Static , // Immovable objects (terrain, walls)
Dynamic , // Fully simulated objects affected by forces
Kinematic // Movable but not affected by forces
};
Usage Example
// Static ground
auto ground = std :: make_shared < Rigidbody >();
ground -> setMotionType ( MotionType ::Static);
ground -> addBoxCollider ({ 10.0 f , 0.1 f , 10.0 f });
// Dynamic ball
auto ball = std :: make_shared < Rigidbody >();
ball -> setMotionType ( MotionType ::Dynamic);
ball -> setMass ( 1.0 f );
ball -> addSphereCollider ( 0.5 f );
ball -> applyImpulse ({ 0.0 f , 10.0 f , 0.0 f });
Physics Properties
Mass and Damping
// Set mass (in kilograms)
rigidbody -> setMass ( 10.0 f );
// Set linear and angular damping
rigidbody -> setDamping ( 0.05 f , 0.1 f );
Material Properties
// Set friction coefficient (0.0 to 1.0)
rigidbody -> setFriction ( 0.5 f );
// Set restitution/bounciness (0.0 to 1.0)
rigidbody -> setRestitution ( 0.7 f );
Applying Forces
// Apply continuous force
rigidbody -> applyForce ({ 0.0 f , 100.0 f , 0.0 f });
// Apply force at a specific point
rigidbody -> applyForceAtPoint ({ 10.0 f , 0.0 f , 0.0 f }, { 0.0 f , 1.0 f , 0.0 f });
// Apply instantaneous impulse
rigidbody -> applyImpulse ({ 0.0 f , 0.0 f , 20.0 f });
Velocity Control
// Set linear velocity
rigidbody -> setLinearVelocity ({ 5.0 f , 0.0 f , 0.0 f });
// Add to linear velocity
rigidbody -> addLinearVelocity ({ 0.0 f , 2.0 f , 0.0 f });
// Set angular velocity
rigidbody -> setAngularVelocity ({ 0.0 f , 1.0 f , 0.0 f });
// Get velocities
Velocity3d linearVel = rigidbody -> getLinearVelocity ();
Velocity3d angularVel = rigidbody -> getAngularVelocity ();
Velocity Limits
// Set maximum velocities to prevent instability
rigidbody -> setMaxLinearVelocity ( 50.0 f );
rigidbody -> setMaxAngularVelocity ( 10.0 f );
Sensors (Triggers)
Sensors detect overlaps without physical collision:
auto sensor = std :: make_shared < Sensor >();
sensor -> addSphereCollider ( 1.0 f );
sensor -> setSignal ( "EnteredTrigger" );
Physics Queries
Atlas provides several query types:
Raycast - Cast a ray and detect hits
Overlap - Check for overlapping objects
Sweep - Predict movement collisions
// Raycast from rigidbody
rigidbody -> raycast ({ 0.0 f , - 1.0 f , 0.0 f }, 100.0 f );
// Raycast from world position
rigidbody -> raycastWorld ({ 0.0 f , 10.0 f , 0.0 f }, { 0.0 f , - 1.0 f , 0.0 f }, 100.0 f );
// Results delivered via Component::onQueryReceive(QueryResult&)
Next Steps
Colliders Learn about collision shapes and collider types
Rigidbodies Deep dive into rigidbody physics
Joints Connect objects with physics constraints
Vehicles Build realistic vehicle physics
Additional Resources