Skip to main content

Camera

Struct Camera 

Source
pub struct Camera { /* private fields */ }
Expand description

The map camera state.

Stores the geographic target, orbital parameters (pitch / yaw / distance), projection mode, and viewport dimensions. All derived matrices are computed on demand – the struct itself is plain data.

§Invariants (enforced by setters)

FieldGuarantee
pitchClamped to [0, PI/2 - ?] on every write
yawNormalized to [-?, ?] on every write
distanceAlways positive and finite
fov_yAlways positive and finite

§Thread safety

Camera is Send + Sync (all fields are Copy or trivially safe). It is typically owned by MapState and mutated from a single thread per frame.

Implementations§

Source§

impl Camera

Source

pub fn view_up_vector(&self) -> DVec3

Camera-relative up vector matching view_matrix.

Source

pub fn target(&self) -> &GeoCoord

Geographic center the camera is looking at.

Source

pub fn distance(&self) -> f64

Distance from the target point, in meters.

Source

pub fn projection(&self) -> CameraProjection

Geographic projection used by camera/world coordinate helpers.

Source

pub fn pitch(&self) -> f64

Pitch angle in radians (0 = top-down, ??/2 = horizon).

Source

pub fn yaw(&self) -> f64

Yaw / bearing angle in radians, normalized to [-?, ?].

Source

pub fn mode(&self) -> CameraMode

Projection mode.

Source

pub fn fov_y(&self) -> f64

Vertical field of view in radians (perspective mode only).

Source

pub fn viewport_width(&self) -> u32

Viewport width in pixels.

Source

pub fn viewport_height(&self) -> u32

Viewport height in pixels.

Source

pub fn set_target(&mut self, target: GeoCoord)

Set the camera target coordinate.

Source

pub fn set_projection(&mut self, projection: CameraProjection)

Set the camera’s geographic projection.

Source

pub fn set_distance(&mut self, d: f64)

Set camera distance in meters. Non-finite or non-positive values are rejected in debug builds and ignored in release builds.

Source

pub fn set_pitch(&mut self, p: f64)

Set pitch in radians. Hard-clamped to [0, MAX_PITCH]. Non-finite values are rejected.

Source

pub fn set_yaw(&mut self, y: f64)

Set yaw / bearing in radians. Normalized to [-?, ?]. Non-finite values are rejected.

Source

pub fn set_mode(&mut self, mode: CameraMode)

Set the projection mode.

Adjusts distance so that meters_per_pixel (and therefore the displayed zoom level) stays constant across the transition.

The visible ground height formulas are:

  • Perspective: 2 * distance * tan(fov_y / 2)
  • Orthographic: 2 * distance

Equating the two gives the conversion factor tan(fov_y / 2).

Source

pub fn set_fov_y(&mut self, fov: f64)

Set vertical field-of-view in radians. Non-finite or non-positive values are rejected.

Source

pub fn set_viewport(&mut self, width: u32, height: u32)

Set the viewport dimensions in pixels.

Source

pub fn eye_offset(&self) -> DVec3

Eye position relative to the target (camera-relative origin).

Computed from spherical coordinates with the conventions documented in the module-level docs.

eye.x = d * sin(pitch) * sin(yaw)   -- east component
eye.y = d * sin(pitch) * cos(yaw)   -- north component
eye.z = d * cos(pitch)              -- altitude

At yaw = 0 the camera sits on the +Y (north) side of the target.

Source

pub fn view_matrix(&self, target_world: DVec3) -> DMat4

Build a view matrix (world -> camera clip space, right-handed).

§Up-vector derivation

The up-hint is computed from the orbital geometry in two regimes:

Pitched (pitch > threshold): the camera’s “screen-right” vector is the orbit-sphere tangent in the yaw direction:

right = (cos(yaw), -sin(yaw), 0)

This is always horizontal, always perpendicular to the look direction, and independent of pitch. The up-hint is then right x look (normalised), which is guaranteed to point “above the horizon” from the camera’s perspective and is never degenerate.

Top-down (pitch <= threshold): the look direction is nearly -Z, and the horizontal right vector is degenerate (the orbit tangent’s magnitude approaches zero). Instead the up-hint is set to (sin(yaw), cos(yaw), 0) so the yaw bearing controls which map direction appears at the top of the screen.

