Intégrer la position de la tête dans votre application avec ARCore pour Jetpack XR

Une fois que l'utilisateur a accordé l'autorisation pour le suivi de la tête, votre application peut récupérer les informations sur la pose de la tête via ARCore pour Jetpack XR. Les informations sur la pose de la tête peuvent aider votre application à créer des expériences plus intuitives, comme une fenêtre qui suit le champ de vision de l'utilisateur.

Créer une session ARCore pour Jetpack XR

Obtenez des informations sur la pose de la tête via une session ARCore pour Jetpack XR. Consultez Comprendre le cycle de vie d'une session pour obtenir un Session.

Configurer la session

Le suivi de la tête n'est pas activé par défaut dans les sessions XR. Pour activer le suivi de la tête, configurez la session et définissez le mode 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. */)
}

Récupérer les données de pose de la tête

Les données de pose de la tête sont exposées via un RenderViewpoint. Un RenderViewpoint décrit la pose et le champ de vision pour un point de vue donné d'un appareil. Un appareil peut avoir des points de vue gauche, droit ou mono, selon ses capacités.

Pour obtenir des données pour le point de vue mono :

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

Applications du suivi de la tête

Le suivi de la tête peut être utilisé par votre application pour maintenir les entités dans le champ de vision de l'utilisateur, pour les applications qui nécessitent que vos utilisateurs regardent ou se déplacent.

Évitez d'utiliser des entités verrouillées dans le champ de vision de l'utilisateur, car cela peut provoquer le mal des transports. Utilisez plutôt un mouvement d'entité qui suit la tête de l'utilisateur après une courte durée :

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