在您的 Android NDK 应用中执行点击测试

执行命中测试,以确定 3D 对象在场景中的正确位置。正确的放置可确保 AR 内容以适当的(表观)尺寸呈现。

命中结果类型

一项命中测试可产生四种不同类型的命中结果,如下表所示。

命中结果类型 说明 方向 使用场景 方法调用
深度 (AR_TRACKABLE_DEPTH_POINT) 使用来自整个场景的深度信息来确定点的正确深度和方向 与 3D 表面垂直 将虚拟对象放置在任意表面(不只是地板和墙壁)上 必须启用ArDepthMode才能使用此功能。

ArFrame_hitTest,请检查返回列表中是否有 ArDepthPoint
平面 (AR_TRACKABLE_PLANE) 敲击水平和/或垂直表面,以确定点的正确深度和方向 与 3D 表面垂直 使用平面的完整几何图形将对象放置在平面(地板或墙壁)上。需要立即更正体重。深度点击测试的回退 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 在命中位置处创建一个新的锚点

后续步骤