Scopri come utilizzare l'API per il posizionamento istantaneo nelle tue app.
Prerequisiti
Assicurati di comprendere i concetti fondamentali della realtà aumentata e su come configurare una sessione ARCore prima di procedere.
Configura una nuova sessione con il posizionamento istantaneo
In una nuova sessione ARCore, attiva la modalità Posizionamento istantaneo.
// 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);
Posiziona un oggetto
In una nuova sessione ARCore, esegui un hit test di posizionamento istantaneo con
ArFrame_hitTestInstantPlacement
Quindi crea una nuova ArAnchor
utilizzando
ArInstantPlacementPoint
posa
dal risultato dell'hit 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); }
Il posizionamento istantaneo supporta
monitoraggio dello spazio sullo schermo con distanza approssimativa,
passaggio automatico al monitoraggio completo una volta che il punto di posizionamento istantaneo
ancorate al mondo reale. Recupera la posa attuale con
ArInstantPlacementPoint_getPose()
Ottieni il metodo di monitoraggio corrente con
ArInstantPlacementPoint_getTrackingMethod()
Sebbene ARCore possa eseguire hit test di posizionamento istantaneo su piattaforme di qualsiasi orientato, i risultati dei risultati restituiranno sempre una posa con +Y in alto, contro direzione della gravità. Sulle superfici orizzontali, gli hit test restituiscono dati accurati posizioni molto più velocemente.
Monitorare il metodo di monitoraggio dei punti di posizionamento istantaneo
Se ARCore ha una posa 3D precisa per ArInstantPlacementPoint
restituito da
ArFrame_hitTestInstantPlacement
, inizia con il metodo di monitoraggio
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
In caso contrario, inizierà con il metodo di monitoraggio AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
.
e la transizione a AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
una volta che ARCore ha una posa 3D precisa. Una volta che il metodo di monitoraggio
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
, l'operazione non verrà ripristinata
a
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
.
Semplifica la transizione del metodo di monitoraggio
Quando il metodo di monitoraggio cambia da
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
in un frame a AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
nel frame successivo, la posa salta dalla sua posizione iniziale in base al
fornita distanza approssimativa da un nuovo luogo a una distanza precisa. Questo
un cambiamento istantaneo di posa cambia la scala apparente di qualsiasi oggetto
sono ancorati ad ArInstancePLACEMENTPoint. In altre parole, un oggetto improvvisamente
appare più grande o più piccolo rispetto al frame precedente.
Segui questi passaggi per evitare il salto visivo dovuto all'improvviso cambiamento di apparente scala dell'oggetto:
- Tieni traccia della posa e del metodo di rilevamento di
ArInstantPlacementPoint
in ogni frame. - Attendi che il metodo di monitoraggio venga modificato in
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
. - Usa la posa del frame precedente e quella nel frame corrente per determinare la distanza dell'oggetto dal dispositivo in entrambi i fotogrammi.
- Calcolare la variazione di scala apparente dovuta alla variazione della distanza dal fotocamera.
- Regolare la scala dell'oggetto per contrastare il cambiamento percepito di scala. in modo che le dimensioni dell'oggetto non sembrino cambiare visivamente.
- Se vuoi, puoi regolare facilmente la scala dell'oggetto per riportarlo alla sua originale su più frame.
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_;
Dopo aver creato il punto di posizionamento istantaneo, modifica OnTouched()
per aggregarlo.
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)));
}
Quando il metodo di monitoraggio del punto di posizionamento istantaneo passa da
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
per AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
, utilizza la distanza
salvate per contrastare la variazione apparente di scala.
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;
}
}
}
Considerazioni sulle prestazioni
Quando il posizionamento istantaneo è attivato, ARCore consuma ulteriori cicli della CPU. Se
è un problema, ti consigliamo di disattivare il posizionamento istantaneo dopo che
ha posizionato correttamente l'oggetto e il metodo di monitoraggio di tutti i tipi di
I punti di posizionamento sono cambiati in
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
.
Quando il posizionamento istantaneo è disattivato, utilizza
ArFrame_hitTest
anziché
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);