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)
| Field | Guarantee |
|---|---|
pitch | Clamped to [0, PI/2 - ?] on every write |
yaw | Normalized to [-?, ?] on every write |
distance | Always positive and finite |
fov_y | Always 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
impl Camera
Sourcepub fn view_up_vector(&self) -> DVec3
pub fn view_up_vector(&self) -> DVec3
Camera-relative up vector matching view_matrix.
Sourcepub fn projection(&self) -> CameraProjection
pub fn projection(&self) -> CameraProjection
Geographic projection used by camera/world coordinate helpers.
Sourcepub fn mode(&self) -> CameraMode
pub fn mode(&self) -> CameraMode
Projection mode.
Sourcepub fn viewport_width(&self) -> u32
pub fn viewport_width(&self) -> u32
Viewport width in pixels.
Sourcepub fn viewport_height(&self) -> u32
pub fn viewport_height(&self) -> u32
Viewport height in pixels.
Sourcepub fn set_target(&mut self, target: GeoCoord)
pub fn set_target(&mut self, target: GeoCoord)
Set the camera target coordinate.
Sourcepub fn set_projection(&mut self, projection: CameraProjection)
pub fn set_projection(&mut self, projection: CameraProjection)
Set the camera’s geographic projection.
Sourcepub fn set_distance(&mut self, d: f64)
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.
Sourcepub fn set_pitch(&mut self, p: f64)
pub fn set_pitch(&mut self, p: f64)
Set pitch in radians. Hard-clamped to [0, MAX_PITCH].
Non-finite values are rejected.
Sourcepub fn set_yaw(&mut self, y: f64)
pub fn set_yaw(&mut self, y: f64)
Set yaw / bearing in radians. Normalized to [-?, ?].
Non-finite values are rejected.
Sourcepub fn set_mode(&mut self, mode: CameraMode)
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).
Sourcepub fn set_fov_y(&mut self, fov: f64)
pub fn set_fov_y(&mut self, fov: f64)
Set vertical field-of-view in radians. Non-finite or non-positive values are rejected.
Sourcepub fn set_viewport(&mut self, width: u32, height: u32)
pub fn set_viewport(&mut self, width: u32, height: u32)
Set the viewport dimensions in pixels.
Sourcepub fn eye_offset(&self) -> DVec3
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) -- altitudeAt yaw = 0 the camera sits on the +Y (north) side of the target.
Sourcepub fn view_matrix(&self, target_world: DVec3) -> DMat4
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).
Sourcepub fn perspective_matrix(&self) -> DMat4
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.
Sourcepub fn orthographic_matrix(&self) -> DMat4
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.
Sourcepub fn projection_matrix(&self) -> DMat4
pub fn projection_matrix(&self) -> DMat4
Build the projection matrix based on the current mode.
Sourcepub fn target_world(&self) -> DVec3
pub fn target_world(&self) -> DVec3
Target position in projected world space (meters).
Sourcepub fn view_projection_matrix(&self) -> DMat4
pub fn view_projection_matrix(&self) -> DMat4
Combined view-projection matrix (camera-relative origin).
Sourcepub fn absolute_view_projection_matrix(&self) -> DMat4
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.
Sourcepub fn covering_camera(&self, fractional_zoom: f64) -> Option<CoveringCamera>
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.
Sourcepub fn flat_tile_view(&self) -> Option<FlatTileView>
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.
Sourcepub fn screen_to_ray(&self, px: f64, py: f64) -> (DVec3, DVec3)
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.
Sourcepub fn screen_to_geo(&self, px: f64, py: f64) -> Option<GeoCoord>
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).
Sourcepub fn geo_to_screen(&self, geo: &GeoCoord) -> Option<(f64, f64)>
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.
Sourcepub fn meters_per_pixel(&self) -> f64
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.
Sourcepub fn near_meters_per_pixel(&self) -> f64
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.