diff --git a/alvr/client_openxr/src/extra_extensions/body_tracking_fb.rs b/alvr/client_openxr/src/extra_extensions/body_tracking_fb.rs index a6574cd774..6c9abe355f 100644 --- a/alvr/client_openxr/src/extra_extensions/body_tracking_fb.rs +++ b/alvr/client_openxr/src/extra_extensions/body_tracking_fb.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] -use alvr_common::{anyhow::Result, once_cell::sync::Lazy, ToAny}; +use alvr_common::once_cell::sync::Lazy; use openxr::{self as xr, raw, sys}; use std::ptr; @@ -37,8 +37,15 @@ pub struct BodyTrackerFB { } impl BodyTrackerFB { - pub fn new<G>(session: &xr::Session<G>, body_joint_set: xr::BodyJointSetFB) -> Result<Self> { - let ext_fns = session.instance().exts().fb_body_tracking.to_any()?; + pub fn new<G>( + session: &xr::Session<G>, + body_joint_set: xr::BodyJointSetFB, + ) -> xr::Result<Self> { + let ext_fns = session + .instance() + .exts() + .fb_body_tracking + .ok_or(sys::Result::ERROR_EXTENSION_NOT_PRESENT)?; let mut handle = sys::BodyTrackerFB::NULL; let info = sys::BodyTrackerCreateInfoFB { @@ -47,11 +54,11 @@ impl BodyTrackerFB { body_joint_set, }; unsafe { - super::xr_to_any((ext_fns.create_body_tracker)( + super::xr_res((ext_fns.create_body_tracker)( session.as_raw(), &info, &mut handle, - ))? + ))?; }; Ok(Self { handle, ext_fns }) @@ -62,7 +69,7 @@ impl BodyTrackerFB { time: xr::Time, reference_space: &xr::Space, joint_count: usize, - ) -> Result<Option<Vec<xr::BodyJointLocationFB>>> { + ) -> xr::Result<Option<Vec<xr::BodyJointLocationFB>>> { let locate_info = sys::BodyJointsLocateInfoFB { ty: sys::BodyJointsLocateInfoFB::TYPE, next: ptr::null(), @@ -81,7 +88,7 @@ impl BodyTrackerFB { time: xr::Time::from_nanos(0), }; unsafe { - super::xr_to_any((self.ext_fns.locate_body_joints)( + super::xr_res((self.ext_fns.locate_body_joints)( self.handle, &locate_info, &mut location_info, diff --git a/alvr/client_openxr/src/extra_extensions/eye_tracking_social.rs b/alvr/client_openxr/src/extra_extensions/eye_tracking_social.rs index f6a598f0a4..09c9c63ced 100644 --- a/alvr/client_openxr/src/extra_extensions/eye_tracking_social.rs +++ b/alvr/client_openxr/src/extra_extensions/eye_tracking_social.rs @@ -1,4 +1,3 @@ -use alvr_common::{anyhow::Result, ToAny}; use openxr::{self as xr, raw, sys}; use std::ptr; @@ -8,8 +7,12 @@ pub struct EyeTrackerSocial { } impl EyeTrackerSocial { - pub fn new<G>(session: &xr::Session<G>) -> Result<Self> { - let ext_fns = session.instance().exts().fb_eye_tracking_social.to_any()?; + pub fn new<G>(session: &xr::Session<G>) -> xr::Result<Self> { + let ext_fns = session + .instance() + .exts() + .fb_eye_tracking_social + .ok_or(sys::Result::ERROR_EXTENSION_NOT_PRESENT)?; let mut handle = sys::EyeTrackerFB::NULL; let info = sys::EyeTrackerCreateInfoFB { @@ -17,7 +20,7 @@ impl EyeTrackerSocial { next: ptr::null(), }; unsafe { - super::xr_to_any((ext_fns.create_eye_tracker)( + super::xr_res((ext_fns.create_eye_tracker)( session.as_raw(), &info, &mut handle, @@ -31,7 +34,7 @@ impl EyeTrackerSocial { &self, base: &xr::Space, time: xr::Time, - ) -> Result<[Option<xr::Posef>; 2]> { + ) -> xr::Result<[Option<xr::Posef>; 2]> { let gaze_info = sys::EyeGazesInfoFB { ty: sys::EyeGazesInfoFB::TYPE, next: ptr::null(), @@ -42,7 +45,7 @@ impl EyeTrackerSocial { let mut eye_gazes = sys::EyeGazesFB::out(ptr::null_mut()); let eye_gazes = unsafe { - super::xr_to_any((self.ext_fns.get_eye_gazes)( + super::xr_res((self.ext_fns.get_eye_gazes)( self.handle, &gaze_info, eye_gazes.as_mut_ptr(), diff --git a/alvr/client_openxr/src/extra_extensions/face_tracking2_fb.rs b/alvr/client_openxr/src/extra_extensions/face_tracking2_fb.rs index 3e38823fc0..f5b9211967 100644 --- a/alvr/client_openxr/src/extra_extensions/face_tracking2_fb.rs +++ b/alvr/client_openxr/src/extra_extensions/face_tracking2_fb.rs @@ -1,4 +1,3 @@ -use alvr_common::{anyhow::Result, ToAny}; use openxr::{self as xr, raw, sys}; use std::ptr; @@ -8,8 +7,12 @@ pub struct FaceTracker2FB { } impl FaceTracker2FB { - pub fn new<G>(session: &xr::Session<G>, visual: bool, audio: bool) -> Result<Self> { - let ext_fns = session.instance().exts().fb_face_tracking2.to_any()?; + pub fn new<G>(session: &xr::Session<G>, visual: bool, audio: bool) -> xr::Result<Self> { + let ext_fns = session + .instance() + .exts() + .fb_face_tracking2 + .ok_or(sys::Result::ERROR_EXTENSION_NOT_PRESENT)?; let mut requested_data_sources = vec![]; if visual { @@ -28,7 +31,7 @@ impl FaceTracker2FB { requested_data_sources: requested_data_sources.as_mut_ptr(), }; unsafe { - super::xr_to_any((ext_fns.create_face_tracker2)( + super::xr_res((ext_fns.create_face_tracker2)( session.as_raw(), &info, &mut handle, @@ -38,7 +41,7 @@ impl FaceTracker2FB { Ok(Self { handle, ext_fns }) } - pub fn get_face_expression_weights(&self, time: xr::Time) -> Result<Option<Vec<f32>>> { + pub fn get_face_expression_weights(&self, time: xr::Time) -> xr::Result<Option<Vec<f32>>> { let expression_info = sys::FaceExpressionInfo2FB { ty: sys::FaceExpressionInfo2FB::TYPE, next: ptr::null(), @@ -65,7 +68,7 @@ impl FaceTracker2FB { }; unsafe { - super::xr_to_any((self.ext_fns.get_face_expression_weights2)( + super::xr_res((self.ext_fns.get_face_expression_weights2)( self.handle, &expression_info, &mut expression_weights, diff --git a/alvr/client_openxr/src/extra_extensions/facial_tracking_htc.rs b/alvr/client_openxr/src/extra_extensions/facial_tracking_htc.rs index 8fa2f0dc0d..773ef0e048 100644 --- a/alvr/client_openxr/src/extra_extensions/facial_tracking_htc.rs +++ b/alvr/client_openxr/src/extra_extensions/facial_tracking_htc.rs @@ -1,4 +1,3 @@ -use alvr_common::{anyhow::Result, ToAny}; use openxr::{self as xr, raw, sys}; use std::ptr; @@ -12,8 +11,12 @@ impl FacialTrackerHTC { pub fn new<G>( session: &xr::Session<G>, facial_tracking_type: xr::FacialTrackingTypeHTC, - ) -> Result<Self> { - let ext_fns = session.instance().exts().htc_facial_tracking.to_any()?; + ) -> xr::Result<Self> { + let ext_fns = session + .instance() + .exts() + .htc_facial_tracking + .ok_or(sys::Result::ERROR_EXTENSION_NOT_PRESENT)?; let mut handle = sys::FacialTrackerHTC::NULL; let info = sys::FacialTrackerCreateInfoHTC { @@ -22,7 +25,7 @@ impl FacialTrackerHTC { facial_tracking_type, }; unsafe { - super::xr_to_any((ext_fns.create_facial_tracker)( + super::xr_res((ext_fns.create_facial_tracker)( session.as_raw(), &info, &mut handle, @@ -42,7 +45,7 @@ impl FacialTrackerHTC { }) } - pub fn get_facial_expressions(&self) -> Result<Option<Vec<f32>>> { + pub fn get_facial_expressions(&self) -> xr::Result<Option<Vec<f32>>> { let mut weights = Vec::with_capacity(self.expression_count); let mut facial_expressions = sys::FacialExpressionsHTC { @@ -55,7 +58,7 @@ impl FacialTrackerHTC { }; unsafe { - super::xr_to_any((self.ext_fns.get_facial_expressions)( + super::xr_res((self.ext_fns.get_facial_expressions)( self.handle, &mut facial_expressions, ))?; diff --git a/alvr/client_openxr/src/extra_extensions/mod.rs b/alvr/client_openxr/src/extra_extensions/mod.rs index 54a0e569ed..b433b9efde 100644 --- a/alvr/client_openxr/src/extra_extensions/mod.rs +++ b/alvr/client_openxr/src/extra_extensions/mod.rs @@ -10,13 +10,12 @@ pub use face_tracking2_fb::*; pub use facial_tracking_htc::*; pub use multimodal_input::*; -use alvr_common::anyhow::{anyhow, Result}; -use openxr::sys; +use openxr::{self as xr, sys}; -fn xr_to_any(result: sys::Result) -> Result<()> { +fn xr_res(result: sys::Result) -> xr::Result<()> { if result.into_raw() >= 0 { Ok(()) } else { - Err(anyhow!("OpenXR error: {:?}", result)) + Err(result) } } diff --git a/alvr/client_openxr/src/extra_extensions/multimodal_input.rs b/alvr/client_openxr/src/extra_extensions/multimodal_input.rs index 2471ebc18b..ac55375208 100644 --- a/alvr/client_openxr/src/extra_extensions/multimodal_input.rs +++ b/alvr/client_openxr/src/extra_extensions/multimodal_input.rs @@ -1,7 +1,7 @@ // Code taken from: // https://github.com/meta-quest/Meta-OpenXR-SDK/blob/main/OpenXR/meta_openxr_preview/meta_simultaneous_hands_and_controllers.h -use alvr_common::{anyhow::Result, once_cell::sync::Lazy, ToAny}; +use alvr_common::once_cell::sync::Lazy; use openxr::{ self as xr, sys::{self, pfn::VoidFunction}, @@ -29,7 +29,7 @@ pub type ResumeSimultaneousHandsAndControllersTrackingMETA = pub fn resume_simultaneous_hands_and_controllers_tracking<G>( session: &xr::Session<G>, -) -> Result<()> { +) -> xr::Result<()> { let resume_simultaneous_hands_and_controllers_tracking_meta = unsafe { let mut resume_simultaneous_hands_and_controllers_tracking_meta = None; let _ = (session.instance().fp().get_instance_proc_addr)( @@ -38,10 +38,11 @@ pub fn resume_simultaneous_hands_and_controllers_tracking<G>( &mut resume_simultaneous_hands_and_controllers_tracking_meta, ); - mem::transmute::<VoidFunction, ResumeSimultaneousHandsAndControllersTrackingMETA>( - resume_simultaneous_hands_and_controllers_tracking_meta.to_any()?, - ) - }; + resume_simultaneous_hands_and_controllers_tracking_meta.map(|pfn| { + mem::transmute::<VoidFunction, ResumeSimultaneousHandsAndControllersTrackingMETA>(pfn) + }) + } + .ok_or(sys::Result::ERROR_EXTENSION_NOT_PRESENT)?; let resume_info = SimultaneousHandsAndControllersTrackingResumeInfoMETA { ty: *TYPE_SIMULTANEOUS_HANDS_AND_CONTROLLERS_TRACKING_RESUME_INFO_META, @@ -49,7 +50,7 @@ pub fn resume_simultaneous_hands_and_controllers_tracking<G>( }; unsafe { - super::xr_to_any(resume_simultaneous_hands_and_controllers_tracking_meta( + super::xr_res(resume_simultaneous_hands_and_controllers_tracking_meta( session.as_raw(), &resume_info, ))?; diff --git a/alvr/client_openxr/src/interaction.rs b/alvr/client_openxr/src/interaction.rs index dbc65c73e1..1e1eb4ac26 100644 --- a/alvr/client_openxr/src/interaction.rs +++ b/alvr/client_openxr/src/interaction.rs @@ -260,16 +260,16 @@ pub fn initialize_interaction( .create_action("combined_eye_gaze", "Combined eye gaze", &[]) .unwrap(); - xr_ctx - .instance - .suggest_interaction_profile_bindings( - xr_ctx - .instance - .string_to_path("/interaction_profiles/ext/eye_gaze_interaction") - .unwrap(), - &[binding(&action, "/user/eyes_ext/input/gaze_ext/pose")], - ) - .ok()?; + let res = xr_ctx.instance.suggest_interaction_profile_bindings( + xr_ctx + .instance + .string_to_path("/interaction_profiles/ext/eye_gaze_interaction") + .unwrap(), + &[binding(&action, "/user/eyes_ext/input/gaze_ext/pose")], + ); + if res.is_err() { + warn!("Failed to register combined eye gaze input: {res:?}"); + } let space = action .create_space(xr_ctx.session.clone(), xr::Path::NULL, xr::Posef::IDENTITY) @@ -295,59 +295,80 @@ pub fn initialize_interaction( .create_space(xr_ctx.session.clone(), xr::Path::NULL, xr::Posef::IDENTITY) .unwrap(); - let left_hand_tracker = xr_ctx.session.create_hand_tracker(xr::Hand::LEFT).ok(); - let right_hand_tracker = xr_ctx.session.create_hand_tracker(xr::Hand::RIGHT).ok(); - - let eye_tracker_fb = face_tracking_sources - .as_ref() - .map(|s| s.eye_tracking_fb) - .unwrap_or(false) - .then(|| EyeTrackerSocial::new(&xr_ctx.session).ok()) - .flatten(); - - let face_tracker_fb = face_tracking_sources - .as_ref() - .map(|s| s.face_tracking_fb) - .unwrap_or(false) - .then(|| FaceTracker2FB::new(&xr_ctx.session, true, true).ok()) - .flatten(); - - let eye_tracker_htc = face_tracking_sources - .as_ref() - .map(|s| s.eye_expressions_htc) - .unwrap_or(false) - .then(|| { - FacialTrackerHTC::new(&xr_ctx.session, xr::FacialTrackingTypeHTC::EYE_DEFAULT).ok() - }) - .flatten(); - - let lip_tracker_htc = face_tracking_sources - .map(|s| s.lip_expressions_htc) - .unwrap_or(false) - .then(|| { - FacialTrackerHTC::new(&xr_ctx.session, xr::FacialTrackingTypeHTC::LIP_DEFAULT).ok() - }) - .flatten(); - - let body_tracker_fb = if let Some(body_tracking_fb) = - body_tracking_sources.and_then(|s| s.body_tracking_fb.into_option()) - { - body_tracking_fb - .full_body - .then(|| { - BodyTrackerFB::new(&xr_ctx.session, *BODY_JOINT_SET_FULL_BODY_META) - .ok() - .map(|tracker| (tracker, FULL_BODY_JOINT_COUNT_META)) + fn create_ext_object<T>( + name: &str, + enabled: Option<bool>, + create_cb: impl FnOnce() -> xr::Result<T>, + ) -> Option<T> { + enabled + .unwrap_or(false) + .then(|| match create_cb() { + Ok(obj) => Some(obj), + Err(xr::sys::Result::ERROR_FEATURE_UNSUPPORTED) => { + warn!("Cannot create unsupported {name}"); + None + } + Err(xr::sys::Result::ERROR_EXTENSION_NOT_PRESENT) => None, + Err(e) => { + warn!("Failed to create {name}: {e}"); + None + } }) .flatten() - .or_else(|| { - BodyTrackerFB::new(&xr_ctx.session, xr::BodyJointSetFB::DEFAULT) - .ok() - .map(|tracker| (tracker, xr::BodyJointFB::COUNT.into_raw() as usize)) - }) - } else { - None - }; + } + + let left_hand_tracker = create_ext_object("HandTracker (left)", Some(true), || { + xr_ctx.session.create_hand_tracker(xr::Hand::LEFT) + }); + let right_hand_tracker = create_ext_object("HandTracker (right)", Some(true), || { + xr_ctx.session.create_hand_tracker(xr::Hand::RIGHT) + }); + + let eye_tracker_fb = create_ext_object( + "EyeTrackerSocial", + face_tracking_sources.as_ref().map(|s| s.eye_tracking_fb), + || EyeTrackerSocial::new(&xr_ctx.session), + ); + + let face_tracker_fb = create_ext_object( + "FaceTracker2FB", + face_tracking_sources.as_ref().map(|s| s.face_tracking_fb), + || FaceTracker2FB::new(&xr_ctx.session, true, true), + ); + + let eye_tracker_htc = create_ext_object( + "FacialTrackerHTC (eyes)", + face_tracking_sources + .as_ref() + .map(|s| s.eye_expressions_htc), + || FacialTrackerHTC::new(&xr_ctx.session, xr::FacialTrackingTypeHTC::EYE_DEFAULT), + ); + + let lip_tracker_htc = create_ext_object( + "FacialTrackerHTC (lips)", + face_tracking_sources + .as_ref() + .map(|s| s.lip_expressions_htc), + || FacialTrackerHTC::new(&xr_ctx.session, xr::FacialTrackingTypeHTC::LIP_DEFAULT), + ); + + let body_tracker_fb = create_ext_object( + "BodyTrackerFB (full set)", + body_tracking_sources + .clone() + .and_then(|s| s.body_tracking_fb.into_option()) + .map(|c| c.full_body), + || BodyTrackerFB::new(&xr_ctx.session, *BODY_JOINT_SET_FULL_BODY_META), + ) + .map(|tracker| (tracker, FULL_BODY_JOINT_COUNT_META)) + .or_else(|| { + create_ext_object( + "BodyTrackerFB (default set)", + body_tracking_sources.map(|s| s.body_tracking_fb.enabled()), + || BodyTrackerFB::new(&xr_ctx.session, xr::BodyJointSetFB::DEFAULT), + ) + .map(|tracker| (tracker, xr::BodyJointFB::COUNT.into_raw() as usize)) + }); InteractionContext { action_set,