The two regimes are smoothly blended over 0..threshold using t = pitch / threshold so there is no visible discontinuity.

Key properties:

  • At any yaw and any pitch, the up-hint is never parallel to the look direction (no gimbal-lock or north/south flip).
  • At pitch = 0, screen-up follows the yaw bearing.
  • At high pitch, screen-up is always world-Z (natural horizon).
Source

pub fn perspective_matrix(&self) -> DMat4

Build a perspective projection matrix (right-handed, depth [0, 1]).

§Depth range
  • Near plane: distance * 0.001 – close enough for objects at the camera target, far enough to preserve depth precision.
  • Far plane: distance * 10 * pitch_factor – when pitched toward the horizon the visible ground extends well beyond the orbit distance. pitch_factor = min(1/cos(pitch), 100) scales the far plane to avoid clipping.
Source

pub fn orthographic_matrix(&self) -> DMat4

Build an orthographic projection matrix (right-handed).

Half-height equals distance, so zooming works identically to perspective mode (increase distance = see more ground). The near / far range is +/-distance * 100 to accommodate terrain elevation.

Source

pub fn projection_matrix(&self) -> DMat4

Build the projection matrix based on the current mode.

Source

pub fn target_world(&self) -> DVec3

Target position in projected world space (meters).

Source

pub fn view_projection_matrix(&self) -> DMat4

Combined view-projection matrix (camera-relative origin).

Source

pub fn absolute_view_projection_matrix(&self) -> DMat4

Combined view-projection matrix in absolute world space.

Unlike view_projection_matrix, which places the target at the origin (camera-relative), this computes the VP with world coordinates left as-is. The resulting frustum planes therefore live in the same coordinate space as tile_bounds_world and can be used directly for frustum-based tile culling.

Source

pub fn covering_camera(&self, fractional_zoom: f64) -> Option<CoveringCamera>

Export the current camera as a CoveringCamera suitable for the MapLibre-equivalent covering-tiles traversal with per-tile variable zoom.

Returns None for orthographic mode or non-Mercator projections.

Source

pub fn flat_tile_view(&self) -> Option<FlatTileView>

Export the current perspective camera as flat-tile selection parameters.

Returns None for orthographic mode because footprint-aware flat-tile filtering is only needed for pitched perspective views.

Source

pub fn screen_to_ray(&self, px: f64, py: f64) -> (DVec3, DVec3)

Unproject a screen-space pixel coordinate to a world-space ray.

Returns (origin, direction) in absolute world space (Web Mercator metres). The direction is normalised.

px, py are in logical pixels with (0, 0) at the top-left corner of the viewport.

Returns (DVec3::ZERO, -DVec3::Z) for degenerate viewports (width or height of zero) to avoid NaN propagation.

Source

pub fn screen_to_geo(&self, px: f64, py: f64) -> Option<GeoCoord>

Intersect the unprojected ray with the ground plane (Z = 0) and return the geographic coordinate at the hit point.

Returns None if the ray is parallel to the ground or points away from it (sky).

Source

pub fn geo_to_screen(&self, geo: &GeoCoord) -> Option<(f64, f64)>

Project a geographic coordinate to a screen-space pixel position.

Returns (px, py) in logical pixels with (0, 0) at the top-left corner of the viewport, or None if the point is behind the camera.

Source

pub fn meters_per_pixel(&self) -> f64

Approximate meters-per-pixel at the current zoom level (screen center).

For perspective mode this is the ground-plane resolution at the target point (not at the edges, which varies with pitch). For orthographic mode the resolution is uniform across the viewport.

Source

pub fn near_meters_per_pixel(&self) -> f64

Approximate meters-per-pixel at the near ground (bottom of the screen).

When the camera is pitched toward the horizon, the ground closest to the viewer (bottom of the viewport) has a much finer resolution than the target point. Using this value for zoom selection ensures tiles near the camera are sharp.

The result is clamped so the zoom level increases by at most three steps (factor of 8) relative to meters_per_pixel. When the covering- tiles variable-zoom path is active, the per-tile zoom heuristic automatically assigns lower zoom levels to distant tiles, so this generous ceiling does not cause excessive tile counts.

Returns the same value as meters_per_pixel when pitch is below ~30 degrees or the camera is orthographic.

Trait Implementations§

Source§

impl Clone for Camera

Source§

fn clone(&self) -> Camera

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Camera

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Camera

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.