Android アプリでヒットテストを行う

ヒットテストを行って、シーン内の 3D オブジェクトの正しい配置を確認します。正しく配置することで、AR コンテンツが適切な(見かけの)サイズでレンダリングされます。

ヒット結果のタイプ

ヒットテストでは、次の表に示すように 4 種類のヒット結果が生成されます。

ヒット結果タイプ 説明 オリエンテーション 使用例 メソッド呼び出し
奥行き(DepthPoint シーン全体の奥行き情報を使用して、ポイントの正しい奥行きと向きを決定します。 3D サーフェスに垂直 (床や壁だけでなく)任意の面に仮想オブジェクトを配置する そのためには、ArDepthMode を有効にする必要があります。

Frame.hitTest(…)、戻りリストで DepthPoint を確認します
Plane 水平または垂直のサーフェスにヒットして、ポイントの正しい奥行きと向きを決定します。 3D サーフェスに垂直 飛行機の完全なジオメトリを使用して、平面(床や壁)にオブジェクトを配置します。すぐに正しい体重計が必要です。Depth ヒットテストの代替 Frame.hitTest(…)、戻りリストで Plane を確認します。
機能ポイント(Point ユーザーがタップした地点の周囲の視覚的特徴に基づいて、ポイントの正しい位置と向きを決定します。 3D サーフェスに垂直 床や壁だけでなく、任意の面にオブジェクトを配置します。 Frame.hitTest(…)、戻りリストで Point を確認します。
インスタント プレースメント(InstantPlacementPoint 画面スペースを使用してコンテンツを配置します。最初は、アプリによって推定される深度が使用されます。すぐに機能しますが、ARCore が実際のシーンのジオメトリを決定できるようになると、ポーズと実際の深度は変化します +Y が上向き、重力とは反対 対象物を平面全体(床面や壁面)に設置する場合は、素早く設置することが重要で、初期の深さや規模が不明でも許容されます。 Frame.hitTestInstantPlacement(float, float, float)

標準のヒットテストを行う

Frame.hitTest() を呼び出してヒットテストを行い、TapHelper ユーティリティを使用して AR ビューから MotionEvent を取得します。

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

ヒットの結果を目的のタイプで絞り込みます。たとえば、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.
}

任意の光線と方向を使用してヒットテストを実施する

ヒットテストは通常、デバイスまたはデバイスのカメラからの光線として処理されますが、Frame.hitTest(float[], int, float[], int) を使用すると、画面空間点ではなくワールド空間座標の任意の光線を使用してヒットテストを実施できます。

ヒット結果を使用してアンカーを作成する

ヒット結果を取得したら、そのポーズを入力として使用し、シーンに AR コンテンツを配置できます。HitResult.createAnchor() を使って新しい Anchor を作成し、ヒット結果の基になる Trackable にコンテンツが関連付けられるようにします。たとえば、平面のヒットの結果では、アンカーは検出された平面に取り付けられたままとなるため、現実世界の一部であるかのように見えます。

次のステップ