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

feat: Add support for Pico headsets face tracking #2666

Merged
merged 5 commits into from
Jan 31, 2025

Conversation

curoviyxru
Copy link
Contributor

@curoviyxru curoviyxru commented Jan 26, 2025

Adds face tracking support for Pico headsets. Tested on Pico 4 Pro with Pico OS 5.12.0S.

Resolves #2558, alvr-org/VRCFT-ALVR#3.
See related VRCFT-ALVR pull request: alvr-org/VRCFT-ALVR#4.

@Meister1593
Copy link
Collaborator

Meister1593 commented Jan 27, 2025

Will test a bit later (on p4pro with 5.9 pui), only one thought for now - can you use eye/face tracking separately?
without enabling one or another at the same time (just out of curiosity, maybe question for @zmerp too)

@Meister1593
Copy link
Collaborator

Added to review @The-personified-devil considering you have been in the og issue (maybe interested)

@curoviyxru
Copy link
Contributor Author

curoviyxru commented Jan 27, 2025

can you use eye/face tracking separately?

I don't really see any option to disable eye tracking data from XR_EXT_eye_gaze_interaction so I think you can't for now.

@zmerp
Copy link
Member

zmerp commented Jan 27, 2025

The reason we were enabling eye gaze interaction on pico unconditionally is because we didn't have access to any other api allowing to create the tracker objects separate from the action bindings which don't allow disabling either. If we are able to use the new XR_PICO_eye_tracking, we can skip XR_EXT_eye_gaze_interaction.

@curoviyxru
Copy link
Contributor Author

Pico's private eye-tracking functions also require XR_EXT_eye_gaze_interaction to be enabled. Is there any point in implementing it? I don't think so.

@curoviyxru curoviyxru deleted the branch alvr-org:master January 30, 2025 10:58
@curoviyxru curoviyxru closed this Jan 30, 2025
@curoviyxru curoviyxru deleted the master branch January 30, 2025 10:58
@curoviyxru curoviyxru restored the master branch January 30, 2025 10:58
@curoviyxru
Copy link
Contributor Author

Just wanted to rename branch, didn't know that it will close PR, sorry.

@curoviyxru curoviyxru reopened this Jan 30, 2025
@@ -189,6 +189,7 @@ fn tracking_thread(
fb_face_expression: None,
htc_eye_expression: None,
htc_lip_expression: None,
pico_face_expression: None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed on Discord, this is a breaking change and so we should reuse the fb_face_expression field for pico.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall I rename it into face_expression?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it wouldn't break the protocol (because it's binary and packed) i think we should keep the current name for now. We will add a proper separate field on v21.


impl FaceTrackerPico {
pub fn new<G>(session: xr::Session<G>, visual: bool, audio: bool) -> xr::Result<Self> {
let mut tracking_flags = 0u64;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be no need to specify the type in the literal (u64) but if you do, put a underscore in between: 0_u64

Comment on lines 46 to 57
let get_face_tracking_data = unsafe {
let mut get_face_tracking_data = None;
let _ = (session.instance().fp().get_instance_proc_addr)(
session.instance().as_raw(),
c"xrGetFaceTrackingDataPICO".as_ptr(),
&mut get_face_tracking_data,
);

get_face_tracking_data
.map(|pfn| mem::transmute::<VoidFunction, GetFaceTrackingDataPICO>(pfn))
}
.ok_or(sys::Result::ERROR_EXTENSION_NOT_PRESENT)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this code, you might want to check that the extension exists, using the extra_extensions list (you need to add the parameter in the new()). Check the multimodal extension for a reference.

Comment on lines 84 to 85
super::xr_res(start_eye_tracking(session.as_raw()))?;
super::xr_res(set_tracking_mode(session.as_raw(), tracking_flags))?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like multimodal, this API uses global start/stop functions. so i'd advise to expose those functions from this structure and let the caller site manage when to call those functions. Of course you also would need to rev-eng the stop/pause function signature

})
}

pub fn get_face_expression_weights(&self, time: xr::Time) -> xr::Result<Option<Vec<f32>>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name of this function should reflect more the name of the inner function you are calling. I'd like for the APIs we are exposing in the modules in extra_extensions to be as transparent as possible.

@@ -142,6 +144,10 @@ impl FaceTrackingSink {
self.append_packet_vrcft(b"LipHtc\0\0", &arr);
}

if let Some(arr) = face_data.pico_face_expression {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, instead of the pico_face_expression, you should match fb or pico prefix based on the length of fb_face_expression

@curoviyxru curoviyxru requested a review from zmerp January 30, 2025 21:09
Copy link
Member

@zmerp zmerp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks alright. there is mainly just a couple of lints to fix. Also, you haven't exposed set_tracking_mode separately but I think it's better this way

@zmerp zmerp merged commit 92c82f7 into alvr-org:master Jan 31, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pico 4 Enterprise Face Tracking/ Unity Client
3 participants