1use bb_geometry::rotation3d::Rotation3D;
4use bb_geometry::vector3d::Vector3D;
5use std::f64::consts::PI;
6
7pub struct Camera3D {
8 pos: Vector3D,
9 psi: f64,
10 theta: f64,
11 phi: f64,
12 fov_x: f64,
13 fov_y: f64,
14}
15
16const DEFAULT_FOV_X: f64 = 120.0;
17const DEFAULT_FOV_Y: f64 = 120.0;
18const DEFAULT_POS: Vector3D = Vector3D {
19 x: 0.0,
20 y: 0.0,
21 z: 0.0,
22};
23const DEFAULT_PHI: f64 = 0.0;
24const DEFAULT_THETA: f64 = PI / 2.0;
25
26impl Camera3D {
27 pub fn new() -> Self {
28 Camera3D {
29 pos: DEFAULT_POS,
30 psi: DEFAULT_PHI,
31 theta: DEFAULT_THETA,
32 phi: DEFAULT_PHI,
33 fov_x: DEFAULT_FOV_X,
34 fov_y: DEFAULT_FOV_Y,
35 }
36 }
37
38 pub fn move_pos(&mut self, delta_v: &Vector3D) {
39 self.pos = self.pos.plus(delta_v);
40 }
41
42 pub fn move_psi(&mut self, delta_psi: f64) {
43 self.psi += delta_psi;
44 }
45
46 pub fn move_theta(&mut self, delta_theta: f64) {
47 self.theta += delta_theta;
48 }
49
50 pub fn move_phi(&mut self, delta_phi: f64) {
51 self.phi += delta_phi;
52 }
53
54 pub fn adjust_fov(&mut self, delta_fov_x: f64, delta_fov_y: f64) {
55 self.fov_x += delta_fov_x;
56 self.fov_y += delta_fov_y;
57 }
58
59 pub fn rotation_matrix(&self) -> Rotation3D {
60 Rotation3D::from_euler_angles(self.psi, self.theta, self.phi)
61 }
62
63 pub fn position(&self) -> &Vector3D {
64 &self.pos
65 }
66
67 pub fn theta(&self) -> f64 {
68 self.theta
69 }
70
71 pub fn phi(&self) -> f64 {
72 self.phi
73 }
74
75 pub fn psi(&self) -> f64 {
76 self.psi
77 }
78
79 pub fn fov_x(&self) -> f64 {
80 self.fov_x
81 }
82
83 pub fn fov_y(&self) -> f64 {
84 self.fov_y
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 #[test]
92 fn test_references() {
93 let camera = Camera3D::new();
95
96 let mut x = camera.psi();
98 x += 0.5;
99
100 assert_eq!(x, 0.5);
102 assert_eq!(camera.psi(), 0.0);
103 }
104}