Wykorzystywanie pozycji głowy w aplikacji za pomocą ARCore dla Jetpack XR

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