Skip to main content

roxlap_gpu/
camera.rs

1//! World-space camera state passed to [`crate::GpuRenderer::render_scene`].
2//!
3//! Mirrors `roxlap-core::Camera`'s shape (position + orthonormal
4//! right / down / forward basis) but in `f32` since the GPU does its
5//! ray math at single precision. Host bridges by casting f64 → f32
6//! after computing chunk-local coordinates.
7
8/// World-space camera state in the voxlap convention (Z = down).
9///
10/// `right`, `down`, `forward` form a right-handed orthonormal basis;
11/// `position` is in voxel-world units. `fov_y_rad` is the vertical
12/// field-of-view in radians — voxlap's default is roughly 60°
13/// (`std::f32::consts::FRAC_PI_3`).
14#[derive(Debug, Clone, Copy)]
15pub struct Camera {
16    /// Eye position in world voxel units (1 voxel = 1 world unit).
17    pub position: [f32; 3],
18    /// Unit basis vector toward screen-right. Must satisfy
19    /// `right × down == forward` (right-handed) or frustum culling
20    /// silently rejects sprites.
21    pub right: [f32; 3],
22    /// Unit basis vector toward screen-down. In the voxlap convention
23    /// +z points down (z = 0 sky, z = 255 bedrock), so a level camera
24    /// has `down = [0, 0, 1]`.
25    pub down: [f32; 3],
26    /// Unit view direction (into the screen); the third leg of the
27    /// right-handed `right`/`down`/`forward` basis.
28    pub forward: [f32; 3],
29    /// Vertical field of view in radians, `(0, π)`. Default is
30    /// `FRAC_PI_3` (≈60°, voxlap's default); the horizontal FOV
31    /// follows from the render aspect ratio.
32    pub fov_y_rad: f32,
33}
34
35impl Default for Camera {
36    fn default() -> Self {
37        Self {
38            position: [0.0, 0.0, 0.0],
39            right: [1.0, 0.0, 0.0],
40            down: [0.0, 0.0, 1.0],
41            forward: [0.0, 1.0, 0.0],
42            fov_y_rad: std::f32::consts::FRAC_PI_3,
43        }
44    }
45}