Incorporar a posição da cabeça no app com o ARCore para Jetpack XR

Depois que o usuário concede permissão para o rastreamento da cabeça, o app pode recuperar informações de postura da cabeça usando o ARCore para Jetpack XR. As informações de pose da cabeça podem ajudar seu app a criar experiências mais intuitivas, como uma janela que segue o campo de visão do usuário.

Criar uma sessão do ARCore para Jetpack XR

Receba informações de postura da cabeça em uma sessão do ARCore para Jetpack XR. Consulte Entender o ciclo de vida de uma sessão para receber um Session.

Configurar a sessão

O rastreamento da cabeça não está ativado por padrão nas sessões de RV/RA. Para ativar o rastreamento da cabeça, configure a sessão e defina o modo 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. */)
}

Recuperar dados de postura da cabeça

Os dados de postura da cabeça são expostos por um RenderViewpoint. Um RenderViewpoint descreve a postura e o campo de visão de um determinado ponto de vista de um dispositivo. Um dispositivo pode ter pontos de vista esquerdo, direito ou mono, dependendo dos recursos dele.

Para extrair dados do ponto de vista mono:

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

Aplicações do rastreamento da cabeça

Uma maneira de usar o rastreamento da cabeça é manter as entidades no campo de visão do usuário, para apps que exigem que os usuários olhem ou se movam.

Evite usar entidades fixadas na cabeça no campo de visão do usuário, porque isso pode causar enjoo. Em vez disso, use o movimento da entidade que segue a cabeça do usuário após um pequeno período:

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