Android NDK için Anında Yerleşim geliştirici kılavuzu

Anında Yerleşim API'sini nasıl kullanacağınızı öğrenin. inceleyebilirsiniz.

Ön koşullar

Temel artırılmış gerçeklik kavramlarını anladığınızdan emin olun ve devam etmeden önce ARCore oturumunun nasıl yapılandırılacağı hakkında daha fazla bilgi edinin.

Anında Yerleşim ile yeni bir oturum yapılandırın

Yeni bir ARCore oturumunda Anında Yerleşim modunu etkinleştirin.

// 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);

Nesne yerleştirme

Yeni bir ARCore oturumunda, ArFrame_hitTestInstantPlacement. Ardından şunu kullanarak yeni bir ArAnchor oluşturun: ArInstantPlacementPoint poz isabet sonucunun ARTrackable arasından seçilebilir.

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

Anında Yerleşim desteği yaklaşık mesafeyle ekran alanını izleme, Anında Yerleşim noktası sağlandığında otomatik olarak tam izlemeye gerçek dünyaya bağlı. Şu pozu al: ArInstantPlacementPoint_getPose(). Şununla mevcut izleme yöntemini alın: ArInstantPlacementPoint_getTrackingMethod().

ARCore, herhangi bir yüzeyde Anında Yerleşim isabet testi yapabilir, ancak yönünde her zaman +Y yukarı hareketine sahip bir poz döndürür. yer çekimi yönüdür. Yatay yüzeylerde, isabet testleri doğru sonuç verir çok daha hızlı bir şekilde ayarlayabilirsiniz.

Anında Yerleşim noktası izleme yöntemini izleme

ARCore, ArInstantPlacementPoint için doğru bir 3D duruşa sahipse ArFrame_hitTestInstantPlacement, izleme yöntemiyle başlar AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING. Aksi takdirde AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE izleme yöntemiyle başlar. ve AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING sürümüne geçiş doğru bir 3D poz verdiğinde. Takip yöntemi size AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING, geri döndürülmez - AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE.

İzleme yöntemi geçişini sorunsuz gerçekleştirme

İzleme yöntemi AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE. AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING konumuna tek karede sonraki karede, pozun hareketine dayalı olarak ilk konumundan atlar yeni bir konuma doğru bir uzaklıktaki yaklaşık mesafeyi gösterir. Bu pozdaki ani değişimler, duran nesnelerin görünür ölçeğini değiştirir. Ar InstantYerleşimPoint'e sabitlenir. Yani, aniden bir nesne önceki karede olduğundan daha büyük veya daha küçük görünür.

Görünüşe göre ani değişiklik nedeniyle görsel atlamadan kaçınmak için aşağıdaki adımları uygulayın nesne ölçeği:

  1. ArInstantPlacementPoint cihazının duruşunu ve takip yöntemini takip edin her karede görünür.
  2. İzleme yönteminin AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
  3. Önceki karedeki pozu ve geçerli karedeki pozu kullanın her iki karede de nesnenin cihaza olan mesafesini belirler.
  4. bulun.
  5. Nesnenin ölçeğini, ölçeğe göre algılanan değişime karşı gelecek şekilde ayarlayın. Böylece nesnenin boyutu görsel olarak değişmez.
  6. İsteğe bağlı olarak, nesnenin ölçeğini tekrar orijinaline yavaşça ayarlayın değerini belirlemeniz gerekir.
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_;

Anında Yerleşim noktasını oluşturduktan sonra sarmalamak için OnTouched() öğesini değiştirin.

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

Anında Yerleşim noktasının izleme yöntemi AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE. AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING konumuna uzaklığı kullanın kaydedilen ilerlemeyi kaydedebilirsiniz.

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

Performansla ilgili konular

Anında Yerleşim etkinleştirildiğinde, ARCore ek CPU döngüleri kullanır. Eğer bir sorun oluşturuyorsa, kullanıcı reklamınızı tıkladıktan sonra Anında Yerleşim'i devre dışı bırakmayı düşünün nesnesini ve tüm Anında Arama'nın izleme yöntemini Yerleşim puanları şu şekilde değişti: AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING

Anında Yerleşim devre dışı bırakıldığında, 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);