Instant Placement API verwenden in Ihren eigenen Apps.
Vorbereitung
Machen Sie sich mit den grundlegenden AR-Konzepten vertraut. und Konfigurieren einer ARCore-Sitzung beschrieben, bevor du fortfährst.
Neue Sitzung mit Instant-Placement konfigurieren
Aktivieren Sie in einer neuen ARCore-Sitzung den Modus „Instant-Platzierung“.
// 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);
Objekt platzieren
Führen Sie in einer neuen ARCore-Sitzung einen Treffertest der Instant-Platzierung mit
ArFrame_hitTestInstantPlacement
Erstellen Sie dann ein neues ArAnchor
mit dem
Position von ArInstantPlacementPoint
aus dem Trefferergebnis 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); }
Unterstützung für Instant-Placement
Tracking der Bildschirmfläche mit der ungefähren Entfernung
Automatischer Wechsel zum vollständigen Tracking, sobald der Punkt für die Instant-Platzierung erreicht wird
in der realen Welt verankert. Rufen Sie die aktuelle Position ab mit
ArInstantPlacementPoint_getPose()
Aktuelle Tracking-Methode abrufen mit
ArInstantPlacementPoint_getTrackingMethod()
ARCore kann zwar Treffertests für die Instant-Platzierung auf Oberflächen jeglicher Art durchführen, Ausrichtung wird in den Trefferergebnissen immer eine Position mit +Y nach oben angezeigt, der Schwerkraft. Auf horizontalen Oberflächen liefern Treffertests genaue Ergebnisse viel schneller zu platzieren.
Punkt-Tracking-Methode für die Instant-Platzierung überwachen
Wenn ARCore eine genaue 3D-Pose für die ArInstantPlacementPoint
hat, die von
ArFrame_hitTestInstantPlacement
, beginnt mit der Tracking-Methode
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
Andernfalls beginnt sie mit der Tracking-Methode AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
.
und wechseln zu AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
sobald ARCore eine genaue 3D-Pose hat. Sobald die Tracking-Methode
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
, wird nicht wiederhergestellt
bis
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
.
Den Übergang zur Tracking-Methode gleichmäßiger gestalten
Wenn die Tracking-Methode von
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
in einem Frame zu AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
im nächsten Frame, wechselt die Pose von ihrer ursprünglichen Position
hat die ungefähre Entfernung zu einem neuen Standort mit einer genauen Entfernung angegeben. Dieses
Durch eine sofortige Änderung der Haltung ändert sich die Größe aller Objekte,
sind am ArInstantPlacementPoint verankert. Das heißt, ein Objekt wird plötzlich
größer oder kleiner als im vorherigen Frame erscheint.
Befolgen Sie diese Schritte, um den visuellen Sprung aufgrund der plötzlichen Änderung der Objektskalierung:
- Position und Tracking-Methode des
ArInstantPlacementPoint
im Blick behalten in jedem Frame. - Warten Sie, bis sich die Verfolgungsmethode zu
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
- Mit der Pose aus dem vorherigen Frame und der Pose aus dem aktuellen Frame den Abstand des Objekts zum Gerät in beiden Frames ermitteln.
- Berechnen Sie die scheinbare Skalierungsänderung aufgrund der Abstandsänderung vom Kamera.
- Passen Sie die Größe des Objekts an, um der wahrgenommenen Größenänderung entgegenzuwirken. damit sich die Größe des Objekts nicht mehr ändert.
- Optional: Größe des Objekts reibungslos wieder auf die ursprüngliche Größe zurücksetzen über mehrere Frames hinweg.
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_;
Nachdem Sie den Punkt für die Instant-Platzierung erstellt haben, bearbeiten Sie OnTouched()
, um ihn zu umschließen.
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)));
}
Wenn die Tracking-Methode des Punkts der Instant-Platzierung von
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
bis AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
, verwenden Sie die Entfernung
um der scheinbaren Größenänderung entgegenzuwirken.
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;
}
}
}
Hinweise zur Leistung
Wenn die Instant-Platzierung aktiviert ist, verbraucht ARCore zusätzliche CPU-Zyklen. Wenn
ist die Leistung ein wichtiger Faktor. Deaktivieren Sie gegebenenfalls die Instant-Platzierung,
das Objekt und die Tracking-Methode aller Instant-
Die Placement-Punkte wurden geändert zu
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
Ist das Instant-Placement deaktiviert, verwenden Sie
ArFrame_hitTest
statt
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);