Overview
The Rigidbody component is the foundation of physics simulation in Atlas. It binds a Bezel rigidbody to a GameObject and provides a high-level API for physics interactions.
Creating a Rigidbody
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);
Motion Types
Rigidbodies support three motion types defined in bezel/bezel.h:64:
enum class MotionType {
Static, // Immovable, zero velocity
Dynamic, // Fully simulated with forces and collisions
Kinematic // Movable but not affected by forces
};
Static Bodies
Static bodies never move and are used for terrain, walls, and fixed obstacles:
auto ground = std::make_shared<Rigidbody>();
ground->setMotionType(MotionType::Static);
ground->addBoxCollider({10.0f, 0.1f, 10.0f});
Dynamic Bodies
Dynamic bodies are fully simulated and respond to forces, gravity, and collisions:
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});
Kinematic Bodies
Kinematic bodies can be moved programmatically but don’t respond to forces:
auto platform = std::make_shared<Rigidbody>();
platform->setMotionType(MotionType::Kinematic);
platform->addBoxCollider({2.0f, 0.1f, 2.0f});
// Move directly via transform
Physics Properties
Mass
Mass affects how forces and impulses affect the rigidbody:
// Set mass in kilograms
rigidbody->setMass(10.0f);
// Lower mass = easier to move
rigidbody->setMass(0.5f); // Light object
rigidbody->setMass(100.0f); // Heavy object
Mass is stored in the underlying bezel::Rigidbody struct at bezel.h:475
Friction
Friction controls how much resistance objects have when sliding:
// Set friction coefficient (0.0 = frictionless, 1.0 = high friction)
rigidbody->setFriction(0.5f);
// Examples:
rigidbody->setFriction(0.0f); // Ice
rigidbody->setFriction(0.5f); // Default
rigidbody->setFriction(0.9f); // Rubber
Restitution (Bounciness)
Restitution controls how much energy is retained during collisions:
// Set restitution (0.0 = no bounce, 1.0 = perfect bounce)
rigidbody->setRestitution(0.7f);
// Examples:
rigidbody->setRestitution(0.0f); // No bounce
rigidbody->setRestitution(0.5f); // Some bounce
rigidbody->setRestitution(0.9f); // Very bouncy
Damping
Damping reduces velocity over time to simulate air resistance:
// Set linear and angular damping
rigidbody->setDamping(0.05f, 0.1f);
// Lower values = less damping (objects move longer)
// Higher values = more damping (objects slow down faster)
The default damping values from bezel.h:489-490:
- Linear damping:
0.05f
- Angular damping:
0.1f
Applying Forces and Impulses
Continuous Forces
Forces are applied continuously during physics updates:
// Apply force at center of mass
rigidbody->applyForce({0.0f, 100.0f, 0.0f});
// Apply force at a specific world-space point
rigidbody->applyForceAtPoint(
{10.0f, 0.0f, 0.0f}, // Force vector
{0.0f, 1.0f, 0.0f} // Application point
);
Impulses
Impulses are instantaneous changes in velocity:
// Apply impulse (from test/main.cpp:120)
if (object && object->rigidbody) {
object->rigidbody->applyImpulse({0.0f, 0.0f, 20.0f});
}
Use forces for continuous effects (like jet engines) and impulses for instant events (like explosions or jumping).
Velocity Control
Setting Velocity
// Set linear velocity directly
rigidbody->setLinearVelocity({5.0f, 0.0f, 0.0f});
// Set angular velocity
rigidbody->setAngularVelocity({0.0f, 1.0f, 0.0f});
Adding Velocity
// Add to existing linear velocity
rigidbody->addLinearVelocity({0.0f, 5.0f, 0.0f});
// Add to existing angular velocity
rigidbody->addAngularVelocity({0.0f, 0.5f, 0.0f});
Reading Velocity
// Get current velocities
Velocity3d linearVel = rigidbody->getLinearVelocity();
Velocity3d angularVel = rigidbody->getAngularVelocity();
Velocity3d totalVel = rigidbody->getVelocity();
Velocity Limits
Prevent instability with velocity limits:
// Set maximum velocities
rigidbody->setMaxLinearVelocity(50.0f);
rigidbody->setMaxAngularVelocity(10.0f);
Tagging System
Tags enable filtering and game logic:
// Add tags
rigidbody->addTag("Player");
rigidbody->addTag("Enemy");
// Check for tags
if (rigidbody->hasTag("Player")) {
// Player-specific logic
}
// Remove tags
rigidbody->removeTag("Enemy");
// Use tags with raycasts
rigidbody->raycastTagged({"Enemy", "Obstacle"}, direction, 100.0f);
Tags are stored in bezel::Rigidbody at bezel.h:479:
std::vector<std::string> tags;
Sensors (Triggers)
Sensors detect overlaps without physical collision response:
auto sensor = std::make_shared<Sensor>();
sensor->addSphereCollider(1.0f);
sensor->setSignal("PlayerEnteredZone");
The Sensor class (defined in atlas/physics.h:481-487) is a convenience wrapper:
class Sensor final : public Rigidbody {
public:
Sensor() { Rigidbody::isSensor = true; }
void setSignal(const std::string &signal) {
sendSignal = signal;
}
};
Physics Queries
Rigidbodies support multiple query types. Results are delivered asynchronously via Component::onQueryReceive().
Raycasting
// Cast ray from rigidbody position
rigidbody->raycast({0.0f, -1.0f, 0.0f}, 100.0f);
// Cast ray with all hits
rigidbody->raycastAll({0.0f, -1.0f, 0.0f}, 100.0f);
// Cast ray from arbitrary world position
rigidbody->raycastWorld(
{0.0f, 10.0f, 0.0f}, // Origin
{0.0f, -1.0f, 0.0f}, // Direction
100.0f // Max distance
);
// Cast with tag filtering
rigidbody->raycastTagged(
{"Enemy", "Destructible"}, // Tags to hit
{0.0f, -1.0f, 0.0f},
100.0f
);
Overlap Queries
// Check overlap at current position
rigidbody->overlap();
// Check overlap with specific shapes
rigidbody->overlapSphere(2.0f);
rigidbody->overlapBox({1.0f, 1.0f, 1.0f});
rigidbody->overlapCapsule(0.5f, 2.0f);
// Check overlap at world position
rigidbody->overlapSphereWorld({0.0f, 5.0f, 0.0f}, 1.0f);
Movement Prediction (Sweep)
Predict collisions before moving:
Position3d endPosition = {5.0f, 0.0f, 0.0f};
// Predict movement with current collider
rigidbody->predictMovement(endPosition);
// Predict with specific shapes
rigidbody->predictMovementSphere(endPosition, 0.5f);
rigidbody->predictMovementBox(endPosition, {0.5f, 0.5f, 0.5f});
// Get all hits along path
rigidbody->predictMovementAll(endPosition);
Receiving Query Results
class MyComponent : public Component {
void onQueryReceive(QueryResult& result) override {
if (result.operation == QueryOperation::Raycast) {
if (result.raycastResult.hit.didHit) {
std::cout << "Hit at distance: "
<< result.raycastResult.hit.distance << std::endl;
}
}
}
};
Rigidbody positions can be set programmatically:
// Set position (updates physics body)
rigidbody->body->setPosition(
{10.0f, 5.0f, 0.0f},
physicsWorld
);
// Set rotation (updates physics body)
rigidbody->body->setRotation(
{0.0f, 45.0f, 0.0f},
physicsWorld
);
From bezel.h:496-500, these methods update both the rigidbody state and the backend physics body.
Complete Example
Here’s a complete example creating a bouncing ball:
// Create physics world
auto world = std::make_shared<bezel::PhysicsWorld>();
world->init();
world->setGravity({0.0f, -9.81f, 0.0f});
// Create ground
auto ground = std::make_shared<Rigidbody>();
ground->setMotionType(MotionType::Static);
ground->addBoxCollider({10.0f, 0.1f, 10.0f});
ground->setFriction(0.5f);
// Create ball
auto ball = std::make_shared<Rigidbody>();
ball->setMotionType(MotionType::Dynamic);
ball->setMass(1.0f);
ball->addSphereCollider(0.5f);
ball->setRestitution(0.8f); // Bouncy!
ball->setFriction(0.3f);
ball->applyImpulse({0.0f, 10.0f, 0.0f});
// Update loop
while (running) {
world->update(deltaTime);
}
API Reference
Rigidbody Methods (atlas/physics.h:346-476)
| Method | Description |
|---|
setMotionType(MotionType) | Set static, dynamic, or kinematic mode |
setMass(float) | Set mass in kilograms |
setFriction(float) | Set friction coefficient (0.0-1.0) |
setRestitution(float) | Set bounciness (0.0-1.0) |
setDamping(float, float) | Set linear and angular damping |
applyForce(Position3d) | Apply continuous force |
applyForceAtPoint(Position3d, Position3d) | Apply force at point |
applyImpulse(Position3d) | Apply instant impulse |
setLinearVelocity(Position3d) | Set linear velocity |
addLinearVelocity(Position3d) | Add to linear velocity |
setAngularVelocity(Position3d) | Set angular velocity |
addAngularVelocity(Position3d) | Add to angular velocity |
getLinearVelocity() | Get current linear velocity |
getAngularVelocity() | Get current angular velocity |
setMaxLinearVelocity(float) | Set max linear velocity |
setMaxAngularVelocity(float) | Set max angular velocity |
addTag(string) | Add tag for filtering |
hasTag(string) | Check if tag exists |
removeTag(string) | Remove tag |
See Also