1use glam::{Mat4, Vec3};
3
4#[cfg(cpu)]
5mod cpu;
6#[cfg(cpu)]
7pub use cpu::*;
8
9pub mod shader;
10
11pub fn default_perspective(width: f32, height: f32) -> (Mat4, Mat4) {
36 let projection = perspective(width, height);
37 let eye = Vec3::new(0.0, 12.0, 20.0);
38 let target = Vec3::ZERO;
39 let up = Vec3::Y;
40 let view = Mat4::look_at_rh(eye, target, up);
41 (projection, view)
42}
43
44pub fn perspective(width: f32, height: f32) -> Mat4 {
45 let aspect = width / height;
46 let fovy = core::f32::consts::PI / 4.0;
47 let znear = 0.1;
48 let zfar = 100.0;
49 Mat4::perspective_rh(fovy, aspect, znear, zfar)
50}
51
52pub fn ortho(width: f32, height: f32) -> Mat4 {
59 let left = 0.0;
60 let right = width;
61 let bottom = height;
62 let top = 0.0;
63 let near = -1.0;
64 let far = 1.0;
65 Mat4::orthographic_rh(left, right, bottom, top, near, far)
66}
67
68pub fn look_at(eye: impl Into<Vec3>, target: impl Into<Vec3>, up: impl Into<Vec3>) -> Mat4 {
69 Mat4::look_at_rh(eye.into(), target.into(), up.into())
70}
71
72pub fn default_ortho2d(width: f32, height: f32) -> (Mat4, Mat4) {
80 let left = 0.0;
81 let right = width;
82 let bottom = height;
83 let top = 0.0;
84 let near = -1.0;
85 let far = 1.0;
86 let projection = Mat4::orthographic_rh(left, right, bottom, top, near, far);
87 let view = Mat4::IDENTITY;
88 (projection, view)
89}
90
91#[cfg(test)]
92mod tests {
93 use crate::camera::shader::CameraDescriptor;
94
95 use super::*;
96 use glam::Vec3;
97
98 #[test]
99 fn forward() {
100 let eyes = [Vec3::new(0.0, 0.0, 5.0), Vec3::new(250.0, 200.0, 250.0)];
101
102 let expected_forwards = [
103 Vec3::new(0.0, 0.0, -1.0),
104 Vec3::new(-0.6154574, -0.49236593, -0.6154574),
105 ];
106
107 for (eye, expected_forward) in eyes.into_iter().zip(expected_forwards) {
108 let projection = Mat4::perspective_rh(45.0_f32.to_radians(), 800.0 / 600.0, 0.1, 100.0);
109 let view = Mat4::look_at_rh(eye, Vec3::ZERO, Vec3::Y);
110 let camera = CameraDescriptor::new(projection, view);
111
112 let forward = camera.forward();
113 let distance = forward.distance(expected_forward);
114 const THRESHOLD: f32 = 1e-3;
115 assert!(
116 distance < THRESHOLD,
117 "Forward vector is incorrect\nforward: {forward}\nexpected: \
118 {expected_forward}\ndistance: {distance}, threshold: {THRESHOLD}"
119 );
120 }
121 }
122}