mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-22 16:25:36 +00:00
Fill in some additional System methods
This commit is contained in:
22
src/lib.rs
22
src/lib.rs
@ -181,3 +181,25 @@ pub struct ControllerState {
|
||||
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;
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -1,8 +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;
|
||||
|
||||
@ -210,6 +211,25 @@ impl<'a> System<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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.
|
||||
@ -226,6 +246,46 @@ impl<'a> System<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -300,3 +360,30 @@ impl fmt::Display for TrackedPropertyError {
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,10 @@ impl TrackedDevicePose {
|
||||
pub fn device_is_connected(&self) -> bool { self.0.bDeviceIsConnected }
|
||||
}
|
||||
|
||||
impl From<sys::TrackedDevicePose_t> for TrackedDevicePose {
|
||||
fn from(x: sys::TrackedDevicePose_t) -> Self { TrackedDevicePose(x) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum TrackingResult {
|
||||
Uninitialized = sys::ETrackingResult_TrackingResult_Uninitialized as isize,
|
||||
|
Reference in New Issue
Block a user