Megosztás a következőn keresztül:


Kiterjesztett szemkövetés a Unityben

A kiterjesztett szemkövető minta GitHub-adattárának elérése:

A kiterjesztett szemkövetés egy új képesség a HoloLens 2. Ez a szabványos szemkövetés szuperhalmaza, amely csak kombinált szemnézet-adatokat biztosít. A kiterjesztett szemkövetés egyéni szemnézetadatokat is biztosít, és lehetővé teszi az alkalmazások számára, hogy különböző képkockasebességeket állítsanak be a tekintetadatokhoz, például 30, 60 és 90fps. A HoloLens 2 jelenleg nem támogatja az egyéb funkciókat, például a szem nyitottságát és a szem csúcsosságát.

Az Extended Eye Tracking SDK lehetővé teszi, hogy az alkalmazások hozzáférjenek a kiterjesztett szemkövetés adataihoz és funkcióihoz. OpenXR API-kkal vagy örökölt WinRT API-kkal együtt használható.

Ez a cikk a kiterjesztett szemkövető SDK Unityben való használatát ismerteti a Mixed Reality OpenXR beépülő modullal együtt.

Projekt beállítása

  1. Állítsa be a Unity-projektet a HoloLens-fejlesztéshez.
    • Válassza ki a Tekintet bemenete képességet
  2. Importálja az Mixed Reality OpenXR beépülő modult az MRTK funkcióeszközből.
  3. Importálja az Eye Tracking SDK NuGet-csomagot a Unity-projektbe.
    1. Töltse le és telepítse a NuGetForUnity csomagot.
    2. A Unity-szerkesztőben nyissa meg a NuGet->Manage NuGet Packages-t, majd keressen rá a Microsoft.MixedReality.EyeTracking
    3. Kattintson a Telepítés gombra a NuGet-csomag legújabb verziójának importálásához.
      Képernyőkép a Eye Tracking SDK Nuget-csomagról.
  4. Adja hozzá a Unity segédszkripteket.
    1. Adja hozzá innen a ExtendedEyeGazeDataProvider.cs szkriptet a Unity-projekthez.
    2. Hozzon létre egy jelenetet, majd csatolja a ExtendedEyeGazeDataProvider.cs szkriptet bármely GameObject elemhez.
  5. Használja fel és implementálja a logikák függvényeit ExtendedEyeGazeDataProvider.cs .
  6. Buildelés és üzembe helyezés a HoloLensben.

Az ExtendedEyeGazeDataProvider függvényeinek felhasználása

Megjegyzés

A ExtendedEyeGazeDataProvider szkript a Mixed Reality OpenXR beépülő modul néhány API-jától függ a tekintetadatok koordinátáinak konvertálásához. Nem működik, ha a Unity-projekt az elavult Windows XR beépülő modult vagy a régebbi Unity-verzióban lévő régi beépített XR-t használja. Ahhoz, hogy a kiterjesztett szemkövetés is működjön ezekben a forgatókönyvekben:

  • Ha csak hozzá kell férnie a képkockasebesség-beállításokhoz, nincs szükség az Mixed Reality OpenXR beépülő modulra, és módosíthatja úgy, ExtendedEyeGazeDataProvider hogy csak a képkockasebességgel kapcsolatos logikát tartsa meg.
  • Ha továbbra is hozzá kell férnie az egyes szempillantásadatokhoz, a Unityben WinRT API-kat kell használnia. A kiterjesztett szemkövető SDK WinRT API-kkal való használatáról a "Lásd még" című szakasz nyújt tájékoztatást.

A ExtendedEyeGazeDataProvider osztály burkolja a kiterjesztett szemkövető SDK API-kat. Olyan funkciókat biztosít, hogy a Unity világűrben vagy a fő kamerához képest láthassa az olvasást.

Az alábbiakban a tekintetadatok lekéréséhez használandó ExtendedEyeGazeDataProvider kódmintákat talál.

ExtendedEyeGazeDataProvider extendedEyeGazeDataProvider;
void Update() {
    timestamp = DateTime.Now;

    var leftGazeReadingInWorldSpace = extendedEyeGazeDataProvider.GetWorldSpaceGazeReading(extendedEyeGazeDataProvider.GazeType.Left, timestamp);
    var rightGazeReadingInWorldSpace = extendedEyeGazeDataProvider.GetWorldSpaceGazeReading(extendedEyeGazeDataProvider.GazeType.Right, timestamp);
    var combinedGazeReadingInWorldSpace = extendedEyeGazeDataProvider.GetWorldSpaceGazeReading(extendedEyeGazeDataProvider.GazeType.Combined, timestamp);

    var combinedGazeReadingInCameraSpace = extendedEyeGazeDataProvider.GetCameraSpaceGazeReading(extendedEyeGazeDataProvider.GazeType.Combined, timestamp);
}

ExtendedEyeGazeDataProvider A szkript végrehajtásakor a tekintet adatkeretének sebességét a legmagasabb értékre állítja, amely jelenleg 90fps.

Kiterjesztett szemkövető SDK API-referenciája

A szkript használata ExtendedEyeGazeDataProvider mellett saját szkriptet is létrehozhat az SDK API-k közvetlen felhasználásához.

namespace Microsoft.MixedReality.EyeTracking
{
    /// <summary>
    /// Allow discovery of Eye Gaze Trackers connected to the system
    /// This is the only class from the 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 providing individual 
        /// eye gaze vector and frame rate 
        /// </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 the Perception API, use SpatialGraphInteropPreview.CreateLocatorForNode
        /// for the 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 of 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);
    }
}

Lásd még