Gdy użytkownik zezwoli na śledzenie ruchów głowy, aplikacja może pobierać informacje o pozycji głowy za pomocą ARCore dla Jetpack XR. Informacje o pozycji głowy mogą pomóc aplikacji w tworzeniu bardziej intuicyjnych funkcji, np. okna śledzącego pole widzenia użytkownika.
Tworzenie sesji ARCore w Jetpack XR
Uzyskiwanie informacji o pozycji głowy w sesji ARCore w Jetpacku XR.
Aby uzyskać Session
, przeczytaj artykuł Omówienie cyklu życia sesji.
Konfigurowanie sesji
Monitorowanie ruchów głowy nie jest domyślnie włączone w przypadku sesji XR. Aby włączyć śledzenie ruchu głowy, skonfiguruj sesję i ustaw tryb HeadTrackingMode.LAST_KNOWN
:
val newConfig = session.config.copy( headTracking = Config.HeadTrackingMode.LAST_KNOWN, ) when (val result = session.configure(newConfig)) { is SessionConfigureSuccess -> TODO(/* Success! */) is SessionConfigureConfigurationNotSupported -> TODO(/* Some combinations of configurations are not valid. Handle this failure case. */) else -> TODO(/* The session could not be configured. See SessionConfigureResult for possible causes. */) }
Pobieranie danych o pozycji głowy
Dane dotyczące pozycji głowy są udostępniane za pomocą RenderViewpoint
.
RenderViewpoint
opisuje pozycję i pole widzenia w danym punkcie widzenia urządzenia. Urządzenie może mieć widok z lewej, prawej lub mono, w zależności od jego możliwości.
Aby uzyskać dane dla widoku mono:
val mono = RenderViewpoint.mono(session) ?: return mono.state.collect { state -> val fov = state.fieldOfView val viewpointPose = state.pose }
Zastosowania śledzenia ruchów głowy
Jednym ze sposobów wykorzystania śledzenia głowy w aplikacji jest utrzymywanie obiektów w polu widzenia użytkownika w aplikacjach, które wymagają od użytkowników rozglądania się lub poruszania się.
Unikaj używania elementów zablokowanych w polu widzenia użytkownika, ponieważ może to powodować chorobę lokomocyjną. Zamiast tego użyj ruchu obiektu, który po krótkim czasie będzie podążać za głową użytkownika:
val viewpointPose = RenderViewpoint.left(session)!!.state lifecycleScope.launch { while (true) { delay(2000) val start = panel.getPose() val startTime = session.state.value.timeMark val pose = session.scene.perceptionSpace.transformPoseTo( viewpointPose.value.pose, session.scene.activitySpace ) val target = Pose(pose.translation + pose.forward * 1f, pose.rotation) while (true) { val ratio = (session.state.value.timeMark - startTime).inWholeMilliseconds / 500f panel.setPose(Pose.lerp(start, target, ratio)) if (ratio > 1f) break } } }