Bekerja dengan ARCore untuk Jetpack XR

ARCore untuk Jetpack XR memungkinkan aplikasi berfungsi dengan konsep dasar augmented reality (AR), menggunakan primitif pemahaman scene tingkat rendah dan pelacakan gerakan. Gunakan ARCore untuk Jetpack XR saat mem-build pengalaman AR dan Anda perlu menggunakan data planar atau konten anchor ke lokasi tetap dalam ruang.

Memahami siklus proses Sesi

Semua objek yang dilacak oleh ARCore untuk Jetpack XR harus diakses melalui Sesi. Serupa dengan siklus proses Aktivitas, objek Sesi juga memiliki siklus proses yang harus dipertahankan sesuai dengan penggunaan fitur objek Sesi oleh aplikasi Anda. Jika aplikasi Anda berisi satu aktivitas yang mendukung XR, pertimbangkan untuk menangani siklus proses Sesi menggunakan Komponen berbasis siklus proses.

Membuat Sesi

Sesi harus dibuat sebelum dapat digunakan. Membuat sesi mengharuskan pengguna telah memberikan izin android.permission.SCENE_UNDERSTANDING ke aplikasi Anda.

Untuk membuat sesi:

when (val result = Session.create(owner)) {
  is SessionCreateSuccess -> {
    session = result.session
  }
  is SessionCreatePermissionsNotGranted -> {
   // Request android.permission.SCENE_UNDERSTANDING.
  }
}

Lihat SessionCreateResult untuk mengetahui alasan Sesi gagal dibuat.

Melanjutkan sesi

Melanjutkan sesi harus dilakukan saat aplikasi Anda siap menangani perubahan status dari ARCore untuk Jetpack XR. Dalam banyak kasus, hal ini dilakukan dalam callback onResume() Aktivitas, tetapi aplikasi Anda mungkin ingin menunda pemrosesan hingga interaksi pengguna.

Cuplikan kode berikut menunjukkan contoh melanjutkan sesi.

when (val result = session.resume()) {
  is SessionResumeSuccess -> {
    // Session has been created successfully.
    // Attach any successful handlers here.
  }
  is SessionResumePermissionsNotGranted -> {
    // Request android.permission.SCENE_UNDERSTANDING.
}

Lihat SessionResumeResult untuk mengetahui alasan Sesi gagal dilanjutkan.

Menjeda sesi

Saat aktivitas Anda beralih ke latar belakang, jeda Sesi menggunakan Session.pause(). Menjeda sesi akan menghentikan pelacakan sementara hingga sesi dilanjutkan, mempertahankan status sistem persepsi.

Menghancurkan sesi

Untuk menghapus sesi secara permanen, gunakan Session.destroy(). Tindakan ini akan mengosongkan resource yang digunakan oleh sesi dan menghancurkan semua status sesi.

Mengambil status bidang yang dirasakan

ARCore untuk Jetpack XR menyediakan status bidang melalui StateFlow yang memunculkan status bidang. Berlangganan ke pesawat dalam sesi akan memberi tahu aplikasi Anda saat pesawat ditambahkan, diperbarui, atau dihapus.

Plane.subscribe(session).collect { planes ->
 // Planes have changed; update plane rendering
}

Bidang memiliki properti berikut:

Melakukan hit-test terhadap bidang

Hit-test adalah metode untuk menghitung persimpangan sinar dengan objek yang dilacak oleh sesi. Penerapan umum hit-test adalah dengan mengarahkan kursor ke tabel dan menempatkan objek di lokasi tersebut. Melakukan hit-test akan menghasilkan daftar objek hit. Dengan kata lain, hit-test tidak berhenti pada objek pertama yang dihit. Namun, sering kali Anda hanya tertarik pada hit objek pertama dari jenis tertentu.

Untuk melakukan hit-test, gunakan Interaction.hitTest() dengan Ray:

val results = Interaction.hitTest(session, ray)
// When interested in the first Table hit:
val tableHit = results.firstOrNull {
  val trackable = it.trackable
  trackable is Plane && trackable.state.value.label == Plane.Label.Table
}

Mengaitkan konten ke lokasi tetap dalam ruang

Untuk memberi objek virtual posisi di dunia nyata, gunakan Anchor. Objek Anchor membantu aplikasi Anda melacak lokasi tetap di ruang fisik.

Anchor dibuat menggunakan Pose, yang dapat ditafsirkan secara relatif terhadap Trackable yang ada atau tidak.

Membuat anchor yang relatif terhadap Trackable

Saat anchor dibuat relatif terhadap Trackable, seperti Plane, yang membuat anchor mengikuti Trackable yang terpasang saat bergerak melalui ruang.

val anchor = trackable.createAnchor(pose)

Membuat anchor tanpa Trackable

Untuk membuat anchor yang tidak terpasang ke Trackable:

when (val result = Anchor.create(session, pose)) {
  is AnchorCreateSuccess -> // ...
  else -> // handle failure
}

Melampirkan entitas ke anchor

Untuk merender model di lokasi ini, buat GltfModel dan tetapkan posenya ke pose anchor. Pastikan model disembunyikan saat TrackingState Anchor adalah Stopped.

// renderSession is androidx.xr.core.Session
anchor.state.collect { state ->
  if (state.trackingState == TrackingState.Tracking) {
    gltfEntity.setPose(
      renderSession.perceptionSpace.transformPoseTo(state.pose, renderSession.activitySpace)
    )
  } else if (state.trackingState == TrackingState.Stopped) {
    entity.setHidden(true)
  }
}

Memahami TrackingState

Setiap Trackable memiliki TrackingState yang harus diperiksa sebelum digunakan. Trackable yang memiliki TrackableState Tracking memiliki Pose yang secara aktif diperbarui oleh sistem. Trackable yang Paused dapat menjadi Tracking di masa mendatang, sedangkan Stopped tidak akan pernah menjadi Tracking.

Mempertahankan Anchor di seluruh sesi

Anchor yang tidak dipertahankan akan menghilang setelah sesi dihancurkan. Dengan mempertahankan anchor, aplikasi Anda akan mengingat posisi anchor tersebut dalam data aplikasi pribadinya. Anchor ini dapat diambil dalam sesi berikutnya dan ditautkan di lokasi yang sama di dunia.

Untuk mempertahankan anchor, gunakan anchor.persist() seperti yang ditunjukkan di sini:

val uuid = anchor.persist()

Aplikasi Anda dapat mengambil anchor menggunakan UUID dalam sesi mendatang:

when (val result = Anchor.load(session, uuid)) {
  is AnchorCreateSuccess -> // Loading was successful. The anchor is stored in result.anchor.
  else -> // handle failure
}

Jika Anda tidak memerlukan anchor lagi, panggil unpersist(). Tindakan ini akan menghapus anchor dari penyimpanan aplikasi Anda dan membuat UUID yang diberikan tidak dapat diambil untuk panggilan ke Anchor.load().

Anchor.unpersist(session, uuid)

Aplikasi Anda juga dapat meminta daftar semua anchor yang telah dipertahankan dan masih ada di penyimpanan aplikasi Anda:

val uuids = Anchor.getPersistedAnchorUuids(session)