Skip to content

Commit 4340fdc

Browse files
authored
Implement forwarding XR_EXT_user_presence from client to server to Steam (#3052)
* Implement forwarding XR_EXT_user_presence from client to server to Steam * bump -devXX version to 11 * fixup * alphabetical order * remove logs * change enum order * add c_api event for proximity * rename user_presence to proximity_state * rename last occurance of user presence * fix format * rename remaining instances of proximity_state to headset_is_worn * Send initial state of proximity sensor when reconnecting * undo changes to early hmd initialization * explicit field name headset_is_worn for messages * change order * Revert "Send initial state of proximity sensor when reconnecting" This reverts commit 0ad0037. * change user presence log to debug
1 parent 85c9638 commit 4340fdc

File tree

11 files changed

+45
-1
lines changed

11 files changed

+45
-1
lines changed

alvr/client_core/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,14 @@ impl ClientCoreContext {
223223
}
224224
}
225225

226+
pub fn send_proximity_state(&self, headset_is_worn: bool) {
227+
if let Some(sender) = &mut *self.connection_context.control_sender.lock() {
228+
sender
229+
.send(&ClientControlPacket::ProximityState(headset_is_worn))
230+
.ok();
231+
}
232+
}
233+
226234
pub fn get_total_prediction_offset(&self) -> Duration {
227235
dbg_client_core!("get_total_prediction_offset");
228236

alvr/client_openxr/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod stream;
99
use crate::stream::ParsedStreamConfig;
1010
use alvr_client_core::{ClientCapabilities, ClientCoreContext, ClientCoreEvent};
1111
use alvr_common::{
12-
Fov, HAND_LEFT_ID, Pose, error,
12+
Fov, HAND_LEFT_ID, Pose, debug, error,
1313
glam::{Quat, UVec2, Vec3},
1414
info,
1515
parking_lot::RwLock,
@@ -166,6 +166,7 @@ pub fn entry_point() {
166166
exts.ext_eye_gaze_interaction = available_extensions.ext_eye_gaze_interaction;
167167
exts.ext_hand_tracking = available_extensions.ext_hand_tracking;
168168
exts.ext_local_floor = available_extensions.ext_local_floor;
169+
exts.ext_user_presence = available_extensions.ext_user_presence;
169170
exts.fb_body_tracking = available_extensions.fb_body_tracking;
170171
exts.fb_color_space = available_extensions.fb_color_space;
171172
exts.fb_composition_layer_settings = available_extensions.fb_composition_layer_settings;
@@ -326,6 +327,7 @@ pub fn entry_point() {
326327
let mut passthrough_layer = None;
327328

328329
let mut event_storage = xr::EventDataBuffer::new();
330+
let mut headset_is_worn = true;
329331
'render_loop: loop {
330332
while let Some(event) = xr_instance.poll_event(&mut event_storage).unwrap() {
331333
match event {
@@ -384,6 +386,12 @@ pub fn entry_point() {
384386
| xr::Event::PassthroughStateChangedFB(_) => {
385387
// todo
386388
}
389+
xr::Event::UserPresenceChangedEXT(event) => {
390+
debug!("user present: {:?}", event.is_user_present());
391+
headset_is_worn = event.is_user_present();
392+
393+
core_context.send_proximity_state(event.is_user_present());
394+
}
387395
_ => (),
388396
}
389397
}
@@ -416,6 +424,8 @@ pub fn entry_point() {
416424
}
417425

418426
stream_context = Some(context);
427+
428+
core_context.send_proximity_state(headset_is_worn);
419429
}
420430
ClientCoreEvent::StreamingStopped => {
421431
if passthrough_layer.is_none() {

alvr/packets/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ pub enum ClientControlPacket {
194194
level: LogSeverity,
195195
message: String,
196196
},
197+
ProximityState(bool),
197198
Reserved(String),
198199
ReservedBuffer(Vec<u8>),
199200
}

alvr/server_core/src/c_api.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub enum AlvrEvent {
7171
CaptureFrame,
7272
RestartPending,
7373
ShutdownPending,
74+
ProximityState(bool),
7475
}
7576

7677
#[repr(C)]
@@ -293,6 +294,9 @@ pub unsafe extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent, timeout_ns:
293294
},
294295
ServerCoreEvent::GameRenderLatencyFeedback(_)
295296
| ServerCoreEvent::SetOpenvrProperty { .. } => {} // implementation not needed
297+
ServerCoreEvent::ProximityState(headset_is_worn) => unsafe {
298+
*out_event = AlvrEvent::ProximityState(headset_is_worn);
299+
},
296300
}
297301

298302
true

alvr/server_core/src/connection.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,11 @@ fn connection_pipeline(
13091309
info!("Client {client_hostname}: [{level:?}] {message}")
13101310
}
13111311
ClientControlPacket::KeepAlive | ClientControlPacket::StreamReady => (),
1312+
ClientControlPacket::ProximityState(headset_is_worn) => {
1313+
ctx.events_sender
1314+
.send(ServerCoreEvent::ProximityState(headset_is_worn))
1315+
.ok();
1316+
}
13121317
ClientControlPacket::Reserved(_) | ClientControlPacket::ReservedBuffer(_) => (),
13131318
}
13141319

alvr/server_core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub enum ServerCoreEvent {
8989
GameRenderLatencyFeedback(Duration), // only used for SteamVR
9090
ShutdownPending,
9191
RestartPending,
92+
ProximityState(bool),
9293
}
9394

9495
pub struct ConnectionContext {

alvr/server_openvr/cpp/alvr_server/HMD.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ void Hmd::SetViewParams(const FfiViewParams params[2]) {
296296
);
297297
}
298298

299+
void Hmd::SetProximityState(bool headsetIsWorn) {
300+
vr::VRDriverInput()->UpdateBooleanComponent(m_proximity, headsetIsWorn, 0.0);
301+
}
302+
299303
void Hmd::GetWindowBounds(int32_t* pnX, int32_t* pnY, uint32_t* pnWidth, uint32_t* pnHeight) {
300304
Debug(
301305
"Hmd::GetWindowBounds %dx%d - %dx%d\n",

alvr/server_openvr/cpp/alvr_server/HMD.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Hmd : public TrackedDevice, vr::IVRDisplayComponent {
2929
void StartStreaming();
3030
void StopStreaming();
3131
void SetViewParams(const FfiViewParams params[2]);
32+
void SetProximityState(bool headsetIsWorn);
3233

3334
private:
3435
vr::VRInputComponentHandle_t m_proximity;

alvr/server_openvr/cpp/alvr_server/alvr_server.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,12 @@ void SetButton(unsigned long long buttonID, FfiButtonValue value) {
513513
}
514514
}
515515

516+
void SetProximityState(bool headset_is_worn) {
517+
if (g_driver_provider.hmd) {
518+
g_driver_provider.hmd->SetProximityState(headset_is_worn);
519+
}
520+
}
521+
516522
void SetChaperoneArea(float areaWidth, float areaHeight) {
517523
_SetChaperoneArea(areaWidth, areaHeight);
518524
}

alvr/server_openvr/cpp/alvr_server/bindings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ extern "C" void RegisterButton(void* instancePtr, unsigned long long buttonID);
161161
extern "C" void SetLocalViewParams(const FfiViewParams params[2]);
162162
extern "C" void SetBattery(unsigned long long deviceID, float gauge_value, bool is_plugged);
163163
extern "C" void SetButton(unsigned long long buttonID, FfiButtonValue value);
164+
extern "C" void SetProximityState(bool headset_is_worn);
164165

165166
extern "C" void InitOpenvrClient();
166167
extern "C" void ShutdownOpenvrClient();

0 commit comments

Comments
 (0)