Skip to main content

gizmo_renderer/components/
camera.rs

1use gizmo_math::Vec3;
2
3#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
4pub struct Camera {
5    pub fov: f32,
6    pub near: f32,
7    pub far: f32,
8    pub yaw: f32,
9    pub pitch: f32,
10    pub primary: bool,
11}
12
13impl Camera {
14    pub fn new(
15        mut fov: f32,
16        mut near: f32,
17        mut far: f32,
18        mut yaw: f32,
19        mut pitch: f32,
20        primary: bool,
21    ) -> Self {
22        fov = fov.max(0.001);
23        near = near.max(0.001);
24        far = far.max(near + 0.1);
25        yaw %= std::f32::consts::TAU;
26        pitch = pitch.clamp(
27            -std::f32::consts::PI / 2.0 + 0.001,
28            std::f32::consts::PI / 2.0 - 0.001,
29        );
30
31        Self {
32            fov,
33            near,
34            far,
35            yaw,
36            pitch,
37            primary,
38        }
39    }
40
41    /// Fazla birikmeyi önlemek icin acilari temizler (yaw mod TAU, pitch clamp)
42    pub fn sanitize_angles(&mut self) {
43        self.yaw %= std::f32::consts::TAU;
44        self.pitch = self.pitch.clamp(
45            -std::f32::consts::PI / 2.0 + 0.001,
46            std::f32::consts::PI / 2.0 - 0.001,
47        );
48    }
49
50    pub fn get_projection(&self, aspect: f32) -> gizmo_math::Mat4 {
51        gizmo_math::Mat4::perspective_rh(self.fov, aspect, self.near, self.far)
52    }
53
54    pub fn get_view(&self, position: Vec3) -> gizmo_math::Mat4 {
55        let front = self.get_front();
56        let right = self.get_right();
57        let up = right.cross(front);
58        gizmo_math::Mat4::look_at_rh(position, position + front, up)
59    }
60
61    pub fn get_front(&self) -> Vec3 {
62        let pitch = self.pitch.clamp(
63            -std::f32::consts::PI / 2.0 + 0.001,
64            std::f32::consts::PI / 2.0 - 0.001,
65        );
66        let fx = self.yaw.cos() * pitch.cos();
67        let fy = pitch.sin();
68        let fz = self.yaw.sin() * pitch.cos();
69        Vec3::new(fx, fy, fz).normalize()
70    }
71
72    pub fn get_right(&self) -> Vec3 {
73        // Front x (0,1,0) reduces mathematically to (-sin(yaw), 0, cos(yaw))
74        Vec3::new(-self.yaw.sin(), 0.0, self.yaw.cos())
75    }
76}
77
78#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
79pub struct Camera2D {
80    pub zoom: f32,
81    pub primary: bool,
82}
83
84impl Camera2D {
85    pub fn new(zoom: f32, primary: bool) -> Self {
86        Self { zoom, primary }
87    }
88
89    pub fn get_projection(&self, width: f32, height: f32) -> gizmo_math::Mat4 {
90        let safe_zoom = self.zoom.max(0.001);
91        let hw = (width / 2.0) / safe_zoom;
92        let hh = (height / 2.0) / safe_zoom;
93        gizmo_math::Mat4::orthographic_rh(-hw, hw, -hh, hh, -1000.0, 1000.0)
94    }
95}