Android NDK-এর জন্য তাত্ক্ষণিক প্লেসমেন্ট বিকাশকারী গাইড

আপনার নিজের অ্যাপে ইনস্ট্যান্ট প্লেসমেন্ট 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 এর সাথে একটি তাত্ক্ষণিক প্লেসমেন্ট হিট-টেস্ট করুন। তারপরে হিট ফলাফলের ARTrackable থেকে ArInstantPlacementPoint পোজ ব্যবহার করে একটি নতুন ArAnchor তৈরি করুন।

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 আপ সহ একটি ভঙ্গি ফিরিয়ে দেবে। অনুভূমিক পৃষ্ঠে, হিট-পরীক্ষা অনেক দ্রুত সঠিক অবস্থান ফেরত দেয়।

ইনস্ট্যান্ট প্লেসমেন্ট পয়েন্ট ট্র্যাকিং পদ্ধতি নিরীক্ষণ

ArFrame_hitTestInstantPlacement দ্বারা ফেরত দেওয়া ArInstantPlacementPoint এর জন্য 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_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 এ পরিবর্তিত হয়, তখন ভঙ্গিটি তার প্রারম্ভিক অবস্থানের উপর ভিত্তি করে প্রারম্ভিক অবস্থানের উপর ভিত্তি করে একটি নতুন অবস্থানের দূরত্বের উপর নির্ভর করে। ভঙ্গিতে এই তাত্ক্ষণিক পরিবর্তন ArInstantPlacementPoint এ নোঙ্গর করা যেকোন বস্তুর আপাত স্কেল পরিবর্তন করে। অর্থাৎ, কোনো বস্তু হঠাৎ করে আগের ফ্রেমের চেয়ে বড় বা ছোট দেখা যায়।

আপাত অবজেক্ট স্কেলে আকস্মিক পরিবর্তনের কারণে চাক্ষুষ লাফ এড়াতে এই পদক্ষেপগুলি অনুসরণ করুন:

  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_hitTestInstantPlacement এর পরিবর্তে ArFrame_hitTest ব্যবহার করুন।

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