Taos API Reference
    Preparing search index...

    Class CameraController

    Dual free-fly + orbit camera controller, in the spirit of PlayCanvas's CameraControls.

    CameraController.mode selects the active scheme; both share the same yaw/pitch + position state, so flipping between them mid-session is seamless (orbit pivots around whatever is in front of you; fly slides off from wherever you were orbiting).

    Fly mode ('fly', default) — FPS-style: WASD (or arrows) for horizontal movement, ControlLeft (or AltLeft) for a 3× speed boost, and a switchable vertical scheme (see CameraController.verticalKeyMode): 'hybrid' (default, either pair), Space/ShiftLeft, or KeyE/KeyQ to ascend/descend. When usePointerLock is true, clicking the canvas acquires pointer lock and mouse motion drives yaw/pitch; when false, left-drag looks around. Middle-drag dollies along the view and right-drag pans the camera in its view plane. The mouse wheel dollies along the view direction (see CameraController.wheelDolly).

    Orbit mode ('orbit') — turntable around a focus point at CameraController.focusDistance: left-drag orbits, middle-drag dollies (drag to zoom, three.js-style), right-drag (or Shift+left-drag) pans the focus, and the wheel zooms (clamped to CameraController.minDistance/CameraController.maxDistance). WASD still flies the focus point along the view. CameraController.focusOn recenters the pivot. Enable CameraController.enableDamping for eased, inertia-like orbit/pan/zoom and a smooth fly-to on focus.

    As a component (recommended) — add the controller to the camera's GameObject and the engine drives it for you: it auto-attaches its DOM listeners (to the engine canvas) and updates against its owner every frame, so no engine.beforeFrame(...) plumbing is needed:

    cameraGO.addComponent(CameraController.create({ ... }));
    

    Standalone — for non-engine drivers (raw render-graph samples, the editor, tests), call CameraController.attach once, then CameraController.update every frame against the camera's GameObject.

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    yaw: number

    Yaw in radians, rotation around world Y.

    pitch: number

    Pitch in radians, rotation around local X (clamped to ±89°).

    speed: number

    Movement speed in world units per second.

    sensitivity: number

    Mouse sensitivity in radians per pixel of movement.

    worldUp: Vec3 = ...

    World-space "up" the controls are relative to. Defaults to +Y (a flat world). Set it to the local surface normal — e.g. the radial direction from a planet's center — to free-fly around a curved body: yaw orbits this up, pitch tilts about the resulting right, Space/Shift move along it, and the horizon stays level as you move. The control frame is the shortest-arc rotation from +Y to this vector, so yaw/pitch keep their world-+Y meaning when it's +Y (unchanged behavior). Re-set it each frame for a moving camera on a sphere.

    moveRelativeToView: boolean = false

    When true, movement is relative to the full view orientation (6-DOF free-fly): forward follows the look direction including pitch, strafe the camera right, and Space/Shift the camera's own up. When false (default), movement uses the surface frame — horizontal forward in the yaw plane (pitch ignored), vertical along worldUp. Set it true in space, where worldUp is detached from the body and a horizontal frame no longer matches the view (W would drift sideways, Space/Shift off-axis).

    inputForward: number = 0

    Analog forward input in [-1, 1] (touch joystick / programmatic).

    inputStrafe: number = 0

    Analog strafe input in [-1, 1] (positive = right).

    inputUp: boolean = false

    Held-up flag (OR-ed with the active ascend key).

    inputDown: boolean = false

    Held-down flag (OR-ed with the active descend key).

    verticalKeyMode: "space-shift" | "eq" | "hybrid" = 'hybrid'

    Which keyboard keys drive vertical (up/down) movement. 'hybrid' (default) accepts both schemes — Space or KeyE to ascend, ShiftLeft or KeyQ to descend; 'space-shift' uses only Space to ascend and ShiftLeft to descend; 'eq' uses only KeyE to ascend and KeyQ to descend. Switch this live to flip between the schemes.

    inputFast: boolean = false

    Held-fast flag (OR-ed with ControlLeft / AltLeft).

    usePointerLock: boolean = false

    Set false to suppress pointer-lock acquisition on canvas click (touch devices).

    wheelDolly: boolean = true

    When true (default), rolling the mouse wheel over the canvas dollies the camera forward/backward along the view direction. Set false to ignore wheel input.

    dollySpeed: number = 1

    World units the camera dollies per wheel notch (scaled by speed).

    mode: CameraControlMode = 'fly'

    Active control scheme. 'fly' (default) is FPS free-fly; 'orbit' turntables around the focus point. Flip it live — the shared yaw/pitch/position state makes the switch seamless.

    focusDistance: number = 10

    Orbit-mode distance from the camera to its focus point, in world units. Also the implicit pivot distance used when entering orbit from fly.

    minDistance: number = 0.1

    Minimum focusDistance the wheel zoom will clamp to (orbit mode).

    maxDistance: number = Infinity

    Maximum focusDistance the wheel zoom will clamp to (orbit mode).

    minPitch: number = -HALF_PI

    Pitch clamp, radians. Defaults to ±89° (just shy of gimbal lock).

    maxPitch: number = HALF_PI
    orbitSpeed: number = 0.005

    Per-pixel rotation rate for orbit drag. Defaults to sensitivity.

    panSpeed: number = 1

    Pan rate multiplier (orbit middle/right-drag). Scaled by focusDistance.

    zoomSpeed: number = 0.1

    Wheel zoom rate (orbit mode); each notch scales focusDistance by exp(±this).

    enableDamping: boolean = false

    When true, orbit/pan/zoom (and focus fly-to) are eased toward their targets instead of applied instantly. Off by default so fly mode stays frame-exact with existing samples.

    damping: number = 0.12

    Damping time-constant in seconds when enableDamping is set (smaller = snappier).

    id: string = ...

    Stable identity for this component, unique within a session. Auto-generated for runtime-created components; the editor overwrites it with a persistent id when projecting a saved document so references survive save / load / undo.

    gameObject: GameObject

    The owning GameObject; assigned by addComponent before onAttach runs.

    Accessors

    • get time(): Time

      The simulation clock of the scene this component belongs to. Read inside update (or any time after the GameObject is added to a scene) for absolute time, frame count, FPS, and timeScale-aware delta — e.g. this.time.elapsed, this.time.delta, this.time.frameCount.

      this.time.delta equals the dt argument passed to update, so components can ignore that argument entirely and pull everything from here.

      Returns Time

      if the owning GameObject is not currently part of a scene.

    Methods

    • Injects a key as if it were currently held.

      Use when the controller is attached after the physical keydown event already fired (e.g. double-tap toggle).

      Parameters

      • code: string

        KeyboardEvent.code value, e.g. 'KeyW'.

      Returns void

    • Adds the given delta to yaw and pitch (with the same sensitivity scaling as mouse movement). Used by touch-drag look handlers and similar programmatic camera input.

      Parameters

      • dx: number

        Horizontal movement in pixels (positive = right).

      • dy: number

        Vertical movement in pixels (positive = down).

      Returns void

    • Recenters the orbit focus on a world-space point (orbit mode), optionally setting a new focusDistance. With enableDamping on, the camera eases (flies) to the new framing; otherwise it snaps. Yaw/pitch are unchanged, so the viewing angle is preserved.

      Parameters

      • point: Vec3

        World-space point to orbit around.

      • Optionaldistance: number

        Optional new distance from the camera to that point.

      Returns void

    • Advances the controller, applying input to the GameObject's position and rotation.

      Yaw and pitch are composed as independent quaternions so the camera never accumulates roll.

      Two call forms:

      • As a Component the engine invokes update(dt) during scene.update, driving the controller's owning GameObject. On the first such call it lazily attaches its DOM listeners to the engine canvas, so adding the controller to the camera is all the wiring an app needs.
      • Standalone drivers call update(gameObject, dt) against an explicit GameObject (after a manual attach).

      Parameters

      • dt: number

        Frame delta time in seconds.

      Returns void

    • Advances the controller, applying input to the GameObject's position and rotation.

      Yaw and pitch are composed as independent quaternions so the camera never accumulates roll.

      Two call forms:

      • As a Component the engine invokes update(dt) during scene.update, driving the controller's owning GameObject. On the first such call it lazily attaches its DOM listeners to the engine canvas, so adding the controller to the camera is all the wiring an app needs.
      • Standalone drivers call update(gameObject, dt) against an explicit GameObject (after a manual attach).

      Parameters

      • gameObject: GameObject

        GameObject whose transform represents the camera.

      • dt: number

        Frame delta time in seconds.

      Returns void

    • Called once when the component is added to a GameObject. Override to acquire references to siblings/children or initialize resources.

      Returns void

    • Called every frame by the GameObject's render traversal, after update and any input/controller mutations to the transform. Override to refresh per-frame state that render passes consume (e.g. Camera recomputes its cached view/projection matrices here).

      Parameters

      • _ctx: RenderContext

        Active render context (provides canvas width/height etc.).

      Returns void