Bagikan melalui


Tatapan kepala dan input tatapan mata di DirectX

Catatan

Artikel ini berkaitan dengan API asli WinRT warisan. Untuk proyek aplikasi asli baru, sebaiknya gunakan OpenXR API.

Dalam Windows Mixed Reality, input tatapan mata dan kepala digunakan untuk menentukan apa yang dilihat pengguna. Anda dapat menggunakan data untuk mendorong model input utama seperti tatapan kepala dan penerapan, dan memberikan konteks untuk jenis interaksi yang berbeda. Ada dua jenis vektor tatapan yang tersedia melalui API: tatapan kepala dan tatapan mata. Keduanya disediakan sebagai sinar tiga dimensi dengan asal dan arah. Aplikasi kemudian dapat melakukan raycast ke dalam adegan mereka, atau dunia nyata, dan menentukan apa yang ditargetkan pengguna.

Tatapan kepala mewakili arah yang ditunjukkan oleh kepala pengguna. Anggap tatapan kepala sebagai posisi dan arah ke depan perangkat itu sendiri, dengan posisi sebagai titik tengah di antara kedua layar. Tatapan kepala tersedia di semua perangkat Mixed Reality.

Tatapan mata mewakili arah yang dipandang mata pengguna. Asal terletak di antara mata pengguna. Ini tersedia di perangkat Mixed Reality yang mencakup sistem pelacakan mata.

Sinar tatapan kepala dan mata dapat diakses melalui API SpatialPointerPose . Panggil SpatialPointerPose::TryGetAtTimestamp untuk menerima objek SpatialPointerPose baru pada tanda waktu dan sistem koordinat yang ditentukan. SpatialPointerPose ini berisi asal dan arah tatapan kepala. Ini juga berisi asal tatapan mata dan arah jika pelacakan mata tersedia.

Dukungan perangkat

Fitur HoloLens (generasi ke-1) HoloLens 2 Headset imersif
Tatapan kepala ✔️ ✔️ ✔️
Tatapan mata ✔️

Menggunakan tatapan kepala

Untuk mengakses tatapan kepala, mulailah dengan memanggil SpatialPointerPose::TryGetAtTimestamp untuk menerima objek SpatialPointerPose baru. Berikan parameter berikut.

  • SpatialCoordinateSystem yang mewakili sistem koordinat yang Anda inginkan untuk tatapan kepala. Ini diwakili oleh variabel coordinateSystem dalam kode berikut. Untuk informasi selengkapnya, kunjungi panduan pengembang sistem koordinat kami.
  • Tanda Waktu yang mewakili waktu yang tepat dari pose kepala yang diminta. Biasanya, Anda akan menggunakan tanda waktu yang sesuai dengan waktu ketika bingkai saat ini akan ditampilkan. Anda bisa mendapatkan tanda waktu tampilan yang diprediksi ini dari objek HolographicFramePrediction , yang dapat diakses melalui HolographicFrame saat ini. Objek HolographicFramePrediction ini diwakili oleh variabel prediksi dalam kode berikut.

Setelah Anda memiliki SpatialPointerPose yang valid, posisi kepala dan arah maju dapat diakses sebagai properti. Kode berikut menunjukkan cara mengaksesnya.

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
}

Menggunakan tatapan mata

Agar pengguna Anda menggunakan input tatapan mata, setiap pengguna harus melalui kalibrasi pengguna pelacakan mata saat pertama kali menggunakan perangkat. API tatapan mata mirip dengan tatapan kepala. Ini menggunakan API SpatialPointerPose yang sama, yang menyediakan asal sinar dan arah yang dapat Anda raycast terhadap adegan Anda. Satu-satunya perbedaan adalah Anda perlu secara eksplisit mengaktifkan pelacakan mata sebelum menggunakannya:

  1. Minta izin pengguna untuk menggunakan pelacakan mata di aplikasi Anda.
  2. Aktifkan kemampuan "Gaze Input" dalam manifes paket Anda.

Meminta akses ke input tatapan mata

Saat aplikasi Anda dimulai, panggil EyesPose::RequestAccessAsync untuk meminta akses ke pelacakan mata. Sistem akan meminta pengguna jika diperlukan, dan mengembalikan GazeInputAccessStatus::Allowed setelah akses diberikan. Ini adalah panggilan asinkron, sehingga membutuhkan sedikit manajemen ekstra. Contoh berikut memutar std::thread yang dilepas untuk menunggu hasilnya, yang disimpannya ke variabel anggota yang disebut 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();

Memulai utas yang dilepas hanyalah salah satu opsi untuk menangani panggilan asinkron. Anda juga dapat menggunakan fungsionalitas co_await baru yang didukung oleh C++/WinRT. Berikut adalah contoh lain untuk meminta izin pengguna:

  • EyesPose::IsSupported() memungkinkan aplikasi untuk memicu dialog izin hanya jika ada pelacak mata.
  • GazeInputAccessStatus m_gazeInputAccessStatus; Ini untuk mencegah munculnya permintaan izin berulang-ulang.
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;	
		}
	});
}

Mendeklarasikan kemampuan Input Tatapan

