Utiliser ARCore pour Jetpack XR

ARCore pour Jetpack XR peut fournir des informations sur les mains détectées de l'utilisateur, et fournit des informations sur la position des mains et des articulations associées. Ces données sur les mains peuvent être utilisées pour associer des entités et des modèles aux mains d'un utilisateur, par exemple un menu d'outils:

Obtenir une session

Accédez aux informations sur les mains via un Session Android XR. Consultez la section Comprendre le cycle de vie d'une session pour obtenir un Session.

Configurer la session

Le suivi des mains n'est pas activé par défaut dans les sessions XR. Pour recevoir des données de main, configurez la session:

val newConfig = session.config.copy(
    handTracking = Config.HandTrackingMode.Enabled
)
when (val result = session.configure(newConfig)) {
    is SessionConfigureConfigurationNotSupported ->
        TODO(/* Some combinations of configurations are not valid. Handle this failure case. */)
    is SessionConfigurePermissionsNotGranted ->
        TODO(/* The required permissions in result.permissions have not been granted. */)
    is SessionConfigureSuccess -> TODO(/* Success! */)
}

Récupérer les données des mains

Les données sur les mains sont disponibles séparément pour la main gauche et la main droite. Utilisez le state de chaque main pour accéder aux positions de pose pour chaque articulation:

Hand.left(session)?.state?.collect { handState -> // or Hand.right(session)
    // Hand state has been updated.
    // Use the state of hand joints to update an entity's position.
    renderPlanetAtHandPalm(handState)
}

Les mains ont les propriétés suivantes:

  • isActive: indique si la main est suivie ou non.
  • handJoints: mappe des articulations des mains aux poses. Les poses des articulations des mains sont spécifiées par les normes OpenXR.

Utiliser les données de la main dans votre application

Les positions des articulations des mains d'un utilisateur peuvent être utilisées pour ancrer des objets 3D à ses mains, par exemple pour attacher un modèle à la paume gauche:

val palmPose = leftHandState.handJoints[HandJointType.PALM] ?: return

// the down direction points in the same direction as the palm
val angle = Vector3.angleBetween(palmPose.rotation * Vector3.Down, Vector3.Up)
palmEntity.setHidden(angle > Math.toRadians(40.0))

val transformedPose =
    scenecoreSession.perceptionSpace.transformPoseTo(
        palmPose,
        scenecoreSession.activitySpace,
    )
val newPosition = transformedPose.translation + transformedPose.down * 0.05f
palmEntity.setPose(Pose(newPosition, transformedPose.rotation))

Pour associer un modèle à l'extrémité de l'index de votre main droite:

val tipPose = rightHandState.handJoints[HandJointType.INDEX_TIP] ?: return

// the forward direction points towards the finger tip.
val angle = Vector3.angleBetween(tipPose.rotation * Vector3.Forward, Vector3.Up)
indexFingerEntity.setHidden(angle > Math.toRadians(40.0))

val transformedPose =
    scenecoreSession.perceptionSpace.transformPoseTo(
        tipPose,
        scenecoreSession.activitySpace,
    )
val position = transformedPose.translation + transformedPose.forward * 0.03f
val rotation = Quaternion.fromLookTowards(transformedPose.up, Vector3.Up)
indexFingerEntity.setPose(Pose(position, rotation))