Интегрируйте положение головы в свое приложение с помощью ARCore для Jetpack XR

После того, как пользователь даст разрешение на отслеживание положения головы , ваше приложение сможет получать информацию о положении головы через ARCore для Jetpack XR. Информация о положении головы поможет вашему приложению создавать более интуитивно понятный интерфейс, например, окно, отслеживающее поле зрения пользователя.

Создайте сеанс ARCore для Jetpack XR

Получите информацию о положении головы через сеанс ARCore для Jetpack XR. Чтобы получить информацию о Session , см. раздел «Понимание жизненного цикла сеанса» .

Настройте сеанс

Отслеживание положения головы по умолчанию в сеансах XR отключено. Чтобы включить отслеживание положения головы, настройте сеанс и установите режим 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. */)
}

Получить данные о положении головы

Данные о положении головы предоставляются через RenderViewpoint . RenderViewpoint описывает позу и поле зрения для заданной точки обзора устройства. Устройство может иметь левую, правую или моноточку обзора в зависимости от его возможностей.

Чтобы получить данные для моноточки зрения:

val mono = RenderViewpoint.mono(session) ?: return
mono.state.collect { state ->
    val fov = state.fieldOfView
    val viewpointPose = state.pose
}

Применение слежения за положением головы

Одним из способов использования отслеживания положения головы в вашем приложении является удержание объектов в поле зрения пользователя, например, в приложениях, требующих от пользователей осмотра или перемещения.

Избегайте использования сущностей, закреплённых в поле зрения пользователя, поскольку это может вызвать укачивание. Вместо этого используйте движение сущностей, которое следует за головой пользователя с небольшой задержкой:

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