Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose eye calibration state when using XR SDK #11269

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions Assets/MRTK/Providers/OpenXR/Scripts/OpenXREyeGazeDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
using UnityEngine.XR.OpenXR.Features.Interactions;
#endif // UNITY_OPENXR

#if MSFT_OPENXR && WINDOWS_UWP
using Windows.Perception;
using Windows.Perception.People;
using Windows.Perception.Spatial;
using Windows.UI.Input.Spatial;
#endif // MSFT_OPENXR && WINDOWS_UWP

namespace Microsoft.MixedReality.Toolkit.XRSDK.OpenXR
{
[MixedRealityDataProvider(
Expand Down Expand Up @@ -163,12 +170,12 @@ public override void Update()

if (!eyeTrackingDevice.isValid)
{
Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, false);
UpdateEyeTrackingCalibrationStatus(false);
return;
}
}

Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, true);
UpdateEyeTrackingCalibrationStatus(true);

#if UNITY_OPENXR
if (eyeTrackingDevice.TryGetFeatureValue(CommonUsages.isTracked, out bool gazeTracked)
Expand All @@ -191,5 +198,26 @@ public override void Update()
#endif // UNITY_OPENXR
}
}

private void UpdateEyeTrackingCalibrationStatus(bool defaultValue)
{
#if MSFT_OPENXR && WINDOWS_UWP
if (MixedReality.OpenXR.PerceptionInterop.GetSceneCoordinateSystem(Pose.identity) is SpatialCoordinateSystem worldOrigin)
{
SpatialPointerPose pointerPose = SpatialPointerPose.TryGetAtTimestamp(worldOrigin, PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now));
if (pointerPose != null)
{
EyesPose eyes = pointerPose.Eyes;
if (eyes != null)
{
Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, eyes.IsCalibrationValid);
return;
}
}
}
#endif // MSFT_OPENXR && WINDOWS_UWP

Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, defaultValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@
using Unity.Profiling;
using Unity.XR.WindowsMR;
using UnityEngine.XR;

#if WINDOWS_UWP
using Windows.Perception;
using Windows.Perception.People;
using Windows.Perception.Spatial;
using Windows.UI.Input.Spatial;
#elif UNITY_WSA && DOTNETWINRT_PRESENT
using Microsoft.Windows.Perception;
using Microsoft.Windows.Perception.People;
using Microsoft.Windows.Perception.Spatial;
using Microsoft.Windows.UI.Input.Spatial;
#endif
#endif // WMR_2_7_0_OR_NEWER || WMR_4_4_2_OR_NEWER || WMR_5_2_2_OR_NEWER

namespace Microsoft.MixedReality.Toolkit.XRSDK.WindowsMixedReality
Expand Down Expand Up @@ -172,18 +184,18 @@ public override void Update()
centerEye = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye);
if (!centerEye.isValid)
{
Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, false);
UpdateEyeTrackingCalibrationStatus(false);
return;
}
}

if (!centerEye.TryGetFeatureValue(WindowsMRUsages.EyeGazeAvailable, out bool gazeAvailable) || !gazeAvailable)
{
Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, false);
UpdateEyeTrackingCalibrationStatus(false);
return;
}

Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, true);
UpdateEyeTrackingCalibrationStatus(true);

if (centerEye.TryGetFeatureValue(WindowsMRUsages.EyeGazeTracked, out bool gazeTracked)
&& gazeTracked
Expand All @@ -204,6 +216,28 @@ public override void Update()
}
}
}

private void UpdateEyeTrackingCalibrationStatus(bool defaultValue)
{
#if WINDOWS_UWP || (UNITY_WSA && DOTNETWINRT_PRESENT)
SpatialCoordinateSystem worldOrigin = Toolkit.WindowsMixedReality.WindowsMixedRealityUtilities.SpatialCoordinateSystem;
if (worldOrigin != null)
{
SpatialPointerPose pointerPose = SpatialPointerPose.TryGetAtTimestamp(worldOrigin, PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now));
if (pointerPose != null)
{
EyesPose eyes = pointerPose.Eyes;
if (eyes != null)
{
Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, eyes.IsCalibrationValid);
return;
}
}
}
#endif // WINDOWS_UWP || (UNITY_WSA && DOTNETWINRT_PRESENT)

Service?.EyeGazeProvider?.UpdateEyeTrackingStatus(this, defaultValue);
}
#endif // WMR_2_7_0_OR_NEWER || WMR_4_4_2_OR_NEWER || WMR_5_2_2_OR_NEWER
}
}