Partager via


Suivi oculaire étendu dans le moteur natif

Le suivi oculaire étendu est une nouvelle fonctionnalité dans HoloLens 2. Il s’agit d’un sur-ensemble du suivi oculaire standard, qui fournit uniquement des données combinées sur le regard. Le suivi oculaire étendu fournit également des données de regard individuels et permet aux applications de définir différentes fréquences d’images pour les données de regard, telles que 30, 60 et 90fps. D’autres fonctionnalités telles que l’ouverture des yeux et la vergence des yeux ne sont pas prises en charge par HoloLens 2 pour l’instant.

Le SDK Suivi oculaire étendu permet aux applications d’accéder aux données et aux fonctionnalités du suivi oculaire étendu. Il peut être utilisé avec les API WinRT ou OpenXR.

Cet article décrit les façons d’utiliser le SDK de suivi oculaire étendu dans le moteur natif (C# ou C++/WinRT) avec les API WinRT.

Configuration du projet

  1. Créez un Holographic DirectX 11 App (Universal Windows) projet ou avec Holographic DirectX 11 App (Universal Windows) (C++/WinRT) Visual Studio 2019 ou une version ultérieure, ou ouvrez votre projet Visual Studio holographique existant.
  2. Importez le SDK de suivi oculaire étendu dans le projet.
    1. Dans le Explorateur de solutions Visual Studio, cliquez avec le bouton droit sur votre projet -> Gérer les packages NuGet...
    2. Vérifiez que la source du package dans le coin supérieur droit pointe vers nuget.org : https://api.nuget.org/v3/index.json
    3. Cliquez sur l’onglet Navigateur, puis recherchez Microsoft.MixedReality.EyeTracking.
    4. Cliquez sur le bouton Installer pour installer la dernière version du Kit de développement logiciel (SDK).
      Capture d’écran du package Nuget du Kit de développement logiciel (SDK) Eye Tracking.
  3. Définir la fonctionnalité d’entrée du regard
    1. Double-cliquez sur le fichier Package.appxmanifest dans Explorateur de solutions.
    2. Cliquez sur l’onglet Fonctionnalités, puis case activée l’entrée du regard.
  4. Inclure le fichier principal et utiliser l’espace de noms.
    • Pour un projet C# :
    using Microsoft.MixedReality.EyeTracking;
    
    • Pour un projet C++/WinRT :
    #include <winrt/Microsoft.MixedReality.EyeTracking.h>
    using namespace winrt::Microsoft::MixedReality::EyeTracking;
    
  5. Consommez les API étendues du KIT de développement logiciel (SDK) de suivi oculaire et implémentez votre logique.
  6. Générez et déployez sur HoloLens.

Vue d’ensemble des étapes pour obtenir les données du regard

L’obtention des données du regard par le biais des API du SDK De suivi oculaire étendu nécessite les étapes suivantes :

  1. Obtenez l’accès aux fonctionnalités de suivi oculaire auprès de l’utilisateur.
  2. Surveillez les connexions et les déconnexions du suivi du regard.
  3. Ouvrez le dispositif de suivi du regard, puis interrogez ses fonctionnalités.
  4. Lisez à plusieurs reprises les données du regard à partir du dispositif de suivi du regard.
  5. Transférez les données du regard vers d’autres SpatialCoordinateSystems.

Accéder aux fonctionnalités de suivi oculaire

Pour utiliser des informations relatives aux yeux, l’application doit d’abord demander le consentement de l’utilisateur.

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

Détecter le dispositif de suivi du regard

La détection du suivi du regard est effectuée à l’aide de la EyeGazeTrackerWatcher classe . EyeGazeTrackerAdded les événements et EyeGazeTrackerRemoved sont respectivement déclenchés lorsqu’un dispositif de suivi du regard est détecté ou déconnecté.

L’observateur doit être explicitement démarré avec la StartAsync() méthode , qui se termine de façon asynchrone lorsque les suivis déjà connectés ont été signalés via l’événement EyeGazeTrackerAdded .

Lorsqu’un dispositif de suivi du regard est détecté, un EyeGazeTracker instance est passé à l’application dans les paramètres de l’événement EyeGazeTrackerAdded ; de façon réciproque, lorsqu’un suivi est déconnecté, le instance correspondant EyeGazeTracker est passé à l’événement 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)
{
    ...
}

Suivi du regard ouvert

Lors de la réception d’une EyeGazeTracker instance, l’application doit d’abord l’ouvrir en appelant la OpenAsync() méthode . Il peut ensuite interroger les fonctionnalités de suivi si nécessaire. La OpenAsync() méthode prend un paramètre booléen ; cela indique si l’application doit accéder à des fonctionnalités qui n’appartiennent pas au suivi oculaire standard, telles que des vecteurs de regard individuels ou la modification de la fréquence d’images du dispositif de suivi.

Le regard combiné est une fonctionnalité obligatoire prise en charge par tous les dispositifs de suivi du regard. D’autres fonctionnalités, telles que l’accès au regard individuel, sont facultatives et peuvent être prises en charge ou non en fonction du dispositif de suivi et de son pilote. Pour ces fonctionnalités facultatives, la EyeGazeTracker classe expose une propriété indiquant si la fonctionnalité est prise en charge, par exemple, la AreLeftAndRightGazesSupported propriété , qui indique si les informations individuelles du regard sont prises en charge par l’appareil.

