Menggunakan anchor Geospasial untuk memosisikan konten dunia nyata di Android NDK

Anchor geospasial adalah jenis anchor yang memungkinkan Anda menempatkan konten 3D di dunia nyata.

Jenis anchor Geospasial

Ada tiga jenis anchor Geospasial, yang masing-masing menangani ketinggian secara berbeda:

  1. Anchor WGS84:
    Anchor WGS84 memungkinkan Anda menempatkan konten 3D pada garis lintang tertentu, bujur, dan ketinggian.

  2. Anchor medan:
    Anchor medan memungkinkan Anda menempatkan konten hanya menggunakan lintang dan garis bujur dengan ketinggian relatif terhadap medan di posisi tersebut. Ketinggian ditentukan relatif terhadap tanah atau lantai sebagaimana diketahui oleh VPS.

  3. Anchor atap:
    Anchor atap memungkinkan Anda menempatkan konten hanya menggunakan garis lintang dan garis bujur dengan ketinggian relatif terhadap atap bangunan pada posisi tersebut. Ketinggian ditentukan relatif terhadap bagian atas bangunan sebagaimana diketahui oleh Streetscape Geometry. Setelan ini akan menetapkan ketinggian medan jika tidak ditempatkan di atas bangunan secara default.

WGS84 Medan Atap
Posisi Horizontal Lintang, Bujur Lintang, Bujur Lintang, Bujur
Posisi Vertikal Relatif terhadap ketinggian WGS84 Relatif terhadap tingkat medan yang ditentukan oleh Google Maps Relatif terhadap tingkat atap yang ditentukan oleh Google Maps
Perlu diselesaikan server? Tidak Ya Ya

Prasyarat

Pastikan Anda mengaktifkan Geospatial API sebelum melanjutkan.

Menempatkan anchor Geospasial

Setiap jenis anchor memiliki API khusus untuk membuatnya; lihat Jenis anchor Geospasial untuk mengetahui informasi selengkapnya.

Membuat anchor dari hit-test

Anda juga dapat membuat anchor Geospasial dari hasil hit-test. Gunakan Pose dari hit-test dan konversikan menjadi ArGeospatialPose. Gunakan untuk menempatkan salah satu dari 3 jenis anchor yang dijelaskan.

Ambil Pose Geospasial dari Pose AR

ArEarth_getGeospatialPose() memberikan cara tambahan untuk menentukan lintang dan bujur dengan mengonversi Pose AR menjadi Pose Geospasial.

Ambil Pose AR dari Pose Geospasial

ArEarth_getPose() mengonversi posisi horizontal, ketinggian, dan rotasi kuarternion yang ditentukan Bumi sehubungan dengan bingkai koordinat timur-atas-selatan menjadi Pose AR sehubungan dengan koordinat dunia GL.

Pilih metode yang sesuai dengan kasus penggunaan Anda

Setiap metode pembuatan anchor memiliki konsekuensi terkait yang perlu diingat:

  • Saat menggunakan Streetscape Geometry, menggunakan hit-test untuk memasang konten ke sebuah bangunan.
  • Memilih Anchor Medan atau Atap daripada anchor WGS84 karena menggunakan nilai ketinggian yang ditentukan oleh Google Maps.

Menentukan lintang dan bujur suatu lokasi

Ada tiga cara untuk menghitung lintang dan bujur lokasi:

  • Gunakan Geospatial Creator untuk melihat dan memperkaya dunia dengan konten 3D tanpa harus pergi ke suatu lokasi secara fisik. Ini memungkinkan Anda menempatkan konten imersif 3D secara visual menggunakan Google Maps di Editor Unity. Lintang, bujur, rotasi, dan ketinggian konten akan dihitung secara otomatis untuk Anda.
  • Gunakan Google Maps
  • Gunakan Google Earth. Perhatikan bahwa memperoleh koordinat ini menggunakan Google Earth, bukan dengan Google Maps, akan memberi Anda margin kesalahan hingga beberapa meter.
  • Pergi ke lokasi fisik

Gunakan Google Maps

