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


Fej-tekintet és szem-tekintet bemenet a DirectX-ben

Megjegyzés

Ez a cikk az örökölt WinRT natív API-kkal kapcsolatos. Új natív alkalmazásprojektek esetén az OpenXR API használatát javasoljuk.

A Windows Mixed Reality szem- és fejnézet bemenete határozza meg, hogy mit néz a felhasználó. Az adatokkal olyan elsődleges bemeneti modelleket hajthat végre, mint a tekintet és a véglegesítés, és kontextust biztosíthat a különböző interakciótípusokhoz. Az API-val kétféle tekintetvektor érhető el: a fej-tekintet és a tekintet. Mindkettő háromdimenziós sugárként van megadva, amelynek eredete és iránya van. Az alkalmazások ezután besugárzhatják a jeleneteiket vagy a valós világot, és megállapíthatják, hogy a felhasználó mit céloz meg.

A fej-tekintet azt az irányt jelöli, amelybe a felhasználó feje mutat. Gondoljon a fej-tekintetre úgy, mint az eszköz helyzetére és előre irányára, a két kijelző közötti középponttal. A tekintet minden Mixed Reality eszközön elérhető.

A szempillantás azt az irányt jelöli, amelyet a felhasználó szeme keres. A forrás a felhasználó szeme között található. Olyan Mixed Reality eszközökön érhető el, amelyek szemkövető rendszert is tartalmaznak.

A head és a eye-gaze sugarak is elérhetők a SpatialPointerPose API-val. Hívja meg a SpatialPointerPose::TryGetAtTimestamp parancsot egy új SpatialPointerPose objektum fogadásához a megadott időbélyegzőn és koordinátarendszeren. Ez a SpatialPointerPose egy szempillantású forrást és irányt tartalmaz. Emellett szem-tekintet forrást és irányt is tartalmaz, ha elérhető a szemkövetés.

Eszköztámogatás

Szolgáltatás HoloLens (1. generációs) HoloLens 2 Modern headsetek
Fej-tekintet ✔️ ✔️ ✔️
Szempillantás ✔️

Fej-tekintet használata

A tekintethez való hozzáféréshez először hívja meg a SpatialPointerPose::TryGetAtTimestamp parancsot egy új SpatialPointerPose objektum fogadásához. Adja meg az alábbi paramétereket.

  • Egy SpatialCoordinateSystem, amely a fej-tekintethez használni kívánt koordinátarendszert jelöli. Ezt a koordinátaRendszer változó jelöli az alábbi kódban. További információt a koordinátarendszerek fejlesztői útmutatójában talál.
  • Egy időbélyeg, amely a kért fejpóz pontos idejét jelöli. Általában olyan időbélyeget használ, amely megfelel az aktuális keret megjelenítésének időpontjának. Ezt az előrejelzett megjelenítési időbélyeget egy HolographicFramePrediction objektumból szerezheti be, amely az aktuális HolographicFrame-keretrendszeren keresztül érhető el. Ezt a HolographicFramePrediction objektumot az előrejelzési változó jelöli az alábbi kódban.

Ha már rendelkezik érvényes SpatialPointerPose-tal, a fej pozíciója és az előre mutató irány tulajdonságokként lesz elérhető. Az alábbi kód bemutatja, hogyan érheti el őket.

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
}

Szempillantás használata

Ahhoz, hogy a felhasználók szem-tekintet bemenetet használjanak, minden felhasználónak át kell mennie egy szemkövető felhasználó kalibrálásán az eszköz első használatakor. A szem-tekintet API hasonló a fej-tekintethez. Ugyanazt a SpatialPointerPose API-t használja, amely egy sugár eredetét és irányát biztosítja, amelyet a jeleneten átsugározhat. Az egyetlen különbség az, hogy a használat előtt explicit módon engedélyeznie kell a szemkövetést:

  1. Kérjen felhasználói engedélyt a szemkövetés használatára az alkalmazásban.
  2. Engedélyezze a "Tekintet bemenete" funkciót a csomagjegyzékben.

Hozzáférés kérése a szempillantás bemenetéhez

Az alkalmazás indításakor hívja fel a EyesPose::RequestAccessAsync parancsot, hogy hozzáférést kérjen a szemkövetéshez. A rendszer szükség esetén rákérdez a felhasználóra, és visszaadja a GazeInputAccessStatus::Allowed értéket a hozzáférés megadása után. Ez egy aszinkron hívás, ezért egy kis extra felügyeletet igényel. Az alábbi példa egy leválasztott std::szálat hoz létre, amely megvárja az eredményt, amelyet egy m_isEyeTrackingEnabled nevű tagváltozóban tárol.

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

A leválasztott szálak indítása csak egy lehetőség az aszinkron hívások kezelésére. Használhatja a C++/WinRT által támogatott új co_await funkciót is. Íme egy másik példa a felhasználói engedély kérésére:

  • EyesPose::IsSupported() lehetővé teszi, hogy az alkalmazás csak akkor aktiválja az engedély párbeszédpanelt, ha van szemkövető.
  • GazeInputAccessStatus m_gazeInputAccessStatus; Ennek célja, hogy megakadályozza az engedélykérés ismételt és ismételt felbukkanását.
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;	
		}
	});
}

A tekintet bemenetének deklarálása

