Skip to content

Camera Showcase

App: apps/camera_showcase/

The camera system end to end (Camera epic, ADR 0058). A cyan “player” node circles the arena; the camera follows it in third-person, then blends to an orbit rig (with a handheld noise sway), then takes an impulse shake — all with draw() being nothing but scene.draw() + the mesh draws. There is no Graphics.setViewMatrix, no aspect math, no camera node in the game code.

Terminal window
% ./plume3d camera_showcase

Self-screenshots cam_third (the follow) and cam_orbit (after the blend), then exits.

On init, it makes two rigs over the same player node — the first auto-activates:

_third = Cam.thirdPerson(_scene, _player).distance(6).shoulder(0.6, 1.6).damping(0.25)
_orbit = Cam.orbit(_scene, _player, 11).noise(0.12, 0.5)

Each frame it moves the player in a circle and, on cue, blends and shakes:

update(dt) {
_t = _t + dt
_player.setPosition(_t.sin * 5, 0.5, _t.cos * 5) // the camera follows
if (_fc == 130) Cam.blendTo(_orbit, 1.2, Ease.easeInOut) // eased hand-off between rigs
if (_fc == 210) {
var p = _player.getPosition()
Impulse.emit(_scene, 1.6, p[0], 0.5, p[2]) // shake the live camera
}
}
draw() {
_scene.draw() // NO camera plumbing
// ...draw the floor, player, and obstacle cubes...
}

The engine’s per-scene camera director solves the active rig at the end of each frame (after update, so it tracks the player’s final position) and pushes the view/projection — which survives to the renderer untouched, so draw() never touches the camera.