Gdy użytkownik przyzna uprawnienia do śledzenia ruchów głowy, aplikacja będzie mogła 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
Uzyskaj informacje o pozycji głowy za pomocą środowiska wykonawczego Jetpack XR Session, które może utworzyć Twoja aplikacja.
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 dla danego punktu 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 z perspektywy 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
Śledzenie ruchu głowy może być wykorzystywane w aplikacji na przykład do utrzymywania elementó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 przytwierdzonych do głowy 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 ruchem głowy 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 } } }