mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-22 16:25:36 +00:00
Merge pull request #29 from Ralith/more-system-methods
More system methods
This commit is contained in:
@ -16,7 +16,7 @@ repository = "https://github.com/rust-openvr/rust-openvr"
|
||||
description = "A safe binding for openvr."
|
||||
|
||||
[dependencies]
|
||||
openvr_sys = { git = "https://github.com/Ralith/rust-openvr-sys.git", branch = "update" }
|
||||
openvr_sys = { git = "https://github.com/Ralith/rust-openvr-sys.git", branch = "enum-rename" }
|
||||
|
||||
[dev_dependencies]
|
||||
glium = "0.14.0"
|
||||
|
@ -16,7 +16,7 @@ fn print_matrix_4x3(offset: u32, mat: [[f32; 4]; 3]) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let context = match openvr::init(openvr::ApplicationType::Other) {
|
||||
let context = match unsafe { openvr::init(openvr::ApplicationType::Other) } {
|
||||
Ok(ivr) => ivr,
|
||||
Err(err) => {
|
||||
println!("Failed to initialize openvr {:?}", err);
|
||||
|
@ -21,27 +21,14 @@ use super::*;
|
||||
|
||||
impl<'a> Compositor<'a> {
|
||||
pub fn vulkan_instance_extensions_required(&self) -> Vec<CString> {
|
||||
let temp = unsafe {
|
||||
let n = self.0.GetVulkanInstanceExtensionsRequired.unwrap()(ptr::null_mut(), 0);
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
buffer.resize(n as usize, mem::uninitialized());
|
||||
(self.0.GetVulkanInstanceExtensionsRequired.unwrap())(buffer.as_mut_ptr() as *mut i8, n);
|
||||
buffer.truncate((n-1) as usize); // Strip trailing null
|
||||
buffer
|
||||
};
|
||||
temp.split(|&x| x == b' ').map(|x| CString::new(x.to_vec()).expect("extension name contained null byte")).collect()
|
||||
let temp = unsafe { get_string(|ptr, n| self.0.GetVulkanInstanceExtensionsRequired.unwrap()(ptr, n)) }.unwrap();
|
||||
temp.as_bytes().split(|&x| x == b' ').map(|x| CString::new(x.to_vec()).expect("extension name contained null byte")).collect()
|
||||
}
|
||||
|
||||
pub fn vulkan_device_extensions_required(&self, physical_device: *mut VkPhysicalDevice_T) -> Vec<CString> {
|
||||
let temp = unsafe {
|
||||
let n = self.0.GetVulkanDeviceExtensionsRequired.unwrap()(physical_device, ptr::null_mut(), 0);
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
buffer.resize(n as usize, mem::uninitialized());
|
||||
(self.0.GetVulkanDeviceExtensionsRequired.unwrap())(physical_device as *mut _, buffer.as_mut_ptr() as *mut i8, n);
|
||||
buffer.truncate((n-1) as usize); // Strip trailing null
|
||||
buffer
|
||||
};
|
||||
temp.split(|&x| x == b' ').map(|x| CString::new(x.to_vec()).expect("extension name contained null byte")).collect()
|
||||
/// Safety: physical_device must be a valid VkPhysicalDevice
|
||||
pub unsafe fn vulkan_device_extensions_required(&self, physical_device: *mut VkPhysicalDevice_T) -> Vec<CString> {
|
||||
let temp = get_string(|ptr, n| self.0.GetVulkanDeviceExtensionsRequired.unwrap()(physical_device, ptr, n)).unwrap();
|
||||
temp.as_bytes().split(|&x| x == b' ').map(|x| CString::new(x.to_vec()).expect("extension name contained null byte")).collect()
|
||||
}
|
||||
|
||||
/// Sets tracking space returned by WaitGetPoses
|
||||
@ -58,7 +45,7 @@ impl<'a> Compositor<'a> {
|
||||
let mut result: WaitPoses = mem::uninitialized();
|
||||
let e = self.0.WaitGetPoses.unwrap()(result.render.as_mut().as_mut_ptr() as *mut _, result.render.len() as u32,
|
||||
result.game.as_mut().as_mut_ptr() as *mut _, result.game.len() as u32);
|
||||
if e == sys::EVRCompositorError_EVRCompositorError_VRCompositorError_None {
|
||||
if e == sys::EVRCompositorError_VRCompositorError_None {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(CompositorError(e))
|
||||
@ -69,12 +56,16 @@ impl<'a> Compositor<'a> {
|
||||
/// Display the supplied texture for the next frame.
|
||||
///
|
||||
/// If `bounds` is None, the entire texture will be used. Lens distortion is handled by the OpenVR implementation.
|
||||
pub fn submit(&self, eye: Eye, texture: &Texture, bounds: Option<&texture::Bounds>) -> Result<(), CompositorError> {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The handles you supply must be valid and comply with the graphics API's synchronization requirements.
|
||||
pub unsafe fn submit(&self, eye: Eye, texture: &Texture, bounds: Option<&texture::Bounds>) -> Result<(), CompositorError> {
|
||||
use self::texture::Handle::*;
|
||||
let flags = match texture.handle {
|
||||
Vulkan(_) => sys::EVRSubmitFlags_EVRSubmitFlags_Submit_Default,
|
||||
OpenGLTexture(_) => sys::EVRSubmitFlags_EVRSubmitFlags_Submit_Default,
|
||||
OpenGLRenderBuffer(_) => sys::EVRSubmitFlags_EVRSubmitFlags_Submit_GlRenderBuffer,
|
||||
Vulkan(_) => sys::EVRSubmitFlags_Submit_Default,
|
||||
OpenGLTexture(_) => sys::EVRSubmitFlags_Submit_Default,
|
||||
OpenGLRenderBuffer(_) => sys::EVRSubmitFlags_Submit_GlRenderBuffer,
|
||||
};
|
||||
let texture = sys::Texture_t {
|
||||
handle: match texture.handle {
|
||||
@ -83,25 +74,32 @@ impl<'a> Compositor<'a> {
|
||||
OpenGLRenderBuffer(x) => x as *mut _,
|
||||
},
|
||||
eType: match texture.handle {
|
||||
Vulkan(_) => sys::ETextureType_ETextureType_TextureType_Vulkan,
|
||||
OpenGLTexture(_) => sys::ETextureType_ETextureType_TextureType_OpenGL,
|
||||
OpenGLRenderBuffer(_) => sys::ETextureType_ETextureType_TextureType_OpenGL,
|
||||
Vulkan(_) => sys::ETextureType_TextureType_Vulkan,
|
||||
OpenGLTexture(_) => sys::ETextureType_TextureType_OpenGL,
|
||||
OpenGLRenderBuffer(_) => sys::ETextureType_TextureType_OpenGL,
|
||||
},
|
||||
eColorSpace: texture.color_space as sys::EColorSpace,
|
||||
};
|
||||
let e = unsafe {
|
||||
self.0.Submit.unwrap()(eye as sys::EVREye,
|
||||
let e = self.0.Submit.unwrap()(
|
||||
eye as sys::EVREye,
|
||||
&texture as *const _ as *mut _,
|
||||
bounds.map(|x| x as *const _ as *mut texture::Bounds as *mut _).unwrap_or(ptr::null_mut()),
|
||||
flags)
|
||||
};
|
||||
if e == sys::EVRCompositorError_EVRCompositorError_VRCompositorError_None {
|
||||
flags);
|
||||
if e == sys::EVRCompositorError_VRCompositorError_None {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(CompositorError(e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Call immediately after presenting your app's window (i.e. companion window) to unblock the compositor.
|
||||
///
|
||||
/// This is an optional call, which only needs to be used if you can't instead call `wait_get_poses` immediately
|
||||
/// after submitting frames. For example, if your engine's render and game loop are not on separate threads, or
|
||||
/// blocking the render thread until 3ms before the next vsync would introduce a deadlock of some sort. This
|
||||
/// function tells the compositor that you have finished all rendering after having Submitted buffers for both eyes,
|
||||
/// and it is free to start its rendering work. This should only be called from the same thread you are rendering
|
||||
/// on.
|
||||
pub fn post_present_handoff(&self) {
|
||||
unsafe { (self.0.PostPresentHandoff.unwrap())() };
|
||||
}
|
||||
@ -110,6 +108,13 @@ impl<'a> Compositor<'a> {
|
||||
pub fn is_fullscreen(&self) -> bool {
|
||||
unsafe { (self.0.IsFullscreen.unwrap())() }
|
||||
}
|
||||
|
||||
/// Clears the frame that was sent with the last call to `submit.
|
||||
///
|
||||
/// This will cause the compositor to show the grid until `submit` is called again.
|
||||
pub fn clear_last_submitted_frame(&self) {
|
||||
unsafe { self.0.ClearLastSubmittedFrame.unwrap()() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@ -126,16 +131,17 @@ pub struct CompositorError(sys::EVRCompositorError);
|
||||
pub mod compositor_error {
|
||||
use super::*;
|
||||
|
||||
pub const REQUEST_FAILED: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_RequestFailed);
|
||||
pub const INCOMPATIBLE_VERSION: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_IncompatibleVersion);
|
||||
pub const DO_NOT_HAVE_FOCUS: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_DoNotHaveFocus);
|
||||
pub const INVALID_TEXTURE: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_InvalidTexture);
|
||||
pub const IS_NOT_SCENE_APPLICATION: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_IsNotSceneApplication);
|
||||
pub const TEXTURE_IS_ON_WRONG_DEVICE: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_TextureIsOnWrongDevice);
|
||||
pub const TEXTURE_USES_UNSUPPORTED_FORMAT: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_TextureUsesUnsupportedFormat);
|
||||
pub const SHARED_TEXTURES_NOT_SUPPORTED: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_SharedTexturesNotSupported);
|
||||
pub const INDEX_OUT_OF_RANGE: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_IndexOutOfRange);
|
||||
pub const ALREADY_SUBMITTED: CompositorError = CompositorError(sys::EVRCompositorError_EVRCompositorError_VRCompositorError_AlreadySubmitted);
|
||||
pub const REQUEST_FAILED: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_RequestFailed);
|
||||
pub const INCOMPATIBLE_VERSION: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_IncompatibleVersion);
|
||||
pub const DO_NOT_HAVE_FOCUS: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_DoNotHaveFocus);
|
||||
pub const INVALID_TEXTURE: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_InvalidTexture);
|
||||
pub const IS_NOT_SCENE_APPLICATION: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_IsNotSceneApplication);
|
||||
pub const TEXTURE_IS_ON_WRONG_DEVICE: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_TextureIsOnWrongDevice);
|
||||
pub const TEXTURE_USES_UNSUPPORTED_FORMAT: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_TextureUsesUnsupportedFormat);
|
||||
pub const SHARED_TEXTURES_NOT_SUPPORTED: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_SharedTexturesNotSupported);
|
||||
pub const INDEX_OUT_OF_RANGE: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_IndexOutOfRange);
|
||||
pub const ALREADY_SUBMITTED: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_AlreadySubmitted);
|
||||
pub const INVALID_BOUNDS: CompositorError = CompositorError(sys::EVRCompositorError_VRCompositorError_InvalidBounds);
|
||||
}
|
||||
|
||||
impl fmt::Debug for CompositorError {
|
||||
@ -158,6 +164,7 @@ impl error::Error for CompositorError {
|
||||
SHARED_TEXTURES_NOT_SUPPORTED => "SHARED_TEXTURES_NOT_SUPPORTED",
|
||||
INDEX_OUT_OF_RANGE => "INDEX_OUT_OF_RANGE",
|
||||
ALREADY_SUBMITTED => "ALREADY_SUBMITTED",
|
||||
INVALID_BOUNDS => "INVALID_BOUNDS",
|
||||
_ => "UNKNOWN",
|
||||
}
|
||||
}
|
||||
@ -168,8 +175,3 @@ impl fmt::Display for CompositorError {
|
||||
f.pad(error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub use sys::VkPhysicalDevice_T;
|
||||
pub use sys::VkDevice_T;
|
||||
pub use sys::VkInstance_T;
|
||||
pub use sys::VkQueue_T;
|
||||
|
@ -39,7 +39,7 @@ pub enum Handle {
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum ColorSpace {
|
||||
Auto = sys::EColorSpace_EColorSpace_ColorSpace_Auto as isize,
|
||||
Gamma = sys::EColorSpace_EColorSpace_ColorSpace_Gamma as isize,
|
||||
Linear = sys::EColorSpace_EColorSpace_ColorSpace_Linear as isize,
|
||||
Auto = sys::EColorSpace_ColorSpace_Auto as isize,
|
||||
Gamma = sys::EColorSpace_ColorSpace_Gamma as isize,
|
||||
Linear = sys::EColorSpace_ColorSpace_Linear as isize,
|
||||
}
|
||||
|
134
src/lib.rs
134
src/lib.rs
@ -1,39 +1,52 @@
|
||||
extern crate openvr_sys;
|
||||
|
||||
use std::sync::atomic::{Ordering, AtomicBool, ATOMIC_BOOL_INIT};
|
||||
use std::{fmt, error};
|
||||
use std::ffi::CStr;
|
||||
use std::{fmt, error, ptr, mem};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::cell::Cell;
|
||||
|
||||
use openvr_sys as sys;
|
||||
|
||||
mod tracking;
|
||||
|
||||
mod system;
|
||||
mod compositor;
|
||||
pub mod system;
|
||||
pub mod compositor;
|
||||
pub mod render_models;
|
||||
pub mod property;
|
||||
|
||||
pub use tracking::*;
|
||||
|
||||
pub use sys::VkPhysicalDevice_T;
|
||||
pub use sys::VkDevice_T;
|
||||
pub use sys::VkInstance_T;
|
||||
pub use sys::VkQueue_T;
|
||||
|
||||
static INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT;
|
||||
|
||||
/// Initialize OpenVR
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the library has already been initialized
|
||||
pub fn init(ty: ApplicationType) -> Result<Context, InitError> {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The `Context` MUST be dropped or shut down with `Context::shutdown` before shutting down the graphics API.
|
||||
pub unsafe fn init(ty: ApplicationType) -> Result<Context, InitError> {
|
||||
if INITIALIZED.swap(true, Ordering::Acquire) {
|
||||
panic!("OpenVR has already been initialized!");
|
||||
}
|
||||
|
||||
let mut error = sys::EVRInitError_EVRInitError_VRInitError_None;
|
||||
unsafe { sys::VR_InitInternal(&mut error, ty as sys::EVRApplicationType) };
|
||||
if error != sys::EVRInitError_EVRInitError_VRInitError_None {
|
||||
let mut error = sys::EVRInitError_VRInitError_None;
|
||||
sys::VR_InitInternal(&mut error, ty as sys::EVRApplicationType);
|
||||
if error != sys::EVRInitError_VRInitError_None {
|
||||
return Err(InitError(error));
|
||||
}
|
||||
if !unsafe { sys::VR_IsInterfaceVersionValid(sys::IVRSystem_Version.as_ptr() as *const i8) } {
|
||||
unsafe { sys::VR_ShutdownInternal() }
|
||||
return Err(InitError(sys::EVRInitError_EVRInitError_VRInitError_Init_InterfaceNotFound));
|
||||
if !sys::VR_IsInterfaceVersionValid(sys::IVRSystem_Version.as_ptr() as *const i8) {
|
||||
sys::VR_ShutdownInternal();
|
||||
return Err(InitError(sys::EVRInitError_VRInitError_Init_InterfaceNotFound));
|
||||
}
|
||||
Ok(Context {})
|
||||
Ok(Context { live: Cell::new(true) })
|
||||
}
|
||||
|
||||
pub struct System<'a>(&'a sys::VR_IVRSystem_FnTable);
|
||||
@ -43,15 +56,15 @@ pub struct RenderModels<'a>(&'a sys::VR_IVRRenderModels_FnTable);
|
||||
/// Entry points into OpenVR.
|
||||
///
|
||||
/// At most one of this object may exist at a time.
|
||||
pub struct Context {}
|
||||
pub struct Context { live: Cell<bool> }
|
||||
|
||||
fn load<T>(suffix: &[u8]) -> Result<*const T, InitError> {
|
||||
let mut magic = Vec::from(b"FnTable:".as_ref());
|
||||
magic.extend(suffix);
|
||||
let mut error = sys::EVRInitError_EVRInitError_VRInitError_None;
|
||||
let mut error = sys::EVRInitError_VRInitError_None;
|
||||
let result = unsafe { sys::VR_GetGenericInterface(magic.as_ptr() as *const i8, &mut error) };
|
||||
if error != sys::EVRInitError_EVRInitError_VRInitError_None {
|
||||
return Err(InitError(sys::EVRInitError_EVRInitError_VRInitError_Init_InterfaceNotFound));
|
||||
if error != sys::EVRInitError_VRInitError_None {
|
||||
return Err(InitError(sys::EVRInitError_VRInitError_Init_InterfaceNotFound));
|
||||
}
|
||||
Ok(result as *const T)
|
||||
}
|
||||
@ -64,31 +77,47 @@ impl Context {
|
||||
|
||||
impl Drop for Context {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::VR_ShutdownInternal() }
|
||||
unsafe { self.shutdown() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Shut down OpenVR. Repeated calls are safe.
|
||||
///
|
||||
/// Called implicitly by `Context::drop`. This MUST be called before shutting down the graphics API, or OpenVR may
|
||||
/// invoke undefined behavior.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// No OpenVR calls may be made after this has been called unless a new `Context` is subsequently constructed.
|
||||
pub unsafe fn shutdown(&self) {
|
||||
if self.live.replace(false) {
|
||||
sys::VR_ShutdownInternal();
|
||||
INITIALIZED.store(false, Ordering::Release);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum ApplicationType {
|
||||
/// Some other kind of application that isn't covered by the other entries
|
||||
Other = sys::EVRApplicationType_EVRApplicationType_VRApplication_Other as isize,
|
||||
Other = sys::EVRApplicationType_VRApplication_Other as isize,
|
||||
/// Application will submit 3D frames
|
||||
Scene = sys::EVRApplicationType_EVRApplicationType_VRApplication_Scene as isize,
|
||||
Scene = sys::EVRApplicationType_VRApplication_Scene as isize,
|
||||
/// Application only interacts with overlays
|
||||
Overlay = sys::EVRApplicationType_EVRApplicationType_VRApplication_Overlay as isize,
|
||||
Overlay = sys::EVRApplicationType_VRApplication_Overlay as isize,
|
||||
/// Application should not start SteamVR if it's not already running, and should not keep it running if everything
|
||||
/// else quits.
|
||||
Background = sys::EVRApplicationType_EVRApplicationType_VRApplication_Background as isize,
|
||||
Background = sys::EVRApplicationType_VRApplication_Background as isize,
|
||||
/// Init should not try to load any drivers. The application needs access to utility interfaces (like IVRSettings
|
||||
/// and IVRApplications) but not hardware.
|
||||
Utility = sys::EVRApplicationType_EVRApplicationType_VRApplication_Utility as isize,
|
||||
Utility = sys::EVRApplicationType_VRApplication_Utility as isize,
|
||||
/// Reserved for vrmonitor
|
||||
VRMonitor = sys::EVRApplicationType_EVRApplicationType_VRApplication_VRMonitor as isize,
|
||||
VRMonitor = sys::EVRApplicationType_VRApplication_VRMonitor as isize,
|
||||
/// Reserved for Steam
|
||||
SteamWatchdog = sys::EVRApplicationType_EVRApplicationType_VRApplication_SteamWatchdog as isize,
|
||||
SteamWatchdog = sys::EVRApplicationType_VRApplication_SteamWatchdog as isize,
|
||||
/// Start up SteamVR
|
||||
Bootstrapper = sys::EVRApplicationType_EVRApplicationType_VRApplication_Bootstrapper as isize,
|
||||
Bootstrapper = sys::EVRApplicationType_VRApplication_Bootstrapper as isize,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -120,6 +149,57 @@ impl fmt::Display for InitError {
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Eye {
|
||||
Left = sys::EVREye_EVREye_Eye_Left as isize,
|
||||
Right = sys::EVREye_EVREye_Eye_Right as isize,
|
||||
Left = sys::EVREye_Eye_Left as isize,
|
||||
Right = sys::EVREye_Eye_Right as isize,
|
||||
}
|
||||
|
||||
/// Helper to call OpenVR functions that return strings
|
||||
unsafe fn get_string<F: FnMut(*mut std::os::raw::c_char, u32) -> u32>(mut f: F) -> Option<CString> {
|
||||
let n = f(ptr::null_mut(), 0);
|
||||
if n == 0 { return None }
|
||||
let mut storage = Vec::new();
|
||||
storage.reserve_exact(n as usize);
|
||||
storage.resize(n as usize, mem::uninitialized());
|
||||
let n_ = f(storage.as_mut_ptr() as *mut _, n);
|
||||
assert!(n == n_);
|
||||
storage.truncate((n-1) as usize); // Strip trailing null
|
||||
Some(CString::from_vec_unchecked(storage))
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ControllerAxis {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ControllerState {
|
||||
pub packet_num: u32,
|
||||
pub button_pressed: u64,
|
||||
pub button_touched: u64,
|
||||
pub axis: [ControllerAxis; 5],
|
||||
}
|
||||
|
||||
pub mod button_id {
|
||||
use super::sys;
|
||||
pub const SYSTEM: sys::EVRButtonId = sys::EVRButtonId_k_EButton_System;
|
||||
pub const APPLICATION_MENU: sys::EVRButtonId = sys::EVRButtonId_k_EButton_ApplicationMenu;
|
||||
pub const GRIP: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Grip;
|
||||
pub const DPAD_LEFT: sys::EVRButtonId = sys::EVRButtonId_k_EButton_DPad_Left;
|
||||
pub const DPAD_UP: sys::EVRButtonId = sys::EVRButtonId_k_EButton_DPad_Up;
|
||||
pub const DPAD_RIGHT: sys::EVRButtonId = sys::EVRButtonId_k_EButton_DPad_Right;
|
||||
pub const DPAD_DOWN: sys::EVRButtonId = sys::EVRButtonId_k_EButton_DPad_Down;
|
||||
pub const A: sys::EVRButtonId = sys::EVRButtonId_k_EButton_A;
|
||||
pub const PROXIMITY_SENSOR: sys::EVRButtonId = sys::EVRButtonId_k_EButton_ProximitySensor;
|
||||
pub const AXIS0: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Axis0;
|
||||
pub const AXIS1: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Axis1;
|
||||
pub const AXIS2: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Axis2;
|
||||
pub const AXIS3: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Axis3;
|
||||
pub const AXIS4: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Axis4;
|
||||
pub const STEAM_VR_TOUCHPAD: sys::EVRButtonId = sys::EVRButtonId_k_EButton_SteamVR_Touchpad;
|
||||
pub const STEAM_VR_TRIGGER: sys::EVRButtonId = sys::EVRButtonId_k_EButton_SteamVR_Trigger;
|
||||
pub const DASHBOARD_BACK: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Dashboard_Back;
|
||||
pub const MAX: sys::EVRButtonId = sys::EVRButtonId_k_EButton_Max;
|
||||
}
|
||||
|
123
src/property.rs
Normal file
123
src/property.rs
Normal file
@ -0,0 +1,123 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use openvr_sys as sys;
|
||||
use super::TrackedDeviceProperty;
|
||||
|
||||
pub const Invalid: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Invalid;
|
||||
pub const TrackingSystemName_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_TrackingSystemName_String;
|
||||
pub const ModelNumber_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ModelNumber_String;
|
||||
pub const SerialNumber_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_SerialNumber_String;
|
||||
pub const RenderModelName_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_RenderModelName_String;
|
||||
pub const WillDriftInYaw_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_WillDriftInYaw_Bool;
|
||||
pub const ManufacturerName_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ManufacturerName_String;
|
||||
pub const TrackingFirmwareVersion_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_TrackingFirmwareVersion_String;
|
||||
pub const HardwareRevision_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HardwareRevision_String;
|
||||
pub const AllWirelessDongleDescriptions_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_AllWirelessDongleDescriptions_String;
|
||||
pub const ConnectedWirelessDongle_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ConnectedWirelessDongle_String;
|
||||
pub const DeviceIsWireless_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DeviceIsWireless_Bool;
|
||||
pub const DeviceIsCharging_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DeviceIsCharging_Bool;
|
||||
pub const DeviceBatteryPercentage_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DeviceBatteryPercentage_Float;
|
||||
pub const StatusDisplayTransform_Matrix34: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_StatusDisplayTransform_Matrix34;
|
||||
pub const Firmware_UpdateAvailable_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Firmware_UpdateAvailable_Bool;
|
||||
pub const Firmware_ManualUpdate_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Firmware_ManualUpdate_Bool;
|
||||
pub const Firmware_ManualUpdateURL_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Firmware_ManualUpdateURL_String;
|
||||
pub const HardwareRevision_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HardwareRevision_Uint64;
|
||||
pub const FirmwareVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_FirmwareVersion_Uint64;
|
||||
pub const FPGAVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_FPGAVersion_Uint64;
|
||||
pub const VRCVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_VRCVersion_Uint64;
|
||||
pub const RadioVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_RadioVersion_Uint64;
|
||||
pub const DongleVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DongleVersion_Uint64;
|
||||
pub const BlockServerShutdown_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_BlockServerShutdown_Bool;
|
||||
pub const CanUnifyCoordinateSystemWithHmd_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_CanUnifyCoordinateSystemWithHmd_Bool;
|
||||
pub const ContainsProximitySensor_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ContainsProximitySensor_Bool;
|
||||
pub const DeviceProvidesBatteryStatus_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DeviceProvidesBatteryStatus_Bool;
|
||||
pub const DeviceCanPowerOff_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DeviceCanPowerOff_Bool;
|
||||
pub const Firmware_ProgrammingTarget_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Firmware_ProgrammingTarget_String;
|
||||
pub const DeviceClass_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DeviceClass_Int32;
|
||||
pub const HasCamera_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HasCamera_Bool;
|
||||
pub const DriverVersion_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DriverVersion_String;
|
||||
pub const Firmware_ForceUpdateRequired_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Firmware_ForceUpdateRequired_Bool;
|
||||
pub const ViveSystemButtonFixRequired_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ViveSystemButtonFixRequired_Bool;
|
||||
pub const ParentDriver_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ParentDriver_Uint64;
|
||||
pub const ResourceRoot_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ResourceRoot_String;
|
||||
pub const ReportsTimeSinceVSync_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ReportsTimeSinceVSync_Bool;
|
||||
pub const SecondsFromVsyncToPhotons_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float;
|
||||
pub const DisplayFrequency_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayFrequency_Float;
|
||||
pub const UserIpdMeters_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_UserIpdMeters_Float;
|
||||
pub const CurrentUniverseId_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_CurrentUniverseId_Uint64;
|
||||
pub const PreviousUniverseId_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_PreviousUniverseId_Uint64;
|
||||
pub const DisplayFirmwareVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayFirmwareVersion_Uint64;
|
||||
pub const IsOnDesktop_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_IsOnDesktop_Bool;
|
||||
pub const DisplayMCType_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCType_Int32;
|
||||
pub const DisplayMCOffset_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCOffset_Float;
|
||||
pub const DisplayMCScale_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCScale_Float;
|
||||
pub const EdidVendorID_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_EdidVendorID_Int32;
|
||||
pub const DisplayMCImageLeft_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCImageLeft_String;
|
||||
pub const DisplayMCImageRight_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCImageRight_String;
|
||||
pub const DisplayGCBlackClamp_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayGCBlackClamp_Float;
|
||||
pub const EdidProductID_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_EdidProductID_Int32;
|
||||
pub const CameraToHeadTransform_Matrix34: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_CameraToHeadTransform_Matrix34;
|
||||
pub const DisplayGCType_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayGCType_Int32;
|
||||
pub const DisplayGCOffset_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayGCOffset_Float;
|
||||
pub const DisplayGCScale_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayGCScale_Float;
|
||||
pub const DisplayGCPrescale_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayGCPrescale_Float;
|
||||
pub const DisplayGCImage_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayGCImage_String;
|
||||
pub const LensCenterLeftU_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_LensCenterLeftU_Float;
|
||||
pub const LensCenterLeftV_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_LensCenterLeftV_Float;
|
||||
pub const LensCenterRightU_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_LensCenterRightU_Float;
|
||||
pub const LensCenterRightV_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_LensCenterRightV_Float;
|
||||
pub const UserHeadToEyeDepthMeters_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_UserHeadToEyeDepthMeters_Float;
|
||||
pub const CameraFirmwareVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_CameraFirmwareVersion_Uint64;
|
||||
pub const CameraFirmwareDescription_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_CameraFirmwareDescription_String;
|
||||
pub const DisplayFPGAVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayFPGAVersion_Uint64;
|
||||
pub const DisplayBootloaderVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayBootloaderVersion_Uint64;
|
||||
pub const DisplayHardwareVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayHardwareVersion_Uint64;
|
||||
pub const AudioFirmwareVersion_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_AudioFirmwareVersion_Uint64;
|
||||
pub const CameraCompatibilityMode_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_CameraCompatibilityMode_Int32;
|
||||
pub const ScreenshotHorizontalFieldOfViewDegrees_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ScreenshotHorizontalFieldOfViewDegrees_Float;
|
||||
pub const ScreenshotVerticalFieldOfViewDegrees_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ScreenshotVerticalFieldOfViewDegrees_Float;
|
||||
pub const DisplaySuppressed_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplaySuppressed_Bool;
|
||||
pub const DisplayAllowNightMode_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayAllowNightMode_Bool;
|
||||
pub const DisplayMCImageWidth_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCImageWidth_Int32;
|
||||
pub const DisplayMCImageHeight_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCImageHeight_Int32;
|
||||
pub const DisplayMCImageNumChannels_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCImageNumChannels_Int32;
|
||||
pub const DisplayMCImageData_Binary: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayMCImageData_Binary;
|
||||
pub const SecondsFromPhotonsToVblank_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_SecondsFromPhotonsToVblank_Float;
|
||||
pub const DriverDirectModeSendsVsyncEvents_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DriverDirectModeSendsVsyncEvents_Bool;
|
||||
pub const DisplayDebugMode_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayDebugMode_Bool;
|
||||
pub const GraphicsAdapterLuid_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_GraphicsAdapterLuid_Uint64;
|
||||
pub const AttachedDeviceId_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_AttachedDeviceId_String;
|
||||
pub const SupportedButtons_Uint64: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_SupportedButtons_Uint64;
|
||||
pub const Axis0Type_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Axis0Type_Int32;
|
||||
pub const Axis1Type_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Axis1Type_Int32;
|
||||
pub const Axis2Type_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Axis2Type_Int32;
|
||||
pub const Axis3Type_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Axis3Type_Int32;
|
||||
pub const Axis4Type_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_Axis4Type_Int32;
|
||||
pub const ControllerRoleHint_Int32: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ControllerRoleHint_Int32;
|
||||
pub const FieldOfViewLeftDegrees_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_FieldOfViewLeftDegrees_Float;
|
||||
pub const FieldOfViewRightDegrees_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_FieldOfViewRightDegrees_Float;
|
||||
pub const FieldOfViewTopDegrees_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_FieldOfViewTopDegrees_Float;
|
||||
pub const FieldOfViewBottomDegrees_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_FieldOfViewBottomDegrees_Float;
|
||||
pub const TrackingRangeMinimumMeters_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_TrackingRangeMinimumMeters_Float;
|
||||
pub const TrackingRangeMaximumMeters_Float: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_TrackingRangeMaximumMeters_Float;
|
||||
pub const ModeLabel_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_ModeLabel_String;
|
||||
pub const IconPathName_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_IconPathName_String;
|
||||
pub const NamedIconPathDeviceOff_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceOff_String;
|
||||
pub const NamedIconPathDeviceSearching_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceSearching_String;
|
||||
pub const NamedIconPathDeviceSearchingAlert_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceSearchingAlert_String;
|
||||
pub const NamedIconPathDeviceReady_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceReady_String;
|
||||
pub const NamedIconPathDeviceReadyAlert_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceReadyAlert_String;
|
||||
pub const NamedIconPathDeviceNotReady_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceNotReady_String;
|
||||
pub const NamedIconPathDeviceStandby_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceStandby_String;
|
||||
pub const NamedIconPathDeviceAlertLow_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_NamedIconPathDeviceAlertLow_String;
|
||||
pub const DisplayHiddenArea_Binary_Start: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_Start;
|
||||
pub const DisplayHiddenArea_Binary_End: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_End;
|
||||
pub const UserConfigPath_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_UserConfigPath_String;
|
||||
pub const InstallPath_String: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_InstallPath_String;
|
||||
pub const HasDisplayComponent_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HasDisplayComponent_Bool;
|
||||
pub const HasControllerComponent_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HasControllerComponent_Bool;
|
||||
pub const HasCameraComponent_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HasCameraComponent_Bool;
|
||||
pub const HasDriverDirectModeComponent_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HasDriverDirectModeComponent_Bool;
|
||||
pub const HasVirtualDisplayComponent_Bool: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_HasVirtualDisplayComponent_Bool;
|
||||
pub const VendorSpecific_Reserved_Start: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_Start;
|
||||
pub const VendorSpecific_Reserved_End: TrackedDeviceProperty = sys::ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_End;
|
@ -1,225 +1,261 @@
|
||||
use openvr_sys;
|
||||
use openvr_sys::EVRRenderModelError::*;
|
||||
use std::{fmt, ptr, slice, mem};
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use std::string::String;
|
||||
use std::ptr::null_mut;
|
||||
use std::slice;
|
||||
use subsystems::render_models;
|
||||
use error::*;
|
||||
use openvr_sys as sys;
|
||||
|
||||
pub struct IVRRenderModels(pub *const ());
|
||||
use {RenderModels, ControllerState, get_string};
|
||||
|
||||
pub struct RenderModel(*mut openvr_sys::RenderModel_t);
|
||||
pub struct RenderModelTexture(*mut openvr_sys::RenderModel_TextureMap_t);
|
||||
|
||||
trait AsyncError {
|
||||
/// checks if result is currently loading
|
||||
fn is_loading(&self) -> bool;
|
||||
}
|
||||
|
||||
impl AsyncError for Error<openvr_sys::EVRRenderModelError> {
|
||||
fn is_loading(&self) -> bool {
|
||||
match self.to_raw() {
|
||||
EVRRenderModelError_VRRenderModelError_Loading => {
|
||||
true
|
||||
},
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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::VR_IVRRenderModels_FnTable};
|
||||
models.FreeRenderModel.unwrap()(
|
||||
self.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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::VR_IVRRenderModels_FnTable};
|
||||
models.FreeTexture.unwrap()(
|
||||
self.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderModel {
|
||||
/// Returns an iterator that iterates over vertices
|
||||
pub fn vertex_iter(&self) -> slice::Iter<openvr_sys::RenderModel_Vertex_t> {
|
||||
unsafe {
|
||||
let slice = slice::from_raw_parts((*self.0).rVertexData, (*self.0).unVertexCount as usize);
|
||||
slice.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator that iterates over indices
|
||||
pub fn index_iter(&self) -> slice::Iter<u16> {
|
||||
unsafe {
|
||||
let slice = slice::from_raw_parts((*self.0).rIndexData, (*self.0).unTriangleCount as usize * 3);
|
||||
slice.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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<RenderModelTexture, Error<openvr_sys::EVRRenderModelError>> {
|
||||
unsafe {
|
||||
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()(
|
||||
(*self.0).diffuseTextureId,
|
||||
&mut resp
|
||||
);
|
||||
|
||||
match err {
|
||||
EVRRenderModelError_VRRenderModelError_None => {
|
||||
Ok(RenderModelTexture (resp))
|
||||
},
|
||||
_ => {
|
||||
Err(Error::from_raw(err))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// loads the texture for current model
|
||||
pub fn load_texture(&self) -> Result<RenderModelTexture, Error<openvr_sys::EVRRenderModelError>> {
|
||||
use std;
|
||||
|
||||
loop {
|
||||
let result = self.load_texture_async();
|
||||
match result {
|
||||
Ok(texture) => {
|
||||
return Ok(texture);
|
||||
},
|
||||
Err(err) => {
|
||||
if !err.is_loading() {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderModelTexture {
|
||||
/// Returns the dimension from the texture (width, height)
|
||||
pub fn dimension(&self) -> (usize, usize) {
|
||||
unsafe {
|
||||
((*self.0).unWidth as usize, (*self.0).unHeight as usize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a 1 dimensional vector of pixels, format: rgba@32
|
||||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
unsafe {
|
||||
let dimension = self.dimension();
|
||||
let slice = slice::from_raw_parts((*self.0).rubTextureMapData, dimension.0 * dimension.1 * 4);
|
||||
let mut vec = Vec::new();
|
||||
vec.extend_from_slice(slice);
|
||||
vec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IVRRenderModels {
|
||||
pub unsafe fn from_raw(ptr: *const ()) -> Self {
|
||||
IVRRenderModels(ptr as *mut ())
|
||||
}
|
||||
|
||||
/// Returns the amount of render models available
|
||||
pub fn get_count(&self) -> u32 {
|
||||
unsafe {
|
||||
let models = * { self.0 as *mut openvr_sys::VR_IVRRenderModels_FnTable};
|
||||
|
||||
models.GetRenderModelCount.unwrap()()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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::VR_IVRRenderModels_FnTable};
|
||||
let name_out = String::with_capacity(256);
|
||||
|
||||
let size = models.GetRenderModelName.unwrap()(
|
||||
index,
|
||||
name_out.as_ptr() as *mut i8,
|
||||
256
|
||||
);
|
||||
|
||||
if size > 0 {
|
||||
return String::from_raw_parts(name_out.as_ptr() as *mut _, (size - 1) as usize, (size - 1) as usize);
|
||||
} else {
|
||||
return String::from("");
|
||||
}
|
||||
impl<'a> RenderModels<'a> {
|
||||
/// Loads and returns a render model for use in the application. `name` should be a render model name from the
|
||||
/// `RenderModelName_String` property or an absolute path name to a render model on disk.
|
||||
///
|
||||
/// The method returns `Ok(None)` while the render model is still being loaded. Call it at regular intervals until
|
||||
/// it returns `Ok(Some(model))`.
|
||||
pub fn load_render_model(&self, name: &CStr) -> Result<Option<Model>> {
|
||||
let mut ptr = ptr::null_mut();
|
||||
let r = unsafe {
|
||||
self.0.LoadRenderModel_Async.unwrap()(name.as_ptr() as *mut _, &mut ptr)
|
||||
};
|
||||
}
|
||||
|
||||
/// Loads an render model into local memory
|
||||
/// blocks the thread and waits until driver responds with model
|
||||
pub fn load(&self, name: String) -> Result<RenderModel, Error<openvr_sys::EVRRenderModelError>> {
|
||||
use std;
|
||||
|
||||
loop {
|
||||
let result = self.load_async(name.clone());
|
||||
match result {
|
||||
Ok(model) => {
|
||||
return Ok(model);
|
||||
},
|
||||
Err(err) => {
|
||||
if !err.is_loading() {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
match Error(r) {
|
||||
error::NONE => Ok(Some(Model { ptr: ptr, sys: self.0 })),
|
||||
error::LOADING => Ok(None),
|
||||
x => Err(x),
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads an render model into local memory
|
||||
/// When called for the first time openvr will start to load the model into memory
|
||||
/// In the mean time this call will respond with EVRRenderModelError_VRRenderModelError_Loading
|
||||
/// It is designed to be used wihtin the render loop as it won't block the user, for sync usage use load()
|
||||
pub fn load_async(&self, name: String) -> Result<RenderModel, Error<openvr_sys::EVRRenderModelError>> {
|
||||
use std;
|
||||
/// Returns the number of components of the specified render model.
|
||||
///
|
||||
/// Components are useful when client application wish to draw, label, or otherwise interact with components of tracked objects.
|
||||
/// Examples controller components:
|
||||
/// renderable things such as triggers, buttons
|
||||
/// non-renderable things which include coordinate systems such as 'tip', 'base', a neutral controller agnostic hand-pose
|
||||
/// If all controller components are enumerated and rendered, it will be equivalent to drawing the traditional render model
|
||||
/// Returns 0 if components not supported, >0 otherwise
|
||||
pub fn component_count(&self, model: &CStr) -> u32 {
|
||||
unsafe { self.0.GetComponentCount.unwrap()(model.as_ptr() as *mut _) }
|
||||
}
|
||||
|
||||
/// Get the names of available components.
|
||||
///
|
||||
/// `component` does not correlate to a tracked device index, but is only used for iterating over all available
|
||||
/// components. If it's out of range, this function will return None.
|
||||
pub fn component_name(&self, model: &CStr, component: u32) -> Option<CString> {
|
||||
unsafe { get_string(|ptr, n| self.0.GetComponentName.unwrap()(model.as_ptr() as *mut _, component, ptr, n)) }
|
||||
}
|
||||
|
||||
/// Gets all component names of a given model
|
||||
pub fn component_names(&self, model: &CStr) -> ::std::vec::IntoIter<CString> { // FIXME: impl Iterator rather than allocating
|
||||
let n = self.component_count(model);
|
||||
(0..n).map(|i| self.component_name(model, i).expect("inconsistent component presence reported by OpenVR")).collect::<Vec<_>>().into_iter()
|
||||
}
|
||||
|
||||
/// Use this to get the render model name for the specified rendermodel/component combination, to be passed to
|
||||
/// `load_render_model`.
|
||||
///
|
||||
/// If the component name is out of range, this function will return None.
|
||||
/// Otherwise, it will return the size of the buffer required for the name.
|
||||
pub fn component_render_model_name(&self, model: &CStr, component: &CStr) -> Option<CString> {
|
||||
unsafe {
|
||||
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();
|
||||
|
||||
let err = models.LoadRenderModel_Async.unwrap()(
|
||||
rawname,
|
||||
&mut resp
|
||||
);
|
||||
|
||||
let _ = std::ffi::CString::from_raw(rawname);
|
||||
|
||||
match err {
|
||||
EVRRenderModelError_VRRenderModelError_None => {
|
||||
Ok(RenderModel ( resp ))
|
||||
},
|
||||
_ => {
|
||||
Err(Error::from_raw(err))
|
||||
get_string(|ptr, n| self.0.GetComponentRenderModelName.unwrap()(
|
||||
model.as_ptr() as *mut _, component.as_ptr() as *mut _, ptr, n))
|
||||
}
|
||||
}
|
||||
|
||||
/// Use this to query information about the component, as a function of the controller state.
|
||||
///
|
||||
/// Returns None if the component is invalid.
|
||||
///
|
||||
/// Check `ComponentState::is_visible()` to determine whether the returned component should be rendered.
|
||||
///
|
||||
/// For dynamic controller components (ex: trigger) values will reflect component motions.
|
||||
/// For static components this will return a consistent value independent of the `ControllerState`.
|
||||
pub fn component_state(&self, model: &CStr, component: &CStr, state: &ControllerState, mode: &ControllerMode) -> Option<ComponentState> {
|
||||
unsafe {
|
||||
let mut out = mem::uninitialized();
|
||||
if self.0.GetComponentState.unwrap()(model.as_ptr() as *mut _, component.as_ptr() as *mut _,
|
||||
state as *const _ as *mut _, mode as *const _ as *mut _,
|
||||
&mut out as *mut _ as *mut _) {
|
||||
Some(out)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads and returns a texture for use in the application. Texture IDs can be obtained from
|
||||
/// `Model::diffuse_texture_id()`.
|
||||
///
|
||||
/// The method returns `Ok(None)` while the texture is still being loaded. Call it at regular intervals until it
|
||||
/// returns `Ok(Some(texture))`.
|
||||
pub fn load_texture(&self, id: TextureId) -> Result<Option<Texture>> {
|
||||
let mut ptr = ptr::null_mut();
|
||||
let r = unsafe {
|
||||
self.0.LoadTexture_Async.unwrap()(id, &mut ptr)
|
||||
};
|
||||
match Error(r) {
|
||||
error::NONE => Ok(Some(Texture { ptr: ptr, sys: self.0 })),
|
||||
error::LOADING => Ok(None),
|
||||
x => Err(x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub struct Error(sys::EVRRenderModelError);
|
||||
|
||||
pub mod error {
|
||||
use super::{sys, Error};
|
||||
|
||||
pub const NONE: Error = Error(sys::EVRRenderModelError_VRRenderModelError_None);
|
||||
pub const LOADING: Error = Error(sys::EVRRenderModelError_VRRenderModelError_Loading);
|
||||
pub const NOT_SUPPORTED: Error = Error(sys::EVRRenderModelError_VRRenderModelError_NotSupported);
|
||||
pub const INVALID_ARG: Error = Error(sys::EVRRenderModelError_VRRenderModelError_InvalidArg);
|
||||
pub const INVALID_MODEL: Error = Error(sys::EVRRenderModelError_VRRenderModelError_InvalidModel);
|
||||
pub const NO_SHAPES: Error = Error(sys::EVRRenderModelError_VRRenderModelError_NoShapes);
|
||||
pub const MULTIPLE_SHAPES: Error = Error(sys::EVRRenderModelError_VRRenderModelError_MultipleShapes);
|
||||
pub const TOO_MANY_VERTICES: Error = Error(sys::EVRRenderModelError_VRRenderModelError_TooManyVertices);
|
||||
pub const MULTIPLE_TEXTURES: Error = Error(sys::EVRRenderModelError_VRRenderModelError_MultipleTextures);
|
||||
pub const BUFFER_TOO_SMALL: Error = Error(sys::EVRRenderModelError_VRRenderModelError_BufferTooSmall);
|
||||
pub const NOT_ENOUGH_NORMALS: Error = Error(sys::EVRRenderModelError_VRRenderModelError_NotEnoughNormals);
|
||||
pub const NOT_ENOUGH_TEX_COORDS: Error = Error(sys::EVRRenderModelError_VRRenderModelError_NotEnoughTexCoords);
|
||||
pub const INVALID_TEXTURE: Error = Error(sys::EVRRenderModelError_VRRenderModelError_InvalidTexture);
|
||||
}
|
||||
|
||||
impl fmt::Debug for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad(::std::error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
use self::error::*;
|
||||
match *self {
|
||||
NONE => "NONE",
|
||||
LOADING => "LOADING",
|
||||
NOT_SUPPORTED => "NOT_SUPPORTED",
|
||||
INVALID_ARG => "INVALID_ARG",
|
||||
INVALID_MODEL => "INVALID_MODEL",
|
||||
NO_SHAPES => "NO_SHAPES",
|
||||
MULTIPLE_SHAPES => "MULTIPLE_SHAPES",
|
||||
TOO_MANY_VERTICES => "TOO_MANY_VERTICES",
|
||||
MULTIPLE_TEXTURES => "MULTIPLE_TEXTURES",
|
||||
BUFFER_TOO_SMALL => "BUFFER_TOO_SMALL",
|
||||
NOT_ENOUGH_NORMALS => "NOT_ENOUGH_NORMALS",
|
||||
NOT_ENOUGH_TEX_COORDS => "NOT_ENOUGH_TEX_COORDS",
|
||||
INVALID_TEXTURE => "INVALID_TEXTURE",
|
||||
_ => "UNKNOWN",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad(::std::error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = ::std::result::Result<T, Error>;
|
||||
|
||||
/// 3D geometry for rendering as an indexed triangle list
|
||||
pub struct Model<'a> {
|
||||
ptr: *mut sys::RenderModel_t,
|
||||
sys: &'a sys::VR_IVRRenderModels_FnTable,
|
||||
}
|
||||
|
||||
impl<'a> Model<'a> {
|
||||
pub fn vertices(&self) -> &[Vertex] {
|
||||
unsafe {
|
||||
let model = &*self.ptr;
|
||||
slice::from_raw_parts(model.rVertexData as *mut Vertex, model.unVertexCount as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indices(&self) -> &[u16] {
|
||||
unsafe {
|
||||
let model = &*self.ptr;
|
||||
slice::from_raw_parts(model.rIndexData, 3 * model.unTriangleCount as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn diffuse_texture_id(&self) -> Option<TextureId> {
|
||||
let id = unsafe { (&*self.ptr).diffuseTextureId };
|
||||
if id < 0 { None } else { Some(id) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for Model<'a> {
|
||||
fn drop(&mut self) { unsafe { self.sys.FreeRenderModel.unwrap()(self.ptr) } }
|
||||
}
|
||||
|
||||
pub struct Texture<'a> {
|
||||
ptr: *mut sys::RenderModel_TextureMap_t,
|
||||
sys: &'a sys::VR_IVRRenderModels_FnTable,
|
||||
}
|
||||
|
||||
impl<'a> Texture<'a> {
|
||||
pub fn dimensions(&self) -> (u16, u16) {
|
||||
let tex = unsafe { &*self.ptr };
|
||||
(tex.unWidth, tex.unHeight)
|
||||
}
|
||||
|
||||
/// R8G8B8A8
|
||||
pub fn data(&self) -> &[u8] {
|
||||
unsafe {
|
||||
let tex = &*self.ptr;
|
||||
slice::from_raw_parts(tex.rubTextureMapData, tex.unWidth as usize * tex.unHeight as usize * 4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for Texture<'a> {
|
||||
fn drop(&mut self) { unsafe { self.sys.FreeTexture.unwrap()(self.ptr) } }
|
||||
}
|
||||
|
||||
pub type TextureId = sys::TextureID_t;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Vertex {
|
||||
pub position: [f32; 3],
|
||||
pub normal: [f32; 3],
|
||||
pub texture_coord: [f32; 2],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ControllerMode {
|
||||
pub scroll_wheel_visible: bool,
|
||||
}
|
||||
|
||||
impl Default for ControllerMode {
|
||||
fn default() -> Self { ControllerMode { scroll_wheel_visible: false } }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ComponentState {
|
||||
pub tracking_to_component_render_model: [[f32; 4]; 3],
|
||||
pub tracking_to_component_local: [[f32; 4]; 3],
|
||||
pub properties: ComponentProperties,
|
||||
}
|
||||
|
||||
impl ComponentState {
|
||||
pub fn is_static(&self) -> bool { self.properties & component_properties::IS_STATIC != 0 }
|
||||
pub fn is_visible(&self) -> bool { self.properties & component_properties::IS_VISIBLE != 0 }
|
||||
pub fn is_touched(&self) -> bool { self.properties & component_properties::IS_TOUCHED != 0 }
|
||||
pub fn is_pressed(&self) -> bool { self.properties & component_properties::IS_PRESSED != 0 }
|
||||
pub fn is_scrolled(&self) -> bool { self.properties & component_properties::IS_SCROLLED != 0 }
|
||||
}
|
||||
|
||||
type ComponentProperties = sys::VRComponentProperties;
|
||||
|
||||
pub mod component_properties {
|
||||
use super::{sys, ComponentProperties};
|
||||
|
||||
pub const IS_STATIC: ComponentProperties = sys::EVRComponentProperty_VRComponentProperty_IsStatic;
|
||||
pub const IS_VISIBLE: ComponentProperties = sys::EVRComponentProperty_VRComponentProperty_IsVisible;
|
||||
pub const IS_TOUCHED: ComponentProperties = sys::EVRComponentProperty_VRComponentProperty_IsTouched;
|
||||
pub const IS_PRESSED: ComponentProperties = sys::EVRComponentProperty_VRComponentProperty_IsPressed;
|
||||
pub const IS_SCROLLED: ComponentProperties = sys::EVRComponentProperty_VRComponentProperty_IsScrolled;
|
||||
}
|
||||
|
@ -271,6 +271,7 @@ pub enum Event {
|
||||
Notification_BeginInteraction,
|
||||
Notification_Destroyed,
|
||||
|
||||
/// The application has been asked to quit
|
||||
Quit(Process),
|
||||
ProcessQuit(Process),
|
||||
QuitAborted_UserPrompt(Process),
|
||||
@ -345,116 +346,116 @@ impl Event {
|
||||
|
||||
#[allow(deprecated)]
|
||||
match ty {
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedDeviceActivated => TrackedDeviceActivated,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedDeviceDeactivated => TrackedDeviceDeactivated,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedDeviceUpdated => TrackedDeviceUpdated,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedDeviceUserInteractionStarted => TrackedDeviceUserInteractionStarted,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedDeviceUserInteractionEnded => TrackedDeviceUserInteractionEnded,
|
||||
sys::EVREventType_EVREventType_VREvent_IpdChanged => IpdChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_EnterStandbyMode => EnterStandbyMode,
|
||||
sys::EVREventType_EVREventType_VREvent_LeaveStandbyMode => LeaveStandbyMode,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedDeviceRoleChanged => TrackedDeviceRoleChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_WatchdogWakeUpRequested => WatchdogWakeUpRequested,
|
||||
sys::EVREventType_EVREventType_VREvent_LensDistortionChanged => LensDistortionChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_PropertyChanged => PropertyChanged(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_ButtonPress => ButtonPress(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_ButtonUnpress => ButtonUnpress(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_ButtonTouch => ButtonTouch(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_ButtonUntouch => ButtonUntouch(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_MouseMove => MouseMove(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_MouseButtonDown => MouseButtonDown(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_MouseButtonUp => MouseButtonUp(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_FocusEnter => FocusEnter(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_FocusLeave => FocusLeave(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_Scroll => Scroll(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_TouchPadMove => TouchPadMove(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_OverlayFocusChanged => OverlayFocusChanged(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_InputFocusCaptured => InputFocusCaptured(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_InputFocusReleased => InputFocusReleased(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_SceneFocusLost => SceneFocusLost(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_SceneFocusGained => SceneFocusGained(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_SceneApplicationChanged => SceneApplicationChanged(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_SceneFocusChanged => SceneFocusChanged(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_InputFocusChanged => InputFocusChanged(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_SceneApplicationSecondaryRenderingStarted => SceneApplicationSecondaryRenderingStarted(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_HideRenderModels => HideRenderModels,
|
||||
sys::EVREventType_EVREventType_VREvent_ShowRenderModels => ShowRenderModels,
|
||||
sys::EVREventType_EVREventType_VREvent_OverlayShown => OverlayShown,
|
||||
sys::EVREventType_EVREventType_VREvent_OverlayHidden => OverlayHidden,
|
||||
sys::EVREventType_EVREventType_VREvent_DashboardActivated => DashboardActivated,
|
||||
sys::EVREventType_EVREventType_VREvent_DashboardDeactivated => DashboardDeactivated,
|
||||
sys::EVREventType_EVREventType_VREvent_DashboardThumbSelected => DashboardThumbSelected,
|
||||
sys::EVREventType_EVREventType_VREvent_DashboardRequested => DashboardRequested,
|
||||
sys::EVREventType_EVREventType_VREvent_ResetDashboard => ResetDashboard,
|
||||
sys::EVREventType_EVREventType_VREvent_RenderToast => RenderToast,
|
||||
sys::EVREventType_EVREventType_VREvent_ImageLoaded => ImageLoaded,
|
||||
sys::EVREventType_EVREventType_VREvent_ShowKeyboard => ShowKeyboard,
|
||||
sys::EVREventType_EVREventType_VREvent_HideKeyboard => HideKeyboard,
|
||||
sys::EVREventType_EVREventType_VREvent_OverlayGamepadFocusGained => OverlayGamepadFocusGained,
|
||||
sys::EVREventType_EVREventType_VREvent_OverlayGamepadFocusLost => OverlayGamepadFocusLost,
|
||||
sys::EVREventType_EVREventType_VREvent_OverlaySharedTextureChanged => OverlaySharedTextureChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_DashboardGuideButtonDown => DashboardGuideButtonDown,
|
||||
sys::EVREventType_EVREventType_VREvent_DashboardGuideButtonUp => DashboardGuideButtonUp,
|
||||
sys::EVREventType_EVREventType_VREvent_ScreenshotTriggered => ScreenshotTriggered,
|
||||
sys::EVREventType_EVREventType_VREvent_ImageFailed => ImageFailed,
|
||||
sys::EVREventType_EVREventType_VREvent_DashboardOverlayCreated => DashboardOverlayCreated,
|
||||
sys::EVREventType_EVREventType_VREvent_RequestScreenshot => RequestScreenshot,
|
||||
sys::EVREventType_EVREventType_VREvent_ScreenshotTaken => ScreenshotTaken,
|
||||
sys::EVREventType_EVREventType_VREvent_ScreenshotFailed => ScreenshotFailed,
|
||||
sys::EVREventType_EVREventType_VREvent_SubmitScreenshotToDashboard => SubmitScreenshotToDashboard,
|
||||
sys::EVREventType_EVREventType_VREvent_ScreenshotProgressToDashboard => ScreenshotProgressToDashboard,
|
||||
sys::EVREventType_EVREventType_VREvent_PrimaryDashboardDeviceChanged => PrimaryDashboardDeviceChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_Notification_Shown => Notification_Shown,
|
||||
sys::EVREventType_EVREventType_VREvent_Notification_Hidden => Notification_Hidden,
|
||||
sys::EVREventType_EVREventType_VREvent_Notification_BeginInteraction => Notification_BeginInteraction,
|
||||
sys::EVREventType_EVREventType_VREvent_Notification_Destroyed => Notification_Destroyed,
|
||||
sys::EVREventType_EVREventType_VREvent_Quit => Quit(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_ProcessQuit => ProcessQuit(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_QuitAborted_UserPrompt => QuitAborted_UserPrompt(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_QuitAcknowledged => QuitAcknowledged(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_DriverRequestedQuit => DriverRequestedQuit,
|
||||
sys::EVREventType_EVREventType_VREvent_ChaperoneDataHasChanged => ChaperoneDataHasChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_ChaperoneUniverseHasChanged => ChaperoneUniverseHasChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_ChaperoneTempDataHasChanged => ChaperoneTempDataHasChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_ChaperoneSettingsHaveChanged => ChaperoneSettingsHaveChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_SeatedZeroPoseReset => SeatedZeroPoseReset,
|
||||
sys::EVREventType_EVREventType_VREvent_AudioSettingsHaveChanged => AudioSettingsHaveChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_BackgroundSettingHasChanged => BackgroundSettingHasChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_CameraSettingsHaveChanged => CameraSettingsHaveChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_ReprojectionSettingHasChanged => ReprojectionSettingHasChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_ModelSkinSettingsHaveChanged => ModelSkinSettingsHaveChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_EnvironmentSettingsHaveChanged => EnvironmentSettingsHaveChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_PowerSettingsHaveChanged => PowerSettingsHaveChanged,
|
||||
sys::EVREventType_EVREventType_VREvent_StatusUpdate => StatusUpdate,
|
||||
sys::EVREventType_EVREventType_VREvent_MCImageUpdated => MCImageUpdated,
|
||||
sys::EVREventType_EVREventType_VREvent_FirmwareUpdateStarted => FirmwareUpdateStarted,
|
||||
sys::EVREventType_EVREventType_VREvent_FirmwareUpdateFinished => FirmwareUpdateFinished,
|
||||
sys::EVREventType_EVREventType_VREvent_KeyboardClosed => KeyboardClosed,
|
||||
sys::EVREventType_EVREventType_VREvent_KeyboardCharInput => KeyboardCharInput(get(data)),
|
||||
sys::EVREventType_EVREventType_VREvent_KeyboardDone => KeyboardDone,
|
||||
sys::EVREventType_EVREventType_VREvent_ApplicationTransitionStarted => ApplicationTransitionStarted,
|
||||
sys::EVREventType_EVREventType_VREvent_ApplicationTransitionAborted => ApplicationTransitionAborted,
|
||||
sys::EVREventType_EVREventType_VREvent_ApplicationTransitionNewAppStarted => ApplicationTransitionNewAppStarted,
|
||||
sys::EVREventType_EVREventType_VREvent_ApplicationListUpdated => ApplicationListUpdated,
|
||||
sys::EVREventType_EVREventType_VREvent_ApplicationMimeTypeLoad => ApplicationMimeTypeLoad,
|
||||
sys::EVREventType_EVREventType_VREvent_ApplicationTransitionNewAppLaunchComplete => ApplicationTransitionNewAppLaunchComplete,
|
||||
sys::EVREventType_EVREventType_VREvent_ProcessConnected => ProcessConnected,
|
||||
sys::EVREventType_EVREventType_VREvent_ProcessDisconnected => ProcessDisconnected,
|
||||
sys::EVREventType_EVREventType_VREvent_Compositor_MirrorWindowShown => Compositor_MirrorWindowShown,
|
||||
sys::EVREventType_EVREventType_VREvent_Compositor_MirrorWindowHidden => Compositor_MirrorWindowHidden,
|
||||
sys::EVREventType_EVREventType_VREvent_Compositor_ChaperoneBoundsShown => Compositor_ChaperoneBoundsShown,
|
||||
sys::EVREventType_EVREventType_VREvent_Compositor_ChaperoneBoundsHidden => Compositor_ChaperoneBoundsHidden,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedCamera_StartVideoStream => TrackedCamera_StartVideoStream,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedCamera_StopVideoStream => TrackedCamera_StopVideoStream,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedCamera_PauseVideoStream => TrackedCamera_PauseVideoStream,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedCamera_ResumeVideoStream => TrackedCamera_ResumeVideoStream,
|
||||
sys::EVREventType_EVREventType_VREvent_TrackedCamera_EditingSurface => TrackedCamera_EditingSurface,
|
||||
sys::EVREventType_EVREventType_VREvent_PerformanceTest_EnableCapture => PerformanceTest_EnableCapture,
|
||||
sys::EVREventType_EVREventType_VREvent_PerformanceTest_DisableCapture => PerformanceTest_DisableCapture,
|
||||
sys::EVREventType_EVREventType_VREvent_PerformanceTest_FidelityLevel => PerformanceTest_FidelityLevel,
|
||||
sys::EVREventType_EVREventType_VREvent_MessageOverlay_Closed => MessageOverlay_Closed,
|
||||
x if x >= sys::EVREventType_EVREventType_VREvent_VendorSpecific_Reserved_Start
|
||||
&& x <= sys::EVREventType_EVREventType_VREvent_VendorSpecific_Reserved_End => VendorSpecific(x),
|
||||
sys::EVREventType_VREvent_TrackedDeviceActivated => TrackedDeviceActivated,
|
||||
sys::EVREventType_VREvent_TrackedDeviceDeactivated => TrackedDeviceDeactivated,
|
||||
sys::EVREventType_VREvent_TrackedDeviceUpdated => TrackedDeviceUpdated,
|
||||
sys::EVREventType_VREvent_TrackedDeviceUserInteractionStarted => TrackedDeviceUserInteractionStarted,
|
||||
sys::EVREventType_VREvent_TrackedDeviceUserInteractionEnded => TrackedDeviceUserInteractionEnded,
|
||||
sys::EVREventType_VREvent_IpdChanged => IpdChanged,
|
||||
sys::EVREventType_VREvent_EnterStandbyMode => EnterStandbyMode,
|
||||
sys::EVREventType_VREvent_LeaveStandbyMode => LeaveStandbyMode,
|
||||
sys::EVREventType_VREvent_TrackedDeviceRoleChanged => TrackedDeviceRoleChanged,
|
||||
sys::EVREventType_VREvent_WatchdogWakeUpRequested => WatchdogWakeUpRequested,
|
||||
sys::EVREventType_VREvent_LensDistortionChanged => LensDistortionChanged,
|
||||
sys::EVREventType_VREvent_PropertyChanged => PropertyChanged(get(data)),
|
||||
sys::EVREventType_VREvent_ButtonPress => ButtonPress(get(data)),
|
||||
sys::EVREventType_VREvent_ButtonUnpress => ButtonUnpress(get(data)),
|
||||
sys::EVREventType_VREvent_ButtonTouch => ButtonTouch(get(data)),
|
||||
sys::EVREventType_VREvent_ButtonUntouch => ButtonUntouch(get(data)),
|
||||
sys::EVREventType_VREvent_MouseMove => MouseMove(get(data)),
|
||||
sys::EVREventType_VREvent_MouseButtonDown => MouseButtonDown(get(data)),
|
||||
sys::EVREventType_VREvent_MouseButtonUp => MouseButtonUp(get(data)),
|
||||
sys::EVREventType_VREvent_FocusEnter => FocusEnter(get(data)),
|
||||
sys::EVREventType_VREvent_FocusLeave => FocusLeave(get(data)),
|
||||
sys::EVREventType_VREvent_Scroll => Scroll(get(data)),
|
||||
sys::EVREventType_VREvent_TouchPadMove => TouchPadMove(get(data)),
|
||||
sys::EVREventType_VREvent_OverlayFocusChanged => OverlayFocusChanged(get(data)),
|
||||
sys::EVREventType_VREvent_InputFocusCaptured => InputFocusCaptured(get(data)),
|
||||
sys::EVREventType_VREvent_InputFocusReleased => InputFocusReleased(get(data)),
|
||||
sys::EVREventType_VREvent_SceneFocusLost => SceneFocusLost(get(data)),
|
||||
sys::EVREventType_VREvent_SceneFocusGained => SceneFocusGained(get(data)),
|
||||
sys::EVREventType_VREvent_SceneApplicationChanged => SceneApplicationChanged(get(data)),
|
||||
sys::EVREventType_VREvent_SceneFocusChanged => SceneFocusChanged(get(data)),
|
||||
sys::EVREventType_VREvent_InputFocusChanged => InputFocusChanged(get(data)),
|
||||
sys::EVREventType_VREvent_SceneApplicationSecondaryRenderingStarted => SceneApplicationSecondaryRenderingStarted(get(data)),
|
||||
sys::EVREventType_VREvent_HideRenderModels => HideRenderModels,
|
||||
sys::EVREventType_VREvent_ShowRenderModels => ShowRenderModels,
|
||||
sys::EVREventType_VREvent_OverlayShown => OverlayShown,
|
||||
sys::EVREventType_VREvent_OverlayHidden => OverlayHidden,
|
||||
sys::EVREventType_VREvent_DashboardActivated => DashboardActivated,
|
||||
sys::EVREventType_VREvent_DashboardDeactivated => DashboardDeactivated,
|
||||
sys::EVREventType_VREvent_DashboardThumbSelected => DashboardThumbSelected,
|
||||
sys::EVREventType_VREvent_DashboardRequested => DashboardRequested,
|
||||
sys::EVREventType_VREvent_ResetDashboard => ResetDashboard,
|
||||
sys::EVREventType_VREvent_RenderToast => RenderToast,
|
||||
sys::EVREventType_VREvent_ImageLoaded => ImageLoaded,
|
||||
sys::EVREventType_VREvent_ShowKeyboard => ShowKeyboard,
|
||||
sys::EVREventType_VREvent_HideKeyboard => HideKeyboard,
|
||||
sys::EVREventType_VREvent_OverlayGamepadFocusGained => OverlayGamepadFocusGained,
|
||||
sys::EVREventType_VREvent_OverlayGamepadFocusLost => OverlayGamepadFocusLost,
|
||||
sys::EVREventType_VREvent_OverlaySharedTextureChanged => OverlaySharedTextureChanged,
|
||||
sys::EVREventType_VREvent_DashboardGuideButtonDown => DashboardGuideButtonDown,
|
||||
sys::EVREventType_VREvent_DashboardGuideButtonUp => DashboardGuideButtonUp,
|
||||
sys::EVREventType_VREvent_ScreenshotTriggered => ScreenshotTriggered,
|
||||
sys::EVREventType_VREvent_ImageFailed => ImageFailed,
|
||||
sys::EVREventType_VREvent_DashboardOverlayCreated => DashboardOverlayCreated,
|
||||
sys::EVREventType_VREvent_RequestScreenshot => RequestScreenshot,
|
||||
sys::EVREventType_VREvent_ScreenshotTaken => ScreenshotTaken,
|
||||
sys::EVREventType_VREvent_ScreenshotFailed => ScreenshotFailed,
|
||||
sys::EVREventType_VREvent_SubmitScreenshotToDashboard => SubmitScreenshotToDashboard,
|
||||
sys::EVREventType_VREvent_ScreenshotProgressToDashboard => ScreenshotProgressToDashboard,
|
||||
sys::EVREventType_VREvent_PrimaryDashboardDeviceChanged => PrimaryDashboardDeviceChanged,
|
||||
sys::EVREventType_VREvent_Notification_Shown => Notification_Shown,
|
||||
sys::EVREventType_VREvent_Notification_Hidden => Notification_Hidden,
|
||||
sys::EVREventType_VREvent_Notification_BeginInteraction => Notification_BeginInteraction,
|
||||
sys::EVREventType_VREvent_Notification_Destroyed => Notification_Destroyed,
|
||||
sys::EVREventType_VREvent_Quit => Quit(get(data)),
|
||||
sys::EVREventType_VREvent_ProcessQuit => ProcessQuit(get(data)),
|
||||
sys::EVREventType_VREvent_QuitAborted_UserPrompt => QuitAborted_UserPrompt(get(data)),
|
||||
sys::EVREventType_VREvent_QuitAcknowledged => QuitAcknowledged(get(data)),
|
||||
sys::EVREventType_VREvent_DriverRequestedQuit => DriverRequestedQuit,
|
||||
sys::EVREventType_VREvent_ChaperoneDataHasChanged => ChaperoneDataHasChanged,
|
||||
sys::EVREventType_VREvent_ChaperoneUniverseHasChanged => ChaperoneUniverseHasChanged,
|
||||
sys::EVREventType_VREvent_ChaperoneTempDataHasChanged => ChaperoneTempDataHasChanged,
|
||||
sys::EVREventType_VREvent_ChaperoneSettingsHaveChanged => ChaperoneSettingsHaveChanged,
|
||||
sys::EVREventType_VREvent_SeatedZeroPoseReset => SeatedZeroPoseReset,
|
||||
sys::EVREventType_VREvent_AudioSettingsHaveChanged => AudioSettingsHaveChanged,
|
||||
sys::EVREventType_VREvent_BackgroundSettingHasChanged => BackgroundSettingHasChanged,
|
||||
sys::EVREventType_VREvent_CameraSettingsHaveChanged => CameraSettingsHaveChanged,
|
||||
sys::EVREventType_VREvent_ReprojectionSettingHasChanged => ReprojectionSettingHasChanged,
|
||||
sys::EVREventType_VREvent_ModelSkinSettingsHaveChanged => ModelSkinSettingsHaveChanged,
|
||||
sys::EVREventType_VREvent_EnvironmentSettingsHaveChanged => EnvironmentSettingsHaveChanged,
|
||||
sys::EVREventType_VREvent_PowerSettingsHaveChanged => PowerSettingsHaveChanged,
|
||||
sys::EVREventType_VREvent_StatusUpdate => StatusUpdate,
|
||||
sys::EVREventType_VREvent_MCImageUpdated => MCImageUpdated,
|
||||
sys::EVREventType_VREvent_FirmwareUpdateStarted => FirmwareUpdateStarted,
|
||||
sys::EVREventType_VREvent_FirmwareUpdateFinished => FirmwareUpdateFinished,
|
||||
sys::EVREventType_VREvent_KeyboardClosed => KeyboardClosed,
|
||||
sys::EVREventType_VREvent_KeyboardCharInput => KeyboardCharInput(get(data)),
|
||||
sys::EVREventType_VREvent_KeyboardDone => KeyboardDone,
|
||||
sys::EVREventType_VREvent_ApplicationTransitionStarted => ApplicationTransitionStarted,
|
||||
sys::EVREventType_VREvent_ApplicationTransitionAborted => ApplicationTransitionAborted,
|
||||
sys::EVREventType_VREvent_ApplicationTransitionNewAppStarted => ApplicationTransitionNewAppStarted,
|
||||
sys::EVREventType_VREvent_ApplicationListUpdated => ApplicationListUpdated,
|
||||
sys::EVREventType_VREvent_ApplicationMimeTypeLoad => ApplicationMimeTypeLoad,
|
||||
sys::EVREventType_VREvent_ApplicationTransitionNewAppLaunchComplete => ApplicationTransitionNewAppLaunchComplete,
|
||||
sys::EVREventType_VREvent_ProcessConnected => ProcessConnected,
|
||||
sys::EVREventType_VREvent_ProcessDisconnected => ProcessDisconnected,
|
||||
sys::EVREventType_VREvent_Compositor_MirrorWindowShown => Compositor_MirrorWindowShown,
|
||||
sys::EVREventType_VREvent_Compositor_MirrorWindowHidden => Compositor_MirrorWindowHidden,
|
||||
sys::EVREventType_VREvent_Compositor_ChaperoneBoundsShown => Compositor_ChaperoneBoundsShown,
|
||||
sys::EVREventType_VREvent_Compositor_ChaperoneBoundsHidden => Compositor_ChaperoneBoundsHidden,
|
||||
sys::EVREventType_VREvent_TrackedCamera_StartVideoStream => TrackedCamera_StartVideoStream,
|
||||
sys::EVREventType_VREvent_TrackedCamera_StopVideoStream => TrackedCamera_StopVideoStream,
|
||||
sys::EVREventType_VREvent_TrackedCamera_PauseVideoStream => TrackedCamera_PauseVideoStream,
|
||||
sys::EVREventType_VREvent_TrackedCamera_ResumeVideoStream => TrackedCamera_ResumeVideoStream,
|
||||
sys::EVREventType_VREvent_TrackedCamera_EditingSurface => TrackedCamera_EditingSurface,
|
||||
sys::EVREventType_VREvent_PerformanceTest_EnableCapture => PerformanceTest_EnableCapture,
|
||||
sys::EVREventType_VREvent_PerformanceTest_DisableCapture => PerformanceTest_DisableCapture,
|
||||
sys::EVREventType_VREvent_PerformanceTest_FidelityLevel => PerformanceTest_FidelityLevel,
|
||||
sys::EVREventType_VREvent_MessageOverlay_Closed => MessageOverlay_Closed,
|
||||
x if x >= sys::EVREventType_VREvent_VendorSpecific_Reserved_Start
|
||||
&& x <= sys::EVREventType_VREvent_VendorSpecific_Reserved_End => VendorSpecific(x),
|
||||
x => Unknown(x),
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
//! The `System` interface provides access to display configuration information, tracking data, controller state,
|
||||
//! events, and device properties. It is the main interface of OpenVR.
|
||||
|
||||
use std::mem;
|
||||
use std::{mem, slice, ptr};
|
||||
use std::ffi::CString;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use openvr_sys as sys;
|
||||
|
||||
@ -89,12 +91,12 @@ impl<'a> System<'a> {
|
||||
pub fn tracked_device_class(&self, index: TrackedDeviceIndex) -> TrackedDeviceClass {
|
||||
use self::TrackedDeviceClass::*;
|
||||
match unsafe { self.0.GetTrackedDeviceClass.unwrap()(index) } {
|
||||
sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_Invalid => Invalid,
|
||||
sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_HMD => HMD,
|
||||
sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_Controller => Controller,
|
||||
sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_GenericTracker => GenericTracker,
|
||||
sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_TrackingReference => TrackingReference,
|
||||
sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_DisplayRedirect => DisplayRedirect,
|
||||
sys::ETrackedDeviceClass_TrackedDeviceClass_Invalid => Invalid,
|
||||
sys::ETrackedDeviceClass_TrackedDeviceClass_HMD => HMD,
|
||||
sys::ETrackedDeviceClass_TrackedDeviceClass_Controller => Controller,
|
||||
sys::ETrackedDeviceClass_TrackedDeviceClass_GenericTracker => GenericTracker,
|
||||
sys::ETrackedDeviceClass_TrackedDeviceClass_TrackingReference => TrackingReference,
|
||||
sys::ETrackedDeviceClass_TrackedDeviceClass_DisplayRedirect => DisplayRedirect,
|
||||
_ => Invalid,
|
||||
}
|
||||
}
|
||||
@ -147,11 +149,143 @@ impl<'a> System<'a> {
|
||||
pub fn get_controller_role_for_tracked_device_index(&self, i: TrackedDeviceIndex) -> Option<TrackedControllerRole> {
|
||||
let x = unsafe { self.0.GetControllerRoleForTrackedDeviceIndex.unwrap()(i) };
|
||||
match x {
|
||||
sys::ETrackedControllerRole_ETrackedControllerRole_TrackedControllerRole_LeftHand => Some(TrackedControllerRole::LeftHand),
|
||||
sys::ETrackedControllerRole_ETrackedControllerRole_TrackedControllerRole_RightHand => Some(TrackedControllerRole::RightHand),
|
||||
sys::ETrackedControllerRole_TrackedControllerRole_LeftHand => Some(TrackedControllerRole::LeftHand),
|
||||
sys::ETrackedControllerRole_TrackedControllerRole_RightHand => Some(TrackedControllerRole::RightHand),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vulkan_output_device(&self) -> Option<*mut VkPhysicalDevice_T> {
|
||||
unsafe {
|
||||
let mut device = mem::uninitialized();
|
||||
self.0.GetOutputDevice.unwrap()(&mut device, sys::ETextureType_TextureType_Vulkan);
|
||||
if device == 0 { None } else { Some(device as usize as *mut _) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bool_tracked_device_property(&self, device: TrackedDeviceIndex, property: TrackedDeviceProperty) -> Result<bool, TrackedPropertyError> {
|
||||
unsafe {
|
||||
let mut error: TrackedPropertyError = mem::uninitialized();
|
||||
let r = self.0.GetBoolTrackedDeviceProperty.unwrap()(device, property, &mut error.0);
|
||||
if error == tracked_property_error::SUCCESS { Ok(r) } else { Err(error) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn float_tracked_device_property(&self, device: TrackedDeviceIndex, property: TrackedDeviceProperty) -> Result<f32, TrackedPropertyError> {
|
||||
unsafe {
|
||||
let mut error: TrackedPropertyError = mem::uninitialized();
|
||||
let r = self.0.GetFloatTrackedDeviceProperty.unwrap()(device, property, &mut error.0);
|
||||
if error == tracked_property_error::SUCCESS { Ok(r) } else { Err(error) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn int32_tracked_device_property(&self, device: TrackedDeviceIndex, property: TrackedDeviceProperty) -> Result<i32, TrackedPropertyError> {
|
||||
unsafe {
|
||||
let mut error: TrackedPropertyError = mem::uninitialized();
|
||||
let r = self.0.GetInt32TrackedDeviceProperty.unwrap()(device, property, &mut error.0);
|
||||
if error == tracked_property_error::SUCCESS { Ok(r) } else { Err(error) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uint64_tracked_device_property(&self, device: TrackedDeviceIndex, property: TrackedDeviceProperty) -> Result<u64, TrackedPropertyError> {
|
||||
unsafe {
|
||||
let mut error: TrackedPropertyError = mem::uninitialized();
|
||||
let r = self.0.GetUint64TrackedDeviceProperty.unwrap()(device, property, &mut error.0);
|
||||
if error == tracked_property_error::SUCCESS { Ok(r) } else { Err(error) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn matrix34_tracked_device_property(&self, device: TrackedDeviceIndex, property: TrackedDeviceProperty) -> Result<[[f32; 4]; 3], TrackedPropertyError> {
|
||||
unsafe {
|
||||
let mut error: TrackedPropertyError = mem::uninitialized();
|
||||
let r = self.0.GetMatrix34TrackedDeviceProperty.unwrap()(device, property, &mut error.0);
|
||||
if error == tracked_property_error::SUCCESS { Ok(r.m) } else { Err(error) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn string_tracked_device_property(&self, device: TrackedDeviceIndex, property: TrackedDeviceProperty) -> Result<CString, TrackedPropertyError> {
|
||||
unsafe {
|
||||
let mut error = mem::uninitialized();
|
||||
let res = get_string(|ptr, n| self.0.GetStringTrackedDeviceProperty.unwrap()(device, property, ptr, n, &mut error));
|
||||
res.map_or(Err(TrackedPropertyError(error)), Ok)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the hidden area mesh for the current HMD.
|
||||
///
|
||||
/// The pixels covered by this mesh will never be seen by the user after the lens distortion is applied based on
|
||||
/// visibility to the panels. If this HMD does not have a hidden area mesh, None is returned. This mesh is meant to
|
||||
/// be rendered into the stencil buffer (or into the depth buffer setting nearz) before rendering each eye's view.
|
||||
/// This will improve performance by letting the GPU early-reject pixels the user will never see before running the
|
||||
/// pixel shader.
|
||||
///
|
||||
/// NOTE: Render this mesh with backface culling disabled since the winding order of the vertices can
|
||||
/// be different per-HMD or per-eye.
|
||||
///
|
||||
/// Passing `HiddenAreaMeshType::Inverse` will produce the visible area mesh that is commonly used in place of
|
||||
/// full-screen quads. The visible area mesh covers all of the pixels the hidden area mesh does not cover.
|
||||
// TODO: Handle line loops with a separate method and return type, since HiddenAreaMesh assumes triangles.
|
||||
pub fn hidden_area_mesh(&self, eye: Eye, ty: HiddenAreaMeshType) -> Option<HiddenAreaMesh> {
|
||||
let mesh = unsafe { self.0.GetHiddenAreaMesh.unwrap()(eye as sys::EVREye, ty as sys::EHiddenAreaMeshType) };
|
||||
if mesh.pVertexData == ptr::null_mut() { None } else { Some(HiddenAreaMesh { mesh, _phantom: PhantomData }) }
|
||||
}
|
||||
|
||||
/// Looks up the current input state of a controller.
|
||||
///
|
||||
/// Returns None if the device is not a controller, or if the user is currently in the system menu.
|
||||
///
|
||||
/// Needed for rendering controller components (e.g. trigger) accurately wrt. user input using the `render_models`
|
||||
/// API.
|
||||
pub fn controller_state(&self, device: TrackedDeviceIndex) -> Option<ControllerState> {
|
||||
unsafe {
|
||||
let mut state = mem::uninitialized();
|
||||
if self.0.GetControllerState.unwrap()(device, &mut state as *mut _ as *mut _, mem::size_of_val(&state) as u32) {
|
||||
Some(state)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn controller_state_with_pose(&self, origin: TrackingUniverseOrigin, device: TrackedDeviceIndex) -> Option<(ControllerState, TrackedDevicePose)> {
|
||||
unsafe {
|
||||
let mut state = mem::uninitialized();
|
||||
let mut pose = mem::uninitialized();
|
||||
if self.0.GetControllerStateWithPose.unwrap()(
|
||||
origin as sys::ETrackingUniverseOrigin,
|
||||
device, &mut state as *mut _ as *mut _, mem::size_of_val(&state) as u32,
|
||||
&mut pose) {
|
||||
Some((state, pose.into()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Trigger a single haptic pulse on a controller.
|
||||
///
|
||||
/// After this call the application may not trigger another haptic pulse on this controller and axis combination for
|
||||
/// 5ms.
|
||||
///
|
||||
/// Vive controller haptics respond to axis 0. OpenVR seems to reject durations longer than 3999us.
|
||||
pub fn trigger_haptic_pulse(&self, device: TrackedDeviceIndex, axis: u32, microseconds: u16) {
|
||||
unsafe { self.0.TriggerHapticPulse.unwrap()(device, axis, microseconds) }
|
||||
}
|
||||
|
||||
/// Call this to acknowledge to the system that `Event::Quit` has been received and that the process is exiting.
|
||||
///
|
||||
/// This extends the timeout until the process is killed.
|
||||
pub fn acknowledge_quit_exiting(&self) {
|
||||
unsafe { self.0.AcknowledgeQuit_Exiting.unwrap()(); }
|
||||
}
|
||||
|
||||
/// Call this to tell the system that the user is being prompted to save data.
|
||||
///
|
||||
/// This halts the timeout and dismisses the dashboard (if it was up). Applications should be sure to actually
|
||||
/// prompt the user to save and then exit afterward, otherwise the user will be left in a confusing state.
|
||||
pub fn acknowledge_quit_user_prompt(&self) {
|
||||
unsafe { self.0.AcknowledgeQuit_Exiting.unwrap()(); }
|
||||
}
|
||||
}
|
||||
|
||||
/// Values represent the tangents of the half-angles from the center view axis
|
||||
@ -173,3 +307,83 @@ pub struct DistortionCoordinates {
|
||||
pub green: [f32; 2],
|
||||
pub blue: [f32; 2],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub struct TrackedPropertyError(sys::TrackedPropertyError);
|
||||
|
||||
pub mod tracked_property_error {
|
||||
use super::{sys, TrackedPropertyError};
|
||||
|
||||
pub const SUCCESS: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_Success);
|
||||
pub const WRONG_DATA_TYPE: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_WrongDataType);
|
||||
pub const WRONG_DEVICE_CLASS: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_WrongDeviceClass);
|
||||
pub const BUFFER_TOO_SMALL: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_BufferTooSmall);
|
||||
pub const UNKNOWN_PROPERTY: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_UnknownProperty);
|
||||
pub const INVALID_DEVICE: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_InvalidDevice);
|
||||
pub const COULD_NOT_CONTACT_SERVER: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_CouldNotContactServer);
|
||||
pub const VALUE_NOT_PROVIDED_BY_DEVICE: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_ValueNotProvidedByDevice);
|
||||
pub const STRING_EXCEEDS_MAXIMUM_LENGTH: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_StringExceedsMaximumLength);
|
||||
pub const NOT_YET_AVAILABLE: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_NotYetAvailable);
|
||||
pub const PERMISSION_DENIED: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_PermissionDenied);
|
||||
pub const INVALID_OPERATION: TrackedPropertyError = TrackedPropertyError(sys::ETrackedPropertyError_TrackedProp_InvalidOperation);
|
||||
}
|
||||
|
||||
impl fmt::Debug for TrackedPropertyError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad(::std::error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::error::Error for TrackedPropertyError {
|
||||
fn description(&self) -> &str {
|
||||
use self::tracked_property_error::*;
|
||||
match *self {
|
||||
SUCCESS => "SUCCESS",
|
||||
WRONG_DATA_TYPE => "WRONG_DATA_TYPE",
|
||||
WRONG_DEVICE_CLASS => "WRONG_DEVICE_CLASS",
|
||||
BUFFER_TOO_SMALL => "BUFFER_TOO_SMALL",
|
||||
UNKNOWN_PROPERTY => "UNKNOWN_PROPERTY",
|
||||
INVALID_DEVICE => "INVALID_DEVICE",
|
||||
COULD_NOT_CONTACT_SERVER => "COULD_NOT_CONTACT_SERVER",
|
||||
VALUE_NOT_PROVIDED_BY_DEVICE => "VALUE_NOT_PROVIDED_BY_DEVICE",
|
||||
STRING_EXCEEDS_MAXIMUM_LENGTH => "STRING_EXCEEDS_MAXIMUM_LENGTH",
|
||||
NOT_YET_AVAILABLE => "NOT_YET_AVAILABLE",
|
||||
PERMISSION_DENIED => "PERMISSION_DENIED",
|
||||
INVALID_OPERATION => "INVALID_OPERATION",
|
||||
_ => "UNKNOWN",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TrackedPropertyError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad(::std::error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum HiddenAreaMeshType {
|
||||
/// The mesh that covers pixels which cannot be seen by the wearer of the HMD for optical reasons.
|
||||
Standard = sys::EHiddenAreaMeshType_k_eHiddenAreaMesh_Standard as isize,
|
||||
/// The inverse of `Standard`, useful for doing full-screen render passes such as postprocessing.
|
||||
Inverse = sys::EHiddenAreaMeshType_k_eHiddenAreaMesh_Inverse as isize,
|
||||
}
|
||||
|
||||
impl Default for HiddenAreaMeshType {
|
||||
fn default() -> Self { HiddenAreaMeshType::Standard }
|
||||
}
|
||||
|
||||
/// A triangle mesh containing geometry determined by `HiddenAreaMeshType`.
|
||||
///
|
||||
/// Render this mesh with backface culling disabled since the winding order of the vertices can be different per-HMD or
|
||||
/// per-eye.
|
||||
pub struct HiddenAreaMesh<'a> {
|
||||
mesh: sys::HiddenAreaMesh_t,
|
||||
_phantom: PhantomData<&'a [[f32; 2]]>,
|
||||
}
|
||||
|
||||
impl<'a> ::std::ops::Deref for HiddenAreaMesh<'a> {
|
||||
type Target = [[f32; 2]];
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { slice::from_raw_parts(&(*self.mesh.pVertexData).v, self.mesh.unTriangleCount as usize * 3) }
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ use openvr_sys as sys;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum TrackingUniverseOrigin {
|
||||
Seated = sys::ETrackingUniverseOrigin_ETrackingUniverseOrigin_TrackingUniverseSeated as isize,
|
||||
Standing = sys::ETrackingUniverseOrigin_ETrackingUniverseOrigin_TrackingUniverseStanding as isize,
|
||||
RawAndUncalibrated = sys::ETrackingUniverseOrigin_ETrackingUniverseOrigin_TrackingUniverseRawAndUncalibrated as isize,
|
||||
Seated = sys::ETrackingUniverseOrigin_TrackingUniverseSeated as isize,
|
||||
Standing = sys::ETrackingUniverseOrigin_TrackingUniverseStanding as isize,
|
||||
RawAndUncalibrated = sys::ETrackingUniverseOrigin_TrackingUniverseRawAndUncalibrated as isize,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -18,11 +18,11 @@ impl TrackedDevicePose {
|
||||
pub fn tracking_result(&self) -> TrackingResult {
|
||||
use self::TrackingResult::*;
|
||||
match self.0.eTrackingResult {
|
||||
sys::ETrackingResult_ETrackingResult_TrackingResult_Uninitialized => Uninitialized,
|
||||
sys::ETrackingResult_ETrackingResult_TrackingResult_Calibrating_InProgress => CalibratingInProgress,
|
||||
sys::ETrackingResult_ETrackingResult_TrackingResult_Calibrating_OutOfRange => CalibratingOutOfRange,
|
||||
sys::ETrackingResult_ETrackingResult_TrackingResult_Running_OK => OK,
|
||||
sys::ETrackingResult_ETrackingResult_TrackingResult_Running_OutOfRange => RunningOutOfRange,
|
||||
sys::ETrackingResult_TrackingResult_Uninitialized => Uninitialized,
|
||||
sys::ETrackingResult_TrackingResult_Calibrating_InProgress => CalibratingInProgress,
|
||||
sys::ETrackingResult_TrackingResult_Calibrating_OutOfRange => CalibratingOutOfRange,
|
||||
sys::ETrackingResult_TrackingResult_Running_OK => OK,
|
||||
sys::ETrackingResult_TrackingResult_Running_OutOfRange => RunningOutOfRange,
|
||||
_ => panic!("unrecognized tracking result")
|
||||
}
|
||||
}
|
||||
@ -30,23 +30,27 @@ impl TrackedDevicePose {
|
||||
pub fn device_is_connected(&self) -> bool { self.0.bDeviceIsConnected }
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum TrackingResult {
|
||||
Uninitialized = sys::ETrackingResult_ETrackingResult_TrackingResult_Uninitialized as isize,
|
||||
CalibratingInProgress = sys::ETrackingResult_ETrackingResult_TrackingResult_Calibrating_InProgress as isize,
|
||||
CalibratingOutOfRange = sys::ETrackingResult_ETrackingResult_TrackingResult_Calibrating_OutOfRange as isize,
|
||||
OK = sys::ETrackingResult_ETrackingResult_TrackingResult_Running_OK as isize,
|
||||
RunningOutOfRange = sys::ETrackingResult_ETrackingResult_TrackingResult_Running_OutOfRange as isize,
|
||||
impl From<sys::TrackedDevicePose_t> for TrackedDevicePose {
|
||||
fn from(x: sys::TrackedDevicePose_t) -> Self { TrackedDevicePose(x) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum TrackingResult {
|
||||
Uninitialized = sys::ETrackingResult_TrackingResult_Uninitialized as isize,
|
||||
CalibratingInProgress = sys::ETrackingResult_TrackingResult_Calibrating_InProgress as isize,
|
||||
CalibratingOutOfRange = sys::ETrackingResult_TrackingResult_Calibrating_OutOfRange as isize,
|
||||
OK = sys::ETrackingResult_TrackingResult_Running_OK as isize,
|
||||
RunningOutOfRange = sys::ETrackingResult_TrackingResult_Running_OutOfRange as isize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum TrackedDeviceClass {
|
||||
Invalid = sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_Invalid as isize,
|
||||
HMD = sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_HMD as isize,
|
||||
Controller = sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_Controller as isize,
|
||||
GenericTracker = sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_GenericTracker as isize,
|
||||
TrackingReference = sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_TrackingReference as isize,
|
||||
DisplayRedirect = sys::ETrackedDeviceClass_ETrackedDeviceClass_TrackedDeviceClass_DisplayRedirect as isize,
|
||||
Invalid = sys::ETrackedDeviceClass_TrackedDeviceClass_Invalid as isize,
|
||||
HMD = sys::ETrackedDeviceClass_TrackedDeviceClass_HMD as isize,
|
||||
Controller = sys::ETrackedDeviceClass_TrackedDeviceClass_Controller as isize,
|
||||
GenericTracker = sys::ETrackedDeviceClass_TrackedDeviceClass_GenericTracker as isize,
|
||||
TrackingReference = sys::ETrackedDeviceClass_TrackedDeviceClass_TrackingReference as isize,
|
||||
DisplayRedirect = sys::ETrackedDeviceClass_TrackedDeviceClass_DisplayRedirect as isize,
|
||||
}
|
||||
|
||||
pub type TrackedDeviceIndex = sys::TrackedDeviceIndex_t;
|
||||
@ -59,10 +63,12 @@ pub mod tracked_device_index {
|
||||
|
||||
pub type TrackedDeviceProperty = sys::ETrackedDeviceProperty;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum TrackedControllerRole {
|
||||
LeftHand = sys::ETrackedControllerRole_ETrackedControllerRole_TrackedControllerRole_LeftHand as isize,
|
||||
RightHand = sys::ETrackedControllerRole_ETrackedControllerRole_TrackedControllerRole_RightHand as isize,
|
||||
LeftHand = sys::ETrackedControllerRole_TrackedControllerRole_LeftHand as isize,
|
||||
RightHand = sys::ETrackedControllerRole_TrackedControllerRole_RightHand as isize,
|
||||
}
|
||||
|
||||
pub type TrackedDevicePoses = [TrackedDevicePose; sys::k_unMaxTrackedDeviceCount as usize];
|
||||
pub const MAX_TRACKED_DEVICE_COUNT: usize = sys::k_unMaxTrackedDeviceCount as usize;
|
||||
|
||||
pub type TrackedDevicePoses = [TrackedDevicePose; MAX_TRACKED_DEVICE_COUNT];
|
||||
|
Reference in New Issue
Block a user