Android NDK용 인스턴트 게재위치 개발자 가이드

Instant Placement API를 사용하는 방법 알아보기 활용할 수 있습니다.

기본 요건

기본 AR 개념을 이해합니다. ARCore 세션을 구성하는 방법을 알아보세요.

순간 게재위치에서 새 세션 구성

새 ARCore 세션에서 인스턴트 배치 모드를 사용 설정합니다.

// Create a session config.
ArConfig* ar_config = NULL;
ArConfig_create(ar_session, &ar_config);

// Enable Instant Placement mode.
ArConfig_setInstantPlacementMode(ar_session, ar_config,
                                 AR_INSTANT_PLACEMENT_MODE_LOCAL_Y_UP);
CHECK(ArSession_configure(ar_session, ar_config) == AR_SUCCESS);

// Release config resources.
ArConfig_destroy(ar_config);

객체 배치

새 ARCore 세션에서 다음을 사용하여 인스턴트 게재위치 조회 테스트를 실행합니다. ArFrame_hitTestInstantPlacement 그런 다음ArAnchor ArInstantPlacementPoint 자세 조회 결과의 ARTrackable에서 가져옴

ArFrame* ar_frame = NULL;
if (ArSession_update(ar_session, ar_frame) != AR_SUCCESS) {
  // Get the latest frame.
  LOGE("ArSession_update error");
  return;
}

// Place an object on tap.
// Use the estimated distance from the user's device to the closest
// available surface, based on expected user interaction and behavior.
float approximate_distance_meters = 2.0f;

ArHitResultList* hit_result_list = NULL;
ArHitResultList_create(ar_session, &hit_result_list);
CHECK(hit_result_list);

// Returns a single result if the hit test was successful.
ArFrame_hitTestInstantPlacement(ar_session, ar_frame, x, y,
                                approximate_distance_meters, hit_result_list);

int32_t hit_result_list_size = 0;
ArHitResultList_getSize(ar_session, hit_result_list, &hit_result_list_size);
if (hit_result_list_size > 0) {
  ArHitResult* ar_hit_result = NULL;
  ArHitResult_create(ar_session, &ar_hit_result);
  CHECK(ar_hit_result);
  ArHitResultList_getItem(ar_session, hit_result_list, 0, ar_hit_result);
  if (ar_hit_result == NULL) {
    LOGE("ArHitResultList_getItem error");
    return;
  }

  ArTrackable* ar_trackable = NULL;
  ArHitResult_acquireTrackable(ar_session, ar_hit_result, &ar_trackable);
  if (ar_trackable == NULL) {
    LOGE("ArHitResultList_acquireTrackable error");
    return;
  }
  ArTrackableType ar_trackable_type = AR_TRACKABLE_NOT_VALID;
  ArTrackable_getType(ar_session, ar_trackable, &ar_trackable_type);

  if (ar_trackable_type == AR_TRACKABLE_INSTANT_PLACEMENT_POINT) {
    ArInstantPlacementPoint* point = (ArInstantPlacementPoint*)ar_trackable;

    // Gets the pose of the Instant Placement point.
    ArPose* ar_pose = NULL;
    ArPose_create(ar_session, NULL, &ar_pose);
    CHECK(ar_pose);
    ArInstantPlacementPoint_getPose(ar_session, point, ar_pose);

    // Attaches an anchor to the Instant Placement point.
    ArAnchor* anchor = NULL;
    ArStatus status = ArTrackable_acquireNewAnchor(ar_session, ar_trackable,
                                                   ar_pose, &anchor);
    ArPose_destroy(ar_pose);
    // Render content at the anchor.
    // ...
  }

  ArTrackable_release(ar_trackable);
}

인스턴트 게재위치 지원 대략적인 거리로 화면 공간 추적 인스턴트 게재위치 포인트가 전환되면 전체 추적으로 자동 전환됩니다. 실생활에 얽매여 있습니다. 다음을 사용하여 현재 포즈를 가져옵니다. ArInstantPlacementPoint_getPose() 다음과 같이 현재 추적 방법을 가져옵니다. ArInstantPlacementPoint_getTrackingMethod()

ARCore는 모든 표면에서 인스턴트 게재위치 히트 테스트를 실행할 수 있지만 방향에 따라 히트 결과가 항상 +Y를 위로 향한 포즈를 반환하고 일어날 수 있습니다. 수평면에서는 Hit Test가 정확한 결과를 반환함 훨씬 더 빠르게 포착을 할 수 있습니다.

순간 게재위치 포인트 추적 방법 모니터링

ARCore에 의해 반환된 ArInstantPlacementPoint의 정확한 3D 포즈가 있는 경우 ArFrame_hitTestInstantPlacement, 추적 메서드로 시작함 AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING 그렇지 않으면 추적 메서드 AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE로 시작합니다. AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING(으)로 전환 ARCore가 정확한 3D 포즈를 취합니다. 추적 방법이 AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING, 되돌릴 수 없습니다. ~ AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE입니다.

추적 메서드 전환 매끄럽게

추적 방법이 AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE 한 프레임에서 AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING로 이동합니다. 다음 프레임에서는 프레임에 따라 포즈가 초기 위치에서 정확한 거리에서 새 위치까지의 대략적인 거리를 제공합니다. 이 포즈의 순간적인 변화는 이미지를 그리는 물체의 겉보기 크기를 ArInstant PlacementPoint에 고정됩니다. 즉, 객체가 갑자기 이전 프레임보다 크거나 작게 표시될 때가 있습니다.

