diff --git a/AlternativePlay/Models/TrackedDeviceManager.cs b/AlternativePlay/Models/TrackedDeviceManager.cs index 8b55f93..2a9b894 100644 --- a/AlternativePlay/Models/TrackedDeviceManager.cs +++ b/AlternativePlay/Models/TrackedDeviceManager.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Text; using UnityEngine; +using UnityEngine.XR; using Valve.VR; using Zenject; using static Valve.VR.IVRSystem; @@ -37,6 +38,7 @@ public class TrackedDeviceManager #pragma warning restore CS0649 public List TrackedDevices { get; private set; } = new List(); + public List OpenXrDevices { get; private set; } = new List(); /// /// Updates the list of valid tracked devices and their properties only. Use to get the @@ -84,7 +86,9 @@ public void LoadTrackedDeviceProperties() /// public void PollTrackedDevices() { - const float predictionBiasSeconds = 0.0255f; + const float minPredictionSeconds = 0.0f; + const float maxPredictionSeconds = 0.1f; + const float predictionBiasSeconds = 0.0225f; // Calculate time to predict into the future float secondsSinceLastVsync = 0.0f; @@ -99,6 +103,9 @@ public void PollTrackedDevices() float predictedSecondsFromNow = frameDuration - secondsSinceLastVsync + fVsyncToPhotons; predictedSecondsFromNow += predictionBiasSeconds; + if (predictedSecondsFromNow < minPredictionSeconds) { predictedSecondsFromNow = minPredictionSeconds; } + if (predictedSecondsFromNow > maxPredictionSeconds) { predictedSecondsFromNow = maxPredictionSeconds; } + // Get all tracked device poses from OpenVR API TrackedDevicePose_t[] trackedDevicePoseArray = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount]; this.openVRManager.System.GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin.TrackingUniverseStanding, predictedSecondsFromNow, trackedDevicePoseArray); @@ -148,13 +155,55 @@ public OpenVRDeviceInfo GetInputDeviceFromSerial(string serial) public Pose? GetPoseFromRightController() { uint index = this.openVRManager.System.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.RightHand); - var device = this.TrackedDevices.ElementAtOrDefault((int)index); + var device = this.TrackedDevices.FirstOrDefault(d => d.Index == (int)index); if (device == null) { return null; } return device.Pose; } + public Pose? GetPoseFromOpenXrLeftController() + { + if (TryGetOpenXrControllerPose(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left, out Pose pose)) + { + return pose; + } + + return null; + } + + public Pose? GetPoseFromOpenXrRightController() + { + if (TryGetOpenXrControllerPose(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right, out Pose pose)) + { + return pose; + } + + return null; + } + + private bool TryGetOpenXrControllerPose(InputDeviceCharacteristics characteristics, out Pose pose) + { + List devices = this.OpenXrDevices; + InputDevices.GetDevicesWithCharacteristics(characteristics, devices); + + var device = devices.FirstOrDefault(d => + d.TryGetFeatureValue(CommonUsages.devicePosition, out _) && + d.TryGetFeatureValue(CommonUsages.deviceRotation, out _) + ); + + if (device.isValid) + { + device.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 position); + device.TryGetFeatureValue(CommonUsages.deviceRotation, out Quaternion rotation); + pose = new Pose(position, rotation); + return true; + } + + pose = default; + return false; + } + /// /// This method calls on to compute the tracked position /// given the serial number of the tracker. diff --git a/AlternativePlay/SaberDeviceManager.cs b/AlternativePlay/SaberDeviceManager.cs index d73db38..856f306 100644 --- a/AlternativePlay/SaberDeviceManager.cs +++ b/AlternativePlay/SaberDeviceManager.cs @@ -61,7 +61,7 @@ public Pose GetLeftSaberPose(TrackerConfigData configData) if (!this.calibrated) return new Pose(); // Return adjusted position from the saber - Pose controllerPose = this.trackedDeviceManager.GetPoseFromLeftController() ?? new Pose(); + Pose controllerPose = this.trackedDeviceManager.GetPoseFromOpenXrLeftController() ?? this.trackedDeviceManager.GetPoseFromLeftController() ?? new Pose(); Pose adjustedControllerPose = this.AdjustForPlayerOrigin(controllerPose); return TrackedDeviceManager.GetTrackedObjectPose(this.savedLeftSaber, this.savedLeftController, adjustedControllerPose); } @@ -87,7 +87,7 @@ public Pose GetRightSaberPose(TrackerConfigData configData) if (!this.calibrated) return new Pose(); // Return adjusted position from the saber - Pose controllerPose = this.trackedDeviceManager.GetPoseFromRightController() ?? new Pose(); + Pose controllerPose = this.trackedDeviceManager.GetPoseFromOpenXrRightController() ?? this.trackedDeviceManager.GetPoseFromRightController() ?? new Pose(); Pose adjustedControllerPose = this.AdjustForPlayerOrigin(controllerPose); return TrackedDeviceManager.GetTrackedObjectPose(this.savedRightSaber, this.savedRightController, adjustedControllerPose); }