Utilizzare gli ancoraggi geospaziali per posizionare contenuti reali su Unity

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, che gestiscono l'altitudine in modo diverso:

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

  2. Ancoraggi al terreno:
    Gli ancoraggi dei rilievi ti consentono di inserire contenuti utilizzando solo latitudine e e longitudine con un'altezza relativa al terreno in quella posizione. L'altitudine è determinata in relazione al suolo o al piano come indicato di VPS.

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

WGS84 Rilievo Da tetto auto
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 abilitare l'API Geospatial prima di procedere.

Posiziona ancoraggi geospaziali

Ogni tipo di ancoraggio ha API dedicate per crearli; consulta Tipi di ancoraggi geospaziali per ulteriori informazioni.

Creare un ancoraggio da un hit test

Puoi anche creare un ancoraggio geospaziale da un risultato hit-test. Usa la posa dell'hit test e convertila in una GeospatialPose. Usala per posizionare uno dei 3 tipi di ancoraggio descritti.

Ottieni una posizione geospaziale da una posizione AR

AREarthManager.Convert(Pose) fornisce un modo aggiuntivo per determinare la latitudine e la longitudine convertendo una posizione AR in una posizione geospaziale.

Ottieni una posizione AR da una posizione geospaziale

AREarthManager.Convert(GeospatialPose) converte una rotazione di posizione orizzontale, altitudine e quaternione specificate dalla Terra rispetto a un frame di coordinate est-alto-sud in una posizione AR rispetto alla coordinata globale del GL.

Scegli il metodo più adatto al tuo caso d'uso

A ogni metodo di creazione di un ancoraggio sono associati dei compromessi da tenere presenti:

  • Quando utilizzi la geometria di Streetscape, utilizzare un hit-test per allegare contenuti a un edificio.
  • Preferisci gli ancoraggi al terreno o al tetto rispetto agli ancoraggi WGS84 perché utilizzano i valori di altitudine determinati da Google Maps.

Determinare la latitudine e la longitudine di un luogo

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

  • Utilizza Geospatial Creator per visualizzare e ampliare il mondo con contenuti 3D senza dover recarti fisicamente in una località. In questo modo puoi posizionare visivamente contenuti 3D immersivi utilizzando Google Maps nell'editor Unity. La latitudine, la longitudine, la rotazione e l'altitudine dei contenuti verranno calcolati automaticamente.
  • Utilizza Google Maps
  • Utilizzare Google Earth. Tieni presente che il recupero delle coordinate utilizzando Google Earth, invece che Google Maps, ti consente di ottenere un margine di errore anche di alcuni metri.
  • Vai al luogo fisico

Utilizza Google Maps

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

  1. Accedi a Google Maps sul tuo 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 la prospettiva 2D ed elimina i possibili errori che potrebbero derivare da una visualizzazione 3D inclinata.

  4. Sulla mappa, fai clic con il tasto destro del mouse sulla località e seleziona la longitudine/latitudine per copiarla negli appunti.

Utilizza Google Earth

Per calcolare la latitudine e la longitudine di un luogo a partire da Google Earth, fai clic su un luogo nell'interfaccia utente e leggi i dati del segnaposto.

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

  1. Apri Google Earth sul tuo computer.

  2. Vai al menu a tre linee e seleziona Stile mappa.

  3. Disattiva l'opzione Edifici in 3D.

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

  5. Specifica un progetto che contenga il segnaposto e fai clic su Salva.

  6. Nel campo Titolo del segnaposto, assegnagli un nome.

  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> separate da virgole, come segue:

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

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

Vai al luogo fisico

Puoi calcolare l'altitudine di una località andando fisicamente sul luogo e facendo un'osservazione locale.

Ottieni il quaternione di rotazione

GeospatialPose.EunRotation estrae l'orientamento da una posizione geospaziale e restituisce un quaternone che rappresenta la matrice di rotazione che trasforma un vettore dal target al sistema di coordinate est-up-north (EUN). X+ punti verso est, Y+ punti verso l'alto dalla gravità e Z+ punti verso nord.

Ancoraggi WGS84

Un ancoraggio WGS84 è un tipo di ancoraggio che consente di posizionare contenuti 3D a qualsiasi latitudine, longitudine e altitudine specificate. Si basa su una posa e un orientamento per essere collocato nel mondo reale. La posizione è composta dai valori di latitudine, longitudine e altitudine, specificati nel sistema di coordinate WGS84. L'orientamento consiste in una rotazione del quaternione.

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

Posiziona un ancoraggio WGS84 nel mondo reale

Determinare l'altitudine di un luogo

Esistono diversi modi per determinare l'altitudine di una posizione per 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 indicate la latitudine e la longitudine, utilizza l'API Elevation per ottenere un'altitudine in base alla specifica EGM96. Devi convertire l'elevazione EGM96 dell'API di Google Maps in WGS84 per il confronto con l'altitudine di GeospatialPose. Vedi il documento GeoidEval che presenta sia una riga di comando sia un'interfaccia HTML. L'API di Google Maps registra latitudine e longitudine in base alla specifica WGS84 senza bisogno di ulteriori configurazioni.
  • Puoi ottenere la latitudine, la longitudine e l'altitudine di una località da Google Earth. In questo modo otterrai un margine di errore fino a diversi metri. Utilizza nel file KML la latitudine, la longitudine e l'altitudine dei tag <coordinates>, non dei tag <LookAt>.
  • Se un ancoraggio esistente è nelle vicinanze e se non sei su una pendenza ripida, potresti essere in grado di utilizzare l'altitudine della videocamera GeospatialPose senza ricorrere a un'altra sorgente, ad esempio l'API di Google Maps.

Crea l'ancoraggio

