From 040bc8d88a63dd737aab5fdfbae13d07caf9a2a8 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Sun, 11 Dec 2022 13:58:18 +0100 Subject: [PATCH] fixed the view frustum calculation --- src/projection.rs | 59 ++++++++++++++++++++++++++++++++++++++--------- src/viewer.rs | 2 +- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/projection.rs b/src/projection.rs index 4923bcc..1e5552b 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -19,7 +19,6 @@ pub fn make_projection_rh_from_frustum(left: f32, right: f32, bottom: f32, top: Vec4::new(0.0, 0.0, d, 0.0)) } - /// creates a projection from a frustum planes with a reversed depth mapped to [0..1] pub fn make_projection_rh_from_frustum_reversed(left: f32, right: f32, bottom: f32, top: f32, z_near:f32, z_far:f32) -> Mat4 { @@ -57,7 +56,7 @@ pub fn make_projection_rh_custom(fov_y: f32, aspect_ratio: f32, z_near: f32, z_f } -fn create_offaxis_matrices( +pub fn create_offaxis_matrices( screen_lower_left: Vec3, screen_lower_right: Vec3, screen_upper_left: Vec3, @@ -79,22 +78,29 @@ fn create_offaxis_matrices( let vec_normal = vec_right_normalized.cross(vec_up_normalized).normalize(); - let dist = -vec_right.dot(vec_normal); + let dist = -frustum_left.normalize().dot(vec_normal); + + // println!("vec_right_normalized {}",vec_right_normalized); + // println!("vec_up_normalized {}",vec_up_normalized); + // println!("vec_normal {}",vec_normal); + + // println!("Dist {}",dist); let z_near = 0.001_f32.max(dist - 0.01); - let left = vec_right.dot(frustum_left) * z_near / dist; - let right = vec_right.dot(frustum_right) * z_near / dist; - let bottom = vec_up.dot(frustum_left) * z_near / dist; - let top = vec_up.dot(frustum_up) * z_near / dist; + let left = vec_right_normalized.dot(frustum_left) * z_near / dist; + let right = vec_right_normalized.dot(frustum_right) * z_near / dist; + let bottom = vec_up_normalized.dot(frustum_left) * z_near / dist; + let top = vec_up_normalized.dot(frustum_up) * z_near / dist; + // println!("l r b t {} {} {} {}",left,right,bottom,top); let projection_matrix = make_projection_rh_from_frustum_reversed(left,right,bottom,top,z_near,z_far); let view_matrix_rotation = Mat4::from_cols( - Vec4::new(vec_right.x, vec_up.x, vec_normal.x ,0.0), - Vec4::new(vec_right.y, vec_up.y, vec_normal.y ,0.0), - Vec4::new(vec_right.z, vec_up.z, vec_normal.z ,0.0), + Vec4::new(vec_right_normalized.x, vec_up_normalized.x, vec_normal.x ,0.0), + Vec4::new(vec_right_normalized.y, vec_up_normalized.y, vec_normal.y ,0.0), + Vec4::new(vec_right_normalized.z, vec_up_normalized.z, vec_normal.z ,0.0), Vec4::W ); @@ -114,7 +120,9 @@ fn create_offaxis_matrices( #[cfg(test)] mod tests { - use bevy::prelude::Mat4; + use bevy::prelude::*; + + use crate::{screeninfo, projection::create_offaxis_matrices}; use super::make_projection_rh_from_frustum; @@ -146,4 +154,33 @@ mod tests { } + + #[test] + fn create_view_matrices() { + + // Assumptions: Screensize 6.0m x 1.8m + // Viewer is 5m away from center + + + let screen_lower_left = Vec3::new(-3.0,-0.9,0.0); + let screen_lower_right = Vec3::new(3.0,-0.9,0.0); + let screen_upper_left = Vec3::new(-3.0,0.9,0.0); + + + let eye_pos = Vec3::Z * 5.0; + + let z_far = 100.0_f32; + + + let (view,projection) = create_offaxis_matrices(screen_lower_left, screen_lower_right, screen_upper_left, eye_pos, z_far); + + + println!("View {:?}",view); + println!("Projection {:?}",projection); + + // assert!(!view.is_nan()); + // assert!(!projection.is_nan()); + + } + } diff --git a/src/viewer.rs b/src/viewer.rs index 1c95127..2a4b984 100644 --- a/src/viewer.rs +++ b/src/viewer.rs @@ -29,7 +29,7 @@ impl Viewer { } } -pub fn simulate_viewer(mut query: Query<&mut Viewer>, screen_info: Query<&ScreenInfo>) { +pub fn simulate_viewer(mut query: Query<&mut Viewer>) { for mut v in query.iter_mut() { //v.position += Vec3::Y * 0.005; v.alpha += 0.01;