mraphics_core/math/
camera.rs1use std::f32::consts::PI;
2
3use nalgebra::{Isometry3, Matrix4, Perspective3, Point3, Vector3};
4
5pub trait Camera {
6 fn view_mat_data(&self) -> &[u8];
7 fn projection_mat_data(&self) -> &[u8];
8
9 fn look_at(&mut self, target: &Point3<f32>);
10 fn set_center(&mut self, center: &Vector3<f32>);
11}
12
13pub struct PerspectiveCamera {
14 pub view_transform: Isometry3<f32>,
15 view_mat: Matrix4<f32>,
16
17 pub up: Vector3<f32>,
18 center: Vector3<f32>,
19
20 pub proj_transform: Perspective3<f32>,
21 proj_mat: Matrix4<f32>,
22}
23
24impl PerspectiveCamera {
25 pub fn center(&self) -> &Vector3<f32> {
26 &self.center
27 }
28
29 pub fn set_rotation(&mut self, rotarion: &Vector3<f32>) {
30 self.view_transform =
31 Isometry3::new(self.view_transform.translation.vector, rotarion.clone());
32 self.view_mat = self.view_transform.to_homogeneous();
33 }
34
35 pub fn set_aspect(&mut self, aspect: f32) {
36 self.proj_transform.set_aspect(aspect);
37 self.proj_mat = self.proj_transform.to_homogeneous();
38 }
39
40 pub fn set_far(&mut self, far: f32) {
41 self.proj_transform.set_zfar(far);
42 self.proj_mat = self.proj_transform.to_homogeneous();
43 }
44
45 pub fn set_near(&mut self, near: f32) {
46 self.proj_transform.set_znear(near);
47 self.proj_mat = self.proj_transform.to_homogeneous();
48 }
49
50 pub fn set_fov_rad(&mut self, fov_rad: f32) {
51 self.proj_transform.set_zfar(fov_rad);
52 self.proj_mat = self.proj_transform.to_homogeneous();
53 }
54}
55
56impl Default for PerspectiveCamera {
57 fn default() -> Self {
58 let (far, near, aspect, fov_rad) = (1000.0, 0.1, 1.0, PI / 4.0);
59 let (center, rotation) = (Vector3::new(0.0, 0.0, 5.0), Vector3::new(0.0, 0.0, 0.0));
60 let (view_transform, proj_transform) = (
61 Isometry3::new(-center, rotation),
62 Perspective3::new(aspect, fov_rad, near, far),
63 );
64
65 Self {
66 view_mat: view_transform.to_homogeneous(),
67 view_transform,
68 proj_mat: proj_transform.to_homogeneous(),
69 proj_transform,
70
71 up: Vector3::y(),
72 center,
73 }
74 }
75}
76
77impl Camera for PerspectiveCamera {
78 fn view_mat_data(&self) -> &[u8] {
79 bytemuck::cast_slice(self.view_mat.as_slice())
80 }
81
82 fn projection_mat_data(&self) -> &[u8] {
83 bytemuck::cast_slice(self.proj_mat.as_slice())
84 }
85
86 fn look_at(&mut self, target: &Point3<f32>) {
87 self.view_transform = Isometry3::look_at_rh(
88 &Point3::from_slice(&self.center.as_slice()),
89 target,
90 &self.up,
91 );
92 self.view_mat = self.view_transform.to_homogeneous();
93 }
94
95 fn set_center(&mut self, center: &Vector3<f32>) {
96 self.center.copy_from(¢er);
97 self.view_transform.translation.vector.copy_from(&-center);
98 self.view_mat = self.view_transform.to_homogeneous();
99 }
100}