diff --git a/Cargo.lock b/Cargo.lock index 9165a32..8f0f179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,9 +74,9 @@ checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e" [[package]] name = "android_logger" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0c6cfd3264e874d461c0316a78fb78e4147562c68a64881af36fe10573613e" +checksum = "8619b80c242aa7bd638b5c7ddd952addeecb71f69c75e33f1d47b2804f8f883a" dependencies = [ "android_log-sys", "env_logger", @@ -1817,9 +1817,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] @@ -2506,9 +2506,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ "hermit-abi", "libc", diff --git a/README.md b/README.md index 60aa65e..628301e 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,11 @@ PixSpace deals/ plans to deal with: * [x] custom projection matrices * [~] build a system that updates a cameras frustum (w/ offaxis) +* [~] VRPN (https://github.com/seichter/vrpn-rs) - sync_client.rs seems to do what we need - issue it is Rust 2018 * [ ] multiple cameras * [ ] render to texture -* [~] VRPN (https://github.com/seichter/vrpn-rs) - sync_client.rs seems to do what we need - issue it is Rust 2018 -# Contributions +# Contributions / Notes Though, I am mostly writing this software on my own, I often ask for help and fortunately FOSS people will be happy to help @@ -34,3 +34,10 @@ https://github.com/bevyengine/bevy/blob/main/examples/3d/split_screen.rs https://github.com/bevyengine/bevy/blob/main/examples/3d/render_to_texture.rs And ria8651 on bevy #rendering Discord channel explained pointed me towards reversed Z frustum + +further + +https://thxforthefish.com/posts/reverse_z/ +https://vincent-p.github.io/posts/vulkan_perspective_matrix/ + + diff --git a/src/main.rs b/src/main.rs index 34458bc..7207e01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,9 @@ fn main() { .add_startup_system(offaxis_camera_setup) // .add_startup_system(setup_tracker) // .add_system(update_tracker) - .add_startup_system(setup_threaded_tracker) + // .add_startup_system(setup_threaded_tracker) + // .add_startup_system(setup_threaded_tracker_simple) + .init_resource::() .add_plugin(CameraProjectionPlugin::::default()) // .add_system(simulate_viewer_with_circle) diff --git a/src/offaxis.rs b/src/offaxis.rs index cb0e4a0..59f6fc8 100644 --- a/src/offaxis.rs +++ b/src/offaxis.rs @@ -24,7 +24,11 @@ impl CameraProjection for OffAxisProjection { // what to do on window resize fn update(&mut self, width: f32, height: f32) { - // self.aspect = width / height; + + + // extract sx and sy from matrix + // let sx = self.projection_matrix.x_axis.x; + // let sy = self.projection_matrix.y_axis.y; } fn far(&self) -> f32 { diff --git a/src/projection.rs b/src/projection.rs index 8e3f666..e6a2fd8 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -48,11 +48,8 @@ pub fn make_projection_rh_from_frustum_reversed( info!("near {:?}", z_near); // - // reversed z 0..1 projection based on https://thxforthefish.com/posts/reverse_z/ and - // https://vincent-p.github.io/posts/vulkan_perspective_matrix/ + // reversed z 0..1 projection // - - let a = (right + left) / (right - left); // position in frame horizontal let b = (top + bottom) / (top - bottom); // position in frame vertical @@ -95,12 +92,13 @@ pub fn create_offaxis_matrices( screen_upper_left: Vec3, pos_eye: Vec3, z_far: f32, -) -> (Mat4, Mat4) { + ) -> (Mat4, Mat4) +{ // let vec_right = screen_lower_right - screen_lower_left; // vr - let vec_up = screen_upper_left - screen_lower_left; // vu + let vec_up = screen_upper_left - screen_lower_left; // vu - let frustum_left = screen_lower_left - pos_eye; // va + 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 diff --git a/src/scene.rs b/src/scene.rs index 1541b27..73aace9 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -26,7 +26,7 @@ pub fn build_scene( shadows_enabled: true, ..default() }, - transform: Transform::from_xyz(4.0, 4.0, -1.5), + transform: Transform::from_xyz(4.0, 4.0, 0.0), ..default() }); } diff --git a/src/tracker.rs b/src/tracker.rs index d77513d..048f7ae 100644 --- a/src/tracker.rs +++ b/src/tracker.rs @@ -1,3 +1,4 @@ + use bevy::prelude::*; extern crate bytes; @@ -13,7 +14,7 @@ use std::{ net::{SocketAddr, TcpStream}, }; -use std::sync::mpsc::{Receiver,channel}; +use std::sync::mpsc::{channel, Receiver}; use vrpn::{ codec::peek_u32, @@ -23,67 +24,98 @@ use vrpn::{ message::MessageSize, sync_io::{read_cookie, write_cookie, EndpointSyncTcp}, tracker::PoseReport, - unbuffer, CookieData, Message, Result, SequencedGenericMessage, TypeDispatcher, Unbuffer, TypedBodylessHandler, + unbuffer, CookieData, Message, Result, SequencedGenericMessage, TypeDispatcher, + TypedBodylessHandler, Unbuffer, }; - struct TrackerProxy; +#[derive(Resource, Debug)] +pub struct Tracker; -#[derive(Resource,Debug)] -struct Tracker; - -impl Tracker { - - pub fn start_tracker(&self) { +impl FromWorld for Tracker { + fn from_world(world: &mut World) -> Self { + let (sender, receiver): (_, Receiver) = channel(); std::thread::spawn(move || { - - let (sender, receiver): (_, Receiver) = channel(); - - let addr: SocketAddr = "127.0.0.1:3883".parse().unwrap(); let mut stream = TcpStream::connect(addr).unwrap(); stream.set_nodelay(true).unwrap(); - + // We first write our cookie, then read and check the server's cookie, before the loop. write_cookie(&mut stream, CookieData::from(MAGIC_DATA)).unwrap(); let cookie_buf = read_cookie(&mut stream).unwrap(); let mut cookie_buf = Bytes::from(&cookie_buf[..]); - + CookieData::unbuffer_ref(&mut cookie_buf) - .and_then(|msg| check_ver_nonfile_compatible(msg.version)).unwrap(); - - let mut endpoint = EndpointSyncTcp::new(stream); - let mut dispatcher = TypeDispatcher::new(); - - //let _ = dispatcher.add_typed_handler(Box::new(TrackerHandler {}), None).unwrap(); - - let _ = dispatcher.add_typed_handler(Box::new( Tracker {} ), None).unwrap(); - - // setup a channel - // let (tx, rx) = mpsc::channel(); - + .and_then(|msg| check_ver_nonfile_compatible(msg.version)) + .unwrap(); + + // Not actually doing anything with the messages here, just receiving them and printing them. loop { - - // vrpn implementation is rather verbose - we need to see what specific errors - // should be handled properly! - endpoint.poll_endpoint(&mut dispatcher).unwrap_or_else(|err| { - info!("error from tracker thread {:?}",err); - }) - - // dispatcher.han - + let mut buf = BytesMut::new(); + + // Read the message header and padding + buf.resize(24, 0); + stream.read_exact(buf.as_mut()).unwrap(); + + // Peek the size field, to compute the MessageSize. + let total_len = peek_u32(&buf.clone().freeze()).unwrap().unwrap(); + let size = MessageSize::from_length_field(total_len); + + // Read the body of the message + let mut body_buf = BytesMut::new(); + body_buf.resize(size.padded_body_size(), 0); + stream.read_exact(body_buf.as_mut()).unwrap(); + + // Combine the body with the header + buf.extend_from_slice(&body_buf[..]); + let mut buf = buf.freeze(); + + // Unbuffer the message. + let unbuffered = SequencedGenericMessage::unbuffer_ref(&mut buf).unwrap(); + + let message = Message::from(unbuffered); + + + // let result: Message = Message::try_from_generic(&message)?; + + let result = Message::::try_from_generic(&message); + + match result { + + Ok(result) => { eprintln!("Ok! {:?}",result.body);}, + Err(_) => {} + + } + // match result { + // Ok(i) => i, + // _ => false + // } + + // match result { + // Message => println!("") + + // } + + + // eprintln!( + // "{:?} {:?}", + // typed_message.body.sensor, typed_message.body.pos + // ); } }); - - - + Self {} } - } +// pub fn setup_threaded_tracker_simple(mut commands: Commands) { + +// commands.spawn(Tracker::new()); + +// } + // impl TypedBodylessHandler for Tracker { // type Item = PoseReport; // fn handle_typed_bodyless(&mut self, header: &vrpn::MessageHeader) -> Result { @@ -92,41 +124,13 @@ impl Tracker { // } // } -impl TypedHandler for Tracker { - type Item = PoseReport; - fn handle_typed(&mut self, msg: &Message) -> Result { - println!("{:?}\n {:?}", msg.header, msg.body); - Ok(HandlerCode::ContinueProcessing) - } -} - -impl FromWorld for Tracker { - fn from_world(world: &mut World) -> Self { - Self {} - } -} - - - - - - - - - - - - - - - - - - - - - - +// impl TypedHandler for Tracker { +// type Item = PoseReport; +// fn handle_typed(&mut self, msg: &Message) -> Result { +// println!("{:?}\n {:?}", msg.header, msg.body); +// Ok(HandlerCode::ContinueProcessing) +// } +// } #[derive(Debug)] struct TrackerHandler; @@ -151,27 +155,29 @@ pub fn setup_threaded_tracker(mut commands: Commands) { let mut cookie_buf = Bytes::from(&cookie_buf[..]); CookieData::unbuffer_ref(&mut cookie_buf) - .and_then(|msg| check_ver_nonfile_compatible(msg.version)).unwrap(); + .and_then(|msg| check_ver_nonfile_compatible(msg.version)) + .unwrap(); let mut endpoint = EndpointSyncTcp::new(stream); let mut dispatcher = TypeDispatcher::new(); - let _ = dispatcher.add_typed_handler(Box::new(TrackerHandler {}), None).unwrap(); + let _ = dispatcher + .add_typed_handler(Box::new(TrackerHandler {}), None) + .unwrap(); - // setup a channel // let (tx, rx) = mpsc::channel(); loop { - - // vrpn implementation is rather verbose - we need to see what specific errors + // vrpn implementation is rather verbose - we need to see what specific errors // should be handled properly! - endpoint.poll_endpoint(&mut dispatcher).unwrap_or_else(|err| { - info!("error from tracker thread {:?}",err); - }) + endpoint + .poll_endpoint(&mut dispatcher) + .unwrap_or_else(|err| { + info!("error from tracker thread {:?}", err); + }) // dispatcher.han - } }); }