Uitgebreide ogentracering in systeemeigen engine

Uitgebreide ogentracering is een nieuwe functie in HoloLens 2. Het is een superset van de standaard oogtracering, die alleen gecombineerde oogklikkengegevens biedt. Uitgebreide ogentracering biedt ook individuele blikgegevens en stelt toepassingen in staat om verschillende framerates in te stellen voor de staargegevens, zoals 30, 60 en 90 fps. Andere functies, zoals openheid van ogen en ogen, worden op dit moment niet ondersteund door HoloLens 2.

Met de Extended Eye Tracking SDK kunnen toepassingen toegang krijgen tot gegevens en functies van uitgebreide oogtracering. Het kan worden gebruikt in combinatie met WinRT-API's of OpenXR-API's.

In dit artikel worden de manieren besproken waarop u de SDK voor uitgebreide ogentracering kunt gebruiken in de systeemeigen engine (C# of C++/WinRT), samen met WinRT-API's.

Instellen van het project

  1. Maak een Holographic DirectX 11 App (Universal Windows) - of Holographic DirectX 11 App (Universal Windows) (C++/WinRT) -project met Visual Studio 2019 of hoger, of open uw bestaande holografische Visual Studio-project.
  2. Importeer de SDK voor uitgebreide ogentracering in het project.
    1. Klik in Solution Explorer van Visual Studio met de rechtermuisknop op uw project -> NuGet-pakketten beheren...
    2. Zorg ervoor dat de pakketbron in de rechterbovenhoek verwijst naar nuget.org: https://api.nuget.org/v3/index.json
    3. Klik op het tabblad Browser en zoek vervolgens naar Microsoft.MixedReality.EyeTracking.
    4. Klik op de knop Installeren om de nieuwste versie van de SDK te installeren.
      Schermopname van het Nuget-pakket van de Eye Tracking SDK.
  3. Mogelijkheid voor gaze-invoer instellen
    1. Dubbelklik in Solution Explorer op het bestand Package.appxmanifest.
    2. Klik op het tabblad Mogelijkheden en controleer vervolgens de Gaze-invoer.
  4. Voeg het hoofdbestand toe en gebruik naamruimte.
    • Voor een C#-project:
    using Microsoft.MixedReality.EyeTracking;
    
    • Voor een C++/WinRT-project:
    #include <winrt/Microsoft.MixedReality.EyeTracking.h>
    using namespace winrt::Microsoft::MixedReality::EyeTracking;
    
  5. Gebruik de API's van de SDK voor uitgebreide ogentracering en implementeer uw logica.
  6. Bouw en implementeer op HoloLens.

Overzicht van stappen om de staargegevens op te halen

Voor het ophalen van de oogklikken via de API's van de Extended Eye Tracking SDK zijn de volgende stappen vereist:

  1. Krijg toegang tot de functies voor ogentracering van de gebruiker.
  2. Let op oogkijk-trackerverbindingen en verbroken verbindingen.
  3. Open de oogklikkentracering en voer een query uit op de mogelijkheden.
  4. Lees herhaaldelijk staargegevens van de oogklikken tracker.
  5. Breng gaze-gegevens over naar andere SpatialCoordinateSystems.

Toegang krijgen tot de oogtraceringsfuncties

Als u ooggerelateerde informatie wilt gebruiken, moet de toepassing eerst toestemming van de gebruiker aanvragen.

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);

Detectie van oogklikken tracker

Detectie van oog staren tracker wordt gemaakt door het gebruik van de EyeGazeTrackerWatcher klasse. EyeGazeTrackerAdded en EyeGazeTrackerRemoved gebeurtenissen worden respectievelijk gegenereerd wanneer een oogklikken tracker wordt gedetecteerd of losgekoppeld.

De watcher moet expliciet worden gestart met de StartAsync() methode, die asynchroon wordt voltooid wanneer trackers die al zijn verbonden, zijn gesignaleerd via de EyeGazeTrackerAdded gebeurtenis.

Wanneer een oogkijktracker wordt gedetecteerd, wordt een EyeGazeTracker exemplaar doorgegeven aan de toepassing in de EyeGazeTrackerAdded gebeurtenisparameters. Wanneer de verbinding met een tracker wordt verbroken, wordt het bijbehorende EyeGazeTracker exemplaar doorgegeven aan de gebeurtenis EyeGazeTrackerRemoved.

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)
{
    ...
}

Open ogen kijken tracker

Wanneer u een EyeGazeTracker exemplaar ontvangt, moet de toepassing deze eerst openen door de methode aan OpenAsync() te roepen. Vervolgens kan er zo nodig een query worden uitgevoerd op de mogelijkheden van de tracker. De OpenAsync() methode maakt gebruik van een booleaanse parameter. Dit geeft aan of de toepassing toegang moet hebben tot functies die niet behoren tot standaard oogtracering, zoals afzonderlijke ogenboogvectoren of het wijzigen van de framerate van de tracker.

Gecombineerde blik is een verplichte functie die wordt ondersteund door alle eye gaze trackers. Andere functies, zoals toegang tot individuele staren, zijn optioneel en kunnen worden ondersteund of niet, afhankelijk van de tracker en het stuurprogramma. Voor deze optionele functies geeft de EyeGazeTracker klasse een eigenschap weer die aangeeft of de functie wordt ondersteund, bijvoorbeeld de AreLeftAndRightGazesSupported eigenschap, die aangeeft of afzonderlijke oog staren-informatie wordt ondersteund door het apparaat.

