Share via


Unity'de genişletilmiş göz izleme

Genişletilmiş göz izleme örneğinin GitHub deposuna erişmek için:

Genişletilmiş göz izleme, HoloLens 2 yeni bir özelliktir. Standart göz izlemenin yalnızca birleşik göz bakışı verilerini sağlayan bir üst kümesidir. Genişletilmiş göz izleme ayrıca tek tek göz bakışı verileri sağlar ve uygulamaların bakış verileri için 30, 60 ve 90fps gibi farklı kare hızları ayarlamasına olanak tanır. Göz açıklığı ve göz dalgalanması gibi diğer özellikler şu anda HoloLens 2 tarafından desteklenmiyor.

Genişletilmiş Göz İzleme SDK'sı, uygulamaların genişletilmiş göz izleme verilerine ve özelliklerine erişmesini sağlar. OpenXR API'leri veya eski WinRT API'leri ile birlikte kullanılabilir.

Bu makalede, Unity'deki genişletilmiş göz izleme SDK'sını Karma Gerçeklik OpenXR Eklentisi ile birlikte kullanmanın yolları açıklamaktadır.

Proje ayarları

  1. HoloLens geliştirmesi için Unity projesini ayarlayın.
    • Bakış Girişi özelliğini seçin
  2. MRTK özellik aracından Karma Gerçeklik OpenXR Eklentisini içeri aktarın.
  3. Göz İzleme SDK'sı NuGet paketini Unity projenize aktarın.
    1. NuGetForUnity paketini indirip yükleyin.
    2. Unity düzenleyicisinde adresine>Manage NuGet Packages gidin NuGetveMicrosoft.MixedReality.EyeTracking
    3. NuGet paketinin en son sürümünü içeri aktarmak için Yükle düğmesine tıklayın.
      Göz İzleme SDK'sı Nuget paketinin ekran görüntüsü.
  4. Unity yardımcı betiklerini ekleyin.
    1. ExtendedEyeGazeDataProvider.cs Betiği buradan Unity projenize ekleyin.
    2. Bir sahne oluşturun, ardından betiği herhangi bir GameObject'e ekleyin ExtendedEyeGazeDataProvider.cs .
  5. işlevlerini ExtendedEyeGazeDataProvider.cs kullanma ve mantığınızı uygulama.
  6. Derleme ve HoloLens'e dağıtma.

ExtendedEyeGazeDataProvider işlevlerini kullanma

Not

Betik, ExtendedEyeGazeDataProvider bakış verilerinin koordinatlarını dönüştürmek için Karma Gerçeklik OpenXR Eklentisindeki bazı API'lere bağlıdır. Unity projeniz kullanım dışı bırakılmış Windows XR eklentisini veya eski Unity sürümündeki eski Yerleşik XR'yi kullanıyorsa bu işlem kullanılamaz. Genişletilmiş göz izlemenin bu senaryolarda da çalışmasını sağlamak için:

  • Yalnızca kare hızı ayarlarına erişmeniz gerekiyorsa OpenXR Eklentisi Karma Gerçeklik gerekli değildir ve ayarını yalnızca kare hızıyla ilgili mantığı korumak için değiştirebilirsinizExtendedEyeGazeDataProvider.
  • Göz bakışı verilerine yine de erişmeniz gerekiyorsa Unity'de WinRT API'lerini kullanmanız gerekir. WinRT API'leriyle genişletilmiş göz izleme SDK'sının nasıl kullanılacağını görmek için "Ayrıca Bkz. " bölümüne bakın.

sınıfı genişletilmiş ExtendedEyeGazeDataProvider göz izleme SDK API'lerini sarmalar. Unity dünya alanında veya ana kameraya göre bakış okuması yapmak için işlevler sağlar.

Bakış verilerini almak için kullanılacak ExtendedEyeGazeDataProvider kod örnekleri aşağıdadır.

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 Betik yürütürken, bakış veri çerçevesi hızını şu anda 90fps olan en yüksek seçeneğe ayarlar.

Genişletilmiş göz izleme SDK'sının API başvurusu

Betiği kullanmanın ExtendedEyeGazeDataProvider dışında, aşağıdaki SDK API'lerini doğrudan kullanmak için kendi betiğinizi de oluşturabilirsiniz.

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

Ayrıca bkz.