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