Skip to main content

Overview

The Camera class represents a camera in 3D space, capable of generating view and projection matrices. It includes built-in controls for moving and looking with native support for both perspective and orthographic projections.

Creating a Camera

#include "atlas/camera.h"

// Create a camera instance
Camera camera;

// Set the camera position
camera.setPosition({-5.0f, 1.0f, 0.0f});

// Make the camera look at a target point
camera.lookAt({0.0f, 1.0f, 0.0f});

// Configure clipping planes
camera.nearClip = 0.5f;
camera.farClip = 1000.0f;

// Set field of view (perspective only)
camera.fov = 45.0f;

// Attach camera to window
window.setCamera(&camera);

Camera Properties

position
Position3d
The position of the camera in 3D space
target
Point3d
The point where the camera is looking at in 3D space
fov
float
default:"45.0f"
Field of view in degrees (for perspective projection)
nearClip
float
default:"0.5f"
Near clipping plane distance. Everything closer will be clipped
farClip
float
default:"1000.0f"
Far clipping plane distance. Everything farther will be clipped
orthographicSize
float
default:"5.0f"
Size of the orthographic projection
movementSpeed
float
default:"2.0f"
Speed at which the camera moves through the scene
mouseSensitivity
float
default:"0.1f"
Factor by which the camera’s mouse input is scaled
lookSmoothness
float
default:"0.15f"
Factor to determine how smoothly the camera looks at the target
useOrthographic
bool
default:"false"
Whether the camera is using orthographic projection

Camera Movement

Keyboard Controls

Update the camera each frame with user input:
void update(Window &window) override {
    camera.update(window);
    
    // Custom movement
    if (window.isKeyPressed(Key::Q)) {
        camera.position.y -= 10.0f * window.getDeltaTime();
    }
}
Default WASD movement is built-in when calling camera.update(window).

Mouse Look

Handle mouse movement for camera rotation:
void onMouseMove(Window &window, Movement2d movement) override {
    camera.updateLook(window, movement);
}

Programmatic Movement

// Move by delta
camera.move({0.0f, 1.0f, 0.0f});

// Move in a specific direction
camera.moveTo(Direction3d(0.0f, 1.0f, 0.0f), 5.0f);

// Set absolute position
camera.setPosition({10.0f, 5.0f, 10.0f});

// Set position while keeping orientation
camera.setPositionKeepingOrientation({0.0f, 10.0f, 0.0f});

Projection Types

Perspective Projection

Default projection mode for 3D scenes:
camera.useOrthographic = false;
camera.fov = 60.0f;  // Wider field of view
camera.nearClip = 0.1f;
camera.farClip = 500.0f;

Orthographic Projection

Useful for 2D games or technical visualization:
camera.useOrthographic = true;
camera.orthographicSize = 10.0f;  // Size of the view

View Matrix

The camera automatically calculates the view matrix:
glm::mat4 viewMatrix = camera.calculateViewMatrix();
This is used internally by the rendering system, but you can access it for custom shaders or calculations.

Camera Vectors

Front Vector

Get the direction the camera is facing:
Normal3d front = camera.getFrontVector();
Useful for raycasting, projectile spawning, or movement:
// Spawn projectile in camera direction
projectile.setPosition(camera.position);
projectile.velocity = camera.getFrontVector() * 20.0f;

Velocity

Get the camera’s current velocity based on movement:
Magnitude3d velocity = camera.getVelocity();

Depth of Field

Configure depth of field for post-processing effects:
focusDepth
float
default:"20.0f"
The depth value at which objects are in perfect focus
focusRange
float
default:"10.0f"
The range around focusDepth where objects gradually transition from sharp to blurred
camera.focusDepth = 15.0f;  // Focus at 15 units
camera.focusRange = 5.0f;   // Gradual falloff

Complete Example

Here’s a complete example from the test suite:
class MainScene : public Scene {
    Camera camera;
    bool doesUpdate = true;
    bool fall = false;

public:
    void initialize(Window &window) override {
        // Create camera
        camera = Camera();
        camera.setPosition({-5.0f, 1.0f, 0.0f});
        camera.lookAt({0.0f, 1.0f, 0.0f});
        camera.farClip = 1000.0f;
        window.setCamera(&camera);
    }

    void update(Window &window) override {
        if (!doesUpdate)
            return;

        camera.update(window);
        
        if (window.isKeyPressed(Key::Escape)) {
            window.releaseMouse();
            doesUpdate = false;
        } else if (window.isKeyClicked(Key::Q)) {
            fall = !fall;
        }
        
        if (fall) {
            camera.position.y -= 10.0f * window.getDeltaTime();
        }
    }

    void onMouseMove(Window &window, Movement2d movement) override {
        if (!doesUpdate) {
            return;
        }
        camera.updateLook(window, movement);
    }
};

ViewInformation

For systems that need camera context (weather, atmosphere, etc.):
struct ViewInformation {
    Position3d position;  // Camera position
    Position3d target;    // Look-at target
    float time;           // Absolute engine time
    float deltaTime;      // Time since previous update
};

Best Practices

Smooth Movement

Use deltaTime from the window for frame-independent movement:
camera.position.y += speed * window.getDeltaTime();

Far Clip Optimization

Set farClip based on your scene size to avoid rendering distant objects:
camera.farClip = 100.0f;  // For indoor scenes
camera.farClip = 5000.0f; // For outdoor scenes

Mouse Capture

Capture the mouse for FPS-style controls:
Window window({
    .title = "My Game",
    .width = 1920,
    .height = 1080,
    .mouseCaptured = true  // Capture mouse
});

See Also

Build docs developers (and LLMs) love