Utilizzare gli ancoraggi geospaziali per posizionare contenuti reali su Android NDK

Gli ancoraggi geospaziali sono un tipo di ancoraggio che ti consente di posizionare contenuti 3D nel mondo reale.

Tipi di ancoraggi geospaziali

Esistono tre tipi di ancoraggi geospaziali, ciascuno dei quali gestisce l'altitudine in modo diverso:

  1. Ancoraggi WGS84:
    Gli ancoraggi WGS84 consentono di inserire contenuti 3D a qualsiasi latitudine, longitudine e altitudine.

  2. Ancoraggi del terreno:
    Gli ancoraggi del terreno ti consentono di posizionare i contenuti utilizzando solo la latitudine e la longitudine con un'altezza relativa al terreno in quella posizione. L'altitudine è determinata in base al suolo o al piano, come noto da VPS.

  3. Ancoraggi per tetti:
    Gli ancoraggi per tetti ti consentono di posizionare i contenuti utilizzando solo la latitudine e la longitudine con un'altezza relativa al tetto di un edificio in quella posizione. L'altitudine è determinata in relazione alla cima di un edificio secondo Streetscape Geometry. Se non posizionato su un edificio, per impostazione predefinita viene selezionata l'altitudine del terreno.

WGS84 Terreno Da tetto
Posizione orizzontale Latitudine, longitudine Latitudine, longitudine Latitudine, longitudine
Posizione verticale Rispetto all'altitudine WGS84 Rispetto al livello del terreno determinato da Google Maps Rispetto al livello del tetto determinato da Google Maps
Deve essere risolta dal server? No

Prerequisiti

Assicurati di aver abilitato l'API Geospatial prima di procedere.

Posiziona i ancoraggi geospaziali

Ogni tipo di ancoraggio dispone di API dedicate per la loro creazione. Consulta la sezione Tipi di ancoraggi geospaziali per ulteriori informazioni.

Creare un anchor da un hit test

Puoi anche creare un ancoraggio geospaziale da un risultato hit test. Utilizza la POSA dell'hit test e convertila in una ArGeospatialPose. Utilizzalo per posizionare uno dei tre tipi di ancoraggio descritti.

Ottenere una posizione geospaziale da una posizione AR

ArEarth_getGeospatialPose() fornisce un metodo aggiuntivo per determinare la latitudine e la longitudine convertendo una posizione AR in una posizione geospaziale.

Ottenere una posa AR da una posizione geospaziale

ArEarth_getPose() converte una posizione orizzontale, un'altitudine e una rotazione di quaternione specificati dalla Terra rispetto a un frame di coordinate est-sud in una posizione AR rispetto alla coordinata mondiale GL.

Scegli il metodo adatto al tuo caso d'uso

Ogni metodo di creazione di un anchor ha compromessi associati da tenere presente:

  • Se utilizzi Streetscape Geometry, utilizza un hit test per allegare contenuti a un edificio.
  • Preferisco gli ancoraggi per terreni o per tetti rispetto agli ancoraggi WGS84 perché utilizzano valori di altitudine determinati da Google Maps.

Determinare la latitudine e la longitudine di una località

Esistono tre modi per calcolare la latitudine e la longitudine di una località:

  • Utilizza Geospaziale Creator per visualizzare e arricchire il mondo con contenuti 3D senza doverti recare fisicamente in una località. In questo modo, puoi inserire visivamente contenuti immersivi 3D utilizzando Google Maps nell'editor di Unity. La latitudine, la longitudine, la rotazione e l'altitudine dei contenuti verranno calcolate automaticamente.
  • Utilizza Google Maps
  • Utilizzare Google Earth. Tieni presente che ottenere queste coordinate utilizzando Google Earth, anziché Google Maps, ti darà un margine di errore fino a diversi metri.
  • Recati al luogo fisico

Utilizza Google Maps

Per ottenere la latitudine e la longitudine di un luogo utilizzando Google Maps:

  1. Accedi a Google Maps dal computer.

  2. Vai a Livelli > Altro.

  3. Imposta Tipo di mappa su Satellite e deseleziona la casella di controllo Vista globo nell'angolo in basso a sinistra dello schermo.

    In questo modo viene forzata una prospettiva 2D ed eliminati eventuali errori che potrebbero provenire da una vista 3D inclinata.

  4. Sulla mappa, fai clic con il tasto destro del mouse sul luogo e seleziona la longitudine/latitudine per copiarlo negli appunti.

Utilizzare Google Earth

Puoi calcolare la latitudine e la longitudine di un luogo da Google Earth facendo clic su una posizione nell'interfaccia utente e leggendo i dati dei dettagli del segnaposto.

