Vstup pohledem hlavy a pohledem do očí v DirectX
Poznámka
Tento článek se týká starších nativních rozhraní API WinRT. V případě nových nativních projektů aplikací doporučujeme použít rozhraní API OpenXR.
Ve Windows Mixed Reality se vstup očí a hlavy používá k určení toho, na co se uživatel dívá. Data můžete použít k řízení primárních vstupních modelů, jako je pohled hlavy a potvrzení, a poskytnout kontext pro různé typy interakcí. Prostřednictvím rozhraní API jsou k dispozici dva typy vektorů pohledů: pohled hlavy a pohled na oči. Obě jsou poskytovány jako trojrozměrný paprsek s původem a směrem. Aplikace pak můžou raycast na jejich scény nebo skutečný svět a určit, na co uživatel cílí.
Pohled na hlavu představuje směr, ve kterému je hlava uživatele nasměrovaná. Představte si pohled hlavy jako polohu a směr dopředu samotného zařízení, přičemž pozice je středovým bodem mezi dvěma displeji. Pohled na hlavu je k dispozici na všech Mixed Reality zařízeních.
Pohled na oči představuje směr, ke kterému se uživatel dívá. Původ se nachází mezi očima uživatele. Je k dispozici na Mixed Reality zařízeních, která obsahují systém sledování očí.
Paprsky hlavy i očí jsou přístupné prostřednictvím rozhraní API SpatialPointerPose . Volání SpatialPointerPose::TryGetAtTimestamp pro příjem nového objektu SpatialPointerPose v zadaném časovém razítku a souřadnicovém systému. Tato spatialpointerPose obsahuje původ hlavy a směr. Obsahuje také původ očí a směr, pokud je k dispozici sledování očí.
Podpora zařízení
Funkce | HoloLens (1. generace) | HoloLens 2 | Asistivní náhlavní soupravy |
Pohled na hlavu | ✔️ | ✔️ | ✔️ |
Pohled na oči | ❌ | ✔️ | ❌ |
Použití pohledu hlavy
Pokud chcete získat přístup k přehledu hlavy, začněte voláním SpatialPointerPose::TryGetAtTimestamp pro příjem nového objektu SpatialPointerPose. Předejte následující parametry.
- SpatialCoordinateSystem, který představuje souřadnicový systém, který chcete pro pohled hlavy. Toto je reprezentováno proměnnou coordinateSystem v následujícím kódu. Další informace najdete v naší příručce pro vývojáře souřadnicových systémů .
- Časové razítko, které představuje přesný čas požadované hlavy. Obvykle použijete časové razítko, které odpovídá času, kdy se zobrazí aktuální snímek. Toto předpovězené časové razítko můžete získat z objektu HolographicFramePrediction , který je přístupný prostřednictvím aktuálního holografického rámce. Tento holographicFramePrediction objekt je reprezentován prediktivní proměnnou v následujícím kódu.
Jakmile budete mít platnou funkci SpatialPointerPose, bude pozice hlavy a směr vpřed přístupné jako vlastnosti. Následující kód ukazuje, jak k nim získat přístup.
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
}
Použití očního pohledu
Aby uživatelé mohli používat vstup pohledem, musí každý uživatel projít kalibrací uživatelů sledování očí při prvním použití zařízení. Rozhraní API pro pohled očí je podobné pohledu na hlavu. Používá stejné rozhraní API SpatialPointerPose , které poskytuje původ paprsku a směr, který můžete raycastovat proti scéně. Jediným rozdílem je, že před použitím je potřeba explicitně povolit sledování očí:
- Požádejte uživatele o oprávnění k používání sledování očí ve vaší aplikaci.
- Povolte funkci "Gaze Input" v manifestu balíčku.
Žádost o přístup ke vstupu s pohledem na oči
Při spuštění aplikace zavolejte EyesPose::RequestAccessAsync a požádejte o přístup ke sledování očí. Systém v případě potřeby vyzve uživatele a po udělení přístupu vrátí funkce GazeInputAccessStatus::Allowed . Jedná se o asynchronní volání, takže vyžaduje trochu další správy. Následující příklad vytočí odpojený std::thread, aby čekal na výsledek, který ukládá do členské proměnné s názvem m_isEyeTrackingEnabled.
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();
Spuštění odpojeného vlákna je jen jedna možnost pro zpracování asynchronních volání. Můžete také použít nové funkce co_await podporované C++/WinRT. Tady je další příklad pro žádost o oprávnění uživatele:
- EyesPose::IsSupported() umožňuje aplikaci aktivovat dialogové okno oprávnění pouze v případě, že je tam sledování očí.
- GazeInputAccessStatus m_gazeInputAccessStatus; Toto je, aby se zabránilo opětovnému spuštění výzvy k oprávnění.
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;
}
});
}
Deklarování možnosti vstupu pohledů
Poklikejte na soubor appxmanifest v Průzkumník řešení. Pak přejděte do části Možnosti a zkontrolujte možnost Pohled vstup .
Tím přidáte do oddílu Balíček v souboru appxmanifest následující řádky:
<Capabilities>
<DeviceCapability Name="gazeInput" />
</Capabilities>
Získání očního pohledu paprsku
Jakmile dostanete přístup k ET, můžete si vzít oči-pohled paprsky každý rám. Stejně jako u pohledů hlavy získejte SpatialPointerPose voláním SpatialPointerPose::TryGetAtTimestamp s požadovaným časovým razítkem a souřadnicovým systémem. SpatialPointerPose obsahuje objekt EyesPose prostřednictvím vlastnosti Eyes . Toto není null pouze v případě, že je povolené sledování očí. Odtud můžete zkontrolovat, jestli má uživatel v zařízení kalibraci sledování očí voláním EyesPose::IsCalibrationValid. Dále použijte vlastnost Gaze k získání prostorovéray obsahující pozici a směr očí. Vlastnost Gaze může někdy být null, takže nezapomeňte to zkontrolovat. K tomu může dojít v případě, že kalibrovaný uživatel dočasně zavře oči.
Následující kód ukazuje, jak získat přístup k očnímu paprsku.
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
}
}
}
Náhradní, když sledování očí není k dispozici
Jak jsme zmínili v dokumentaci k návrhu sledování očí, měli by návrháři i vývojáři vědět o instancích, kde data sledování očí nemusí být dostupná.
Data nejsou k dispozici z různých důvodů:
- Uživatel, který se nekalibruje
- Uživatel odepřel aplikaci přístup k datům sledování očí
- Dočasné interference, jako jsou šmudky na visor HoloLens nebo vlasy occluding očí uživatele.
Zatímco některá rozhraní API již byla v tomto dokumentu zmíněna, v následujícím článku uvádíme souhrn toho, jak zjistit, že sledování očí je k dispozici jako rychlá reference:
Zkontrolujte, jestli systém podporuje sledování očí vůbec. Zavolejte následující metodu: Windows.Perception.Lidé. EyesPose.IsSupported()
Zkontrolujte, jestli je uživatel kalibrovaný. Zavolejte následující vlastnost: Windows.Perception.Lidé. EyesPose.IsCalibrationValid
Zkontrolujte, jestli uživatel udělil vaší aplikaci oprávnění k používání dat sledování očí: Načtěte aktuální "GazeInputAccessStatus". Příklad toho, jak to udělat, je vysvětleno v žádosti o přístup ke vstupu pohledem.
Můžete také zkontrolovat, že data sledování očí nejsou zastaralá přidáním časového limitu mezi aktualizacemi přijatých dat sledování očí a jinak se vrátit k přehledům hlavy, jak je popsáno níže. Další informace najdete v našich aspektech náhradního návrhu .
Korelace pohledů s jinými vstupy
Někdy můžete zjistit, že potřebujete SpatialPointerPose , která odpovídá události v minulosti. Pokud například uživatel provede Air Tap, může vaše aplikace chtít vědět, na co se dívá. Pro účely tohoto účelu by jednoduše použití SpatialPointerPose::TryGetAtTimestamp s předpovězenou dobou rámce bylo nepřesné kvůli latenci mezi zpracováním vstupu systému a časem zobrazení. Také pokud používáte pohled na cílení, naše oči mají tendenci se pohybovat i před dokončením akce potvrzení. To je méně problém pro jednoduchý Air Tap, ale stává se důležitější při kombinování dlouhých hlasových příkazů s rychlým pohybem očí. Jedním ze způsobů, jak tento scénář zpracovat, je vytvořit další volání SpatialPointerPose::TryGetAtTimestamp pomocí historického časového razítka, které odpovídá vstupní události.
Pro vstup, který směruje přes SpatialInteractionManager, je ale jednodušší metoda. SpatialInteractionSourceState má vlastní funkci TryGetAtTimestamp. Volání, které bude poskytovat dokonale korelované SpatialPointerPose bez odhadu. Další informace o práci s SpatialInteractionSourceStates najdete v dokumentaci k ovládacím prvkům Hands a Motion Controller.
Kalibrace
Aby sledování očí fungovalo přesně, musí každý uživatel projít kalibrací uživatele sledování očí. To umožňuje zařízení upravit systém pro pohodlnější a kvalitnější zobrazení pro uživatele a zajistit přesné sledování očí najednou. Vývojáři nemusí dělat nic na jejich konci, aby mohli spravovat kalibraci uživatelů. Systém zajistí, aby se uživateli zobrazila výzva ke kalibraci zařízení za následujících okolností:
- Uživatel zařízení používá poprvé.
- Uživatel se dříve odhlásil z procesu kalibrace.
- Proces kalibrace nebyl úspěšný při posledním použití zařízení uživatelem.
Vývojáři by měli zajistit odpovídající podporu uživatelům, kteří nemusí být k dispozici data sledování očí. Přečtěte si další informace o náhradních řešeních při sledování očí na HoloLens 2.