@@ -155,7 +155,6 @@ public bool UninstallApp ( string vrmanifestPath ) {
155
155
bool hasFocus = true ;
156
156
public ETrackingUniverseOrigin TrackingOrigin { get ; private set ; } = ( ETrackingUniverseOrigin ) ( - 1 ) ;
157
157
TrackedDevicePose_t [ ] renderPoses = new TrackedDevicePose_t [ Valve . VR . OpenVR . k_unMaxTrackedDeviceCount ] ;
158
- TrackedDevicePose_t [ ] gamePoses = new TrackedDevicePose_t [ Valve . VR . OpenVR . k_unMaxTrackedDeviceCount ] ;
159
158
Dictionary < int , ( VrDevice device , VrDevice . Owner owner ) > trackedDeviceOwners = new ( ) ;
160
159
HashSet < VrDevice > activeDevices = new ( ) ;
161
160
// although in theory this should be on the update thread,
@@ -166,7 +165,7 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
166
165
Valve . VR . OpenVR . Compositor . SetTrackingSpace ( origin ) ;
167
166
}
168
167
169
- var error = Valve . VR . OpenVR . Compositor . WaitGetPoses ( renderPoses , gamePoses ) ;
168
+ var error = Valve . VR . OpenVR . Compositor . WaitGetPoses ( renderPoses , Array . Empty < TrackedDevicePose_t > ( ) ) ;
170
169
if ( error is EVRCompositorError . DoNotHaveFocus ) {
171
170
if ( hasFocus ) {
172
171
hasFocus = false ;
@@ -220,11 +219,9 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
220
219
if ( pose . bDeviceIsConnected ) {
221
220
if ( ! activeDevices . Contains ( device ) ) {
222
221
activeDevices . Add ( device ) ;
223
- if ( device is Controller controller ) {
224
- inputScheduler . Enqueue ( ( ) => {
225
- updateableInputDevices . Add ( controller ) ;
226
- } ) ;
227
- }
222
+ inputScheduler . Enqueue ( ( ) => {
223
+ updateableInputDevices . Add ( ( device , owner ) ) ;
224
+ } ) ;
228
225
updateScheduler . Enqueue ( ( ) => {
229
226
owner . IsEnabled = true ;
230
227
} ) ;
@@ -233,12 +230,12 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
233
230
else {
234
231
if ( activeDevices . Contains ( device ) ) {
235
232
activeDevices . Remove ( device ) ;
236
- if ( device is Controller controller ) {
237
- inputScheduler . Enqueue ( ( ) => {
238
- updateableInputDevices . Remove ( controller ) ;
233
+ inputScheduler . Enqueue ( ( ) => {
234
+ updateableInputDevices . Remove ( ( device , owner ) ) ;
235
+ if ( device is Controller controller ) {
239
236
controller . OnTurnedOff ( ) ;
240
- } ) ;
241
- }
237
+ }
238
+ } ) ;
242
239
updateScheduler . Enqueue ( ( ) => {
243
240
owner . IsEnabled = false ;
244
241
} ) ;
@@ -248,11 +245,6 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
248
245
if ( pose . bPoseIsValid ) {
249
246
owner . RenderPosition = ExtractPosition ( ref pose . mDeviceToAbsoluteTracking ) ;
250
247
owner . RenderRotation = ExtractRotation ( ref pose . mDeviceToAbsoluteTracking ) ;
251
- pose = ref gamePoses [ i ] ;
252
- owner . Position = ExtractPosition ( ref pose . mDeviceToAbsoluteTracking ) ;
253
- owner . Rotation = ExtractRotation ( ref pose . mDeviceToAbsoluteTracking ) ;
254
- owner . Velocity = new ( pose . vVelocity . v0 , pose . vVelocity . v1 , pose . vVelocity . v2 ) ;
255
- owner . AngularVelocity = new ( pose . vAngularVelocity . v0 , pose . vAngularVelocity . v1 , - pose . vAngularVelocity . v2 ) ;
256
248
}
257
249
258
250
if ( pose . eTrackingResult != owner . offThreadTrackingState ) {
@@ -267,19 +259,33 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
267
259
#endregion
268
260
#region Input Thread
269
261
ConcurrentQueue < Action > inputScheduler = new ( ) ;
270
- HashSet < Controller > updateableInputDevices = new ( ) ;
262
+ HashSet < ( VrDevice device , VrDevice . Owner owner ) > updateableInputDevices = new ( ) ;
263
+ TrackedDevicePose_t [ ] gamePoses = new TrackedDevicePose_t [ Valve . VR . OpenVR . k_unMaxTrackedDeviceCount ] ;
271
264
272
265
/// <summary>
273
266
/// Updates inputs. Should be called on the input or update thread.
267
+ /// You can supply a time in seconds for openvr to predict input poses
274
268
/// </summary>
275
- public void UpdateInput ( ) {
269
+ public void UpdateInput ( float posePredictionTime = 0 ) {
276
270
while ( inputScheduler . TryDequeue ( out var action ) ) {
277
271
action ( ) ;
278
272
}
279
273
280
274
if ( ! State . HasFlag ( VrState . OK ) )
281
275
return ;
282
276
277
+ CVR . GetDeviceToAbsoluteTrackingPose ( TrackingOrigin , posePredictionTime , gamePoses ) ;
278
+ foreach ( var ( device , owner ) in updateableInputDevices ) {
279
+ ref var pose = ref gamePoses [ device . DeviceIndex ] ;
280
+ if ( ! pose . bPoseIsValid )
281
+ continue ;
282
+
283
+ owner . Position = ExtractPosition ( ref pose . mDeviceToAbsoluteTracking ) ;
284
+ owner . Rotation = ExtractRotation ( ref pose . mDeviceToAbsoluteTracking ) ;
285
+ owner . Velocity = new ( pose . vVelocity . v0 , pose . vVelocity . v1 , pose . vVelocity . v2 ) ;
286
+ owner . AngularVelocity = new ( pose . vAngularVelocity . v0 , pose . vAngularVelocity . v1 , - pose . vAngularVelocity . v2 ) ;
287
+ }
288
+
283
289
if ( actionSets != null ) {
284
290
var error = Valve . VR . OpenVR . Input . UpdateActionState ( actionSets , ( uint ) Marshal . SizeOf < VRActiveActionSet_t > ( ) ) ;
285
291
if ( error != EVRInputError . None ) {
@@ -293,7 +299,8 @@ public void UpdateInput () {
293
299
}
294
300
295
301
foreach ( var i in updateableInputDevices ) {
296
- i . UpdateInput ( ) ;
302
+ if ( i . device is Controller controller )
303
+ controller . UpdateInput ( ) ;
297
304
}
298
305
}
299
306
#endregion
0 commit comments