mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-22 16:25:36 +00:00
Add chaperone API
This commit is contained in:
committed by
Benjamin Saunders
parent
710131c111
commit
ed3a65427f
186
src/chaperone.rs
Normal file
186
src/chaperone.rs
Normal 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)
|
||||
);
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user