Toutes les informations spatiales exposées par le dispositif de suivi du regard sont publiées en rapport avec un dispositif de suivi lui-même, qui est identifié par un ID de nœud dynamique. L’utilisation du nodeId pour obtenir un SpatialCoordinateSystem avec des API WinRT peut transformer les coordonnées des données du regard en un autre système de coordonnées.

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

Définir la fréquence d’images du suivi du regard

La EyeGazeTracker.SupportedTargetFrameRates propriété retourne la liste de la fréquence d’images cible prise en charge par le suivi. HoloLens 2 prend en charge 30, 60 et 90fps.

Utilisez la EyeGazeTracker.SetTargetFrameRate() méthode pour définir la fréquence d’images cible.

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

Lire les données du regard à partir du dispositif de suivi du regard

Un dispositif de suivi du regard publie régulièrement ses états dans une mémoire tampon circulaire. Cela permet à l’application de lire l’état du dispositif de suivi à un moment appartenant à un petit intervalle de temps. Il permet, par exemple, la récupération de l’état le plus récent du dispositif de suivi, ou de son état au moment d’un événement tel qu’un mouvement de la main de l’utilisateur.

Méthodes qui récupèrent l’état du suivi en tant qu’instance EyeGazeTrackerReading :

  • Les TryGetReadingAtTimestamp() méthodes et TryGetReadingAtSystemRelativeTime() retournent le EyeGazeTrackerReading plus proche du temps passé par l’application. Le suivi contrôle la planification de la publication, de sorte que la lecture retournée peut être légèrement plus ancienne ou plus récente que l’heure de la requête. Les EyeGazeTrackerReading.Timestamp propriétés et EyeGazeTrackerReading.SystemRelativeTime permettent à l’application de connaître l’heure exacte de l’état publié.

  • Les TryGetReadingAfterTimestamp() méthodes et TryGetReadingAfterSystemRelativeTime() retournent le premier EyeGazeTrackerReading avec un horodatage strictement supérieur à l’heure passée en tant que paramètre. Cela permet à une application de lire de manière séquentielle tous les états publiés par le suivi. Notez que toutes ces méthodes interrogent la mémoire tampon existante et qu’elles retournent immédiatement. Si aucun état n’est disponible, ils retournent null (en d’autres termes, ils ne font pas attendre qu’un état soit publié).

En plus de son horodatage, un EyeGazeTrackerReading instance possède une IsCalibrationValid propriété qui indique si l’étalonnage du suivi oculaire est valide ou non.

Enfin, les données de regard peuvent être récupérées via un ensemble de méthodes telles que TryGetCombinedEyeGazeInTrackerSpace() ou TryGetLeftEyeGazeInTrackerSpace(). Toutes ces méthodes retournent une valeur booléenne indiquant une réussite. L’échec de l’obtention de certaines données peut signifier que les données ne sont pas prises en charge (EyeGazeTracker possède des propriétés pour détecter ce cas) ou que le dispositif de suivi n’a pas pu obtenir les données (par exemple, un étalonnage non valide ou un œil masqué).

Si, par exemple, l’application souhaite afficher un curseur correspondant au regard combiné, elle peut interroger le suivi à l’aide d’un horodatage de la prédiction du frame en cours de préparation comme suit.

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

Transformer les données du regard vers un autre SpatialCoordinateSystem

Les API WinRT qui retournent des données spatiales telles qu’une position nécessitent toujours un PerceptionTimestamp et un SpatialCoordinateSystem. Par exemple, pour récupérer le regard combiné de HoloLens 2 à l’aide de l’API WinRT, l’API SpatialPointerPose.TryGetAtTimestamp() nécessite deux paramètres : un SpatialCoordinateSystem et un PerceptionTimestamp. Lorsque le regard combiné est alors accessible via SpatialPointerPose.Eyes.Gaze, son origine et sa direction sont exprimées dans le SpatialCoordinateSystem passé.

Les API du SDK de suivi tye étendu n’ont pas besoin de prendre un SpatialCoordinateSystem et les données de regard sont toujours exprimées dans le système de coordonnées du suivi. Mais vous pouvez transformer ces données de regard en un autre système de coordonnées avec la pose du dispositif de suivi liée à l’autre système de coordonnées.

  • Comme indiqué dans la section ci-dessus nommée « Open eye gaze tracker », pour obtenir un SpatialLocator pour le suivi du regard, appelez Windows.Perception.Spatial.Preview.SpatialGraphInteropPreview.CreateLocatorForNode() avec la EyeGazeTracker.TrackerSpaceLocatorNodeId propriété .

  • Les origines du regard et les directions récupérées par le biais EyeGazeTrackerReading sont liées au dispositif de suivi du regard.

  • SpatialLocator.TryLocateAtTimestamp() retourne l’emplacement 6DoF complet du dispositif de suivi du regard à un donné PerceptionTimeStamp et associé à un donné SpatialCoordinateSystem, qui peut être utilisé pour construire une matrice de transformation Matrix4x4.

  • Utilisez la matrice de transformation Matrix4x4 construite pour transférer les origines et les directions du regard vers d’autres SpatialCoordinateSystem.

Les exemples de code suivants montrent comment calculer la position d’un cube situé dans le sens du regard combiné, deux mètres devant l’origine du regard ;

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

Informations de référence sur l’API du KIT de développement logiciel (SDK) de suivi oculaire étendu

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

Voir aussi