Untuk mendapatkan lintang dan bujur suatu lokasi menggunakan Google Maps:

  1. Buka Google Maps di komputer desktop.

  2. Buka Lapisan > Lainnya.

  3. Ubah Jenis Peta menjadi Satelit dan hapus centang pada kotak Tampilan Globe di sudut kiri bawah layar.

    Tindakan ini akan memaksakan perspektif 2D dan menghilangkan kemungkinan error yang dapat muncul dari tampilan 3D miring.

  4. Pada peta, klik kanan lokasi lalu pilih bujur/lintang untuk disalin ke papan klip.

Menggunakan Google Earth

Anda dapat menghitung lintang dan bujur lokasi dari Google Earth dengan mengklik lokasi di UI dan membaca data dari detail penanda letak.

Untuk mendapatkan lintang dan bujur suatu lokasi menggunakan Google Earth:

  1. Buka Google Earth di komputer desktop.

  2. Buka menu tiga garis dan pilih Map Style.

  3. Nonaktifkan tombol Bangunan 3D.

  4. Setelah tombol Bangunan 3D dinonaktifkan, klik ikon pin untuk menambahkan penanda letak di lokasi yang dipilih.

  5. Tentukan project untuk menyertakan penanda letak Anda, lalu klik Simpan.

  6. Di kolom Judul untuk penanda letak, masukkan nama untuk penanda letak.

  7. Klik panah kembali di panel project dan pilih menu Tindakan Lainnya .

  8. Pilih Ekspor sebagai file KML dari menu.

File KLM melaporkan lintang, bujur, dan ketinggian untuk penanda letak di tag <coordinates> yang dipisahkan dengan koma, sebagai berikut:

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

Jangan gunakan lintang dan bujur dari tag <LookAt>, yang menentukan posisi kamera, bukan lokasi.

Pergi ke lokasi fisik

Anda dapat menghitung ketinggian lokasi dengan pergi ke sana secara fisik dan melakukan observasi lokal.

Mendapatkan kuarternion rotasi

ArGeospatialPose_getEastUpSouthQuaternion() mengekstrak orientasi dari Pose Geospasial dan menghasilkan kuartal yang mewakili matriks rotasi yang mentransformasikan vektor dari target ke sistem koordinat timur-atas-selatan (EUS). X+ menunjuk ke timur, Y+ menunjuk ke atas, dan Z+ menunjuk ke selatan. Nilai ditulis dalam urutan {x, y, z, w}.

Anchor WGS84

Anchor WGS84 adalah jenis anchor yang memungkinkan Anda menempatkan konten 3D pada lintang, bujur, dan ketinggian tertentu. Tema bergantung pada Pose, dan orientasi, untuk ditempatkan di dunia nyata. Posisi terdiri dari lintang, bujur, dan ketinggian, yang ditetapkan dalam sistem koordinat WGS84. Orientasi terdiri dari rotasi kuaternion.

Ketinggian dilaporkan dalam meter di atas elipsoid WGS84 referensi sehingga permukaan tanah bukan nol. Aplikasi Anda bertanggung jawab memberikan koordinat ini untuk setiap anchor yang dibuat.

Tempatkan anchor WGS84 di dunia nyata

Menentukan ketinggian lokasi

Ada beberapa cara untuk menentukan ketinggian lokasi untuk menempatkan anchor:

  • Jika lokasi anchor secara fisik dekat dengan pengguna, Anda dapat menggunakan ketinggian yang serupa dengan ketinggian perangkat pengguna.
  • Setelah Anda memiliki lintang dan bujur, gunakan Elevation API untuk mendapatkan elevasi berdasarkan spesifikasi EGM96. Anda harus mengonversi ketinggian Maps API EGM96 menjadi WGS84 untuk dibandingkan dengan ketinggian ArGeospatialPose. Lihat GeoidEval yang memiliki command line dan antarmuka HTML. Maps API melaporkan lintang dan bujur sesuai dengan spesifikasi WGS84 yang siap pakai.
  • Anda dapat memperoleh lintang, bujur, dan ketinggian lokasi dari Google Earth. Tindakan ini akan memberi Anda margin error hingga beberapa meter. Gunakan lintang, bujur, dan ketinggian dari tag <coordinates>, bukan tag <LookAt>, di file KML.
  • Jika anchor yang ada berada dekat dan jika Anda tidak berada di lereng yang curam, Anda mungkin dapat menggunakan ketinggian dari ArGeospatialPose kamera tanpa menggunakan sumber lain, seperti Maps API.