Kattintson duplán az appxmanifest fájlra a Megoldáskezelőben. Ezután lépjen a Képességek szakaszra, és ellenőrizze a Tekintet bemenete képességet.

A betekintő beviteli képessége

Ez hozzáadja a következő sorokat az appxmanifest fájl Csomag szakaszához:

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

A szem-tekintet sugarának lekérése

Miután megkapta a hozzáférést az ET-hez, minden képkockán szabadon megragadhatja a szem-tekintet sugarát. A head-tekintethez hasonlóan a SpatialPointerPose::TryGetAtTimestamp hívásával is beszerezheti a SpatialPointerPose-t a kívánt időbélyeggel és koordinátarendszerrel. A SpatialPointerPose egy EyesPose objektumot tartalmaz a Eyes tulajdonságon keresztül. Ez csak akkor nem null értékű, ha a szemkövetés engedélyezve van. Innen a EyesPose:IsCalibrationValid hívásával ellenőrizheti, hogy az eszköz felhasználója rendelkezik-e szemkövetési kalibrációval. Ezután használja a Tekintet tulajdonságot a szem-tekintet pozíciót és irányt tartalmazó SpatialRay lekéréséhez. A Tekintet tulajdonság néha null értékű is lehet, ezért mindenképpen ellenőrizze ezt. Ez akkor fordulhat elő, ha egy kalibrált felhasználó ideiglenesen bezárja a szemét.

Az alábbi kód bemutatja, hogyan lehet hozzáférni a szem-tekintet sugarához.

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

Tartalék, ha a szemkövetés nem érhető el

Amint azt a szemkövetési tervezési dokumentációnkban is említettük, a tervezőknek és a fejlesztőknek is tisztában kell lenniük azokkal a példányokkal, ahol a szemkövetési adatok nem érhetők el.

Az adatok nem érhetők el különböző okokból:

  • A felhasználó nincs kalibrálva
  • Egy felhasználó megtagadta az alkalmazás hozzáférését a szemkövetési adataihoz
  • Ideiglenes interferenciák, például a HoloLens-viszoron vagy a felhasználó szemét elzáró hajon történő elmosódások.

Bár az API-k némelyike már szerepel ebben a dokumentumban, a következőkben röviden bemutatjuk, hogyan észlelhető a szemkövetés gyorshivatkozásként:

Azt is érdemes ellenőrizni, hogy a szemkövetési adatok nem elavultak-e, ha időtúllépést ad hozzá a kapott szemkövetési adatok frissítései között, és ellenkező esetben visszaesik a tekintetre az alábbiakban ismertetett módon. További információért tekintse meg a tartalék kialakítással kapcsolatos szempontokat .


Tekintet korrelálása más bemenetekkel

Előfordulhat, hogy olyan SpatialPointerPose-ra van szüksége, amely megfelel egy múltbeli eseménynek. Ha például a felhasználó légi koppintással végzi el a műveletet, előfordulhat, hogy az alkalmazás tudni szeretné, hogy mit néztek. Ehhez egyszerűen használja a SpatialPointerPose::TryGetAtTimestamp paramétert az előrejelzett keretidővel, mert a rendszer bemenetének feldolgozása és a megjelenítési idő közötti késés miatt pontatlan. Továbbá, ha szem-tekintetet használ a célzáshoz, a szemünk hajlamosak továbblépni még a véglegesítési művelet befejezése előtt is. Ez kevésbé jelent problémát egy egyszerű légcsapolás esetében, de kritikusabbá válik a hosszú hangparancsok és a gyors szemmozgások kombinálásakor. Ennek a forgatókönyvnek az egyik módja, ha egy további hívást kezdeményez a SpatialPointerPose::TryGetAtTimestamp felé a bemeneti eseménynek megfelelő előzményidőbélyeg használatával.

A SpatialInteractionManageren áthaladó bemenetek esetében azonban van egy egyszerűbb módszer. A SpatialInteractionSourceState saját TryGetAtTimestamp függvénnyel rendelkezik. Olyan hívás, amely tökéletesen korrelált SpatialPointerPose-t biztosít a találgatások nélkül. A SpatialInteractionSourceStates használatával kapcsolatos további információkért tekintse meg a kéz- és mozgásvezérlőket a DirectX dokumentációjában .


Kalibrációs

Ahhoz, hogy a szemkövetés pontosan működjön, minden felhasználónak át kell mennie egy szemkövető felhasználó kalibrálásán. Ez lehetővé teszi az eszköz számára a rendszer beállítását a felhasználó számára kényelmesebb és jobb minőségű megtekintési élmény érdekében, valamint a pontos szemkövetés egyidejű biztosításához. A fejlesztőknek nem kell semmit tenniük a felhasználói kalibrálás kezeléséhez. A rendszer biztosítja, hogy a rendszer a következő körülmények között kérje meg a felhasználót az eszköz kalibrálására:

  • A felhasználó első alkalommal használja az eszközt
  • A felhasználó korábban letiltotta a kalibrálási folyamatot
  • A kalibrálási folyamat nem sikerült, amikor a felhasználó utoljára használta az eszközt

A fejlesztőknek gondoskodniuk kell arról, hogy megfelelő támogatást nyújtsanak azoknak a felhasználóknak, ahol a szemkövetési adatok nem érhetők el. További információ a tartalék megoldások megfontolandó szempontjairól a Szemkövetés a HoloLens 2 oldalon.


Lásd még