ดูวิธีใช้ 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 ใหม่ ให้ทำการทดสอบ Hit ตำแหน่งแบบทันใจกับ
ArFrame_hitTestInstantPlacement
จากนั้นสร้าง ArAnchor
ใหม่โดยใช้
โพสท่า ArInstantPlacementPoint
จากผลลัพธ์ ARTrackable
ของ Hit
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 จะสามารถทดสอบ Hit ของตำแหน่งแบบทันใจกับแพลตฟอร์ม การวางแนว ผลลัพธ์ของ Hit จะแสดงท่าทางที่มี +Y ขึ้นเสมอ ทิศทางของแรงโน้มถ่วง บนพื้นผิวแนวนอน การทดสอบ Hit จะให้ผลที่แม่นยำ ได้เร็วขึ้นมาก
ตรวจสอบวิธีการติดตามคะแนนสำหรับตำแหน่งทันที
หาก ARCore มีท่าทาง 3 มิติที่แม่นยำสำหรับ ArInstantPlacementPoint
ซึ่งแสดงผลโดย
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 มีท่าทาง 3 มิติที่แม่นยำ เมื่อวิธีการติดตามคือ
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
ใน 1 เฟรมเพื่อ AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
ในเฟรมถัดไป ท่าทางจะข้ามจากตำแหน่งเริ่มต้น
ระบุระยะทางโดยประมาณไปยังสถานที่ใหม่ซึ่งมีระยะทางที่ถูกต้อง ช่วงเวลานี้
เมื่อปรากฏการณ์ที่เปลี่ยนไป ขนาดที่เห็นได้ชัดของวัตถุ
จะตรึงอยู่ที่ ArInstantplacementPoint กล่าวคือ อยู่ๆ วัตถุ
แสดงใหญ่ขึ้นหรือเล็กกว่าในเฟรมก่อนหน้า
ทำตามขั้นตอนต่อไปนี้เพื่อหลีกเลี่ยงการข้ามเนื่องจากการเปลี่ยนแปลงอย่างกะทันหัน ขนาดของออบเจ็กต์:
- ติดตามท่าทางและวิธีการติดตามของ
ArInstantPlacementPoint
ในแต่ละเฟรม - รอให้วิธีการติดตามเปลี่ยนเป็น
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
- ใช้ท่าทางจากเฟรมก่อนหน้าและท่าในเฟรมปัจจุบันเพื่อ กำหนดระยะห่างของวัตถุกับอุปกรณ์ในทั้งสองเฟรม
- คำนวณการเปลี่ยนแปลงของสเกลที่ปรากฏเนื่องจากการเปลี่ยนแปลงระยะทางจาก กล้อง
- ปรับขนาดของวัตถุเพื่อรับมือกับการเปลี่ยนแปลงของขนาดที่รับรู้ เพื่อให้วัตถุไม่เปลี่ยนขนาดที่เห็นได้
- (ไม่บังคับ) ปรับสัดส่วนของวัตถุให้กลับไปเป็นต้นฉบับได้ ในหลายเฟรม
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 เพิ่มเติม ถ้า
ก็น่ากังวลเรื่องประสิทธิภาพ พิจารณา
ปิดใช้งานตำแหน่งโฆษณาทันทีหลังจากที่ผู้ใช้
ได้วางอ็อบเจกต์ของตนและวิธีการติดตามของ Instant ทั้งหมด
คะแนนตำแหน่งเปลี่ยนเป็น
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);