Skip to main content

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.0f, -9.81f, 0.0f});

// 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.0f);
rb->addBoxCollider({0.5f, 0.5f, 0.5f});
rb->setFriction(0.8f);

// 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.0f, 0.1f, 10.0f});

// Dynamic ball
auto ball = std::make_shared<Rigidbody>();
ball->setMotionType(MotionType::Dynamic);
ball->setMass(1.0f);
ball->addSphereCollider(0.5f);
ball->applyImpulse({0.0f, 10.0f, 0.0f});

Physics Properties

Mass and Damping

// Set mass (in kilograms)
rigidbody->setMass(10.0f);

// Set linear and angular damping
rigidbody->setDamping(0.05f, 0.1f);

Material Properties

// Set friction coefficient (0.0 to 1.0)
rigidbody->setFriction(0.5f);

// Set restitution/bounciness (0.0 to 1.0)
rigidbody->setRestitution(0.7f);

Applying Forces

// Apply continuous force
rigidbody->applyForce({0.0f, 100.0f, 0.0f});

// Apply force at a specific point
rigidbody->applyForceAtPoint({10.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f});

// Apply instantaneous impulse
rigidbody->applyImpulse({0.0f, 0.0f, 20.0f});

Velocity Control

// Set linear velocity
rigidbody->setLinearVelocity({5.0f, 0.0f, 0.0f});

// Add to linear velocity
rigidbody->addLinearVelocity({0.0f, 2.0f, 0.0f});

// Set angular velocity
rigidbody->setAngularVelocity({0.0f, 1.0f, 0.0f});

// Get velocities
Velocity3d linearVel = rigidbody->getLinearVelocity();
Velocity3d angularVel = rigidbody->getAngularVelocity();

Velocity Limits

// Set maximum velocities to prevent instability
rigidbody->setMaxLinearVelocity(50.0f);
rigidbody->setMaxAngularVelocity(10.0f);

Sensors (Triggers)

Sensors detect overlaps without physical collision:
auto sensor = std::make_shared<Sensor>();
sensor->addSphereCollider(1.0f);
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.0f, -1.0f, 0.0f}, 100.0f);

// Raycast from world position
rigidbody->raycastWorld({0.0f, 10.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, 100.0f);

// 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

Build docs developers (and LLMs) love