Membuat anchor

Setelah memiliki garis lintang, bujur, ketinggian, dan kuaternion rotasi, gunakan ArEarth_acquireNewAnchor() untuk menambatkan konten ke koordinat geografis yang Anda tentukan.

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.
  }
}

Angkur Medan

Anchor medan adalah jenis anchor yang memungkinkan Anda menempatkan objek AR hanya menggunakan lintang dan bujur, yang memanfaatkan informasi dari VPS untuk menemukan ketinggian yang akurat di atas tanah.

Alih-alih memasukkan ketinggian yang diinginkan, Anda memberikan ketinggian di atas medan. Jika nilainya nol, jangkar akan sejajar dengan medan.

Menyetel mode pencarian bidang

Penemuan bidang bersifat opsional dan tidak diwajibkan untuk menggunakan anchor. Perhatikan bahwa hanya bidang horizontal yang digunakan. Bidang horizontal akan membantu penyelarasan dinamis jangkar medan di tanah.

Gunakan ArPlaneFindingMode untuk memilih cara aplikasi mendeteksi pesawat.

Membuat anchor Medan menggunakan Asynchronous API yang baru

Untuk membuat dan menempatkan anchor Medan, panggil ArEarth_resolveAnchorOnTerrainAsync().

Anchor tidak akan langsung siap dan harus diselesaikan. Setelah diselesaikan, masalah tersebut akan tersedia di ArResolveAnchorOnTerrainFuture.

Periksa status anchor medan menggunakan ArResolveAnchorOnTerrainFuture_getResultTerrainAnchorState(). Mendapatkan anchor yang di-resolve menggunakan 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);
  }
}

Periksa Keadaan di Masa Depan

Future akan memiliki ArFutureState terkait.

Negara Bagian Deskripsi
AR_FUTURE_STATE_PENDING Operasi masih tertunda.
AR_FUTURE_STATE_DONE Operasi selesai dan hasilnya tersedia.
AR_FUTURE_STATE_CANCELLED Operasi telah dibatalkan.

Memeriksa status tetap Medan dari hasil Mendatang

ArTerrainAnchorState milik operasi asinkron dan merupakan bagian dari hasil Future akhir.

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;
}

Angkur Atap

Banner Besar Jangkar Atap

Anchor atap adalah jenis anchor dan sangat mirip dengan Anchor medan di atas. Perbedaannya adalah Anda akan memberikan ketinggian di atas atap bukan ketinggian di atas medan.

Membuat Rooftop Anchor menggunakan Asynchronous API yang baru

Anchor tidak akan langsung siap dan harus diselesaikan.

Untuk membuat dan menempatkan Anchor atap, panggil ArEarth_resolveAnchorOnRooftopAsync(). Sama halnya dengan Anchor Medan, Anda juga akan mengakses ArFutureState Future. Kemudian, Anda dapat memeriksa hasil Future untuk mengakses ArRooftopAnchorState.

Gunakan ArEarth_resolveAnchorOnRooftopAsync() untuk membuat ArResolveAnchorOnRooftopFuture.

Periksa status anchor atap menggunakan ArResolveAnchorOnRooftopFuture_getResultRooftopAnchorState().

Mendapatkan anchor yang di-resolve menggunakan 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);
  }
}

Periksa Keadaan di Masa Depan

Future akan memiliki ArFutureState terkait, lihat tabel di atas.

Memeriksa status anchor atap dari hasil Future

ArRooftopAnchorState milik operasi asinkron dan merupakan bagian dari hasil Future akhir.

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;
}

Langkah berikutnya