diff --git a/src/bin/click.rs b/src/bin/click.rs new file mode 100644 index 0000000..cb4f40d --- /dev/null +++ b/src/bin/click.rs @@ -0,0 +1,94 @@ +extern crate vrtue; +use vrtue::vr; + +extern crate env_logger; +extern crate gfx; +#[macro_use] extern crate log; +extern crate openvr_sys; +extern crate piston_window; + +use self::piston_window::{PistonWindow, Window, WindowSettings}; + +pub type ColorFormat = gfx::format::Srgba8; +pub type DepthFormat = gfx::format::DepthStencil; + +pub fn main() { + let mut vr = vr::VR::new().expect("VR init"); + + let mut window: PistonWindow = + WindowSettings::new("Click Test", [512; 2]) + .exit_on_esc(true) + .vsync(false) + .build().expect("Building Window"); + + let render_size = vr.recommended_render_target_size(); + let left: vr::EyeBuffer = vr::create_eyebuffer(&mut window.factory, render_size) + .expect("create left renderbuffer"); + let right: vr::EyeBuffer = vr::create_eyebuffer(&mut window.factory, render_size) + .expect("create right renderbuffer"); + window.encoder.clear(&left.target, [1.0, 0.0, 0.0, 1.0]); + window.encoder.clear_depth(&left.depth, 1.0); + window.encoder.clear(&right.target, [0.0, 1.0, 0.0, 1.0]); + window.encoder.clear_depth(&right.depth, 1.0); + window.encoder.flush(&mut window.device); + + let mut pads = ::std::collections::BTreeMap::<_, Option>::new(); + 'main: loop { + let _poses = vr.poses(); + vr.submit(vr::Eye::Left, &left.tex); + vr.submit(vr::Eye::Right, &right.tex); + + while let Some(ev) = vr.poll_next_event() { + match ev { + vr::Event::Press { dev_idx, controller } => { + println!("Press event on #{}: {:?}", dev_idx, controller); + }, + vr::Event::Unpress { dev_idx, controller } => { + println!("Unpress event on #{}: {:?}", dev_idx, controller); + }, + vr::Event::Touch { dev_idx, controller } => { + if controller.button == openvr_sys::EVRButtonId_k_EButton_SteamVR_Touchpad as u32 { + pads.insert(dev_idx, None); + } + println!("Touch event on #{}: {:?}", dev_idx, controller); + }, + vr::Event::Untouch { dev_idx, controller } => { + if controller.button == openvr_sys::EVRButtonId_k_EButton_SteamVR_Touchpad as u32 { + pads.remove(&dev_idx); + } + println!("Untouch event on #{}: {:?}", dev_idx, controller); + }, + /* + t if t == openvr_sys::EVREventType::EVREventType_VREvent_TouchPadMove as u32 => { + let touch; + unsafe { + touch = *ev.data.touchPadMove(); + } + println!("TouchPadMove event on #{}: {:?}", ev.trackedDeviceIndex, touch); + }, + */ + _ => () + } + } + + for (pad, old) in pads.iter_mut() { + if let Some(state) = vr.get_controller_state(*pad) { + if let Some(old_state) = *old { + if state.unPacketNum == old_state.unPacketNum { + continue; + } + } + *old = Some(state); + println!("state for {}: {:?}", *pad, state); + } + } + + // handle window events + while let Some(ev) = window.poll_event() { + match ev { + piston_window::Input::Text(_) => break 'main, + _ => debug!("\t{:?}", ev) + } + } + } +} diff --git a/src/vr.rs b/src/vr.rs index e7f8182..c30b66c 100644 --- a/src/vr.rs +++ b/src/vr.rs @@ -13,6 +13,7 @@ use self::gfx_device_gl::Resources as GLResources; use self::na::Inverse; use self::num_traits::identities::Zero; use self::num_traits::identities::One; +use self::openvr_sys::{VREvent_Controller_t, VREvent_t}; pub struct VR { system: vr::IVRSystem, @@ -20,7 +21,13 @@ pub struct VR { gfx_handles: gfx::handle::Manager, } -pub struct Event { +#[derive(Debug)] +pub enum Event { + Touch { dev_idx: u32, controller: VREvent_Controller_t }, + Press { dev_idx: u32, controller: VREvent_Controller_t }, + Unpress { dev_idx: u32, controller: VREvent_Controller_t }, + Untouch { dev_idx: u32, controller: VREvent_Controller_t }, + Other(VREvent_t), } impl VR { @@ -60,6 +67,48 @@ impl VR { assert!(mat.inverse_mut(), "inverse eye matrix"); mat } + + pub fn poll_next_event(&mut self) -> Option { + use self::openvr_sys::EVREventType as EvType; + unsafe { + let system = * { self.system.0 as *mut openvr_sys::VR_IVRSystem_FnTable }; + let mut event: openvr_sys::VREvent_t = ::std::mem::zeroed(); + + if system.PollNextEvent.unwrap()(&mut event, + ::std::mem::size_of::() as u32 + ) == 0 { + return None; + } + + let dev_idx = event.trackedDeviceIndex; + Some(match ::std::mem::transmute(event.eventType) { + EvType::EVREventType_VREvent_ButtonTouch => + Event::Touch { dev_idx: dev_idx as u32, controller: *event.data.controller() }, + EvType::EVREventType_VREvent_ButtonPress => + Event::Press { dev_idx: dev_idx as u32, controller: *event.data.controller() }, + EvType::EVREventType_VREvent_ButtonUnpress => + Event::Unpress { dev_idx: dev_idx as u32, controller: *event.data.controller() }, + EvType::EVREventType_VREvent_ButtonUntouch => + Event::Untouch { dev_idx: dev_idx as u32, controller: *event.data.controller() }, + _ => Event::Other(event), + }) + } + } + + pub fn get_controller_state(&self, index: u32) -> Option { + unsafe { + let system = * { self.system.0 as *const openvr_sys::VR_IVRSystem_FnTable }; + let mut state: openvr_sys::VRControllerState_t = ::std::mem::zeroed(); + + match system.GetControllerState.unwrap()( + index, + &mut state, + ) { + 0 => None, + _ => Some(state) + } + } + } } impl Drop for VR {