Découvrez comment utiliser l'API Instant Placement. dans vos propres applications.
Prérequis
Assurez-vous de bien maîtriser les concepts fondamentaux de la RA. et comment configurer une session ARCore avant de continuer.
Configurer une nouvelle session à l'aide des emplacements instantanés
Dans une nouvelle session ARCore, activez le mode Emplacement instantané.
// 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);
Placer un objet
Dans une nouvelle session ARCore, effectuez un test de positionnement instantané des emplacements avec
ArFrame_hitTestInstantPlacement
Créez ensuite un autre ArAnchor
à l'aide de la méthode
ArInstantPlacementPoint
pose
à partir des ARTrackable
du résultat de l'appel.
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); }
Emplacement instantané compatible
suivi de l'espace à l'écran avec distance approximative
passe automatiquement au suivi complet une fois que le point d'emplacement instantané est
ancré dans le monde réel. Récupérez la pose actuelle avec
ArInstantPlacementPoint_getPose()
Obtenez la méthode de suivi actuelle avec
ArInstantPlacementPoint_getTrackingMethod()
Bien qu'ARCore puisse effectuer des tests de positionnement instantanés des emplacements sur les surfaces l'orientation, les résultats de hit renvoient toujours une pose avec +Y vers le haut, par rapport à la dans la direction de la gravité. Sur les surfaces horizontales, les tests de positionnement renvoient bien plus vite.
Surveiller la méthode de suivi des points pour les emplacements instantanés
Si ARCore a une position 3D précise pour l'élément ArInstantPlacementPoint
renvoyé par
ArFrame_hitTestInstantPlacement
, cela commence par la méthode de suivi
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
Sinon, il commencera par la méthode de suivi AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
.
et passer à AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
une fois qu'ARCore a trouvé une bonne posture en 3D. Une fois que la méthode de suivi est
La valeur AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
ne sera pas rétablie.
à
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
Faciliter la transition vers la méthode de suivi
Lorsque la méthode de suivi passe
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
dans une image sur AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
dans l'image suivante, la pose saute depuis son emplacement initial en fonction
a fourni une distance approximative vers un nouveau lieu à une distance précise. Ce
tout changement instantané de position modifie l'échelle apparente de tout objet
sont ancrées à ArInstantPlacementPoint. C'est-à-dire qu'un objet
soit plus grande ou plus petite
que dans l'image précédente.
Suivez ces étapes pour éviter le saut visuel dû au changement soudain de l'apparente échelle d'objet:
- Effectuez le suivi de la posture et de la méthode de suivi de l'
ArInstantPlacementPoint
. dans chaque image. - Attendez que la méthode de suivi passe à
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
- Utilisez la posture du cadre précédent et celle du cadre actuel pour effectuer les actions suivantes : déterminer la distance entre l'objet et l'appareil dans les deux images.
- Calculer la variation apparente de l'échelle due à la variation de la distance par rapport caméra.
- Ajustez l’échelle de l’objet pour contrebalancer le changement d’échelle perçu afin que la taille de l'objet ne semble pas changer visuellement.
- Vous pouvez aussi ajuster progressivement la taille de l'objet à sa taille d'origine. sur plusieurs frames.
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_;
Après avoir créé le point d'emplacement instantané, modifiez OnTouched()
pour l'encapsuler.
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)));
}
Lorsque la méthode de suivi du point Emplacement instantané passe du
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_SCREENSPACE_WITH_APPROXIMATE_DISTANCE
à AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
, utilisez la distance
économisés pour contrebalancer
ce changement d'échelle.
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;
}
}
}
Considérations sur les performances
Lorsque l'emplacement instantané est activé, ARCore consomme des cycles de processeur supplémentaires. Si
les performances sont préoccupantes, envisagez de désactiver l'emplacement instantané une fois que l'utilisateur
a placé correctement son objet et la méthode de suivi de toutes les recherches instantanées
Les points d'emplacement ont été remplacés par
AR_INSTANT_PLACEMENT_POINT_TRACKING_METHOD_FULL_TRACKING
Lorsque l'emplacement instantané est désactivé, utilisez
ArFrame_hitTest
au lieu de
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);