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) {
33 let projection = perspective(width, height);
34 let eye = Vec3::new(0.0, 12.0, 20.0);
35 let target = Vec3::ZERO;
36 let up = Vec3::Y;
37 let view = Mat4::look_at_rh(eye, target, up);
38 (projection, view)
39}
40
41pub fn perspective(width: f32, height: f32) -> Mat4 {
42 let aspect = width / height;
43 let fovy = core::f32::consts::PI / 4.0;
44 let znear = 0.1;
45 let zfar = 100.0;
46 Mat4::perspective_rh(fovy, aspect, znear, zfar)
47}
48
49pub fn ortho(width: f32, height: f32) -> Mat4 {
50 let left = 0.0;
51 let right = width;
52 let bottom = height;
53 let top = 0.0;
54 let near = -1.0;
55 let far = 1.0;
56 Mat4::orthographic_rh(left, right, bottom, top, near, far)
57}
58
59pub fn look_at(eye: impl Into<Vec3>, target: impl Into<Vec3>, up: impl Into<Vec3>) -> Mat4 {
60 Mat4::look_at_rh(eye.into(), target.into(), up.into())
61}
62
63pub fn default_ortho2d(width: f32, height: f32) -> (Mat4, Mat4) {
66 let left = 0.0;
67 let right = width;
68 let bottom = height;
69 let top = 0.0;
70 let near = -1.0;
71 let far = 1.0;
72 let projection = Mat4::orthographic_rh(left, right, bottom, top, near, far);
73 let view = Mat4::IDENTITY;
74 (projection, view)
75}
76
77#[cfg(test)]
78mod tests {
79 use crate::camera::shader::CameraDescriptor;
80
81 use super::*;
82 use glam::Vec3;
83
84 #[test]
85 fn forward() {
86 let eyes = [Vec3::new(0.0, 0.0, 5.0), Vec3::new(250.0, 200.0, 250.0)];
87
88 let expected_forwards = [
89 Vec3::new(0.0, 0.0, -1.0),
90 Vec3::new(-0.6154574, -0.49236593, -0.6154574),
91 ];
92
93 for (eye, expected_forward) in eyes.into_iter().zip(expected_forwards) {
94 let projection = Mat4::perspective_rh(45.0_f32.to_radians(), 800.0 / 600.0, 0.1, 100.0);
95 let view = Mat4::look_at_rh(eye, Vec3::ZERO, Vec3::Y);
96 let camera = CameraDescriptor::new(projection, view);
97
98 let forward = camera.forward();
99 let distance = forward.distance(expected_forward);
100 const THRESHOLD: f32 = 1e-3;
101 assert!(
102 distance < THRESHOLD,
103 "Forward vector is incorrect\n\
104 forward: {forward}\n\
105 expected: {expected_forward}\n\
106 distance: {distance}, threshold: {THRESHOLD}"
107 );
108 }
109 }
110}