gizmo_renderer/components/
camera.rs1use 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 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 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}