add camera calculations
This commit is contained in:
parent
eece7b275b
commit
759b6a4211
78
src/camera.rs
Normal file
78
src/camera.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
use glam::{Affine3A, Mat3, Mat4, vec3};
|
||||
|
||||
pub(crate) fn rotation(yaw: f32, pitch: f32) -> Mat3 {
|
||||
let (ys, yc) = yaw.sin_cos();
|
||||
let (ps, pc) = pitch.sin_cos();
|
||||
Mat3::from_cols_array_2d(&[[0., 0., -1.], [-1., 0., 0.], [0., 1., 0.]])
|
||||
* Mat3::from_cols_array_2d(&[[pc, 0., -ps], [0., 1., 0.], [ps, 0., pc]])
|
||||
* Mat3::from_cols_array_2d(&[[yc, -ys, 0.], [ys, yc, 0.], [0., 0., 1.]])
|
||||
}
|
||||
|
||||
pub(crate) fn view(yaw: f32, pitch: f32, distance: f32) -> Affine3A {
|
||||
Affine3A::from_mat3_translation(rotation(yaw, pitch), vec3(0., 0., distance))
|
||||
}
|
||||
|
||||
pub(crate) fn projection(fovy: f32, aspect: f32) -> Mat4 {
|
||||
Mat4::perspective_lh(fovy, aspect, 0.1, 10.0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use glam::Vec3;
|
||||
use std::f32::consts::PI;
|
||||
|
||||
#[test]
|
||||
fn test_rotation() {
|
||||
let mut ok = true;
|
||||
for (yaw, pitch, x, y, z) in [
|
||||
(0.0, 0.0, [0., 0., -1.], [-1., 0., 0.], [0., 1., 0.]),
|
||||
(0.5, 0.0, [1., 0., 0.], [0., 0., -1.], [0., 1., 0.]),
|
||||
(0.0, 0.5, [0., -1., 0.], [-1., 0., 0.], [0., 0., -1.]),
|
||||
(0.5, 0.5, [1., 0., 0.], [0., -1., 0.], [0., 0., -1.]),
|
||||
] {
|
||||
let m = rotation(yaw * PI, pitch * PI);
|
||||
if !m.abs_diff_eq(Mat3::from_cols_array_2d(&[x, y, z]), 1e-3) {
|
||||
ok = false;
|
||||
println!("Wrong rotation for {}, {}", 180. * yaw, 180. * pitch);
|
||||
println!("X: expected: {}, actual: {}", Vec3::from_array(x), m.x_axis);
|
||||
println!("Y: expected: {}, actual: {}", Vec3::from_array(y), m.y_axis);
|
||||
println!("Z: expected: {}, actual: {}", Vec3::from_array(z), m.z_axis);
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_view() {
|
||||
let mut ok = true;
|
||||
for (yaw, pitch, x1, y1, z1) in [
|
||||
(0.0, 0.0, [0., 0., 2.], [-1., 0., 3.], [0., 1., 3.]),
|
||||
(0.5, 0.0, [1., 0., 3.], [0., 0., 2.], [0., 1., 3.]),
|
||||
(0.0, 0.5, [0., -1., 3.], [-1., 0., 3.], [0., 0., 2.]),
|
||||
(0.5, 0.5, [1., 0., 3.], [0., -1., 3.], [0., 0., 2.]),
|
||||
] {
|
||||
let m = view(yaw * PI, pitch * PI, 3.);
|
||||
for (label, world, expected) in
|
||||
[('X', Vec3::X, x1), ('Y', Vec3::Y, y1), ('Z', Vec3::Z, z1)]
|
||||
{
|
||||
let expected = Vec3::from_array(expected);
|
||||
let actual = m.transform_point3(world);
|
||||
if !actual.abs_diff_eq(expected, 1e-3) {
|
||||
ok = false;
|
||||
println!(
|
||||
"Wrong transform for {}, {}: for {label}, expected: {expected}, got: {actual}",
|
||||
180. * yaw,
|
||||
180. * pitch
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ use std::error::Error;
|
|||
|
||||
use glam::{UVec2, Vec4, vec4};
|
||||
|
||||
mod camera;
|
||||
|
||||
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth16Unorm;
|
||||
const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user