Per ottenere la latitudine e la longitudine di un luogo utilizzando Google Earth:

  1. Accedi a Google Earth dal computer.

  2. Vai al menu menu e seleziona Stile mappa.

  3. Disattiva l'opzione Edifici in 3D.

  4. Una volta disattivata l'opzione Edifici 3D, fai clic sull'icona a forma di puntina per aggiungere un segnaposto nella località selezionata.

  5. Specifica un progetto in cui inserire il segnaposto e fai clic su Salva.

  6. Nel campo Titolo del segnaposto, inserisci un nome per il segnaposto.

  7. Fai clic sulla Freccia indietro nel riquadro del progetto e seleziona il menu Altre azioni.

  8. Scegli Esporta come file KML dal menu.

Il file KLM segnala la latitudine, la longitudine e l'altitudine di un segnaposto nel tag <coordinates> separati da virgole, come segue:

<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>

Non utilizzare la latitudine e la longitudine dei tag <LookAt>, che specificano la posizione della fotocamera, non la posizione.

Recati al luogo fisico

Puoi calcolare l'altitudine di un luogo andando lì fisicamente ed eseguendo un'osservazione locale.

Ottieni il quaternione di rotazione

ArGeospatialPose_getEastUpSouthQuaternion() estrae l'orientamento da una posa geospaziale e restituisce un quaternione che rappresenta la matrice di rotazione che trasforma un vettore dal target al sistema di coordinate est-su-sud. X+ punti a est, Y+ punta verso l'alto e Z+ punta a sud. I valori sono scritti nell'ordine {x, y, z, w}.

Ancoraggi WGS84

Un ancoraggio WGS84 è un tipo di ancoraggio che consente di posizionare contenuti 3D a qualsiasi latitudine, longitudine e altitudine specifici. Il suo posizionamento nel mondo reale è basato sulla posa e sull'orientamento. La posizione è costituita da latitudine, longitudine e altitudine specificate nel sistema di coordinate WGS84. L'orientamento consiste in una rotazione di quaternione.

L'altitudine è indicata in metri sopra l'ellissoide di riferimento WGS84, in modo che il livello del suolo non sia pari a zero. La tua app deve fornire queste coordinate per ogni ancoraggio creato.

Posiziona un ancoraggio WGS84 nel mondo reale

Determinare l'altitudine di un luogo

Esistono alcuni modi per determinare l'altitudine di un luogo in cui posizionare gli ancoraggi:

  • Se la posizione dell'ancoraggio è fisicamente vicino all'utente, puoi utilizzare un'altitudine simile a quella del dispositivo dell'utente.
  • Una volta ottenuta la latitudine e la longitudine, utilizza l'API Elevation per ottenere l'altitudine in base alla specifica EGM96. Devi convertire l'altitudine EGM96 dell'API di Google Maps in WGS84 per il confronto con l'altitudine ArGeospatialPose. Consulta il documento GeoidEval che contiene sia una riga di comando sia un'interfaccia HTML. L'API di Google Maps segnala immediatamente la latitudine e la longitudine secondo la specifica WGS84.
  • Puoi ottenere la latitudine, la longitudine e l'altitudine di un luogo da Google Earth. In questo modo otterrai un margine di errore di diversi metri. Utilizza la latitudine, la longitudine e l'altitudine dei tag <coordinates>, non dei tag <LookAt>, nel file KML.
  • Se un ancoraggio esistente è nelle vicinanze e non ti trovi su un pendio ripido, puoi utilizzare l'altitudine dalla ArGeospatialPose della videocamera senza utilizzare un'altra sorgente, come l'API di Google Maps.

Crea l'ancoraggio

Una volta ottenuta la latitudine, la longitudine, l'altitudine e il quaternione di rotazione, utilizza ArEarth_acquireNewAnchor() per ancorare i contenuti alle coordinate geografiche specificate.

float eus_quaternion_4[4] = {qx, qy, qz, qw};
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArAnchor* earth_anchor = NULL;
    ArStatus status = ArEarth_acquireNewAnchor(ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude,
        eus_quaternion_4, &earth_anchor);

    // Attach content to the anchor specified by geodetic location and
    // pose.
  }
}

Tasselli

Un ancoraggio del terreno è un tipo di ancoraggio che ti consente di posizionare oggetti AR solo utilizzando latitudine e longitudine, sfruttando le informazioni provenienti da VPS per trovare l'altitudine precisa sul suolo.

Anziché inserire l'altitudine desiderata, fornisci l'altitudine sul terreno. Se il valore è zero, l'ancora sarà allo stesso livello del terreno.

Imposta la modalità di rilevamento dell'aereo

