diff --git a/.gitignore b/.gitignore index 24fa4f5..0780130 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /src/sys/target/ *.lock Cargo.lock +/idea/ diff --git a/Cargo.toml b/Cargo.toml index 7e9e4ce..a9fb9cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openvr" -version = "0.3.0" +version = "0.4.0" authors = [ "Colin Sherratt", "Erick Tryzelaar", @@ -19,7 +19,7 @@ name = "openvr" path = "src/lib.rs" [dependencies] -openvr_sys = "0.1.2" +openvr_sys = "1.0.2" [dev_dependencies] glium = "0.14.0" diff --git a/examples/camera.rs b/examples/camera.rs new file mode 100644 index 0000000..e7ae3ee --- /dev/null +++ b/examples/camera.rs @@ -0,0 +1,26 @@ +extern crate openvr; + +pub fn main () { + // init vr system + let system = match openvr::init() { + Ok(ivr) => ivr, + Err(err) => { + println!("Failed to create IVRSystem subsystem {:?}", err); + return; + } + }; + + let camera = match openvr::subsystems::tracked_camera() { + Ok(ivr) => ivr, + Err(err) => { + println!("Failed to create IVRTrackedCamera subsystem {:?}", err); + return; + } + }; + + for device in system.tracked_devices(0.0).connected_iter() { + println!("Device found: {}", device.index); + println!("\t{:?}", device.device_class()); + println!("\t{:?}", camera.has_camera(&device)); + } +} diff --git a/src/common.rs b/src/common.rs index 80bce9c..f1a77f2 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,5 +1,5 @@ use openvr_sys; -use openvr_sys::Enum_EVREye::*; +use openvr_sys::EVREye::*; #[derive(Debug, Copy, Clone)] pub struct Size { @@ -70,7 +70,7 @@ impl TextureBounds { /// Convert a bounds to a openvr_bounds pub fn to_raw(self) -> openvr_sys::VRTextureBounds_t { - openvr_sys::VRTextureBounds_t{ + openvr_sys::VRTextureBounds_t { uMin: self.u_min, uMax: self.u_max, vMin: self.v_min, diff --git a/src/compositor.rs b/src/compositor.rs index c8659c3..b9c5e6f 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1,7 +1,7 @@ use openvr_sys; -use openvr_sys::Enum_EGraphicsAPIConvention::*; -use openvr_sys::Enum_EVRSubmitFlags::*; -use openvr_sys::Enum_EColorSpace::*; +use openvr_sys::EGraphicsAPIConvention::*; +use openvr_sys::EVRSubmitFlags::*; +use openvr_sys::EColorSpace::*; use common::*; use tracking::*; @@ -16,7 +16,7 @@ impl IVRCompositor { /// Check to see if the compositor is fullscreen pub fn is_fullscreen(&self) -> bool { unsafe { - let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable }; + let comp = * { self.0 as *mut openvr_sys::VR_IVRCompositor_FnTable }; comp.IsFullscreen.unwrap()() > 0 } } @@ -24,7 +24,7 @@ impl IVRCompositor { /// Check if compositor can render a scene pub fn can_render_scene(&self) -> bool { unsafe { - let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable }; + let comp = * { self.0 as *mut openvr_sys::VR_IVRCompositor_FnTable }; comp.CanRenderScene.unwrap()() > 0 } } @@ -37,7 +37,7 @@ impl IVRCompositor { unsafe { use std; - let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable }; + let comp = * { self.0 as *mut openvr_sys::VR_IVRCompositor_FnTable }; let mut t = openvr_sys::Texture_t { eType: EGraphicsAPIConvention_API_OpenGL, eColorSpace: EColorSpace_ColorSpace_Auto, @@ -58,7 +58,7 @@ impl IVRCompositor { use std; unsafe { - let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable }; + let comp = * { self.0 as *mut openvr_sys::VR_IVRCompositor_FnTable }; let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed(); comp.WaitGetPoses.unwrap()( diff --git a/src/error.rs b/src/error.rs index a9c8c29..fbf4977 100644 --- a/src/error.rs +++ b/src/error.rs @@ -48,10 +48,10 @@ macro_rules! impl_raw_error { fn is_err(&self) -> bool { match *self { $none_name => { - true + false }, _ => { - false + true } } } @@ -70,20 +70,34 @@ macro_rules! impl_raw_error { use std::ffi::CStr; use openvr_sys::*; -use openvr_sys::Enum_ETrackedPropertyError::*; -use openvr_sys::Enum_EVRInitError::*; -use openvr_sys::Enum_EVRRenderModelError::*; +use openvr_sys::ETrackedPropertyError::*; +use openvr_sys::EVRInitError::*; +use openvr_sys::EVRRenderModelError::*; +use openvr_sys::EVRTrackedCameraError::*; impl_raw_error!( system, - Struct_VR_IVRSystem_FnTable, + VR_IVRSystem_FnTable, GetPropErrorNameFromEnum, ETrackedPropertyError, ETrackedPropertyError_TrackedProp_Success); +impl_raw_error!( + render_models, + VR_IVRRenderModels_FnTable, + GetRenderModelErrorNameFromEnum, + EVRRenderModelError, + EVRRenderModelError_VRRenderModelError_None); + +impl_raw_error!( + tracked_camera, + VR_IVRTrackedCamera_FnTable, + GetCameraErrorNameFromEnum, + EVRTrackedCameraError, + EVRTrackedCameraError_VRTrackedCameraError_None); // The init error has some special function to retrieve string -impl RawError for Enum_EVRInitError { +impl RawError for EVRInitError { fn is_err(&self) -> bool { match *self { EVRInitError_VRInitError_None => { @@ -103,21 +117,3 @@ impl RawError for Enum_EVRInitError { String::from(sstr) } } - -// RenderModelError has no implementation in 0.1.19 unfortunately -impl RawError for Enum_EVRRenderModelError { - fn is_err(&self) -> bool { - match *self { - EVRRenderModelError_VRRenderModelError_None => { - true - }, - _ => { - false - } - } - } - - fn message(&self) -> String { - String::from(format!("{:?}", *self)) - } -} diff --git a/src/extended_display.rs b/src/extended_display.rs index f530dd9..cfab3f2 100644 --- a/src/extended_display.rs +++ b/src/extended_display.rs @@ -12,7 +12,7 @@ impl IVRExtendedDisplay { /// Get the window bounds pub fn window_bounds(&self) -> Rectangle { unsafe { - let ext = * { self.0 as *mut openvr_sys::Struct_VR_IVRExtendedDisplay_FnTable }; + let ext = * { self.0 as *mut openvr_sys::VR_IVRExtendedDisplay_FnTable }; let mut size = Size{width: 0, height: 0}; let mut pos = Position{x: 0, y: 0}; @@ -35,7 +35,7 @@ impl IVRExtendedDisplay { use std::mem; unsafe { - let ext = * { self.0 as *mut openvr_sys::Struct_VR_IVRExtendedDisplay_FnTable }; + let ext = * { self.0 as *mut openvr_sys::VR_IVRExtendedDisplay_FnTable }; let mut size = Size{width: 0, height: 0}; let mut pos = Position{x: 0, y: 0}; diff --git a/src/lib.rs b/src/lib.rs index 74647da..856d148 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ extern crate openvr_sys; -use openvr_sys::Enum_EVRInitError::*; -use openvr_sys::Enum_EVRApplicationType::*; + +use openvr_sys::EVRInitError::*; +use openvr_sys::EVRApplicationType::*; pub mod common; pub mod error; @@ -9,6 +10,7 @@ pub mod system; pub mod extended_display; pub mod compositor; pub mod render_models; +pub mod tracked_camera; pub mod subsystems; pub use system::IVRSystem; @@ -22,7 +24,7 @@ pub use error::*; pub use common::Eye; /// Inits the open vr interface and returns the system -pub fn init() -> Result> { +pub fn init() -> Result> { let mut err = EVRInitError_VRInitError_None; let app_type = EVRApplicationType_VRApplication_Scene; diff --git a/src/render_models.rs b/src/render_models.rs index b3dcb54..4ea4fd8 100644 --- a/src/render_models.rs +++ b/src/render_models.rs @@ -1,5 +1,5 @@ use openvr_sys; -use openvr_sys::Enum_EVRRenderModelError::*; +use openvr_sys::EVRRenderModelError::*; use std::string::String; use std::ptr::null_mut; @@ -7,7 +7,7 @@ use std::slice; use subsystems::render_models; use error::*; -pub struct IVRRenderModels(*const ()); +pub struct IVRRenderModels(pub *const ()); pub struct RenderModel(*mut openvr_sys::RenderModel_t); pub struct RenderModelTexture(*mut openvr_sys::RenderModel_TextureMap_t); @@ -17,7 +17,7 @@ trait AsyncError { fn is_loading(&self) -> bool; } -impl AsyncError for Error { +impl AsyncError for Error { fn is_loading(&self) -> bool { match self.to_raw() { EVRRenderModelError_VRRenderModelError_Loading => { @@ -34,7 +34,7 @@ impl Drop for RenderModel { /// will inform openvr that the memory for the render model is no longer required fn drop (&mut self) { unsafe { - let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + let models = * { render_models().unwrap().0 as *mut openvr_sys::VR_IVRRenderModels_FnTable}; models.FreeRenderModel.unwrap()( self.0 ); @@ -46,7 +46,7 @@ impl Drop for RenderModelTexture { /// will inform openvr that the memory for the render model is no longer required fn drop (&mut self) { unsafe { - let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + let models = * { render_models().unwrap().0 as *mut openvr_sys::VR_IVRRenderModels_FnTable}; models.FreeTexture.unwrap()( self.0 ); @@ -73,9 +73,9 @@ impl RenderModel { /// asynchronosly loads the texture for the current render model /// see IVRRenderModels::load_async for info how openvr async work - pub fn load_texture_async(&self) -> Result> { + pub fn load_texture_async(&self) -> Result> { unsafe { - let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + let models = * { render_models().unwrap().0 as *mut openvr_sys::VR_IVRRenderModels_FnTable}; let mut resp: *mut openvr_sys::RenderModel_TextureMap_t = null_mut(); let err = models.LoadTexture_Async.unwrap()( @@ -96,7 +96,7 @@ impl RenderModel { } /// loads the texture for current model - pub fn load_texture(&self) -> Result> { + pub fn load_texture(&self) -> Result> { use std; loop { @@ -144,7 +144,7 @@ impl IVRRenderModels { /// Returns the amount of render models available pub fn get_count(&self) -> u32 { unsafe { - let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + let models = * { self.0 as *mut openvr_sys::VR_IVRRenderModels_FnTable}; models.GetRenderModelCount.unwrap()() } @@ -153,7 +153,7 @@ impl IVRRenderModels { /// Returns the name of an available render model pub fn get_name(&self, index: u32) -> String { unsafe { - let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + let models = * { self.0 as *mut openvr_sys::VR_IVRRenderModels_FnTable}; let name_out = String::with_capacity(256); let size = models.GetRenderModelName.unwrap()( @@ -199,7 +199,7 @@ impl IVRRenderModels { use std; unsafe { - let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + let models = * { self.0 as *mut openvr_sys::VR_IVRRenderModels_FnTable}; let mut resp: *mut openvr_sys::RenderModel_t = null_mut(); let cname = std::ffi::CString::new(name.as_str()).unwrap(); let rawname = cname.into_raw(); diff --git a/src/subsystems.rs b/src/subsystems.rs index 8d59a27..54020cc 100644 --- a/src/subsystems.rs +++ b/src/subsystems.rs @@ -1,16 +1,17 @@ extern crate openvr_sys; -use openvr_sys::Enum_EVRInitError::*; +use openvr_sys::EVRInitError::*; use error::*; use system::IVRSystem; use extended_display::IVRExtendedDisplay; use compositor::IVRCompositor; use render_models::IVRRenderModels; +use tracked_camera::IVRTrackedCamera; use std; /// gets the current vr system interface (initialization is required beforehand) -pub fn system() -> Result> { +pub fn system() -> Result> { let mut err = EVRInitError_VRInitError_None; let name = std::ffi::CString::new("FnTable:IVRSystem_012").unwrap(); let ptr = unsafe { @@ -30,7 +31,7 @@ pub fn system() -> Result> { } /// gets the current vr extended display interface (initialization is required beforehand) -pub fn extended_display() -> Result> { +pub fn extended_display() -> Result> { let mut err = EVRInitError_VRInitError_None; let name = std::ffi::CString::new("FnTable:IVRExtendedDisplay_001").unwrap(); let ptr = unsafe { @@ -50,7 +51,7 @@ pub fn extended_display() -> Result Result> { +pub fn compositor() -> Result> { let mut err = EVRInitError_VRInitError_None; let name = std::ffi::CString::new("FnTable:IVRCompositor_013").unwrap(); let ptr = unsafe { @@ -70,7 +71,7 @@ pub fn compositor() -> Result Result> { +pub fn render_models() -> Result> { let mut err = EVRInitError_VRInitError_None; let name = std::ffi::CString::new("FnTable:IVRRenderModels_005").unwrap(); let ptr = unsafe { @@ -88,3 +89,23 @@ pub fn render_models() -> Result Result> { + let mut err = EVRInitError_VRInitError_None; + let name = std::ffi::CString::new("FnTable:IVRTrackedCamera_003").unwrap(); + let ptr = unsafe { + openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err) + }; + + match err { + EVRInitError_VRInitError_None => { + unsafe { + return Ok(IVRTrackedCamera::from_raw(ptr as *const ())); + } + }, + _ => { + return Err(Error::from_raw(err)); + } + } +} diff --git a/src/system.rs b/src/system.rs index 392941b..d9c40a0 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,6 +1,6 @@ use openvr_sys; -use openvr_sys::Enum_EGraphicsAPIConvention::*; -use openvr_sys::Enum_ETrackingUniverseOrigin::*; +use openvr_sys::EGraphicsAPIConvention::*; +use openvr_sys::ETrackingUniverseOrigin::*; use common::*; use tracking::*; @@ -15,7 +15,7 @@ impl IVRSystem { /// Get the recommended render target size pub fn recommended_render_target_size(&self) -> Size { unsafe { - let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable }; + let system = * { self.0 as *mut openvr_sys::VR_IVRSystem_FnTable }; let mut size = Size{width: 0, height: 0}; system.GetRecommendedRenderTargetSize.unwrap()( @@ -32,7 +32,7 @@ impl IVRSystem { /// assumes opengl conventions pub fn projection_matrix(&self, eye: Eye, near: f32, far: f32) -> [[f32; 4]; 4] { unsafe { - let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable }; + let system = * { self.0 as *mut openvr_sys::VR_IVRSystem_FnTable }; let mat = system.GetProjectionMatrix.unwrap()( eye.to_raw(), @@ -47,7 +47,7 @@ impl IVRSystem { /// Computes the distortion caused by the optics pub fn compute_distortion(&self, eye: Eye, u: f32, v: f32) -> DistortionCoordinates { unsafe { - let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable }; + let system = * { self.0 as *mut openvr_sys::VR_IVRSystem_FnTable }; let coord = system.ComputeDistortion.unwrap()( eye.to_raw(), u, v @@ -63,7 +63,7 @@ impl IVRSystem { /// Computes the distortion caused by the optics pub fn eye_to_head_transform(&self, eye: Eye) -> [[f32; 4]; 3] { unsafe { - let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable }; + let system = * { self.0 as *mut openvr_sys::VR_IVRSystem_FnTable }; let mat = system.GetEyeToHeadTransform.unwrap()( eye.to_raw(), ); @@ -74,7 +74,7 @@ impl IVRSystem { /// Computes the distortion caused by the optics pub fn time_since_last_vsync(&self) -> Option<(f32, u64)> { unsafe { - let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable }; + let system = * { self.0 as *mut openvr_sys::VR_IVRSystem_FnTable }; let mut frame = 0; let mut sync = 0.; let found = system.GetTimeSinceLastVsync.unwrap()( @@ -98,7 +98,7 @@ impl IVRSystem { use std; unsafe { - let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable }; + let system = * { self.0 as *mut openvr_sys::VR_IVRSystem_FnTable }; let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed(); system.GetDeviceToAbsoluteTrackingPose.unwrap()( ETrackingUniverseOrigin_TrackingUniverseSeated, diff --git a/src/tracked_camera.rs b/src/tracked_camera.rs new file mode 100644 index 0000000..5834978 --- /dev/null +++ b/src/tracked_camera.rs @@ -0,0 +1,29 @@ +use openvr_sys; + +use tracking::*; +use error::*; + +pub struct IVRTrackedCamera(pub *const ()); + +impl IVRTrackedCamera { + pub unsafe fn from_raw(ptr: *const ()) -> Self { + IVRTrackedCamera(ptr as *mut ()) + } + + /// checks whether the current system has a camera + pub fn has_camera(&self, device: &TrackedDevicePose) -> Result> { + unsafe { + let cam = * { self.0 as *mut openvr_sys::VR_IVRTrackedCamera_FnTable }; + let mut has_cam = 0i32; + + let error = Error::from_raw( + cam.HasCamera.unwrap()(device.index as u32, &mut has_cam as *mut i32)); + + if error.is_ok() { + return Ok(has_cam > 0i32); + } else { + return Err(error); + } + } + } +} diff --git a/src/tracking.rs b/src/tracking.rs index 7c5e9c1..ce6cc57 100644 --- a/src/tracking.rs +++ b/src/tracking.rs @@ -1,5 +1,5 @@ use openvr_sys; -use openvr_sys::Enum_ETrackedPropertyError::*; +use openvr_sys::ETrackedPropertyError::*; use subsystems::*; use error::*; @@ -27,8 +27,8 @@ pub enum TrackedDeviceStringProperty { } impl TrackedDeviceStringProperty { - pub fn to_raw(&self) -> openvr_sys::Enum_ETrackedDeviceProperty { - use openvr_sys::Enum_ETrackedDeviceProperty::*; + pub fn to_raw(&self) -> openvr_sys::ETrackedDeviceProperty { + use openvr_sys::ETrackedDeviceProperty::*; use self::TrackedDeviceStringProperty::*; match *self { @@ -64,9 +64,9 @@ pub enum TrackedDeviceClass { } impl TrackedDeviceClass { - pub fn to_raw(&self) -> openvr_sys::Enum_ETrackedDeviceClass { + pub fn to_raw(&self) -> openvr_sys::ETrackedDeviceClass { use self::TrackedDeviceClass::*; - use openvr_sys::Enum_ETrackedDeviceClass::*; + use openvr_sys::ETrackedDeviceClass::*; match *self { Invalid => ETrackedDeviceClass_TrackedDeviceClass_Invalid, @@ -77,9 +77,9 @@ impl TrackedDeviceClass { } } - pub fn from_raw(raw: openvr_sys::Enum_ETrackedDeviceClass) -> Self { + pub fn from_raw(raw: openvr_sys::ETrackedDeviceClass) -> Self { use self::TrackedDeviceClass::*; - use openvr_sys::Enum_ETrackedDeviceClass::*; + use openvr_sys::ETrackedDeviceClass::*; match raw { ETrackedDeviceClass_TrackedDeviceClass_Invalid => Invalid, @@ -105,15 +105,15 @@ impl TrackedDevicePose { // returns the device class of the tracked object pub fn device_class(&self) -> TrackedDeviceClass { unsafe { - let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable}; + let system = * { system().unwrap().0 as *mut openvr_sys::VR_IVRSystem_FnTable}; TrackedDeviceClass::from_raw(system.GetTrackedDeviceClass.unwrap()(self.index as u32)) } } /// gets a propery as a string - pub fn get_property_string(&self, property: TrackedDeviceStringProperty) -> Result> { + pub fn get_property_string(&self, property: TrackedDeviceStringProperty) -> Result> { unsafe { - let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable}; + let system = * { system().unwrap().0 as *mut openvr_sys::VR_IVRSystem_FnTable}; let val_out = String::with_capacity(256); let mut err = ETrackedPropertyError_TrackedProp_Success;