Tìm hiểu cách sử dụng API Vị trí tức thì trong ứng dụng của chính bạn.
Điều kiện tiên quyết
Đảm bảo rằng bạn hiểu rõ các khái niệm cơ bản về AR và cách định cấu hình phiên ARCore trước khi tiếp tục.
Định cấu hình một phiên mới với Vị trí tức thì
Trong phiên ARCore mới, hãy bật chế độ Vị trí tức thì.
// 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);
Đặt một đối tượng
Trong phiên ARCore mới, hãy thực hiện kiểm tra lượt truy cập Vị trí tức thì với
ArFrame_hitTestInstantPlacement
.
Sau đó, tạo một ArAnchor
mới bằng cách sử dụng
Tư thế ArInstantPlacementPoint
từ ARTrackable
của kết quả lượt truy cập.
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); }
Hỗ trợ Vị trí tức thì
theo dõi không gian màn hình với khoảng cách gần đúng,
tự động chuyển sang theo dõi đầy đủ khi Điểm Vị trí tức thì được
gắn liền với thế giới thực. Truy xuất tư thế hiện tại bằng
ArInstantPlacementPoint_getPose()
.
Tải phương pháp theo dõi hiện tại bằng
ArInstantPlacementPoint_getTrackingMethod()
.
Mặc dù ARCore có thể thực hiện kiểm tra nhấn Vị trí tức thì trên các nền tảng của bất kỳ hướng, kết quả đánh sẽ luôn trả về tư thế với +Y lên, ngược với hướng trọng lực. Trên các bề mặt nằm ngang, các bài kiểm thử va chạm trả về kết quả chính xác vị trí nhanh hơn nhiều.
Theo dõi phương pháp theo dõi điểm Vị trí tức thì
Nếu ARCore có tư thế 3D chính xác cho ArInstantPlacementPoint
được trả về bởi
ArFrame_hitTestInstantPlacement
, bắt đầu bằng phương pháp theo dõi
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
. Nếu không, chiến dịch sẽ bắt đầu bằng phương pháp theo dõi AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
và chuyển đổi sang AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
khi ARCore có tư thế 3D chính xác. Khi phương pháp theo dõi
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
, sự kiện này sẽ không khôi phục về trạng thái ban đầu
đến
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
Dễ dàng chuyển đổi phương pháp theo dõi
Khi phương pháp theo dõi thay đổi từ
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
trong một khung hình đến AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
trong khung hình tiếp theo, tư thế đó sẽ nhảy từ vị trí ban đầu dựa trên
đã cung cấp khoảng cách gần đúng đến một vị trí mới với khoảng cách chính xác. Chiến dịch này
sự thay đổi tức thời về tư thế làm thay đổi tỷ lệ biểu kiến của bất kỳ vật thể nào
được neo vào Ar InstantLocationsPoint. Điều đó nghĩa là một đối tượng đột nhiên
xuất hiện lớn hơn hoặc nhỏ hơn so với khung trước đó.
Hãy làm theo các bước sau để tránh hiện tượng nhảy hình ảnh do sự thay đổi đột ngột về độ rõ ràng tỷ lệ đối tượng:
- Theo dõi tư thế và phương pháp theo dõi của
ArInstantPlacementPoint
trong từng khung hình. - Chờ phương pháp theo dõi đổi thành
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
. - Sử dụng tư thế từ khung hình trước và tư thế trong khung hình hiện tại để xác định khoảng cách của đối tượng đến thiết bị trong cả hai khung.
- Tính sự thay đổi biểu kiến về tỷ lệ do sự thay đổi về khoảng cách từ máy ảnh.
- Điều chỉnh tỷ lệ của đối tượng để chống lại sự thay đổi cảm nhận về quy mô, sao cho đối tượng không thay đổi kích thước về mặt trực quan.
- Không bắt buộc: Điều chỉnh tỷ lệ của đối tượng về trạng thái ban đầu (không bắt buộc) trên một số khung hình.
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_;
Sau khi tạo điểm Vị trí tức thì, hãy sửa đổi OnTouched()
để gói điểm đó.
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)));
}
Khi phương pháp theo dõi của điểm Vị trí tức thì chuyển từ
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
đến AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
, hãy sử dụng khoảng cách
để chống lại sự thay đổi tỷ lệ biểu kiến.
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;
}
}
}
Xem xét hiệu suất
Khi bật Vị trí tức thì, ARCore sẽ sử dụng thêm chu kỳ CPU. Nếu
bạn quan tâm đến hiệu suất, hãy xem xét việc tắt Vị trí tức thì sau khi người dùng
đã đặt thành công đối tượng và phương pháp theo dõi của tất cả
Điểm vị trí đã thay đổi thành
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
.
Khi Vị trí tức thì bị tắt, hãy sử dụng
ArFrame_hitTest
thay vì
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);