Effectuer des tests de positionnement dans votre application Android

Effectuez un test de positionnement pour déterminer l'emplacement correct d'un objet 3D dans votre scène. Un placement correct permet de s'assurer que le contenu de la RA est affiché à la taille (apparente) appropriée.

Types de résultats d'appel

Un test de positionnement peut générer quatre types de résultats d'appel différents, comme l'illustre le tableau suivant.

Type de résultat du hit Description Intégration Cas d'utilisation Appels de méthode
Profondeur (DepthPoint) Utilise les informations de profondeur de toute la scène pour déterminer la profondeur et l'orientation d'un point Perpendiculaire à la surface 3D Placer un objet virtuel sur une surface arbitraire (pas seulement sur les sols et les murs) ArDepthMode doit être activé pour que cela fonctionne.

Frame.hitTest(…), recherchez DepthPoint dans la liste des retours
Plane Appuie sur les surfaces horizontales et/ou verticales pour déterminer la profondeur et l'orientation d'un point Perpendiculaire à la surface 3D Placez un objet sur une surface plane (plancher ou mur) en utilisant toute la géométrie de l'avion. J'ai immédiatement besoin de la bonne échelle. Remplacement pour le test de positionnement de profondeur Frame.hitTest(…), recherchez des Plane dans la liste de retour
Point de caractéristiques (Point) S'appuie sur les caractéristiques visuelles autour du point où l'utilisateur appuie pour déterminer la position et l'orientation correctes d'un point Perpendiculaire à la surface 3D Placer un objet sur une surface arbitraire (pas seulement sur les sols et les murs) Frame.hitTest(…), recherchez des Point dans la liste de retour
Emplacement instantané (InstantPlacementPoint) Utilise l'espace à l'écran pour placer le contenu. Utilise initialement la profondeur estimée fournie par l'application. Le fonctionnement est instantané, mais la position et la profondeur réelle changent une fois qu'ARCore est en mesure de déterminer la géométrie réelle de la scène. +Y pointant vers le haut, à l'opposé de la gravité Placez un objet sur une surface plane (plancher ou paroi) en utilisant sa géométrie complète. Pour que l'expérience puisse tolérer une profondeur et une échelle initiales inconnues, le positionnement doit être rapide. Frame.hitTestInstantPlacement(float, float, float)

Réaliser un test de positionnement standard

Appelez Frame.hitTest() pour effectuer un test de positionnement à l'aide de l'utilitaire TapHelper pour obtenir des MotionEvent à partir de la vue de RA.

Java

MotionEvent tap = tapHelper.poll();
if (tap == null) {
  return;
}

if (usingInstantPlacement) {
  // When using Instant Placement, the value in APPROXIMATE_DISTANCE_METERS will determine
  // how far away the anchor will be placed, relative to the camera's view.
  List<HitResult> hitResultList =
      frame.hitTestInstantPlacement(tap.getX(), tap.getY(), APPROXIMATE_DISTANCE_METERS);
  // Hit-test results using Instant Placement will only have one result of type
  // InstantPlacementResult.
} else {
  List<HitResult> hitResultList = frame.hitTest(tap);
  // TODO: Filter hitResultList to find a hit result of interest.
}

Kotlin

val tap = tapHelper.poll() ?: return
val hitResultList =
  if (usingInstantPlacement) {
    // When using Instant Placement, the value in APPROXIMATE_DISTANCE_METERS will determine
    // how far away the anchor will be placed, relative to the camera's view.
    frame.hitTestInstantPlacement(tap.x, tap.y, APPROXIMATE_DISTANCE_METERS)
    // Hit-test results using Instant Placement will only have one result of type
    // InstantPlacementResult.
  } else {
    frame.hitTest(tap)
  }

Vous pouvez filtrer les résultats d'appel en fonction du type qui vous intéresse. Par exemple, si vous souhaitez vous concentrer sur les DepthPoint:

Java

// Returned hit-test results are sorted by increasing distance from the camera or virtual ray's
// origin.
// The first hit result is often the most relevant when responding to user input.
for (HitResult hit : hitResultList) {
  Trackable trackable = hit.getTrackable();
  if (trackable instanceof DepthPoint) { // Replace with any type of trackable type
    // Do something with this hit result. For example, create an anchor at this point of
    // interest.
    Anchor anchor = hit.createAnchor();
    // TODO: Use this anchor in your AR experience.
    break;
  }
}

Kotlin

// Returned hit-test results are sorted by increasing distance from the camera or virtual ray's
// origin.
// The first hit result is often the most relevant when responding to user input.
val firstHitResult =
  hitResultList.firstOrNull { hit ->
    when (val trackable = hit.trackable!!) {
      is DepthPoint -> true // Replace with any type of trackable type
      else -> false
    }
  }
if (firstHitResult != null) {
  // Do something with this hit result. For example, create an anchor at this point of interest.
  val anchor = firstHitResult.createAnchor()
  // TODO: Use this anchor in your AR experience.
}

Réaliser un test de positionnement à l'aide d'un rayon et d'une direction arbitraires

Les tests de positionnement sont généralement traités comme des rayons provenant de l'appareil photo ou de l'appareil photo, mais vous pouvez utiliser Frame.hitTest(float[], int, float[], int) pour effectuer un test de positionnement en utilisant un rayon arbitraire dans les coordonnées spatiales mondiales au lieu d'un point dans l'espace d'écran.

Créer une ancre à l'aide du résultat du hit

Une fois que vous avez obtenu un résultat, vous pouvez utiliser sa posture comme entrée pour placer le contenu RA dans votre scène. Utilisez HitResult.createAnchor() pour créer un Anchor, en vous assurant que le contenu est associé à la Trackable sous-jacente du résultat de l'appel. Par exemple, l'ancre reste attachée au plan détecté pour un résultat de frappe de plan, semblant ainsi faire partie du monde réel.

Et ensuite ?