Klik dua kali file appxmanifest di Penjelajah Solusi. Kemudian navigasikan ke bagian Kemampuan dan periksa kemampuan Input Tatapan .

Kapabilitas input tatapan

Ini menambahkan baris berikut ke bagian Paket di file appxmanifest:

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

Mendapatkan sinar tatapan mata

Setelah Anda menerima akses ke ET, Anda bebas untuk mengambil sinar tatapan mata setiap bingkai. Seperti tatapan kepala, dapatkan SpatialPointerPose dengan memanggil SpatialPointerPose::TryGetAtTimestamp dengan tanda waktu dan sistem koordinat yang diinginkan. SpatialPointerPose berisi objek EyesPose melalui properti Eyes . Ini non-null hanya jika pelacakan mata diaktifkan. Dari sana, Anda dapat memeriksa apakah pengguna di perangkat memiliki kalibrasi pelacakan mata dengan memanggil EyesPose::IsCalibrationValid. Selanjutnya, gunakan properti Tatapan untuk mendapatkan SpatialRay yang berisi posisi dan arah tatapan mata. Properti Tatapan terkadang null, jadi pastikan untuk memeriksa hal ini. Hal ini dapat terjadi adalah jika pengguna yang dikalibrasi untuk sementara menutup mata mereka.

Kode berikut menunjukkan cara mengakses sinar tatapan mata.

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

Fallback saat pelacakan mata tidak tersedia

Seperti disebutkan dalam dokumen desain pelacakan mata kami, perancang dan pengembang harus mengetahui instans di mana data pelacakan mata mungkin tidak tersedia.

Ada berbagai alasan data tidak tersedia:

  • Pengguna tidak dikalibrasi
  • Pengguna telah menolak akses aplikasi ke data pelacakan matanya
  • Gangguan sementara, seperti gundukan pada visor HoloLens atau rambut yang menempati mata pengguna.

Meskipun beberapa API telah disebutkan dalam dokumen ini, dalam hal berikut, kami memberikan ringkasan tentang cara mendeteksi bahwa pelacakan mata tersedia sebagai referensi cepat:

Anda mungkin juga ingin memeriksa bahwa data pelacakan mata Anda tidak basi dengan menambahkan batas waktu antara pembaruan data pelacakan mata yang diterima dan sebaliknya fallback ke tatapan kepala seperti yang dibahas di bawah ini. Kunjungi pertimbangan desain fallback kami untuk informasi lebih lanjut.


Tatapan berkorelasi dengan input lain

Terkadang Anda mungkin menemukan bahwa Anda memerlukan SpatialPointerPose yang sesuai dengan peristiwa di masa lalu. Misalnya, jika pengguna melakukan Air Tap, aplikasi Anda mungkin ingin mengetahui apa yang mereka lihat. Untuk tujuan ini, cukup gunakan SpatialPointerPose::TryGetAtTimestamp dengan jangka waktu yang diprediksi tidak akan akurat karena latensi antara pemrosesan input sistem dan waktu tampilan. Juga, jika menggunakan tatapan mata untuk penargetan, mata kita cenderung bergerak bahkan sebelum menyelesaikan tindakan penerapan. Ini kurang dari masalah untuk Air Tap sederhana, tetapi menjadi lebih penting saat menggabungkan perintah suara panjang dengan gerakan mata cepat. Salah satu cara untuk menangani skenario ini adalah dengan melakukan panggilan tambahan ke SpatialPointerPose::TryGetAtTimestamp, menggunakan tanda waktu historis yang sesuai dengan peristiwa input.

Namun, untuk input yang merutekan melalui SpatialInteractionManager, ada metode yang lebih mudah. SpatialInteractionSourceState memiliki fungsi TryGetAtTimestamp sendiri. Panggilan yang akan memberikan SpatialPointerPose yang berkorelasi sempurna tanpa tebakan. Untuk informasi selengkapnya tentang bekerja dengan SpatialInteractionSourceStates, lihat dokumentasi Pengontrol Tangan dan Gerakan dalam DirectX .


Kalibrasi

Agar pelacakan mata berfungsi secara akurat, setiap pengguna diharuskan melalui kalibrasi pengguna pelacakan mata. Ini memungkinkan perangkat untuk menyesuaikan sistem untuk pengalaman melihat kualitas yang lebih nyaman dan lebih tinggi bagi pengguna dan untuk memastikan pelacakan mata yang akurat pada saat yang sama. Pengembang tidak perlu melakukan apa pun di ujung mereka untuk mengelola kalibrasi pengguna. Sistem akan memastikan bahwa pengguna diminta untuk mengkalibrasi perangkat dalam keadaan berikut:

  • Pengguna menggunakan perangkat untuk pertama kalinya
  • Pengguna sebelumnya memilih keluar dari proses kalibrasi
  • Proses kalibrasi tidak berhasil terakhir kali pengguna menggunakan perangkat

Pengembang harus memastikan untuk memberikan dukungan yang memadai bagi pengguna di mana data pelacakan mata mungkin tidak tersedia. Pelajari selengkapnya tentang pertimbangan untuk solusi fallback di Pelacakan Mata di HoloLens 2.


Lihat juga