renderling/camera/
shader.rs1use crabslab::SlabItem;
4use glam::{Mat4, Vec2, Vec3, Vec4};
5
6use crate::{bvol::Frustum, math::IsVector};
7
8#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
14#[derive(Default, Clone, Copy, PartialEq, SlabItem)]
15pub struct CameraDescriptor {
16 projection: Mat4,
17 view: Mat4,
18 position: Vec3,
19 frustum: Frustum,
20 z_near_point: Vec3,
22 z_far_point: Vec3,
24}
25
26impl CameraDescriptor {
27 pub fn new(projection: Mat4, view: Mat4) -> Self {
28 CameraDescriptor::default().with_projection_and_view(projection, view)
29 }
30
31 pub fn default_perspective(width: f32, height: f32) -> Self {
32 let (projection, view) = super::default_perspective(width, height);
33 CameraDescriptor::new(projection, view)
34 }
35
36 pub fn default_ortho2d(width: f32, height: f32) -> Self {
37 let (projection, view) = super::default_ortho2d(width, height);
38 CameraDescriptor::new(projection, view)
39 }
40
41 pub fn projection(&self) -> Mat4 {
42 self.projection
43 }
44
45 pub fn set_projection_and_view(&mut self, projection: Mat4, view: Mat4) {
46 self.projection = projection;
47 self.view = view;
48 self.position = view.inverse().transform_point3(Vec3::ZERO);
49 let inverse = (projection * view).inverse();
50 self.z_near_point = inverse.project_point3(Vec3::ZERO);
51 self.z_far_point = inverse.project_point3(Vec2::ZERO.extend(1.0));
52 self.frustum = Frustum::from_camera(self);
53 }
54
55 pub fn with_projection_and_view(mut self, projection: Mat4, view: Mat4) -> Self {
56 self.set_projection_and_view(projection, view);
57 self
58 }
59
60 pub fn set_projection(&mut self, projection: Mat4) {
61 self.set_projection_and_view(projection, self.view);
62 }
63
64 pub fn with_projection(mut self, projection: Mat4) -> Self {
65 self.set_projection(projection);
66 self
67 }
68
69 pub fn view(&self) -> Mat4 {
70 self.view
71 }
72
73 pub fn set_view(&mut self, view: Mat4) {
74 self.set_projection_and_view(self.projection, view);
75 }
76
77 pub fn with_view(mut self, view: Mat4) -> Self {
78 self.set_view(view);
79 self
80 }
81
82 pub fn position(&self) -> Vec3 {
83 self.position
84 }
85
86 pub fn frustum(&self) -> Frustum {
87 self.frustum
88 }
89
90 pub fn view_projection(&self) -> Mat4 {
91 self.projection * self.view
92 }
93
94 pub fn near_plane(&self) -> Vec4 {
95 self.frustum.planes[0]
96 }
97
98 pub fn far_plane(&self) -> Vec4 {
99 self.frustum.planes[5]
100 }
101
102 pub fn z_near(&self) -> f32 {
104 self.z_near_point.distance(self.position)
105 }
106
107 pub fn z_far(&self) -> f32 {
108 self.z_far_point.distance(self.position)
109 }
110
111 pub fn depth(&self) -> f32 {
112 (self.z_far() - self.z_near()).abs()
113 }
114
115 pub fn forward(&self) -> Vec3 {
117 (self.z_far_point - self.z_near_point).alt_norm_or_zero()
118 }
119
120 pub fn frustum_near_point(&self) -> Vec3 {
121 self.forward() * self.z_near()
122 }
123
124 pub fn frustum_far_point(&self) -> Vec3 {
125 self.forward() * self.z_far()
126 }
127}