갑작스러운 변화로 인한 시각적 점프를 피하려면 다음 단계를 따르세요. 객체 스케일:

  1. ArInstantPlacementPoint의 포즈와 추적 메서드를 추적합니다. 확인할 수 있습니다
  2. 추적 방법이 AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
  3. 이전 프레임의 포즈와 현재 프레임의 포즈를 사용하여 두 프레임에서 객체와 기기 간의 거리를 결정합니다.
  4. 기울기와 먼지 사이의 거리 변화로 인한 스케일의 뚜렷한 변화를 있습니다.
  5. 대상의 크기를 조정하여 체감되는 스케일 변화에 대응합니다. 개체 크기가 시각적으로 변하지 않도록 할 수 있습니다.
  6. 원하는 경우 개체의 배율을 원래 값으로 부드럽게 조정합니다. 여러 프레임에 걸쳐 측정됩니다.
class WrappedInstantPlacement {
  ArInstantPlacementPoint* point;
  ArInstantPlacementPointTrackingMethod previous_tracking_method;
  float previous_distance_to_camera;
  float scale_factor = 1.0f;

 public:
  WrappedInstantPlacement(ArInstantPlacementPoint* point,
                          TrackingMethod previous_tracking_method,
                          float previous_distance_to_camera) {
    this.point = point;
    this.previous_tracking_method = previous_tracking_method;
    this.previous_distance_to_camera = previous_distance_to_camera;
  }
};

std::vector<WrappedInstantPlacement> wrapped_points_;

인스턴트 게재위치 포인트를 만든 후 OnTouched()를 수정하여 래핑합니다.

if (ar_trackable_type == AR_TRACKABLE_INSTANT_PLACEMENT_POINT) {
  ArInstantPlacementPoint* point = (ArInstantPlacementPoint*)ar_trackable;
  ArInstantPlacementPointTrackingMethod tracking_method;
  ArInstantPlacementPoint_getTrackingMethod(ar_session, point,
                                            &tracking_method);
  ArCamera* ar_camera = nullptr;
  ArFrame_acquireCamera(ar_session, ar_frame, &ar_camera);
  CHECK(ar_camera);
  wrapped_points_.push_back(WrappedInstantPlacement(
      point, tracking_method, Distance(point, ar_camera)));
}

인스턴트 게재위치 포인트의 추적 메서드가 AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING까지 거리 사용 크기 변경의 압박을 피하기 위해 저장할 수 있습니다

void OnUpdate() {
  for (auto& wrapped_point : wrapped_points_) {
    ArInstantPlacementPoint* point = wrapped_point.point;

    ArTrackingState tracking_state = AR_TRACKING_STATE_STOPPED;
    ArTrackable_getTrackingState(ar_session, (ArTrackable)point,
                                 &tracking_state);

    if (tracking_state == AR_TRACKING_STATE_STOPPED) {
      wrapped_points_.remove(wrapped_point);
      continue;
    }
    if (tracking_state == AR_TRACKING_STATE_PAUSED) {
      continue;
    }

    ArInstantPlacementPointTrackingMethod tracking_method;
    ArInstantPlacementPoint_getTrackingMethod(ar_session, point,
                                              &tracking_method);
    ArCamera* ar_camera = nullptr;
    ArFrame_acquireCamera(ar_session, ar_frame, &ar_camera);
    CHECK(ar_camera);
    const float distance_to_camera = Distance(point, ar_camera);
    if (tracking_method ==
        AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE) {
      // Continue to use the estimated depth and pose. Record the distance to
      // the camera for use in the next frame if the transition to full
      // tracking happens.
      wrapped_point.previous_distance_to_camera = distance_to_camera;
    } else if (
        tracking_method ==
            AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING &&
        wrapped_point.previous_tracking_method ==
            AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE) {
      // Change from the estimated pose to the accurate pose. Adjust the
      // object scale to counteract the apparent change due to pose jump.
      wrapped_point.scale_factor =
          distance_to_camera / wrapped_point.previous_distance_to_camera;
      // Apply the scale factor to the model.
      // ...
      previous_tracking_method =
          AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING;
    }
  }
}

성능에 대한 고려사항

인스턴트 게재위치를 사용 설정하면 ARCore에서 CPU 주기를 추가로 사용합니다. 만약 문제가 되는 경우 사용자가 사이트에서 광고를 게재한 후 인스턴트 게재위치를 해당 객체와 모든 인스턴트의 추적 메서드가 성공적으로 게재위치 점수가 다음으로 변경됨: AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING

순간 게재위치가 비활성화된 경우 ArFrame_hitTest: ArFrame_hitTestInstantPlacement입니다.

ArConfig* ar_config = NULL;
ArConfig_create(ar_session, &ar_config);
// Disable Instant Placement.
ArConfig_setInstantPlacementMode(ar_session, ar_config,
                                 AR_INSTANT_PLACEMENT_MODE_DISABLED);
CHECK(ArSession_configure(ar_session, ar_config) == AR_SUCCESS);
ArConfig_destroy(ar_config);