Erweiterte Augenverfolgung in nativer Engine

Erweiterte Augenverfolgung ist eine neue Funktion in HoloLens 2. Es handelt sich um eine Übermenge der Standard-Augenverfolgung, die nur kombinierte Augensichtdaten bereitstellt. Das erweiterte Eye Tracking bietet auch individuelle Augenaugendaten und ermöglicht es Anwendungen, unterschiedliche Frameraten für die Blickdaten festzulegen, z. B. 30, 60 und 90 fps. Andere Features wie Augenoffenheit und Augenvergänglichkeit werden derzeit von HoloLens 2 nicht unterstützt.

Das Extended Eye Tracking SDK ermöglicht Anwendungen den Zugriff auf Daten und Features des erweiterten Eye Tracking. Es kann zusammen mit WinRT-APIs oder OpenXR-APIs verwendet werden.

In diesem Artikel werden die Möglichkeiten zum Verwenden des erweiterten Eye Tracking SDK in der nativen Engine (C# oder C++/WinRT) zusammen mit WinRT-APIs behandelt.

Projekteinrichtung

  1. Erstellen Sie ein Holographic DirectX 11 App (Universal Windows) Projekt oder Holographic DirectX 11 App (Universal Windows) (C++/WinRT) mit Visual Studio 2019 oder höher, oder öffnen Sie Ihr vorhandenes holografisches Visual Studio-Projekt.
  2. Importieren Sie das erweiterte Eye Tracking SDK in das Projekt.
    1. Klicken Sie im Visual Studio-Projektmappen-Explorer mit der rechten Maustaste auf Ihr Projekt–> Verwalten von NuGet-Paketen...
    2. Stellen Sie sicher, dass die Paketquelle in der oberen rechten Ecke auf nuget.org verweist: https://api.nuget.org/v3/index.json
    3. Klicken Sie auf die Registerkarte Browser, und suchen Sie dann nach Microsoft.MixedReality.EyeTracking.
    4. Klicken Sie auf die Schaltfläche Installieren, um die neueste Version des SDK zu installieren.
      Screenshot des Nuget-Pakets des Eye Tracking SDK
  3. Festlegen der Funktion "Gaze Input"
    1. Doppelklicken Sie in Projektmappen-Explorer auf die Datei Package.appxmanifest.
    2. Klicken Sie auf die Registerkarte Funktionen , und überprüfen Sie dann die Gaze-Eingabe.
  4. Schließen Sie die Hauptdatei ein, und verwenden Sie den Namespace.
    • Für ein C#-Projekt:
    using Microsoft.MixedReality.EyeTracking;
    
    • Für ein C++/WinRT-Projekt:
    #include <winrt/Microsoft.MixedReality.EyeTracking.h>
    using namespace winrt::Microsoft::MixedReality::EyeTracking;
    
  5. Nutzen Sie die erweiterten Eye tracking SDK-APIs, und implementieren Sie Ihre Logik.
  6. Erstellen und Bereitstellen in HoloLens.

Übersicht über die Schritte zum Abrufen der Blickdaten

Um die Blickdaten über die Extended Eye Tracking SDK-APIs zu erhalten, sind die folgenden Schritte erforderlich:

  1. Erhalten Sie vom Benutzer Zugriff auf die Eye Tracking-Features.
  2. Achten Sie auf Eye Gaze Tracker-Verbindungen und Trennungen.
  3. Öffnen Sie den Eye Gaze Tracker, und fragen Sie dann die Funktionen ab.
  4. Lesen Sie wiederholt Blickdaten aus dem Eye Gaze Tracker.
  5. Übertragen Von Blickdaten an andere SpatialCoordinateSystems.

Zugriff auf die Eye-Tracking-Features erhalten

Um augenbezogene Informationen nutzen zu können, muss die Anwendung zuerst die Zustimmung des Benutzers anfordern.

var status = await Windows.Perception.People.EyesPose.RequestAccessAsync();
bool useGaze = (status == Windows.UI.Input.GazeInputAccessStatus.Allowed);
auto accessStatus = co_await winrt::Windows::Perception::People::EyesPose::RequestAccessAsync();
bool useGaze = (accessStatus.get() == winrt::Windows::UI::Input::GazeInputAccessStatus::Allowed);

Erkennen von Eye Gaze Tracker

Die Erkennung von Eye Gaze Tracker erfolgt durch die Verwendung der EyeGazeTrackerWatcher -Klasse. EyeGazeTrackerAdded und EyeGazeTrackerRemoved Ereignisse werden ausgelöst, wenn ein Eye Gaze Tracker erkannt oder getrennt wird.

Der Watcher muss explizit mit der StartAsync() -Methode gestartet werden, die asynchron abgeschlossen wird, wenn Tracker, die bereits verbunden sind, über das EyeGazeTrackerAdded Ereignis signalisiert wurden.

Wenn ein Eye Gaze Tracker erkannt wird, wird ein EyeGazeTracker instance in den Ereignisparametern an die EyeGazeTrackerAdded Anwendung übergeben. Bei der Trennung eines Trackers wird die entsprechende EyeGazeTracker instance an das EyeGazeTrackerRemoved-Ereignis übergeben.

EyeGazeTrackerWatcher watcher = new EyeGazeTrackerWatcher();
watcher.EyeGazeTrackerAdded += _watcher_EyeGazeTrackerAdded;
watcher.EyeGazeTrackerRemoved += _watcher_EyeGazeTrackerRemoved;
await watcher.StartAsync();
...

private async void _watcher_EyeGazeTrackerAdded(object sender, EyeGazeTracker e)
{
    // Implementation is in next section
}

private void _watcher_EyeGazeTrackerRemoved(object sender, EyeGazeTracker e)
{
    ...
}
EyeGazeTrackerWatcher watcher;
watcher.EyeGazeTrackerAdded(std::bind(&SampleEyeTrackingNugetClientAppMain::OnEyeGazeTrackerAdded, this, _1, _2));
watcher.EyeGazeTrackerRemoved(std::bind(&SampleEyeTrackingNugetClientAppMain::OnEyeGazeTrackerRemoved, this, _1, _2));
co_await watcher.StartAsync();
...

winrt::Windows::Foundation::IAsyncAction SampleAppMain::OnEyeGazeTrackerAdded(const EyeGazeTrackerWatcher& sender, const EyeGazeTracker& tracker)
{
    // Implementation is in next section
}
void SampleAppMain::OnEyeGazeTrackerRemoved(const EyeGazeTrackerWatcher& sender, const EyeGazeTracker& tracker)
{
    ...
}

Eye Gaze Tracker öffnen

Wenn sie eine EyeGazeTracker instance empfängt, muss die Anwendung sie zuerst öffnen, indem sie die OpenAsync() -Methode aufruft. Es kann dann bei Bedarf nach den Trackerfunktionen abfragen. Die OpenAsync() Methode nimmt einen booleschen Parameter an. Dies gibt an, ob die Anwendung auf Features zugreifen muss, die nicht zur Standardmäßigen Eye Tracking gehören, z. B. einzelne Augenaugenvektoren oder die Framerate des Trackers ändern.

Kombiniertes Blicken ist ein obligatorisches Feature, das von allen Eye Gaze Trackern unterstützt wird. Andere Features, z. B. der Zugriff auf einzelne Blicke, sind optional und können je nach Tracker und Treiber unterstützt werden oder nicht. Für diese optionalen Features macht die EyeGazeTracker -Klasse eine Eigenschaft verfügbar, die angibt, ob das Feature unterstützt wird, z. B. die AreLeftAndRightGazesSupported -Eigenschaft, die angibt, ob einzelne Blickinformationen vom Gerät unterstützt werden.

Alle räumlichen Informationen, die vom Eye Gaze Tracker verfügbar gemacht werden, werden in Bezug auf einen Tracker selbst veröffentlicht, der durch eine dynamische Knoten-ID identifiziert wird. Die Verwendung der nodeId zum Abrufen einer SpatialCoordinateSystem mit WinRT-APIs könnte die Koordinaten der Blickdaten in ein anderes Koordinatensystem transformieren.

private async void _watcher_EyeGazeTrackerAdded(object sender, EyeGazeTracker e)
{
    try
    {
        // Try to open the tracker with access to restricted features
        await e.OpenAsync(true);

        // If it has succeeded, store it for future use
        _tracker = e;

        // Check support for individual eye gaze
        bool supportsIndividualEyeGaze = _tracker.AreLeftAndRightGazesSupported;

        // Get a spatial locator for the tracker, this will be used to transfer the gaze data to other coordinate systems later
        var trackerNodeId = e.TrackerSpaceLocatorNodeId;
        _trackerLocator = Windows.Perception.Spatial.Preview.SpatialGraphInteropPreview.CreateLocatorForNode(trackerNodeId);
    }
    catch (Exception ex)
    {
        // Unable to open the tracker
    }
}
winrt::Windows::Foundation::IAsyncAction SampleEyeTrackingNugetClientAppMain::OnEyeGazeTrackerAdded(const EyeGazeTrackerWatcher&, const EyeGazeTracker& tracker)
{
   auto newTracker = tracker;

   try
   {
        // Try to open the tracker with access to restricted features
        co_await newTracker.OpenAsync(true);

        // If it has succeeded, store it for future use
        m_gazeTracker = newTracker;

        // Check support for individual eye gaze
        const bool supportsIndividualEyeGaze = m_gazeTracker.AreLeftAndRightGazesSupported();

        // Get a spatial locator for the tracker. This will be used to transfer the gaze data to other coordinate systems later
        const auto trackerNodeId = m_gazeTracker.TrackerSpaceLocatorNodeId();
        m_trackerLocator = winrt::Windows::Perception::Spatial::Preview::SpatialGraphInteropPreview::CreateLocatorForNode(trackerNodeId);
   }
   catch (const winrt::hresult_error& e)
   {
       // Unable to open the tracker
   }
}

Festlegen der Framerate des Eye Gaze Tracker

Die EyeGazeTracker.SupportedTargetFrameRates -Eigenschaft gibt die Liste der vom Tracker unterstützten Zielbildrate zurück. HoloLens 2 unterstützt 30, 60 und 90fps.

Verwenden Sie die EyeGazeTracker.SetTargetFrameRate() -Methode, um die Zielbildrate festzulegen.

// This returns a list of supported frame rate: 30, 60, 90 fps in order
var supportedFrameRates = _tracker.SupportedTargetFrameRates;

// Sets the tracker at the highest supported frame rate (90 fps)
var newFrameRate = supportedFrameRates[supportedFrameRates.Count - 1];
_tracker.SetTargetFrameRate(newFrameRate);
uint newFramesPerSecond = newFrameRate.FramesPerSecond;
// This returns a list of supported frame rate: 30, 60, 90 fps in order
const auto supportedFrameRates = m_gazeTracker.SupportedTargetFrameRates();

// Sets the tracker at the highest supported frame rate (90 fps)
const auto newFrameRate = supportedFrameRates.GetAt(supportedFrameRates.Size() - 1);
m_gazeTracker.SetTargetFrameRate(newFrameRate);
const uint32_t newFramesPerSecond = newFrameRate.FramesPerSecond();

Lesen von Blickdaten aus dem Eye Gaze Tracker

Ein Eye Gaze Tracker veröffentlicht seine Zustände regelmäßig in einem kreisförmigen Puffer. Dadurch kann die Anwendung den Status des Trackers zu einem Zeitpunkt lesen, der zu einer kleinen Zeitspanne gehört. Es ermöglicht beispielsweise den Abruf des neuesten Zustands des Trackers oder seines Zustands zum Zeitpunkt eines Ereignisses, z. B. einer Handbewegung des Benutzers.

Methoden, die den Trackerstatus als EyeGazeTrackerReading instance abrufen:

  • Die TryGetReadingAtTimestamp() Methoden und TryGetReadingAtSystemRelativeTime() geben die EyeGazeTrackerReading der Von der Anwendung verstrichene Zeit am nächsten zurück. Der Tracker steuert den Veröffentlichungszeitplan, sodass der zurückgegebene Lesevorgang möglicherweise etwas älter oder neuer als die Anforderungszeit ist. Die EyeGazeTrackerReading.Timestamp Eigenschaften und EyeGazeTrackerReading.SystemRelativeTime ermöglichen es der Anwendung, den genauen Zeitpunkt des veröffentlichten Zustands zu kennen.

  • Die TryGetReadingAfterTimestamp() Methoden und TryGetReadingAfterSystemRelativeTime() geben den ersten EyeGazeTrackerReading mit einem Zeitstempel zurück, der der als Parameter verstrichenen Zeit streng überlegen ist. Dadurch kann eine Anwendung alle vom Tracker veröffentlichten Zustände sequenziell lesen. Beachten Sie, dass alle diese Methoden den vorhandenen Puffer abfragen und sofort zurückgegeben werden. Wenn kein Zustand verfügbar ist, wird NULL zurückgegeben (d. h., die Anwendung wird nicht auf die Veröffentlichung eines Zustands warten).

Zusätzlich zum Zeitstempel verfügt ein EyeGazeTrackerReading instance über eine IsCalibrationValid Eigenschaft, die angibt, ob die Eye Tracker-Kalibrierung gültig ist oder nicht.

Schließlich können Blickdaten mit einer Reihe von Methoden wie TryGetCombinedEyeGazeInTrackerSpace() oder TryGetLeftEyeGazeInTrackerSpace()abgerufen werden. Alle diese Methoden geben einen booleschen Wert zurück, der einen Erfolg angibt. Ein Fehler beim Abrufen einiger Daten kann entweder bedeuten, dass die Daten nicht unterstützt werden (EyeGazeTracker über Eigenschaften zum Erkennen dieses Falls verfügen) oder dass der Tracker die Daten nicht abrufen konnte (z. B. ungültige Kalibrierung oder ausgeblendetes Auge).

Wenn die Anwendung beispielsweise einen Cursor anzeigen möchte, der dem kombinierten Blick entspricht, kann sie den Tracker mithilfe eines Zeitstempels der Vorhersage des zu erstellenden Frames wie folgt abfragen.

var holographicFrame = holographicSpace.CreateNextFrame();
var prediction = holographicFrame.CurrentPrediction;
var predictionTimestamp = prediction.Timestamp;
var reading = _tracker.TryGetReadingAtTimestamp(predictionTimestamp.TargetTime.DateTime);
if (reading != null)
{
    // Vector3 needs the System.Numerics namespace
    if (reading.TryGetCombinedEyeGazeInTrackerSpace(out Vector3 gazeOrigin, out Vector3 gazeDirection))
    {
        // Use gazeOrigin and gazeDirection to display the cursor
    }
}
auto holographicFrame = m_holographicSpace.CreateNextFrame();
auto prediction = holographicFrame.CurrentPrediction();
auto predictionTimestamp = prediction.Timestamp();
const auto reading = m_gazeTracker.TryGetReadingAtTimestamp(predictionTimestamp.TargetTime());
if (reading)
{
    float3 gazeOrigin;
    float3 gazeDirection;
    if (reading.TryGetCombinedEyeGazeInTrackerSpace(gazeOrigin, gazeDirection))
    {
        // Use gazeOrigin and gazeDirection to display the cursor
    }
}

Transformieren von Blickdaten in andere SpatialCoordinateSystem

WinRT-APIs, die räumliche Daten wie eine Position zurückgeben, erfordern immer sowohl ein als PerceptionTimestamp auch ein SpatialCoordinateSystem. Um beispielsweise den kombinierten Blick von HoloLens 2 mithilfe der WinRT-API abzurufen, erfordert die API SpatialPointerPose.TryGetAtTimestamp() zwei Parameter: a SpatialCoordinateSystem und einen PerceptionTimestamp. Wenn der kombinierte Blick dann durch SpatialPointerPose.Eyes.Gazeerreicht wird, werden sein Ursprung und seine Richtung in der SpatialCoordinateSystem übergebenen ausgedrückt.

Erweiterte Tye-Tracking-SDK-APIs müssen nicht verwendet SpatialCoordinateSystem werden, und die Blickdaten werden immer im Koordinatensystem des Trackers ausgedrückt. Sie können diese Blickdaten jedoch in ein anderes Koordinatensystem transformieren, wobei die Position des Trackers sich auf das andere Koordinatensystem bezieht.

  • Wie der Abschnitt oben "Open eye gaze tracker" genannt wurde, rufen Sie Windows.Perception.Spatial.Preview.SpatialGraphInteropPreview.CreateLocatorForNode() mit der EyeGazeTracker.TrackerSpaceLocatorNodeId Eigenschaft an, um einen SpatialLocator für den Eye Gaze Tracker zu erhalten.

  • Blickherkunft und durchgerufene EyeGazeTrackerReading Richtungen stehen im Zusammenhang mit dem Eye Gaze Tracker.

  • SpatialLocator.TryLocateAtTimestamp() gibt die vollständige 6DoF-Position des Eye Gaze Trackers an einer bestimmten PerceptionTimeStamp und einer bestimmten SpatialCoordinateSystemzurück, die zum Erstellen einer Matrix4x4-Transformationsmatrix verwendet werden könnte.

  • Verwenden Sie die Matrix4x4-Transformationsmatrix, die erstellt wurde, um die Ursprünge und Richtungen des Blicks auf andere SpatialCoordinateSystem zu übertragen.

Die folgenden Codebeispiele zeigen, wie die Position eines Würfels berechnet wird, der sich in Richtung des kombinierten Blicks befindet, zwei Meter vor dem Blickursprung;

var predictionTimestamp = prediction.Timestamp;
var stationaryCS = stationaryReferenceFrame.CoordinateSystem;
var trackerLocation = _trackerLocator.TryLocateAtTimestamp(predictionTimestamp, stationaryCS);
if (trackerLocation != null)
{
    var trackerToStationaryMatrix = Matrix4x4.CreateFromQuaternion(trackerLocation.Orientation) * Matrix4x4.CreateTranslation(trackerLocation.Position);
    var reading = _tracker.TryGetReadingAtTimestamp(predictionTimestamp.TargetTime.DateTime);
    if (reading != null)
    {
        if (reading.TryGetCombinedEyeGazeInTrackerSpace(out Vector3 gazeOriginInTrackerSpace, out Vector3 gazeDirectionInTrackerSpace))
        {
            var cubePositionInTrackerSpace = gazeOriginInTrackerSpace + 2.0f * gazeDirectionInTrackerSpace;
            var cubePositionInStationaryCS = Vector3.Transform(cubePositionInTrackerSpace, trackerToStationaryMatrix);
        }
    }
}
auto predictionTimestamp = prediction.Timestamp();
auto stationaryCS = m_stationaryReferenceFrame.CoordinateSystem();
auto trackerLocation = m_trackerLocator.TryLocateAtTimestamp(predictionTimestamp, stationaryCS);
if (trackerLocation) 
{
    auto trackerOrientation = trackerLocation.Orientation();
    auto trackerPosition = trackerLocation.Position();
    auto trackerToStationaryMatrix = DirectX::XMMatrixRotationQuaternion(DirectX::XMLoadFloat4(reinterpret_cast<const DirectX::XMFLOAT4*>(&trackerOrientation))) * DirectX::XMMatrixTranslationFromVector(DirectX::XMLoadFloat3(&trackerPosition));

    const auto reading = m_gazeTracker.TryGetReadingAtTimestamp(predictionTimestamp.TargetTime());
    if (reading)
    {
        float3 gazeOriginInTrackerSpace;
        float3 gazeDirectionInTrackerSpace;
        if (reading.TryGetCombinedEyeGazeInTrackerSpace(gazeOriginInTrackerSpace, gazeDirectionInTrackerSpace))
        {
            auto cubePositionInTrackerSpace = gazeOriginInTrackerSpace + 2.0f * gazeDirectionInTrackerSpace;
            float3 cubePositionInStationaryCS;
            DirectX::XMStoreFloat3(&cubePositionInStationaryCS, DirectX::XMVector3TransformCoord(DirectX::XMLoadFloat3(&cubePositionInTrackerSpace), trackerToStationaryMatrix));
        }
    }
}

API-Referenz des erweiterten Eye Tracking SDK

namespace Microsoft.MixedReality.EyeTracking
{
    /// <summary>
    /// Allow discovery of Eye Gaze Trackers connected to the system
    /// This is the only class from Extended Eye Tracking SDK that the application will instantiate, 
    /// other classes' instances will be returned by method calls or properties.
    /// </summary>
    public class EyeGazeTrackerWatcher
    {
        /// <summary>
        /// Constructs an instance of the watcher
        /// </summary>
        public EyeGazeTrackerWatcher();

        /// <summary>
        /// Starts trackers enumeration.
        /// </summary>
        /// <returns>Task representing async action; completes when the initial enumeration is completed</returns>
        public System.Threading.Tasks.Task StartAsync();

        /// <summary>
        /// Stop listening to trackers additions and removal
        /// </summary>
        public void Stop();

        /// <summary>
        /// Raised when an Eye Gaze tracker is connected
        /// </summary>
        public event System.EventHandler<EyeGazeTracker> EyeGazeTrackerAdded;

        /// <summary>
        /// Raised when an Eye Gaze tracker is disconnected
        /// </summary>
        public event System.EventHandler<EyeGazeTracker> EyeGazeTrackerRemoved;        
    }

    /// <summary>
    /// Represents an Eye Tracker device
    /// </summary>
    public class EyeGazeTracker
    {
        /// <summary>
        /// True if Restricted mode is supported, which means the driver supports to provide individual 
        /// eye gaze vector and framerate 
        /// </summary>
        public bool IsRestrictedModeSupported;

        /// <summary>
        /// True if Vergence Distance is supported by tracker
        /// </summary>
        public bool IsVergenceDistanceSupported;

        /// <summary>
        /// True if Eye Openness is supported by the driver
        /// </summary>
        public bool IsEyeOpennessSupported;

        /// <summary>
        /// True if individual gazes are supported
        /// </summary>
        public bool AreLeftAndRightGazesSupported;

        /// <summary>
        /// Get the supported target frame rates of the tracker
        /// </summary>
        public System.Collections.Generic.IReadOnlyList<EyeGazeTrackerFrameRate> SupportedTargetFrameRates;

        /// <summary>
        /// NodeId of the tracker, used to retrieve a SpatialLocator or SpatialGraphNode to locate the tracker in the scene
        /// for Perception API, use SpatialGraphInteropPreview.CreateLocatorForNode
        /// for Mixed Reality OpenXR API, use SpatialGraphNode.FromDynamicNodeId
        /// </summary>
        public Guid TrackerSpaceLocatorNodeId;

        /// <summary>
        /// Opens the tracker
        /// </summary>
        /// <param name="restrictedMode">True if restricted mode active</param>
        /// <returns>Task representing async action; completes when the initial enumeration is completed</returns>
        public System.Threading.Tasks.Task OpenAsync(bool restrictedMode);

        /// <summary>
        /// Closes the tracker
        /// </summary>
        public void Close();

        /// <summary>
        /// Changes the target frame rate of the tracker
        /// </summary>
        /// <param name="newFrameRate">Target frame rate</param>
        public void SetTargetFrameRate(EyeGazeTrackerFrameRate newFrameRate);

        /// <summary>
        /// Try to get tracker state at a given timestamp
        /// </summary>
        /// <param name="timestamp">timestamp</param>
        /// <returns>State if available, null otherwise</returns>
        public EyeGazeTrackerReading TryGetReadingAtTimestamp(DateTime timestamp);

        /// <summary>
        /// Try to get tracker state at a system relative time
        /// </summary>
        /// <param name="time">time</param>
        /// <returns>State if available, null otherwise</returns>
        public EyeGazeTrackerReading TryGetReadingAtSystemRelativeTime(TimeSpan time);

        /// <summary>
        /// Try to get first first tracker state after a given timestamp
        /// </summary>
        /// <param name="timestamp">timestamp</param>
        /// <returns>State if available, null otherwise</returns>
        public EyeGazeTrackerReading TryGetReadingAfterTimestamp(DateTime timestamp);

        /// <summary>
        /// Try to get the first tracker state after a system relative time
        /// </summary>
        /// <param name="time">time</param>
        /// <returns>State if available, null otherwise</returns>
        public EyeGazeTrackerReading TryGetReadingAfterSystemRelativeTime(TimeSpan time);
    }

    /// <summary>
    /// Represents a Frame Rate supported by an Eye Tracker
    /// </summary>
    public class EyeGazeTrackerFrameRate
    {
        /// <summary>
        /// Frames per second of the frame rate
        /// </summary>
        public UInt32 FramesPerSecond;
    }

    /// <summary>
    /// Snapshot of Gaze Tracker state
    /// </summary>
    public class EyeGazeTrackerReading
    {
        /// <summary>
        /// Timestamp of state
        /// </summary>
        public DateTime Timestamp;

        /// <summary>
        /// Timestamp of state as system relative time
        /// Its SystemRelativeTime.Ticks could provide the QPC time to locate tracker pose 
        /// </summary>
        public TimeSpan SystemRelativeTime;

        /// <summary>
        /// Indicates user calibration is valid
        /// </summary>
        public bool IsCalibrationValid;

        /// <summary>
        /// Tries to get a vector representing the combined gaze related to the tracker's node
        /// </summary>
        /// <param name="origin">Origin of the gaze vector</param>
        /// <param name="direction">Direction of the gaze vector</param>
        /// <returns></returns>
        public bool TryGetCombinedEyeGazeInTrackerSpace(out System.Numerics.Vector3 origin, out System.Numerics.Vector3 direction);

        /// <summary>
        /// Tries to get a vector representing the left eye gaze related to the tracker's node
        /// </summary>
        /// <param name="origin">Origin of the gaze vector</param>
        /// <param name="direction">Direction of the gaze vector</param>
        /// <returns></returns>
        public bool TryGetLeftEyeGazeInTrackerSpace(out System.Numerics.Vector3 origin, out System.Numerics.Vector3 direction);

        /// <summary>
        /// Tries to get a vector representing the right eye gaze related to the tracker's node position
        /// </summary>
        /// <param name="origin">Origin of the gaze vector</param>
        /// <param name="direction">Direction of the gaze vector</param>
        /// <returns></returns>
        public bool TryGetRightEyeGazeInTrackerSpace(out System.Numerics.Vector3 origin, out System.Numerics.Vector3 direction);

        /// <summary>
        /// Tries to read vergence distance
        /// </summary>
        /// <param name="value">Vergence distance if available</param>
        /// <returns>bool if value is valid</returns>
        public bool TryGetVergenceDistance(out float value);

        /// <summary>
        /// Tries to get left Eye openness information
        /// </summary>
        /// <param name="value">Eye Openness if valid</param>
        /// <returns>bool if value is valid</returns>
        public bool TryGetLeftEyeOpenness(out float value);

        /// <summary>
        /// Tries to get right Eye openness information
        /// </summary>
        /// <param name="value">Eye Openness if valid</param>
        /// <returns>bool if value is valid</returns>
        public bool TryGetRightEyeOpenness(out float value);
    }
}

Weitere Informationen