Skip to content

Commit 850b8aa

Browse files
committed
update "real pose" on input thread
1 parent 27a9e84 commit 850b8aa

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

OpenVR.NET/VR.cs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ public bool UninstallApp ( string vrmanifestPath ) {
155155
bool hasFocus = true;
156156
public ETrackingUniverseOrigin TrackingOrigin { get; private set; } = (ETrackingUniverseOrigin)( -1 );
157157
TrackedDevicePose_t[] renderPoses = new TrackedDevicePose_t[Valve.VR.OpenVR.k_unMaxTrackedDeviceCount];
158-
TrackedDevicePose_t[] gamePoses = new TrackedDevicePose_t[Valve.VR.OpenVR.k_unMaxTrackedDeviceCount];
159158
Dictionary<int, (VrDevice device, VrDevice.Owner owner)> trackedDeviceOwners = new();
160159
HashSet<VrDevice> activeDevices = new();
161160
// although in theory this should be on the update thread,
@@ -166,7 +165,7 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
166165
Valve.VR.OpenVR.Compositor.SetTrackingSpace( origin );
167166
}
168167

169-
var error = Valve.VR.OpenVR.Compositor.WaitGetPoses( renderPoses, gamePoses );
168+
var error = Valve.VR.OpenVR.Compositor.WaitGetPoses( renderPoses, Array.Empty<TrackedDevicePose_t>() );
170169
if ( error is EVRCompositorError.DoNotHaveFocus ) {
171170
if ( hasFocus ) {
172171
hasFocus = false;
@@ -220,11 +219,9 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
220219
if ( pose.bDeviceIsConnected ) {
221220
if ( !activeDevices.Contains( device ) ) {
222221
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+
} );
228225
updateScheduler.Enqueue( () => {
229226
owner.IsEnabled = true;
230227
} );
@@ -233,12 +230,12 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
233230
else {
234231
if ( activeDevices.Contains( device ) ) {
235232
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 ) {
239236
controller.OnTurnedOff();
240-
} );
241-
}
237+
}
238+
} );
242239
updateScheduler.Enqueue( () => {
243240
owner.IsEnabled = false;
244241
} );
@@ -248,11 +245,6 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
248245
if ( pose.bPoseIsValid ) {
249246
owner.RenderPosition = ExtractPosition( ref pose.mDeviceToAbsoluteTracking );
250247
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 );
256248
}
257249

258250
if ( pose.eTrackingResult != owner.offThreadTrackingState ) {
@@ -267,19 +259,33 @@ void pollPoses ( ETrackingUniverseOrigin origin ) {
267259
#endregion
268260
#region Input Thread
269261
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];
271264

272265
/// <summary>
273266
/// 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
274268
/// </summary>
275-
public void UpdateInput () {
269+
public void UpdateInput ( float posePredictionTime = 0 ) {
276270
while ( inputScheduler.TryDequeue( out var action ) ) {
277271
action();
278272
}
279273

280274
if ( !State.HasFlag( VrState.OK ) )
281275
return;
282276

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+
283289
if ( actionSets != null ) {
284290
var error = Valve.VR.OpenVR.Input.UpdateActionState( actionSets, (uint)Marshal.SizeOf<VRActiveActionSet_t>() );
285291
if ( error != EVRInputError.None ) {
@@ -293,7 +299,8 @@ public void UpdateInput () {
293299
}
294300

295301
foreach ( var i in updateableInputDevices ) {
296-
i.UpdateInput();
302+
if ( i.device is Controller controller )
303+
controller.UpdateInput();
297304
}
298305
}
299306
#endregion

VisualTests/Scene/VrModel.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ public VrModel ( VrDevice device, ComponentModel component, Mesh<TexturedVertex>
2121
}
2222

2323
public void Update () {
24-
ParentTransform.Position = new( Device.Position.X, Device.Position.Y, Device.Position.Z );
25-
ParentTransform.Rotation = new( Device.Rotation.X, Device.Rotation.Y, Device.Rotation.Z, Device.Rotation.W );
24+
var pos = Device.RenderPosition;
25+
var rot = Device.RenderRotation;
26+
ParentTransform.Position = new( pos.X, pos.Y, pos.Z );
27+
ParentTransform.Rotation = new( rot.X, rot.Y, rot.Z, rot.W );
2628

2729
var maybeState = (Device as Controller)?.GetComponentState( Component );
2830
if ( maybeState is not Controller.ComponentState state )

0 commit comments

Comments
 (0)