Vstup pohledem a pohledem do očí v rozhraní DirectX

Poznámka

Tento článek se týká starších nativních rozhraní API WinRT. Pro nové projekty nativních aplikací doporučujeme použít rozhraní OpenXR API.

V Windows Mixed Reality se k určení toho, na co se uživatel dívá, používá pohled z očí a hlavy. Data můžete použít k řízení primárních vstupních modelů, jako je pohled a potvrzení, a poskytnout kontext pro různé typy interakcí. Prostřednictvím rozhraní API jsou k dispozici dva typy vektorů pohledu: head-gaze a eye-gaze. Oba jsou k dispozici jako trojrozměrný paprsek s původem a směrem. Aplikace pak můžou vysměrovat do svých scén nebo do skutečného světa a určit, na co uživatel cílí.

Pohled hlavou představuje směr, kterým směřuje hlava uživatele. Pohled hlavou si můžete představit jako polohu a směr samotného zařízení dopředu, přičemž pozice je středovým bodem mezi dvěma displeji. Upřený pohled je k dispozici na všech Mixed Reality zařízeních.

Pohled z očí představuje směr, kterým se oči uživatele dívají. Původ se nachází mezi očima uživatele. Je k dispozici na Mixed Reality zařízeních, která zahrnují systém sledování očí.

Paprsky hlavy i pohledů jsou přístupné prostřednictvím rozhraní API SpatialPointerPose . Volejte SpatialPointerPose::TryGetAtTimestamp pro příjem nového objektu SpatialPointerPose v zadaném systému časových razítek a souřadnic. Tento SpatialPointerPose obsahuje počátek a směr pohledu. Obsahuje také původ a směr zraku, pokud je k dispozici sledování očí.

Podpora zařízení

Funkce HoloLens (1. generace) HoloLens 2 Imerzivní náhlavní soupravy
Pohled z hlavy ✔️ ✔️ ✔️
Pohled z očí ✔️

Použití upřeným pohledem

Pokud chcete získat přístup k hlavnímu pohledu, 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 použít pro pohled hlavou. To 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é pozice hlavy. Obvykle použijete časové razítko, které odpovídá času zobrazení aktuálního rámce. Toto předpovězené časové razítko zobrazení můžete získat z objektu HolographicFramePrediction , který je přístupný prostřednictvím aktuálního objektu HolographicFrame. Tento objekt HolographicFramePrediction je reprezentován prediktivní proměnnou v následujícím kódu.

Jakmile budete mít platnou funkci SpatialPointerPose, pozice hlavy a směr vpřed jsou 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í zrakového pohledu

Aby uživatelé mohli používat vstup pohledem, musí každý uživatel při prvním použití zařízení projít kalibrací uživatele sledování očí . Rozhraní API pro pohled do očí se podobá pohledu z očí. Používá stejné rozhraní API SpatialPointerPose , které poskytuje původ a směr paprsku, 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čí:

  1. Požádejte uživatele o oprávnění používat sledování očí ve vaší aplikaci.
  2. Povolte v manifestu balíčku funkci "Gaze Input".

Žádost o přístup ke vstupu pohledem

Při spouš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í GazeInputAccessStatus::Allowed . Jedná se o asynchronní volání, takže vyžaduje trochu další správy. Následující příklad roztáčí odpojený std::thread, aby počkal na výsledek, který se uloží 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 jednou z možností pro zpracování asynchronních volání. Můžete také použít novou funkci co_await , kterou podporuje C++/WinRT. Tady je další příklad žádosti o oprávnění uživatele:

  • EyesPose::IsSupported() umožňuje aplikaci aktivovat dialogové okno oprávnění jenom v případě, že je k dispozici sledování očí.
  • GazeInputAccessStatus m_gazeInputAccessStatus; Tím zabráníte tomu, aby se výzva k oprávnění zobrazovala znovu a znovu.
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 pohledu

Dvakrát klikněte na soubor appxmanifest v Průzkumník řešení. Pak přejděte do části Capabilities (Možnosti) a zkontrolujte možnost Gaze Input (Vstup pohledu ).

Funkce vstupu pohledu

Tím přidáte následující řádky do oddílu Package v souboru appxmanifest:

  <Capabilities>
    <DeviceCapability Name="gazeInput" />
  </Capabilities>

Získání paprsku očního pohledu

Jakmile dostanete přístup k ET, máte možnost uchopit pohled na každý snímek. Stejně jako při pohledu z 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 EyesPose objekt přes Eyes vlastnost. Tato hodnota není null, pouze pokud 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 pomocí vlastnosti Gaze získejte SpatialRay obsahující polohu a směr pohledu. Vlastnost Gaze může někdy být null, proto ji nezapomeňte 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 paprsku očního pohledu.

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 je uvedeno v naší dokumentaci k návrhu sledování očí, návrháři i vývojáři by měli znát případy, kdy data sledování očí nemusí být k dispozici.

Pro nedostupná data existují různé důvody:

  • Nekalibrovaný uživatel
  • Uživatel odepřel aplikaci přístup k datům sledování očí.
  • Dočasné zásahy, jako jsou šmouhy na cloně HoloLensu nebo vlasy, které zaočkují oči uživatele.

I když některá z rozhraní API už 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 stručná reference:

Můžete také zkontrolovat, že data sledování očí nejsou zastaralá přidáním časového limitu mezi přijatými aktualizacemi dat sledování očí a jiným přechodem do očí, jak je popsáno níže. Další informace najdete v našich aspektech náhradního návrhu .


Korelace pohledu 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, vaše aplikace může chtít vědět, na co se díval. K tomuto účelu by jednoduché použití SpatialPointerPose::TryGetAtTimestamp s predikovaným časem rámce bylo nepřesné kvůli latenci mezi zpracováním vstupu systému a časem zobrazení. Pokud k cílení používáme pohled z očí, naše oči mají tendenci se pohybovat dál i před dokončením akce potvrzení. To není problém u jednoduchého klepnutí vzduchem, ale stává se důležitějším při kombinování dlouhých hlasových příkazů s rychlými pohyby očí. Jedním ze způsobů, jak tento scénář zpracovat, je provést 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é poskytne dokonale korelované SpatialPointerPose bez dohadování. Další informace o práci se službou SpatialInteractionSourceStates najdete v dokumentaci k ovládacím prvkům Hands and Motion Controller v rozhraní DirectX .


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ší prohlížení pro uživatele a současně zajistit přesné sledování očí. Vývojáři nemusí na své straně nic dělat, 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 používá zařízení 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, aby uživatelům poskytovali odpovídající podporu, pokud data sledování očí nemusí být k dispozici. Další informace o náhradních řešeních najdete v tématu Sledování očí na HoloLens 2.


Viz také