@@ -19,14 +19,15 @@ use alvr_common::{
19
19
once_cell:: sync:: Lazy ,
20
20
parking_lot:: { Mutex , RwLock } ,
21
21
settings_schema:: Switch ,
22
- warn, BUTTON_INFO , HAND_LEFT_ID , HAND_RIGHT_ID , HAND_TRACKER_LEFT_ID , HAND_TRACKER_RIGHT_ID ,
23
- HEAD_ID ,
22
+ warn, Pose , BUTTON_INFO , HAND_LEFT_ID , HAND_RIGHT_ID , HAND_TRACKER_LEFT_ID ,
23
+ HAND_TRACKER_RIGHT_ID , HEAD_ID ,
24
24
} ;
25
25
use alvr_filesystem as afs;
26
- use alvr_packets:: { ButtonValue , Haptics } ;
26
+ use alvr_packets:: { ButtonValue , Haptics , ViewParams } ;
27
27
use alvr_server_core:: { HandType , ServerCoreContext , ServerCoreEvent } ;
28
28
use alvr_session:: { CodecType , ControllersConfig } ;
29
29
use std:: {
30
+ collections:: VecDeque ,
30
31
ffi:: { c_char, c_void, CString } ,
31
32
ptr,
32
33
sync:: { mpsc, Once } ,
@@ -45,6 +46,12 @@ static SERVER_CORE_CONTEXT: Lazy<RwLock<Option<ServerCoreContext>>> =
45
46
static EVENTS_RECEIVER : Lazy < Mutex < Option < mpsc:: Receiver < ServerCoreEvent > > > > =
46
47
Lazy :: new ( || Mutex :: new ( None ) ) ;
47
48
49
+ // local frame of reference
50
+ static VIEWS_PARAMS : Lazy < RwLock < [ ViewParams ; 2 ] > > =
51
+ Lazy :: new ( || RwLock :: new ( [ ViewParams :: default ( ) ; 2 ] ) ) ;
52
+ static HEAD_POSE_QUEUE : Lazy < Mutex < VecDeque < ( Duration , Pose ) > > > =
53
+ Lazy :: new ( || Mutex :: new ( VecDeque :: new ( ) ) ) ;
54
+
48
55
extern "C" fn driver_ready_idle ( set_default_chap : bool ) {
49
56
thread:: spawn ( move || {
50
57
let events_receiver = EVENTS_RECEIVER . lock ( ) . take ( ) . unwrap ( ) ;
@@ -88,25 +95,26 @@ extern "C" fn driver_ready_idle(set_default_chap: bool) {
88
95
ServerCoreEvent :: PlayspaceSync ( bounds) => unsafe {
89
96
SetChaperoneArea ( bounds. x , bounds. y )
90
97
} ,
91
- ServerCoreEvent :: ViewsConfig ( config) => unsafe {
98
+ ServerCoreEvent :: ViewsParams ( params) => unsafe {
99
+ * VIEWS_PARAMS . write ( ) = params;
100
+
92
101
SetViewsConfig ( FfiViewsConfig {
93
102
fov : [
94
103
FfiFov {
95
- left : config . fov [ 0 ] . left ,
96
- right : config . fov [ 0 ] . right ,
97
- up : config . fov [ 0 ] . up ,
98
- down : config . fov [ 0 ] . down ,
104
+ left : params [ 0 ] . fov . left ,
105
+ right : params [ 0 ] . fov . right ,
106
+ up : params [ 0 ] . fov . up ,
107
+ down : params [ 0 ] . fov . down ,
99
108
} ,
100
109
FfiFov {
101
- left : config . fov [ 1 ] . left ,
102
- right : config . fov [ 1 ] . right ,
103
- up : config . fov [ 1 ] . up ,
104
- down : config . fov [ 1 ] . down ,
110
+ left : params [ 1 ] . fov . left ,
111
+ right : params [ 1 ] . fov . right ,
112
+ up : params [ 1 ] . fov . up ,
113
+ down : params [ 1 ] . fov . down ,
105
114
} ,
106
115
] ,
107
116
// todo: send full matrix to steamvr
108
- ipd_m : config. local_view_transforms [ 1 ] . position . x
109
- - config. local_view_transforms [ 0 ] . position . x ,
117
+ ipd_m : params[ 1 ] . pose . position . x - params[ 0 ] . pose . position . x ,
110
118
} ) ;
111
119
} ,
112
120
ServerCoreEvent :: Tracking { sample_timestamp } => {
@@ -121,18 +129,36 @@ extern "C" fn driver_ready_idle(set_default_chap: bool) {
121
129
. unwrap_or ( false ) ;
122
130
123
131
if let Some ( context) = & * SERVER_CORE_CONTEXT . read ( ) {
132
+ let target_timestamp =
133
+ sample_timestamp + context. get_motion_to_photon_latency ( ) ;
124
134
let controllers_pose_time_offset = context. get_tracker_pose_time_offset ( ) ;
135
+ let controllers_timestamp =
136
+ target_timestamp. saturating_sub ( controllers_pose_time_offset) ;
137
+
138
+ let predicted_head_motion = context
139
+ . get_predicted_device_motion (
140
+ * HEAD_ID ,
141
+ sample_timestamp,
142
+ target_timestamp,
143
+ )
144
+ . unwrap_or_default ( ) ;
125
145
126
- let ffi_head_motion = context
127
- . get_device_motion ( * HEAD_ID , sample_timestamp)
128
- . map ( |m| tracking:: to_ffi_motion ( * HEAD_ID , m) )
129
- . unwrap_or_else ( FfiDeviceMotion :: default) ;
146
+ let ffi_head_motion =
147
+ tracking:: to_ffi_motion ( * HEAD_ID , predicted_head_motion) ;
130
148
let ffi_left_controller_motion = context
131
- . get_device_motion ( * HAND_LEFT_ID , sample_timestamp)
149
+ . get_predicted_device_motion (
150
+ * HAND_LEFT_ID ,
151
+ sample_timestamp,
152
+ controllers_timestamp,
153
+ )
132
154
. map ( |m| tracking:: to_ffi_motion ( * HAND_LEFT_ID , m) )
133
155
. filter ( |_| tracked) ;
134
156
let ffi_right_controller_motion = context
135
- . get_device_motion ( * HAND_RIGHT_ID , sample_timestamp)
157
+ . get_predicted_device_motion (
158
+ * HAND_RIGHT_ID ,
159
+ sample_timestamp,
160
+ controllers_timestamp,
161
+ )
136
162
. map ( |m| tracking:: to_ffi_motion ( * HAND_RIGHT_ID , m) )
137
163
. filter ( |_| tracked) ;
138
164
@@ -237,6 +263,17 @@ extern "C" fn driver_ready_idle(set_default_chap: bool) {
237
263
ffi_body_tracker_motions. len ( ) as i32 ,
238
264
)
239
265
} ;
266
+
267
+ {
268
+ let mut head_pose_queue_lock = HEAD_POSE_QUEUE . lock ( ) ;
269
+
270
+ head_pose_queue_lock
271
+ . push_back ( ( sample_timestamp, predicted_head_motion. pose ) ) ;
272
+
273
+ if head_pose_queue_lock. len ( ) > 1024 {
274
+ head_pose_queue_lock. pop_front ( ) ;
275
+ }
276
+ }
240
277
}
241
278
}
242
279
ServerCoreEvent :: Buttons ( entries) => {
@@ -344,7 +381,25 @@ extern "C" fn set_video_config_nals(buffer_ptr: *const u8, len: i32, codec: i32)
344
381
extern "C" fn send_video ( timestamp_ns : u64 , buffer_ptr : * mut u8 , len : i32 , is_idr : bool ) {
345
382
if let Some ( context) = & * SERVER_CORE_CONTEXT . read ( ) {
346
383
let buffer = unsafe { std:: slice:: from_raw_parts ( buffer_ptr, len as usize ) } ;
347
- context. send_video_nal ( Duration :: from_nanos ( timestamp_ns) , buffer. to_vec ( ) , is_idr) ;
384
+
385
+ let mut head_pose = Pose :: default ( ) ;
386
+ for ( timestamp, pose) in & * HEAD_POSE_QUEUE . lock ( ) {
387
+ if * timestamp == Duration :: from_nanos ( timestamp_ns) {
388
+ head_pose = * pose;
389
+ break ;
390
+ }
391
+ }
392
+
393
+ let mut view_params = * VIEWS_PARAMS . read ( ) ;
394
+ view_params[ 0 ] . pose = head_pose * view_params[ 0 ] . pose ;
395
+ view_params[ 1 ] . pose = head_pose * view_params[ 1 ] . pose ;
396
+
397
+ context. send_video_nal (
398
+ Duration :: from_nanos ( timestamp_ns) ,
399
+ view_params,
400
+ is_idr,
401
+ buffer. to_vec ( ) ,
402
+ ) ;
348
403
}
349
404
}
350
405
0 commit comments