initial implementation for the off-axis view frustum based on previous code
This commit is contained in:
parent
670e1b1756
commit
10a41fcfce
4 changed files with 118 additions and 76 deletions
|
@ -10,3 +10,7 @@ edition = "2021"
|
|||
bevy = { version = "0.9.1", features = ["dynamic"] }
|
||||
rand = "0.8.4"
|
||||
# vrpn = "0.1.0" # not compatible with 2021
|
||||
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
|
@ -57,6 +57,61 @@ pub fn make_projection_rh_custom(fov_y: f32, aspect_ratio: f32, z_near: f32, z_f
|
|||
}
|
||||
|
||||
|
||||
fn create_offaxis_matrices(
|
||||
screen_lower_left: Vec3,
|
||||
screen_lower_right: Vec3,
|
||||
screen_upper_left: Vec3,
|
||||
pos_eye: Vec3,
|
||||
z_far: f32
|
||||
) -> (Mat4,Mat4)
|
||||
{
|
||||
|
||||
//
|
||||
let vec_right = screen_lower_right - screen_lower_left; // vr
|
||||
let vec_up = screen_upper_left - screen_lower_left; // vu
|
||||
|
||||
let frustum_left = screen_lower_left - pos_eye; // va
|
||||
let frustum_right = screen_lower_right - pos_eye; // vb
|
||||
let frustum_up = screen_upper_left - pos_eye; // vc
|
||||
|
||||
let vec_right_normalized = vec_right.normalize();
|
||||
let vec_up_normalized = vec_up.normalize();
|
||||
|
||||
let vec_normal = vec_right_normalized.cross(vec_up_normalized).normalize();
|
||||
|
||||
let dist = -vec_right.dot(vec_normal);
|
||||
|
||||
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 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::W
|
||||
);
|
||||
|
||||
let view_matrix_eye = Mat4::from_cols(
|
||||
Vec4::X,
|
||||
Vec4::Y,
|
||||
Vec4::Z,
|
||||
(-pos_eye).extend(1.0)
|
||||
);
|
||||
|
||||
let view_matrix = view_matrix_rotation * view_matrix_eye;
|
||||
|
||||
(view_matrix,projection_matrix)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bevy::prelude::Mat4;
|
||||
|
|
|
@ -1,99 +1,87 @@
|
|||
|
||||
use bevy::{prelude::*, math::bool, prelude::shape::Quad };
|
||||
use rand::prelude::*;
|
||||
use bevy::render::primitives::Plane;
|
||||
use bevy::{math::bool, prelude::shape::Quad, prelude::*};
|
||||
use rand::prelude::*;
|
||||
|
||||
enum EyePos {
|
||||
Left,
|
||||
Right
|
||||
Right,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default,Component)]
|
||||
#[derive(Default, Component)]
|
||||
pub struct ScreenInfo {
|
||||
pub name : String, // main (to identify the screen)
|
||||
width : f32, // 3.08 (full width in m)
|
||||
height : f32, // 2.33 (full height in m)
|
||||
pub name: String, // main (to identify the screen)
|
||||
width: f32, // 3.08 (full width in m)
|
||||
height: f32, // 2.33 (full height in m)
|
||||
|
||||
center : Vec3, // 0.0 -1.15 -3.08 (mid point of screen in global coordinated - tracking!)
|
||||
normal : Vec3, // 0.0 0.0 1.0 (orientation of front side)
|
||||
up: Vec3, // 0.0 1.0 0.0 (vertical axis)
|
||||
horizontal: Vec3, // right vector computed as orthonormal
|
||||
center: Vec3, // 0.0 -1.15 -3.08 (mid point of screen in global coordinated - tracking!)
|
||||
normal: Vec3, // 0.0 0.0 1.0 (orientation of front side)
|
||||
up: Vec3, // 0.0 1.0 0.0 (vertical axis)
|
||||
horizontal: Vec3, // right vector computed as orthonormal
|
||||
|
||||
top : Vec3,
|
||||
bottom : Vec3,
|
||||
left : Vec3,
|
||||
right : Vec3
|
||||
}
|
||||
|
||||
impl ScreenInfo {
|
||||
|
||||
pub fn new(name: &str) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
width: 3.08,
|
||||
height: 2.33,
|
||||
center: Vec3 { x: 0.0, y: -1.15, z: -3.08 },
|
||||
center: Vec3 {
|
||||
x: 0.0,
|
||||
y: -1.15,
|
||||
z: -3.08,
|
||||
},
|
||||
normal: Vec3::Z,
|
||||
up: Vec3::Y,
|
||||
horizontal: Vec3::ZERO,
|
||||
top: Vec3::ZERO,
|
||||
bottom: Vec3::ZERO,
|
||||
left: Vec3::ZERO,
|
||||
right: Vec3::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_debug_geometry(&self,
|
||||
pub fn build_debug_geometry(
|
||||
&self,
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
)
|
||||
{
|
||||
// plane
|
||||
) {
|
||||
// plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Mesh::from( Quad { size: Vec2 { x: self.width, y: self.height }, flip:false })),
|
||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||
..default()
|
||||
mesh: meshes.add(Mesh::from(Quad {
|
||||
size: Vec2 {
|
||||
x: self.width,
|
||||
y: self.height,
|
||||
},
|
||||
flip: false,
|
||||
})),
|
||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||
..default()
|
||||
});
|
||||
}
|
||||
|
||||
pub fn update(&mut self) -> &mut Self {
|
||||
// pub fn update(&mut self) -> &mut Self {
|
||||
// // compute right as up ^ forward
|
||||
// self.horizontal = self.up.cross(self.normal);
|
||||
|
||||
// compute right as up ^ forward
|
||||
self.horizontal = self.up.cross(self.normal);
|
||||
// // points of screen
|
||||
// self.top = self.center + self.up * (self.height * 0.5);
|
||||
// self.bottom = self.center - self.up * (self.height * 0.5);
|
||||
// self.left = self.center - self.horizontal * (self.height * 0.5);
|
||||
// self.right = self.center + self.horizontal * (self.height * 0.5);
|
||||
|
||||
// points of screen
|
||||
self.top = self.center + self.up * (self.height * 0.5);
|
||||
self.bottom = self.center - self.up * (self.height * 0.5);
|
||||
self.left = self.center - self.horizontal * (self.height * 0.5);
|
||||
self.right = self.center + self.horizontal * (self.height * 0.5);
|
||||
|
||||
self
|
||||
|
||||
}
|
||||
|
||||
fn intersection(
|
||||
&self,
|
||||
p1: Vec3,
|
||||
p2: Vec3) -> (bool,Vec3)
|
||||
{
|
||||
// self
|
||||
// }
|
||||
|
||||
fn intersection(&self, p1: Vec3, p2: Vec3) -> (bool, Vec3) {
|
||||
let u = self.normal.dot(self.center - p1) / self.normal.dot(p2 - p1);
|
||||
|
||||
let intersection_point = p1 + ((p2 - p1) * u);
|
||||
|
||||
// returns a tuple if the intersection point is in front and the actual point
|
||||
(u >= 0.0 && u <= 1.0,intersection_point)
|
||||
(u >= 0.0 && u <= 1.0, intersection_point)
|
||||
}
|
||||
|
||||
|
||||
fn normal_intersection(&self,
|
||||
p1: Vec3) -> (bool,Vec3)
|
||||
{
|
||||
fn normal_intersection(&self, p1: Vec3) -> (bool, Vec3) {
|
||||
let p2 = p1 - self.normal * 10.0;
|
||||
|
||||
self.intersection(p1, p2)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use bevy::{prelude::*, window::PresentMode, render::camera::CameraProjectionPlugin};
|
||||
use bevy::{prelude::*, render::camera::CameraProjectionPlugin, window::PresentMode};
|
||||
|
||||
use crate::screeninfo::ScreenInfo;
|
||||
// use offaxis::{offaxis_camera_setup, OffAxisProjection};
|
||||
|
||||
|
||||
#[derive(Component,Default)]
|
||||
#[derive(Component, Default)]
|
||||
pub struct Viewer {
|
||||
pub position: Vec3,
|
||||
pub orientation: Quat,
|
||||
|
@ -13,13 +12,11 @@ pub struct Viewer {
|
|||
}
|
||||
|
||||
impl Viewer {
|
||||
|
||||
pub fn new(position: Vec3) ->Self {
|
||||
pub fn new(position: Vec3) -> Self {
|
||||
Self {
|
||||
position,
|
||||
orientation: Quat::IDENTITY,
|
||||
alpha: 0.0,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,34 +24,32 @@ impl Viewer {
|
|||
Self {
|
||||
position: Vec3::ZERO,
|
||||
orientation: Quat::IDENTITY,
|
||||
alpha: 0.0
|
||||
alpha: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simulate_viewer(mut query: Query<&mut Viewer>)
|
||||
{
|
||||
for mut v in query.iter_mut() {
|
||||
pub fn simulate_viewer(mut query: Query<&mut Viewer>, screen_info: Query<&ScreenInfo>) {
|
||||
for mut v in query.iter_mut() {
|
||||
//v.position += Vec3::Y * 0.005;
|
||||
v.alpha += 0.01;
|
||||
let radius = 1.5;
|
||||
|
||||
let z_distance = 8.0_f32;
|
||||
|
||||
v.position = Vec3::new(v.alpha.sin()*radius,v.alpha.cos()*radius + 1.0_f32,z_distance);
|
||||
v.position = Vec3::new(
|
||||
v.alpha.sin() * radius,
|
||||
v.alpha.cos() * radius + 1.0_f32,
|
||||
z_distance,
|
||||
);
|
||||
|
||||
let vm = Mat4::look_at_rh(v.position, Vec3::ZERO, Vec3::Y);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
println!("{:?}",vm);
|
||||
println!("{:?}", vm);
|
||||
|
||||
// view matrices should be orientation only
|
||||
let dir = Quat::from_mat4(&vm);
|
||||
|
||||
v.orientation = dir;
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue