Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support XR_META_body_tracking_full_body #3

Merged
merged 2 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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