Add chaperone API

This commit is contained in:
Travis Finkenauer
2019-02-08 22:06:04 -05:00
committed by Benjamin Saunders
parent 710131c111
commit ed3a65427f
2 changed files with 192 additions and 0 deletions

186
src/chaperone.rs Normal file
View File

@ -0,0 +1,186 @@
use std::convert::From;
use openvr_sys as sys;
use {Chaperone, HmdColor_t, HmdQuad_t, HmdVector3_t};
/// Chaperone warning states
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ChaperoneCalibrationWarningState {
Warning,
BaseStationMayHaveMoved,
BaseStationRemoved,
SeatedBoundsInvalid,
Unknown(u32),
}
impl From<sys::ChaperoneCalibrationState> for ChaperoneCalibrationWarningState {
fn from(state: sys::ChaperoneCalibrationState) -> Self {
use self::ChaperoneCalibrationWarningState::*;
match state {
sys::ChaperoneCalibrationState_Warning => Warning,
sys::ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved => {
BaseStationMayHaveMoved
}
sys::ChaperoneCalibrationState_Warning_BaseStationRemoved => BaseStationRemoved,
sys::ChaperoneCalibrationState_Warning_SeatedBoundsInvalid => SeatedBoundsInvalid,
_ => Unknown(state as u32),
}
}
}
/// Chaperone error states
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ChaperoneCalibrationErrorState {
Error,
BaseStationUninitialized,
BaseStationConflict,
PlayAreaInvalid,
CollisionBoundsInvalid,
Unknown(u32),
}
impl From<sys::ChaperoneCalibrationState> for ChaperoneCalibrationErrorState {
fn from(state: sys::ChaperoneCalibrationState) -> Self {
use self::ChaperoneCalibrationErrorState::*;
match state {
sys::ChaperoneCalibrationState_Error => Error,
sys::ChaperoneCalibrationState_Error_BaseStationUninitialized => {
BaseStationUninitialized
}
sys::ChaperoneCalibrationState_Error_BaseStationConflict => BaseStationConflict,
sys::ChaperoneCalibrationState_Error_PlayAreaInvalid => CollisionBoundsInvalid,
_ => Unknown(state as u32),
}
}
}
/// State of Chaperone calibration.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ChaperoneCalibrationState {
Ok,
Warning(ChaperoneCalibrationWarningState),
Error(ChaperoneCalibrationErrorState),
Unknown(u32),
}
impl From<sys::ChaperoneCalibrationState> for ChaperoneCalibrationState {
fn from(state: sys::ChaperoneCalibrationState) -> Self {
use self::ChaperoneCalibrationState::*;
match state {
1 => Ok,
100...199 => Warning(ChaperoneCalibrationWarningState::from(state)),
200...299 => Error(ChaperoneCalibrationErrorState::from(state)),
_ => Unknown(state as u32),
}
}
}
impl Chaperone {
/// Get the current state of Chaperone calibration.
/// This state can change at any time during a session due to physical base station changes.
/// (NOTE: Some of these error codes are never returned as implementation for the error states
/// is still a work in progress.)
pub fn get_calibration_state(&self) -> ChaperoneCalibrationState {
unsafe { self.0.GetCalibrationState.unwrap()() }.into()
}
/// Returns the width and depth of the Play Area.
pub fn get_play_area_size(&self) -> Option<(f32, f32)> {
let mut x: f32 = 0.0;
let mut z: f32 = 0.0;
let is_ok = unsafe { self.0.GetPlayAreaSize.unwrap()(&mut x, &mut z) };
if is_ok {
Some((x, z))
} else {
None
}
}
/// Returns the 4 corner positions of the PlayArea.
pub fn get_play_area_rect(&self) -> Option<HmdQuad_t> {
let mut play_area_rect = HmdQuad_t {
vCorners: [HmdVector3_t { v: [0.0; 3] }; 4],
};
let is_ok = unsafe { self.0.GetPlayAreaRect.unwrap()(&mut play_area_rect) };
if is_ok {
Some(play_area_rect)
} else {
None
}
}
// Do not understand what this does
/// Reload chaperone info
fn reload_info(&mut self) {
unsafe { self.0.ReloadInfo.unwrap()() };
}
// Do not understand what this does
/// Set scene color
fn set_scene_color(&mut self, color: HmdColor_t) {
unsafe { self.0.SetSceneColor.unwrap()(color) };
}
/// Are chaperone bounds visible?
pub fn are_bounds_visible(&self) -> bool {
unsafe { self.0.AreBoundsVisible.unwrap()() }
}
/// Set chaperone bounds to always be visible. If set to false, chaperone
/// bounds will only show when near the edge.
///
/// Caution: this change is persistent, even after your program exits.
pub fn force_bounds_visible(&self, force: bool) {
unsafe { self.0.ForceBoundsVisible.unwrap()(force) };
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn convert_ChaperoneCalibrationState() {
assert_eq!(
ChaperoneCalibrationState::from(sys::ChaperoneCalibrationState_OK),
ChaperoneCalibrationState::Ok
);
assert_eq!(
ChaperoneCalibrationState::from(sys::ChaperoneCalibrationState_Warning),
ChaperoneCalibrationState::Warning(ChaperoneCalibrationWarningState::Warning)
);
assert_eq!(
ChaperoneCalibrationState::from(199),
ChaperoneCalibrationState::Warning(ChaperoneCalibrationWarningState::Unknown(199))
);
assert_eq!(
ChaperoneCalibrationState::from(
sys::ChaperoneCalibrationState_Warning_BaseStationRemoved
),
ChaperoneCalibrationState::Warning(
ChaperoneCalibrationWarningState::BaseStationRemoved
)
);
assert_eq!(
ChaperoneCalibrationState::from(sys::ChaperoneCalibrationState_Error),
ChaperoneCalibrationState::Error(ChaperoneCalibrationErrorState::Error)
);
assert_eq!(
ChaperoneCalibrationState::from(
sys::ChaperoneCalibrationState_Error_BaseStationUninitialized
),
ChaperoneCalibrationState::Error(
ChaperoneCalibrationErrorState::BaseStationUninitialized
)
);
assert_eq!(
ChaperoneCalibrationState::from(299),
ChaperoneCalibrationState::Error(ChaperoneCalibrationErrorState::Unknown(299))
);
assert_eq!(
ChaperoneCalibrationState::from(2),
ChaperoneCalibrationState::Unknown(2)
);
}
}

View File

@ -14,6 +14,7 @@ mod tracking;
pub mod system;
pub mod compositor;
pub mod render_models;
pub mod chaperone;
pub mod property;
pub use tracking::*;
@ -22,6 +23,9 @@ pub use sys::VkPhysicalDevice_T;
pub use sys::VkDevice_T;
pub use sys::VkInstance_T;
pub use sys::VkQueue_T;
pub use sys::HmdQuad_t;
pub use sys::HmdVector3_t;
pub use sys::HmdColor_t;
static INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT;
@ -55,6 +59,7 @@ pub unsafe fn init(ty: ApplicationType) -> Result<Context, InitError> {
pub struct System(&'static sys::VR_IVRSystem_FnTable);
pub struct Compositor(&'static sys::VR_IVRCompositor_FnTable);
pub struct RenderModels(&'static sys::VR_IVRRenderModels_FnTable);
pub struct Chaperone(&'static sys::VR_IVRChaperone_FnTable);
/// Entry points into OpenVR.
///
@ -78,6 +83,7 @@ impl Context {
pub fn system(&self) -> Result<System, InitError> { load(sys::IVRSystem_Version).map(|x| unsafe { System(&*x) }) }
pub fn compositor(&self) -> Result<Compositor, InitError> { load(sys::IVRCompositor_Version).map(|x| unsafe { Compositor(&*x) }) }
pub fn render_models(&self) -> Result<RenderModels, InitError> { load(sys::IVRRenderModels_Version).map(|x| unsafe { RenderModels(&*x) }) }
pub fn chaperone(&self) -> Result<Chaperone, InitError> { load(sys::IVRChaperone_Version).map(|x| unsafe { Chaperone(&*x) }) }
}
impl Drop for Context {