Android NDK アプリでヒットテストを実行する

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

ヒット結果タイプ

ヒットテストでは、次の表に示すように、4 つの異なるタイプのヒット結果が生成されます。

ヒット結果タイプ 説明 向き ユースケース メソッド呼び出し
奥行き(AR_TRACKABLE_DEPTH_POINT シーン全体の奥行き情報を使用して、ポイントの正しい奥行きと向きを割り出します 3D 表面に垂直 仮想オブジェクトを(床や壁だけでなく)任意の面に置く これを行うには、ArDepthMode を有効にする必要があります。

ArFrame_hitTest、戻り値リストで ArDepthPoint を確認
プレーン(AR_TRACKABLE_PLANE 水平面や垂直面に接触することで、ポイントの正しい奥行きと向きが判断される 3D 表面に垂直 飛行機の完全なジオメトリを使用して、平面(床または壁)にオブジェクトを配置します。すぐに適切なスケールが必要。Depth ヒットテストのフォールバック ArFrame_hitTest、戻り値リストで ArPlane を確認
特徴(AR_TRACKABLE_POINT ユーザーがタップした位置周辺の視覚的な特徴に基づいて、ポイントの正しい位置と向きを判断します。 3D 表面に垂直 (床や壁だけでなく)任意の面にオブジェクトを配置する ArFrame_hitTest、戻り値リストで ArPoint を確認
インスタント プレースメント(AR_TRACKABLE_INSTANT_PLACEMENT_POINT 画面スペースを使用してコンテンツを配置します。最初は、アプリが提供する推定深度を使用します。すぐに使用できますが、ARCore が実際のシーンのジオメトリを決定できるようになると、ポーズと実際の奥行きが変わります 重力の反対の方向、上向き +Y 機内全体を使用して平面(床または壁)にオブジェクトを配置します。その際、すばやい配置が重要となります。また、初期の深さや縮尺が不明でも許容できる ArFrame_hitTestInstantPlacement

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

ArFrame_hitTest を呼び出してヒットテストを行います。

ArHitResultList* hit_result_list = NULL;
ArHitResultList_create(ar_session, &hit_result_list);
CHECK(hit_result_list);
if (is_instant_placement_enabled) {
  ArFrame_hitTestInstantPlacement(ar_session, ar_frame, x, y,
                                  k_approximate_distance_meters,
                                  hit_result_list);
} else {
  ArFrame_hitTest(ar_session, ar_frame, x, y, hit_result_list);
}

目的とするタイプに基づいてヒット結果をフィルタします。たとえば、ArPlane にフォーカスする場合は、次のようにします。

int32_t hit_result_list_size = 0;
ArHitResultList_getSize(ar_session, hit_result_list, &hit_result_list_size);

// 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.
ArHitResult* ar_hit_result = NULL;
for (int32_t i = 0; i < hit_result_list_size; ++i) {
  ArHitResult* ar_hit = NULL;
  ArHitResult_create(ar_session, &ar_hit);
  ArHitResultList_getItem(ar_session, hit_result_list, i, ar_hit);

  if (ar_hit == NULL) {
    LOGE("No item was hit.");
    return;
  }

  ArTrackable* ar_trackable = NULL;
  ArHitResult_acquireTrackable(ar_session, ar_hit, &ar_trackable);
  ArTrackableType ar_trackable_type = AR_TRACKABLE_NOT_VALID;
  ArTrackable_getType(ar_session, ar_trackable, &ar_trackable_type);
  // Creates an anchor if a plane was hit.
  if (ar_trackable_type == AR_TRACKABLE_PLANE) {
    // Do something with this hit result. For example, create an anchor at
    // this point of interest.
    ArAnchor* anchor = NULL;
    ArHitResult_acquireNewAnchor(ar_session, ar_hit, &anchor);

    // TODO: Use this anchor in your AR experience.

    ArAnchor_release(anchor);
    ArHitResult_destroy(ar_hit);
    ArTrackable_release(ar_trackable);
    break;
  }
  ArHitResult_destroy(ar_hit);
  ArTrackable_release(ar_trackable);
}
ArHitResultList_destroy(hit_result_list);

任意の光線と方向を使用してヒットテストを行う

ヒットテストは通常、デバイスまたはデバイスカメラからの光線として扱われますが、ArFrame_hitTestRay を使用すると、画面空間の点ではなく、ワールド空間座標の任意の光線を使用してヒットテストを実行できます。

HitResult にアンカーをアタッチする

ヒット結果が得られたら、そのポーズを入力として使用し、シーンに AR コンテンツを配置できます。ArHitResult_acquireNewAnchor を使用して、ヒットした場所に新しい Anchor を作成します。

次のステップ

  • GitHub の hello_ar_c サンプルアプリをご確認ください。