Skip to content

Commit

Permalink
support XR_META_body_tracking_full_body (#3)
Browse files Browse the repository at this point in the history
* support XR_META_body_tracking_full_body

* full body bool for XR_META_body_tracking_full_body
  • Loading branch information
barnabwhy committed Feb 11, 2024
1 parent cddb769 commit f1f47ff
Show file tree
Hide file tree
Showing 7 changed files with 508 additions and 92 deletions.
80 changes: 0 additions & 80 deletions openxr/src/body_tracking_fb.rs

This file was deleted.

83 changes: 83 additions & 0 deletions openxr/src/body_tracking_full_body_meta.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::{ptr, sync::Arc};

use sys::{BodyJointFullBodyLocationMETA, BodyJointSetFullBodyMETA};

use crate::*;

pub const BODY_JOINT_COUNT_META: usize = 70;
pub const BODY_JOINT_FULL_BODY_COUNT_META: usize = 84;

pub struct BodyTrackerFullBodyMETA {
pub(crate) session: Arc<session::SessionInner>,
handle: sys::BodyTrackerFullBodyMETA,
}

impl BodyTrackerFullBodyMETA {
#[inline]
pub fn as_raw(&self) -> sys::BodyTrackerFullBodyMETA {
self.handle
}

/// Take ownership of an existing body tracker
///
/// # Safety
///
/// `handle` must be a valid body tracker handle associated with `session`.
#[inline]
pub unsafe fn from_raw<G>(session: &Session<G>, handle: sys::BodyTrackerFullBodyMETA) -> Self {
Self {
handle,
session: session.inner.clone(),
}
}

#[inline]
pub(crate) fn fp(&self) -> &raw::BodyTrackingFullBodyMETA {
self.session
.instance
.exts()
.meta_body_tracking_full_body
.as_ref()
.expect("Somehow created BodyTrackingFullBodyMETA without XR_META_body_tracking_full_body being enabled")
}
}

impl<G> Session<G> {
pub fn create_body_tracker_full_body_meta(&self, full_body: bool) -> Result<BodyTrackerFullBodyMETA> {
let fp = self
.inner
.instance
.exts()
.meta_body_tracking_full_body
.as_ref()
.ok_or(sys::Result::ERROR_EXTENSION_NOT_PRESENT)?;

let mut out = sys::BodyTrackerFullBodyMETA::NULL;
let info = sys::BodyTrackerFullBodyCreateInfoMETA {
ty: sys::BodyTrackerFullBodyCreateInfoMETA::TYPE,
next: ptr::null(),
body_joint_set: if full_body { BodyJointSetFullBodyMETA::FULL_BODY } else { BodyJointSetFullBodyMETA::DEFAULT },
};
let handle = unsafe {
cvt((fp.create_body_tracker)(self.as_raw(), &info, &mut out))?;
out
};
Ok(BodyTrackerFullBodyMETA {
session: self.inner.clone(),
handle,
})
}
}

impl Drop for BodyTrackerFullBodyMETA {
fn drop(&mut self) {
unsafe {
(self.fp().destroy_body_tracker)(self.handle);
}
}
}

/// An array of `BodyJointFullBodyLocationMETA`s, one for each `FullBodyJointMETA`.
///
/// `FullBodyJointMETA`s can be used directly as an index for convenience.
pub type BodyJointFullBodyMETALocations = [BodyJointFullBodyLocationMETA; BODY_JOINT_FULL_BODY_COUNT_META];
51 changes: 51 additions & 0 deletions openxr/src/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub struct ExtensionSet {
pub fb_swapchain_update_state: bool,
pub fb_composition_layer_secure_content: bool,
pub fb_body_tracking: bool,
pub meta_body_tracking_full_body: bool,
pub fb_display_refresh_rate: bool,
pub fb_color_space: bool,
pub fb_hand_tracking_mesh: bool,
Expand Down Expand Up @@ -293,6 +294,9 @@ impl ExtensionSet {
raw::BodyTrackingFB::NAME => {
out.fb_body_tracking = true;
}
raw::BodyTrackingFullBodyMETA::NAME => {
out.meta_body_tracking_full_body = true;
}
raw::DisplayRefreshRateFB::NAME => {
out.fb_display_refresh_rate = true;
}
Expand Down Expand Up @@ -775,6 +779,11 @@ impl ExtensionSet {
out.push(raw::BodyTrackingFB::NAME.into());
}
}
{
if self.meta_body_tracking_full_body {
out.push(raw::BodyTrackingFullBodyMETA::NAME.into());
}
}
{
if self.fb_display_refresh_rate {
out.push(raw::DisplayRefreshRateFB::NAME.into());
Expand Down Expand Up @@ -1358,6 +1367,7 @@ pub struct InstanceExtensions {
pub fb_swapchain_update_state: Option<raw::SwapchainUpdateStateFB>,
pub fb_composition_layer_secure_content: Option<raw::CompositionLayerSecureContentFB>,
pub fb_body_tracking: Option<raw::BodyTrackingFB>,
pub meta_body_tracking_full_body: Option<raw::BodyTrackingFullBodyMETA>,
pub fb_display_refresh_rate: Option<raw::DisplayRefreshRateFB>,
pub fb_color_space: Option<raw::ColorSpaceFB>,
pub fb_hand_tracking_mesh: Option<raw::HandTrackingMeshFB>,
Expand Down Expand Up @@ -1632,6 +1642,11 @@ impl InstanceExtensions {
} else {
None
},
meta_body_tracking_full_body: if required.meta_body_tracking_full_body {
Some(raw::BodyTrackingFullBodyMETA::load(entry, instance)?)
} else {
None
},
fb_display_refresh_rate: if required.fb_display_refresh_rate {
Some(raw::DisplayRefreshRateFB::load(entry, instance)?)
} else {
Expand Down Expand Up @@ -3682,6 +3697,42 @@ pub mod raw {
}
}
#[derive(Copy, Clone)]
pub struct BodyTrackingFullBodyMETA {
pub create_body_tracker: pfn::CreateBodyTrackerFullBodyMETA,
pub destroy_body_tracker: pfn::DestroyBodyTrackerFullBodyMETA,
pub locate_body_joints: pfn::LocateBodyJointsFullBodyMETA,
pub get_body_skeleton: pfn::GetBodySkeletonFullBodyMETA,
}
impl BodyTrackingFullBodyMETA {
pub const VERSION: u32 = sys::META_body_tracking_full_body_SPEC_VERSION;
pub const NAME: &'static [u8] = sys::META_BODY_TRACKING_FULL_BODY_EXTENSION_NAME;
#[doc = r" Load the extension's function pointer table"]
#[doc = r""]
#[doc = r" # Safety"]
#[doc = r""]
#[doc = r" `instance` must be a valid instance handle."]
pub unsafe fn load(entry: &Entry, instance: sys::Instance) -> Result<Self> {
Ok(Self {
create_body_tracker: mem::transmute(entry.get_instance_proc_addr(
instance,
CStr::from_bytes_with_nul_unchecked(b"xrCreateBodyTrackerFB\0"),
)?),
destroy_body_tracker: mem::transmute(entry.get_instance_proc_addr(
instance,
CStr::from_bytes_with_nul_unchecked(b"xrDestroyBodyTrackerFB\0"),
)?),
locate_body_joints: mem::transmute(entry.get_instance_proc_addr(
instance,
CStr::from_bytes_with_nul_unchecked(b"xrLocateBodyJointsFB\0"),
)?),
get_body_skeleton: mem::transmute(entry.get_instance_proc_addr(
instance,
CStr::from_bytes_with_nul_unchecked(b"xrGetBodySkeletonFB\0"),
)?),
})
}
}
#[derive(Copy, Clone)]
pub struct DisplayRefreshRateFB {
pub enumerate_display_refresh_rates: pfn::EnumerateDisplayRefreshRatesFB,
pub get_display_refresh_rate: pfn::GetDisplayRefreshRateFB,
Expand Down
6 changes: 6 additions & 0 deletions openxr/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ impl Instance {
Ok(props.supports_body_tracking.into())
}

#[inline]
pub fn supports_meta_body_tracking_full_body(&self, system: SystemId) -> Result<bool> {
let props = self.ext_props(system, sys::SystemBodyTrackingFullBodyPropertiesMETA::out)?;
Ok(props.supports_full_body_tracking.into())
}

#[inline]
pub fn supports_eye_gaze_interaction(&self, system: SystemId) -> Result<bool> {
let props = self.ext_props(system, sys::SystemEyeGazeInteractionPropertiesEXT::out)?;
Expand Down
4 changes: 2 additions & 2 deletions openxr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ mod face_tracking_fb;
pub use face_tracking_fb::*;
mod htc_facial_tracking;
pub use htc_facial_tracking::*;
mod body_tracking_fb;
pub use body_tracking_fb::*;
mod body_tracking_full_body_meta;
pub use body_tracking_full_body_meta::*;

pub use builder::{
CompositionLayerBase, CompositionLayerCubeKHR, CompositionLayerCylinderKHR,
Expand Down
23 changes: 13 additions & 10 deletions openxr/src/space.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::{ffi::CString, mem::MaybeUninit, ptr, sync::Arc};

use sys::BodyJointFullBodyLocationMETA;

use crate::*;

pub struct Space {
Expand Down Expand Up @@ -207,30 +209,31 @@ impl Space {
/// Determine the locations of the joints of a body tracker relative to this space at a
/// specified time, if currently known by the runtime.
///
/// XR_FB_body_tracking must be enabled.
/// XR_META_body_tracking_full_body must be enabled.
#[inline]
pub fn locate_body_joints_fb(
pub fn locate_body_joints_full_body_meta(
&self,
tracker: &BodyTrackerFB,
tracker: &BodyTrackerFullBodyMETA,
time: Time,
) -> Result<Option<BodyJointFBLocations>> {
full_body: bool,
) -> Result<Option<BodyJointFullBodyMETALocations>> {
// This assert allows this function to be safe.
assert_eq!(&*self.session as *const session::SessionInner, &*tracker.session as *const session::SessionInner,
"`self` and `tracker` must have been created, allocated, or retrieved from the same `Session`");
unsafe {
let locate_info = sys::BodyJointsLocateInfoFB {
ty: sys::BodyJointsLocateInfoFB::TYPE,
let locate_info = sys::BodyJointsFullBodyLocateInfoMETA {
ty: sys::BodyJointsFullBodyLocateInfoMETA::TYPE,
next: ptr::null(),
base_space: self.as_raw(),
time,
};
let mut locations = MaybeUninit::<[BodyJointLocationFB; BODY_JOINT_COUNT_FB]>::uninit();
let mut location_info = sys::BodyJointLocationsFB {
ty: sys::BodyJointLocationsFB::TYPE,
let mut locations = MaybeUninit::<[BodyJointFullBodyLocationMETA; BODY_JOINT_FULL_BODY_COUNT_META]>::uninit();
let mut location_info = sys::BodyJointFullBodyLocationsMETA {
ty: sys::BodyJointFullBodyLocationsMETA::TYPE,
next: ptr::null_mut(),
is_active: false.into(),
confidence: 0.0,
joint_count: BODY_JOINT_COUNT_FB as u32,
joint_count: if full_body { BODY_JOINT_FULL_BODY_COUNT_META } else { BODY_JOINT_COUNT_META } as u32,
joint_locations: locations.as_mut_ptr() as _,
skeleton_changed_count: 0,
time: time,
Expand Down

0 comments on commit f1f47ff

Please sign in to comment.