DirectX'te baş bakış ve göz bakışı girişi
Not
Bu makale eski WinRT yerel API'leriyle ilgilidir. Yeni yerel uygulama projeleri için OpenXR API'sini kullanmanızı öneririz.
Windows Mixed Reality' de, kullanıcının neye baktığını belirlemek için göz ve baş bakışı girişi kullanılır. Verileri kullanarak baş bakış ve işleme gibi birincil giriş modellerini yönlendirebilir ve farklı etkileşim türleri için bağlam sağlayabilirsiniz. API aracılığıyla kullanılabilecek iki tür bakış vektörleri vardır: baş bakışı ve göz bakışı. Her ikisi de çıkış ve yön ile üç boyutlu bir ışın olarak sağlanır. Uygulamalar daha sonra sahnelerine veya gerçek dünyaya yayın yapabilir ve kullanıcının neyi hedeflediğini belirleyebilir.
Baş bakışı , kullanıcının kafasının işaret ettiği yönü temsil eder. Baş bakışı cihazın kendisinin konumu ve ileri yönü olarak, konum ise iki ekran arasındaki merkez nokta olarak düşünebilirsiniz. Kafa bakışı tüm Karma Gerçeklik cihazlarda kullanılabilir.
Göz bakışı , kullanıcının gözlerinin baktığı yönü temsil eder. Kaynak, kullanıcının gözleri arasında bulunur. Göz izleme sistemi içeren Karma Gerçeklik cihazlarda kullanılabilir.
Hem baş hem de göz bakışı ışınlarına SpatialPointerPose API'sinde erişilebilir. Belirtilen zaman damgasında ve koordinat sisteminde yeni bir SpatialPointerPose nesnesi almak için SpatialPointerPose::TryGetAtTimestamp çağrısı yapın. Bu SpatialPointerPose bir baş bakış kaynağı ve yönü içerir. Ayrıca göz izleme mevcutsa göz bakışı çıkış noktası ve yönü de içerir.
Cihaz desteği
Özellik | HoloLens (1. nesil) | HoloLens 2 | Çevreleyici kulaklıklar |
Baş bakışı | ✔️ | ✔️ | ✔️ |
Göz bakışı | ❌ | ✔️ | ❌ |
Baş bakışı kullanma
Baş bakışa erişmek için spatialPointerPose::TryGetAtTimestamp çağrısı yaparak yeni bir SpatialPointerPose nesnesi alın. Aşağıdaki parametreleri geçirin.
- Baş bakışı için istediğiniz koordinat sistemini temsil eden SpatialCoordinateSystem . Bu, aşağıdaki kodda coordinateSystem değişkeniyle temsil edilir. Daha fazla bilgi için koordinat sistemleri geliştirici kılavuzumuzu ziyaret edin.
- İstenen baş pozunun tam zamanını temsil eden bir Zaman Damgası . Genellikle, geçerli çerçevenin görüntüleneceği zamana karşılık gelen bir zaman damgası kullanırsınız. Bu tahmin edilen görüntüleme zaman damgasını, geçerli HolographicFrame üzerinden erişilebilen bir HolographicFramePrediction nesnesinden alabilirsiniz. Bu HolographicFramePrediction nesnesi aşağıdaki koddaki tahmin değişkeniyle temsil edilir.
Geçerli bir SpatialPointerPose'a sahip olduğunuzda, baş konumuna ve ileri yöne özellikler olarak erişilebilir. Aşağıdaki kod bunlara nasıl erişeceklerini gösterir.
using namespace winrt::Windows::UI::Input::Spatial;
using namespace winrt::Windows::Foundation::Numerics;
SpatialPointerPose pointerPose = SpatialPointerPose::TryGetAtTimestamp(coordinateSystem, prediction.Timestamp());
if (pointerPose)
{
float3 headPosition = pointerPose.Head().Position();
float3 headForwardDirection = pointerPose.Head().ForwardDirection();
// Do something with the head-gaze
}
Göz bakışı kullanma
Kullanıcılarınızın göz bakışı girişi kullanabilmesi için her kullanıcının cihazı ilk kez kullandığında bir göz izleme kullanıcı ayarından geçmesi gerekir. Göz bakışı API'si, baş bakışına benzer. Aynı SpatialPointerPose API'sini kullanır. Bu API, sahnenize göre raycast oluşturabileceğiniz bir ray kaynağı ve yönü sağlar. Tek fark, göz izlemeyi kullanmadan önce açıkça etkinleştirmeniz gerektiğidir:
- Uygulamanızda göz izlemeyi kullanmak için kullanıcı izni isteyin.
- Paket bildiriminizde "Girişe Bakış" özelliğini etkinleştirin.
Göz bakışı girişine erişim isteme
Uygulamanız başlatılırken göz izlemeye erişim istemek için EyesPose::RequestAccessAsync'i çağırarak. Sistem, gerekirse kullanıcıya sorar ve erişim verildikten sonra GazeInputAccessStatus::Allowed değerini döndürür. Bu zaman uyumsuz bir çağrıdır, bu nedenle biraz ek yönetim gerektirir. Aşağıdaki örnek, sonucu beklemek için ayrılmış bir std::thread oluşturur ve sonucu m_isEyeTrackingEnabled adlı üye değişkenine depolar.
using namespace winrt::Windows::Perception::People;
using namespace winrt::Windows::UI::Input;
std::thread requestAccessThread([this]()
{
auto status = EyesPose::RequestAccessAsync().get();
if (status == GazeInputAccessStatus::Allowed)
m_isEyeTrackingEnabled = true;
else
m_isEyeTrackingEnabled = false;
});
requestAccessThread.detach();
Ayrılmış iş parçacığı başlatmak, zaman uyumsuz çağrıları işlemek için yalnızca bir seçenektir. C++/WinRT tarafından desteklenen yeni co_await işlevselliğini de kullanabilirsiniz. Aşağıda kullanıcı izni istemek için başka bir örnek verilmişti:
- EyesPose::IsSupported() uygulamanın yalnızca bir göz izleyicisi varsa izin iletişim kutusunu tetiklemesini sağlar.
- GazeInputAccessStatus m_gazeInputAccessStatus; Bu, izin isteminin tekrar tekrar ortaya çıkmasını önlemektir.
GazeInputAccessStatus m_gazeInputAccessStatus; // This is to prevent popping up the permission prompt over and over again.
// This will trigger to show the permission prompt to the user.
// Ask for access if there is a corresponding device and registry flag did not disable it.
if (Windows::Perception::People::EyesPose::IsSupported() &&
(m_gazeInputAccessStatus == GazeInputAccessStatus::Unspecified))
{
Concurrency::create_task(Windows::Perception::People::EyesPose::RequestAccessAsync()).then(
[this](GazeInputAccessStatus status)
{
// GazeInputAccessStatus::{Allowed, DeniedBySystem, DeniedByUser, Unspecified}
m_gazeInputAccessStatus = status;
// Let's be sure to not ask again.
if(status == GazeInputAccessStatus::Unspecified)
{
m_gazeInputAccessStatus = GazeInputAccessStatus::DeniedBySystem;
}
});
}
Bakış Girişi özelliğini bildirme
Çözüm Gezgini appxmanifest dosyasına çift tıklayın. Ardından Özellikler bölümüne gidin ve Bakış Girişi özelliğini denetleyin.
Bu, appxmanifest dosyasındaki Paket bölümüne aşağıdaki satırları ekler:
<Capabilities>
<DeviceCapability Name="gazeInput" />
</Capabilities>
Göz bakışı ışınını alma
ET'ye erişim elde ettikten sonra, her kareye göz bakışı ışınını almakta serbestsiniz. Kafa bakışı gibi, istenen zaman damgası ve koordinat sistemiyle SpatialPointerPose::TryGetAtTimestamp çağrısı yaparak SpatialPointerPose değerini alın. SpatialPointerPose, Eyes özelliği aracılığıyla bir EyesPose nesnesi içerir. Bu, yalnızca göz izleme etkinse null değildir. Buradan, EyePose::IsCalibrationValid çağrısı yaparak cihazdaki kullanıcının bir göz izleme ayarına sahip olup olmadığını kontrol edebilirsiniz. Ardından, bakış konumunu ve yönünü içeren SpatialRay'i almak için Gaze özelliğini kullanın. Gaze özelliği bazen null olabilir, bu nedenle bunu denetlemeyi unutmayın. Bu durum, ayarlanmış bir kullanıcının gözlerini geçici olarak kapatması durumunda gerçekleşebilir.
Aşağıdaki kod, göz bakışı ışınlarına nasıl erişeceklerini gösterir.
using namespace winrt::Windows::UI::Input::Spatial;
using namespace winrt::Windows::Foundation::Numerics;
SpatialPointerPose pointerPose = SpatialPointerPose::TryGetAtTimestamp(coordinateSystem, prediction.Timestamp());
if (pointerPose)
{
if (pointerPose.Eyes() && pointerPose.Eyes().IsCalibrationValid())
{
if (pointerPose.Eyes().Gaze())
{
auto spatialRay = pointerPose.Eyes().Gaze().Value();
float3 eyeGazeOrigin = spatialRay.Origin;
float3 eyeGazeDirection = spatialRay.Direction;
// Do something with the eye-gaze
}
}
}
Göz izleme kullanılamadığında geri dönüş
Göz izleme tasarım belgelerimizde belirtildiği gibi, hem tasarımcılar hem de geliştiriciler göz izleme verilerinin kullanılamayabileceği örneklerin farkında olmalıdır.
Verilerin kullanılamamasının çeşitli nedenleri vardır:
- Ayarlanmamış bir kullanıcı
- Bir kullanıcı, göz izleme verilerine uygulama erişimini reddetti
- HoloLens vizöründeki lekeler veya kullanıcının gözlerini tıkaan saçlar gibi geçici girişimler.
Bu belgede bazı API'lerden bahsedilmiş olsa da, aşağıdakilerde göz izlemenin hızlı başvuru olarak nasıl algılandığının bir özetini sunuyoruz:
Sistemin gözle izlemeyi desteklediğini denetleyin. Şu yöntemi çağırın: Windows.Perception.Kişiler. EyesPose.IsSupported()
Kullanıcının kalibre edilmiş olup olmadığını denetleyin. Şu özelliği çağırın: Windows.Perception.Kişiler. EyesPose.IsCalibrationValid
Kullanıcının uygulamanıza göz izleme verilerini kullanma izni verdiğinden emin olun: Geçerli 'GazeInputAccessStatus' değerini alın. Bunun nasıl yapılacağına ilişkin bir örnek, Bakış girişine erişim isteme başlığında açıklanmıştır.
Ayrıca, alınan göz izleme veri güncelleştirmeleri arasına bir zaman aşımı ekleyerek göz izleme verilerinizin eskimediğinden ve aksi takdirde aşağıda açıklandığı gibi kafa bakışına geri dönüp dönmediğinizden de denetlemek isteyebilirsiniz. Daha fazla bilgi için geri dönüş tasarımıyla ilgili dikkat edilmesi gerekenler sayfasını ziyaret edin.
Bakışları diğer girişlerle ilişkilendirme
Bazen geçmişteki bir olaya karşılık gelen bir SpatialPointerPose'a ihtiyacınız olduğunu fark edebilirsiniz. Örneğin, kullanıcı Air Tap yaparsa uygulamanız neye baktığını bilmek isteyebilir. Bu amaçla, sistem girişi işleme ve görüntüleme süresi arasındaki gecikme süresi nedeniyle spatialPointerPose::TryGetAtTimestamp'ın tahmin edilen kare süresiyle kullanılması yanlış olabilir. Ayrıca, hedefleme için göz bakışı kullanıyorsanız, gözlerimiz işleme eylemini tamamlamadan önce bile ilerleme eğilimindedir. Bu, basit bir Air Tap için sorun oluşturmaz, ancak uzun sesli komutları hızlı göz hareketleriyle birleştirirken daha kritik hale gelir. Bu senaryoyu işlemenin bir yolu, giriş olayına karşılık gelen geçmiş bir zaman damgası kullanarak SpatialPointerPose::TryGetAtTimestamp'a ek bir çağrı yapmaktır.
Ancak SpatialInteractionManager aracılığıyla yönlendiren girişler için daha kolay bir yöntem vardır. SpatialInteractionSourceState'in kendi TryGetAtTimestamp işlevi vardır. Tahmine gerek kalmadan mükemmel bağıntılı bir SpatialPointerPose sağlayacak çağrısı. SpatialInteractionSourceStates ile çalışma hakkında daha fazla bilgi için DirectX'te Eller ve Hareket Denetleyicileri belgelerine göz atın.
Kalibrasyon
Gözle izlemenin doğru çalışması için her kullanıcının bir göz izleme kullanıcı ayarından geçmesi gerekir. Bu, cihazın kullanıcı için daha rahat ve daha kaliteli bir görüntüleme deneyimi için sistemi ayarlamasını ve aynı anda doğru göz izlemesini sağlamasını sağlar. Geliştiricilerin kullanıcı kalibrasyonlarını yönetmek için kendi başlarına hiçbir şey yapması gerekmez. Sistem, aşağıdaki koşullarda kullanıcıdan cihazı ayarlamasının istenmesini sağlar:
- Kullanıcı cihazı ilk kez kullanıyor
- Kullanıcı daha önce kalibrasyon işlemini geri çevirmişti
- Kullanıcı cihazı son kullandığında kalibrasyon işlemi başarılı olmadı
Geliştiriciler, göz izleme verilerinin kullanılamayabileceği kullanıcılar için yeterli desteği sağladığında emin olmalıdır. Geri dönüş çözümleriyle ilgili dikkat edilmesi gerekenler hakkında daha fazla bilgi için bkz. HoloLens 2'da göz izleme.