fixed the view frustum calculation

This commit is contained in:
Hartmut Seichter 2022-12-11 13:58:18 +01:00
parent 10a41fcfce
commit 040bc8d88a
2 changed files with 49 additions and 12 deletions

View file

@ -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)) Vec4::new(0.0, 0.0, d, 0.0))
} }
/// creates a projection from a frustum planes with a reversed depth mapped to [0..1] /// 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 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_left: Vec3,
screen_lower_right: Vec3, screen_lower_right: Vec3,
screen_upper_left: 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 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 z_near = 0.001_f32.max(dist - 0.01);
let left = vec_right.dot(frustum_left) * z_near / dist; let left = vec_right_normalized.dot(frustum_left) * z_near / dist;
let right = vec_right.dot(frustum_right) * z_near / dist; let right = vec_right_normalized.dot(frustum_right) * z_near / dist;
let bottom = vec_up.dot(frustum_left) * z_near / dist; let bottom = vec_up_normalized.dot(frustum_left) * z_near / dist;
let top = vec_up.dot(frustum_up) * 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 projection_matrix = make_projection_rh_from_frustum_reversed(left,right,bottom,top,z_near,z_far);
let view_matrix_rotation = Mat4::from_cols( let view_matrix_rotation = Mat4::from_cols(
Vec4::new(vec_right.x, vec_up.x, vec_normal.x ,0.0), Vec4::new(vec_right_normalized.x, vec_up_normalized.x, vec_normal.x ,0.0),
Vec4::new(vec_right.y, vec_up.y, vec_normal.y ,0.0), Vec4::new(vec_right_normalized.y, vec_up_normalized.y, vec_normal.y ,0.0),
Vec4::new(vec_right.z, vec_up.z, vec_normal.z ,0.0), Vec4::new(vec_right_normalized.z, vec_up_normalized.z, vec_normal.z ,0.0),
Vec4::W Vec4::W
); );
@ -114,7 +120,9 @@ fn create_offaxis_matrices(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use bevy::prelude::Mat4; use bevy::prelude::*;
use crate::{screeninfo, projection::create_offaxis_matrices};
use super::make_projection_rh_from_frustum; 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());
}
} }

View file

@ -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() { for mut v in query.iter_mut() {
//v.position += Vec3::Y * 0.005; //v.position += Vec3::Y * 0.005;
v.alpha += 0.01; v.alpha += 0.01;