Skip to main content

geng_utils/torus/
camera.rs

1use geng::prelude::*;
2
3use super::position::PositionTorus;
4
5/// A camera that exists on a torus space.
6///
7/// Use the [project](CameraTorus::project) method to get a normalized position of objects
8/// relative to the camera.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct CameraTorus<T: Float> {
11    pub center: PositionTorus<T>,
12    pub fov: T,
13    pub rotation: Angle<T>,
14}
15
16impl<T: Float> CameraTorus<T> {
17    /// Construct a new camera on a torus with the given size.
18    pub fn new(fov: T, world_size: vec2<T>) -> Self {
19        Self {
20            center: PositionTorus::zero(world_size),
21            fov,
22            rotation: Angle::ZERO,
23        }
24    }
25
26    fn to_camera2d(&self) -> geng::Camera2d {
27        geng::Camera2d {
28            center: self.center.to_world().map(T::as_f32),
29            rotation: Angle::ZERO,
30            fov: self.fov.as_f32(),
31        }
32    }
33
34    /// Project a world position to a position relative to the camera.
35    /// The resulting position can be used to render the object.
36    pub fn project(&self, position: PositionTorus<T>) -> vec2<T> {
37        let center = self.center.to_world();
38        center + self.center.delta_to(position)
39    }
40
41    /// Project a world position to a position relative to the camera.
42    /// The resulting position can be used to render the object.
43    pub fn project_f32(&self, position: PositionTorus<T>) -> vec2<f32> {
44        self.project(position).map(T::as_f32)
45    }
46}
47
48impl<T: Float> geng::AbstractCamera2d for CameraTorus<T> {
49    fn view_matrix(&self) -> mat3<f32> {
50        self.to_camera2d().view_matrix()
51    }
52
53    fn projection_matrix(&self, framebuffer_size: vec2<f32>) -> mat3<f32> {
54        self.to_camera2d().projection_matrix(framebuffer_size)
55    }
56}