Il rilevamento del piano è facoltativo e non è necessario per utilizzare gli ancoraggi. Tieni presente che vengono utilizzati solo piani orizzontali. I piani orizzontali facilitano l'allineamento dinamico degli ancoraggi al suolo.

Utilizza ArPlaneFindingMode per selezionare il modo in cui la tua app rileva gli aerei.

Crea un ancoraggio Terreno utilizzando la nuova API Async

Per creare e posizionare un ancoraggio Terreno, chiama ArEarth_resolveAnchorOnTerrainAsync().

L'ancoraggio non è subito pronto e deve essere risolto. Una volta risolto, sarà disponibile nella ArResolveAnchorOnTerrainFuture.

Controlla lo stato di ancoraggio del terreno utilizzando ArResolveAnchorOnTerrainFuture_getResultTerrainAnchorState(). Ottieni l'ancoraggio risolto utilizzando ArResolveAnchorOnTerrainFuture_acquireResultAnchor().

float eus_quaternion_4[4] = {qx, qy, qz, qw};
void* context = NULL;
ArResolveAnchorOnTerrainCallback callback = NULL;
ArResolveAnchorOnTerrainFuture* future = NULL;
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArStatus status = ArEarth_resolveAnchorOnTerrainAsync(
        ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude_above_terrain, eus_quaternion_4,
        context, callback, &future);
  }
}

Controlla lo stato del futuro

Al futuro sarà associata una ArFutureState.

Stato Descrizione
AR_FUTURE_STATE_PENDING L'operazione è ancora in attesa.
AR_FUTURE_STATE_DONE L'operazione è stata completata e il risultato è disponibile.
AR_FUTURE_STATE_CANCELLED L'operazione è stata annullata.

Controlla lo stato di ancoraggio del terreno nel risultato Futuro

ArTerrainAnchorState appartiene all'operazione asincrona e fa parte del risultato futuro finale.

switch (terrain_anchor_state) {
  case AR_TERRAIN_ANCHOR_STATE_SUCCESS:
    // A resolving task for this anchor has been successfully resolved.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the
    // Geospatial API.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/c/group/ar-anchor#:~:text=from%20this%20error.-,AR_TERRAIN_ANCHOR_STATE_ERROR_NOT_AUTHORIZED,-The%20authorization%20provided
    // for troubleshooting steps.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_INTERNAL:
    // The Terrain anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

Tasselli per tetti

Ancoraggi per tetti hero

I tasselli per tetti sono un tipo di ancoraggio e sono molto simili a quelli per terreno. La differenza è che viene indicata l'altitudine sul tetto anziché l'altitudine sul terreno.

Creare un ancoraggio al tetto utilizzando la nuova API Async

L'ancoraggio non è subito pronto e deve essere risolto.

Per creare e posizionare un ancoraggio per tetto, chiama ArEarth_resolveAnchorOnRooftopAsync(). Analogamente agli ancoraggi Terreno, accederai anche alla sezione ArFutureState del futuro. Dopodiché puoi controllare il Risultato futuro per accedere alla ArRooftopAnchorState.

Utilizza ArEarth_resolveAnchorOnRooftopAsync() per creare un ArResolveAnchorOnRooftopFuture.

Controlla lo stato di ancoraggio sul tetto utilizzando ArResolveAnchorOnRooftopFuture_getResultRooftopAnchorState().

Ottieni l'ancoraggio risolto utilizzando ArResolveAnchorOnRooftopFuture_acquireResultAnchor().

float eus_quaternion_4[4] = {qx, qy, qz, qw};
void* context = NULL;
ArResolveAnchorOnRooftopCallback callback = NULL;
ArResolveAnchorOnRooftopFuture* future = NULL;
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArStatus status = ArEarth_resolveAnchorOnRooftopAsync(
        ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude_above_rooftop, eus_quaternion_4,
        context, callback, &future);
  }
}

Controlla lo stato del futuro

Al futuro sarà associata una ArFutureState; consulta la tabella riportata sopra.

Controlla lo stato dell'ancoraggio al tetto del risultato futuro

ArRooftopAnchorState appartiene all'operazione asincrona e fa parte del risultato futuro finale.

switch (rooftop_anchor_state) {
  case AR_ROOFTOP_ANCHOR_STATE_SUCCESS:
    // A resolving task for this anchor has been successfully resolved.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the
    // Geospatial API.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/c/group/ar-anchor#:~:text=from%20this%20error.-,AR_ROOFTOP_ANCHOR_STATE_ERROR_NOT_AUTHORIZED,-The%20authorization%20provided
    // for troubleshooting steps.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_INTERNAL:
    // The Rooftop anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

Passaggi successivi