Alle ruimtelijke informatie die wordt weergegeven door eye gaze tracker wordt gepubliceerd met betrekking tot een tracker zelf, die wordt geïdentificeerd door een dynamische knooppunt-id. Als u de nodeId gebruikt om een SpatialCoordinateSystem met WinRT-API's te verkrijgen, kunnen de coördinaten van staargegevens worden omgezet in een ander coördinatensysteem.

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
   }
}

Oog star tracker frame rate instellen

De EyeGazeTracker.SupportedTargetFrameRates eigenschap retourneert de lijst met de doelframesnelheid die wordt ondersteund door de tracker. HoloLens 2 ondersteunt 30, 60 en 90 fps.

Gebruik de EyeGazeTracker.SetTargetFrameRate() methode om de doelframesnelheid in te stellen.

// 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();

Blikgegevens van de oogklikken-tracker lezen

Een oogblikken tracker publiceert zijn toestanden periodiek in een cirkelvormige buffer. Hierdoor kan de toepassing de status van de tracker lezen op een moment dat tot een korte periode behoort. Hiermee kunt u bijvoorbeeld de meest recente status van de tracker ophalen, of de status ervan op het moment van een gebeurtenis, zoals een handgebaar van de gebruiker.

Methoden waarmee de status van de tracker wordt opgehaald als een EyeGazeTrackerReading exemplaar:

  • De TryGetReadingAtTimestamp() methoden en TryGetReadingAtSystemRelativeTime() retourneren het EyeGazeTrackerReading dichtst bij de tijd die is verstreken door de toepassing. De tracker bepaalt het publicatieschema, dus de geretourneerde leestijd kan iets ouder of nieuwer zijn dan de aanvraagtijd. Met de EyeGazeTrackerReading.Timestamp eigenschappen en EyeGazeTrackerReading.SystemRelativeTime kan de toepassing de exacte tijd van de gepubliceerde status weten.

  • De TryGetReadingAfterTimestamp() methoden en TryGetReadingAfterSystemRelativeTime() retourneren de eerste EyeGazeTrackerReading met een tijdstempel die strikt superieur is aan de tijd die als parameter is doorgegeven. Hierdoor kan een toepassing sequentieel alle statussen lezen die door de tracker zijn gepubliceerd. Houd er rekening mee dat al deze methoden query's uitvoeren op de bestaande buffer en dat ze onmiddellijk worden geretourneerd. Als er geen status beschikbaar is, retourneren ze null (met andere woorden, ze laten de toepassing niet wachten tot een status is gepubliceerd).

Naast de tijdstempel heeft een EyeGazeTrackerReading exemplaar een IsCalibrationValid eigenschap, die aangeeft of de kalibratie van de oogtracering geldig is of niet.

Ten slotte kunnen staren-gegevens worden opgehaald via een set methoden, zoals TryGetCombinedEyeGazeInTrackerSpace() of TryGetLeftEyeGazeInTrackerSpace(). Al deze methoden retourneren een booleaanse waarde die een succes aangeeft. Het niet ophalen van bepaalde gegevens kan betekenen dat de gegevens niet worden ondersteund (EyeGazeTracker heeft eigenschappen om dit geval te detecteren) of dat de tracker de gegevens niet kan ophalen (bijvoorbeeld ongeldige kalibratie of oog verborgen).

Als de toepassing bijvoorbeeld een cursor wil weergeven die overeenkomt met de gecombineerde blik, kan deze een query uitvoeren op de tracker met behulp van een tijdstempel van de voorspelling van het frame dat als volgt wordt voorbereid.

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
    }
}

Staargegevens transformeren naar een ander SpatialCoordinateSystem

WinRT-API's die ruimtelijke gegevens retourneren, zoals een positie, vereisen altijd zowel een als PerceptionTimestamp een SpatialCoordinateSystem. Als u bijvoorbeeld de gecombineerde blik van HoloLens 2 wilt ophalen met behulp van de WinRT-API, heeft de API SpatialPointerPose.TryGetAtTimestamp() twee parameters nodig: een SpatialCoordinateSystem en een PerceptionTimestamp. Wanneer de gecombineerde blik vervolgens wordt geopend via SpatialPointerPose.Eyes.Gaze, worden de oorsprong en richting uitgedrukt in de SpatialCoordinateSystem doorgegeven in.

Sdk-API's voor uitgebreide tye-tracking hoeven geen gegevens SpatialCoordinateSystem te gebruiken en de staargegevens worden altijd uitgedrukt in het coördinatensysteem van de tracker. Maar u kunt deze staargegevens transformeren naar een ander coördinatensysteem met de houding van de tracker die is gerelateerd aan het andere coördinatensysteem.

  • Zoals in de bovenstaande sectie met de naam 'Open eye gaze tracker' werd vermeld, belt Windows.Perception.Spatial.Preview.SpatialGraphInteropPreview.CreateLocatorForNode() u met de eigenschap aan om een SpatialLocator voor de EyeGazeTracker.TrackerSpaceLocatorNodeId ogen staren tracker te krijgen.

  • Staaroorsprongen en richtingen die door EyeGazeTrackerReading worden opgehaald, zijn gerelateerd aan de ooggagaster.

  • SpatialLocator.TryLocateAtTimestamp() retourneert de volledige 6DoF-locatie van de oogzoeker op een gegeven PerceptionTimeStamp en gerelateerd aan een gegeven SpatialCoordinateSystem, die kan worden gebruikt om een Matrix4x4-transformatiematrix te maken.

  • Gebruik de Matrix4x4-transformatiematrix die is samengesteld om de oorsprong en richting van de blik over te dragen naar een ander SpatialCoordinateSystem.

De volgende codevoorbeelden laten zien hoe de positie van een kubus in de richting van de gecombineerde blik, twee meter voor de oorsprong van de blik, wordt berekend;

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-verwijzing van extended 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);
    }
}

Zie ook