Realizar testes de hit no app Android

Faça um hit-test para determinar o posicionamento correto de um objeto 3D na sua cena. O posicionamento correto garante que o conteúdo de RA seja renderizado no tamanho adequado (aparente).

Tipos de resultados de hit

Um hit-test pode gerar quatro tipos diferentes de resultados de hit, conforme mostrado na tabela a seguir.

Tipo de resultado do hit Descrição Orientação Caso de uso Chamadas de método
Profundidade (DepthPoint) Usa informações de profundidade de toda a cena para determinar a profundidade e a orientação corretas de um ponto Perpendicular à superfície 3D colocar um objeto virtual em uma superfície arbitrária (não apenas no chão e nas paredes); ArDepthMode precisa estar ativado para que isso funcione.

Frame.hitTest(…), verifique se há DepthPoints na lista de retorno.
Plane Atinge superfícies horizontais e/ou verticais para determinar a profundidade e orientação corretas de um ponto Perpendicular à superfície 3D Coloque um objeto em um plano (solo ou parede) usando a geometria completa dele. É necessário corrigir a escala imediatamente. Substituição para o teste de hit de profundidade Frame.hitTest(…), verifique se há Planes na lista retornada.
Ponto de destaque (Point) Depende de recursos visuais ao redor do ponto de toque do usuário para determinar a posição e a orientação corretas de um ponto Perpendicular à superfície 3D colocar um objeto em uma superfície arbitrária (não apenas no chão e nas paredes); Frame.hitTest(…), verifique se há Points na lista retornada.
Canal instantâneo (InstantPlacementPoint) Usa o espaço na tela para posicionar conteúdo. Inicialmente usa a profundidade estimada fornecida pelo app. Funciona instantaneamente, mas a pose e a profundidade real mudam quando o ARCore consegue determinar a geometria real da cena +Y apontando para cima, oposto à gravidade Coloque um objeto em um plano (solo ou parede) usando a geometria completa dele. Nesse local, o posicionamento rápido é essencial, e a experiência pode tolerar a profundidade e a escala iniciais desconhecidas Frame.hitTestInstantPlacement(float, float, float)

Realizar um teste de hit padrão

Chame Frame.hitTest() para fazer um teste de hit usando o utilitário TapHelper para extrair MotionEvents da visualização em 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)
  }

Filtre os resultados de hits com base no tipo em que você tem interesse. Por exemplo, se você quiser se concentrar em DepthPoints:

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

Realizar um teste de hit usando um raio e uma direção arbitrários

Os testes de hit costumam ser tratados como raios da câmera do dispositivo ou da câmera, mas é possível usar Frame.hitTest(float[], int, float[], int) para conduzir um teste de hit usando um raio arbitrário em coordenadas de espaço mundial em vez de um ponto de espaço na tela.

Criar uma âncora usando o resultado de acerto

Depois de ter um resultado de acerto, você pode usar a pose como entrada para colocar conteúdo de RA na cena. Use HitResult.createAnchor() para criar um novo Anchor, garantindo que o conteúdo seja anexado ao Trackable subjacente do resultado do hit. Por exemplo, a âncora permanece presa ao plano detectado para um resultado de hit no avião, parecendo, assim, fazer parte do mundo real.

O que vem em seguida?