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}