Una volta ottenuti i valori di latitudine, longitudine, altitudine e quaternione di rotazione, utilizza ARAnchorManagerExtensions.AddAnchor() per ancorare i contenuti alle coordinate geografiche da te specificate.

if (earthTrackingState == TrackingState.Tracking)
{
  var anchor =
      AnchorManager.AddAnchor(
          latitude,
          longitude,
          altitude,
          quaternion);
  var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
}

Ancoraggi per rilievi

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

Invece di inserire l'altitudine desiderata, devi specificare l'altitudine sopra il livello del terreno. Quando questo valore è pari a zero, l'ancoraggio sarà alla stessa altezza del terreno.

Impostare la modalità di ricerca dei piani

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

Tieni presente che gli ancoraggi del terreno sono interessati da Horizontal e Horizontal | Vertical.

Utilizza il menu a discesa Modalità di rilevamento per impostare la modalità di rilevamento:

Crea un ancoraggio Terreno con la nuova API Async

Per creare e posizionare un ancoraggio del terreno, chiama ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync().

L'ancoraggio non sarà pronto immediatamente e deve essere risolto. Una volta risolto, sarà disponibile nel ResolveAnchorOnTerrainPromise.

public GameObject TerrainAnchorPrefab;

public void Update()
{
    ResolveAnchorOnTerrainPromise terrainPromise =
        AnchorManager.ResolveAnchorOnTerrainAsync(
            latitude, longitude, altitudeAboveTerrain, eunRotation);

    // The anchor will need to be resolved.
    StartCoroutine(CheckTerrainPromise(terrainPromise));
}

private IEnumerator CheckTerrainPromise(ResolveAnchorOnTerrainPromise promise)
{
    yield return promise;

    var result = promise.Result;
    if (result.TerrainAnchorState == TerrainAnchorState.Success &&
        result.Anchor != null)
    {
        // resolving anchor succeeded
        GameObject anchorGO = Instantiate(TerrainAnchorPrefab,
            result.Anchor.gameObject.transform);
        anchorGO.transform.parent = result.Anchor.gameObject.transform;
    }
    else
    {
       // resolving anchor failed
    }

    yield break;
}

Controlla lo stato della promessa

Alla promessa sarà associato un elemento PromiseState.

Stato Descrizione
Pending L'operazione è ancora in attesa.
Done L'operazione è stata completata e il risultato è disponibile.
Cancelled L'operazione è stata annullata.

Controllare lo stato di ancoraggio del terreno del risultato Promise

TerrainAnchorState appartiene all'operazione asincrona e fa parte del risultato finale di Promise.

switch (result.TerrainAnchorState)
{
    case TerrainAnchorState.Success:
        // Anchor has successfully resolved
        break;
    case TerrainAnchorState.ErrorUnsupportedLocation:
        // The requested anchor is in a location that isn't supported by the Geospatial API.
        break;
    case TerrainAnchorState.ErrorNotAuthorized:
        // An error occurred while authorizing your app with the ARCore API. See
        // https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
        // for troubleshooting steps.
        break;
    case TerrainAnchorState.ErrorInternal:
        // The Terrain anchor could not be resolved due to an internal error.
        break;
    default:
        break;
}

Ancoraggi per tetti

Eroe dei tetti ancorati

Gli ancoraggi ai tetti sono un tipo di ancoraggio e sono molto simili agli ancoraggi a terra di cui sopra. La differenza è che verrà indicata l'altitudine sopra il tetto piuttosto che l'altitudine sopra il livello del terreno.

Crea un ancoraggio sul tetto utilizzando la nuova API Async

L'ancoraggio non sarà pronto immediatamente e deve essere risolto.

Per creare e posizionare un ancoraggio sul tetto, chiama ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync(). Come per gli ancoraggi del terreno, accederai anche alla PromiseState della Promessa. Dopodiché potrai controllare il risultato della promessa per accedere al RooftopAnchorState.

public GameObject RooftopAnchorPrefab;

public void Update()
{
    ResolveAnchorOnRooftopPromise rooftopPromise =
        AnchorManager.ResolveAnchorOnRooftopAsync(
            latitude, longitude, altitudeAboveRooftop, eunRotation);

    // The anchor will need to be resolved.
    StartCoroutine(CheckRooftopPromise(rooftopPromise));
}

private IEnumerator CheckRooftopPromise(ResolveAnchorOnTerrainPromise promise)
{
    yield return promise;

    var result = promise.Result;
    if (result.RooftopAnchorState == RooftopAnchorState.Success &&
        result.Anchor != null)
    {
        // resolving anchor succeeded
        GameObject anchorGO = Instantiate(RooftopAnchorPrefab,
            result.Anchor.gameObject.transform);
        anchorGO.transform.parent = result.Anchor.gameObject.transform;
    }
    else
    {
       // resolving anchor failed
    }

    yield break;
}

Controlla lo stato della promessa

La promessa avrà un elemento PromiseState associato; consulta la tabella qui sopra.

Controllare lo stato dell'ancoraggio sul tetto del risultato Promise

RooftopAnchorState appartiene all'operazione asincrona e fa parte del risultato finale di Promise.

switch (result.RooftopAnchorState)
{
    case TerrainAnchorState.Success:
        // Anchor has successfully resolved
        break;
    case RooftopAnchorState.ErrorUnsupportedLocation:
        // The requested anchor is in a location that isn't supported by the Geospatial API.
        break;
    case RooftopAnchorState.ErrorNotAuthorized:
        // An error occurred while authorizing your app with the ARCore API. See
        // https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
        // for troubleshooting steps.
        break;
    case RooftopAnchorState.ErrorInternal:
        // The Rooftop anchor could not be resolved due to an internal error.
        break;
    default:
        break;
}

Passaggi successivi