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