Mendapatkan hasil eksekusi session
Selama session berjalan, transform dari beberapa objek di scene serta gambar kamera akan diubah. Terkadang perubahan ini belum cukup untuk kebutuhan aplikasi, dan perlu mendapatkan hasil eksekusi session setiap frame lalu memproses data tersebut lagi. Artikel ini menjelaskan cara mendapatkan dan menggunakan data tersebut.
Sebelum mulai
- Pahami konsep dasar, komposisi, dan alur kerja session melalui Pengenalan ARSession
- Pelajari cara membuat session
- Pelajari cara mengakses komponen fitur AR
Mendapatkan pembaruan InputFrame
Anda dapat menggunakan event InputFrameUpdate untuk mendapatkan pembaruan InputFrame. Event ini hanya dipicu saat InputFrame berubah pada data keluaran session setiap frame.
Catatan
InputFrameUpdate hanya berlaku pada session yang gambar kameranya digambar oleh EasyAR. Umumnya ini tidak berlaku saat menggunakan AR Foundation atau headset, dan saat itu perlu memakai metode yang disediakan library pihak ketiga tersebut untuk mendapatkan pembaruan data.
Dengan InputFrame, Anda bisa mendapatkan gambar kamera fisik, parameter kamera, timestamp, transform kamera fisik terhadap sistem koordinat dunia, dan status tracking, dan lain-lain. Namun karena transform kamera sudah diterapkan oleh session ke kamera virtual dan objek lain, biasanya tidak perlu mendapatkan transform kamera lewat InputFrame.
Mendapatkan gambar kamera fisik frame saat ini
Anda dapat memakai metode InputFrame.image() untuk mendapatkan data gambar kamera fisik bertipe Image.
Misalnya, kode berikut dapat memperoleh gambar kamera fisik saat InputFrame diperbarui:
Session.InputFrameUpdate += (inputFrame) => {
using (var image = inputFrame.image())
{
}
};
Hati-Hati
Saat memakai data tipe Image dan data tipe class lain yang diperoleh darinya, pastikan Dispose() dipanggil dengan benar (pernyataan using pada kode di atas sudah menjaminnya); jika tidak, dapat terjadi kebocoran memori bahkan gambar berhenti diperbarui.
Jika Anda perlu menyimpan InputFrame atau Image untuk dipakai pada frame berikutnya, tambahkan nilai ARAssembly.ExtraBufferCapacity sesuai jumlah data yang disimpan; jika tidak, pengambilan data dapat gagal karena buffer tidak cukup.
Jika Anda perlu menyimpan InputFrame, Anda juga harus memanggil Clone() untuk membuat salinan referensi, lalu memanggil Dispose() pada salinan tersebut saat tidak diperlukan lagi.
Karena frame rate kamera fisik biasanya lebih rendah daripada frame rate render, tidak setiap frame render akan menerima event InputFrameUpdate, dan sebaliknya gambar kamera fisik juga tidak diperbarui pada setiap frame render. Semua frame render sebelum event InputFrameUpdate berikutnya tetap memiliki isi gambar yang sama dengan InputFrame saat ini.
Catatan
Gambar di dalam InputFrame pasti sama dengan gambar latar kamera virtual pada frame saat ini, tetapi saat merender latar mungkin terjadi penskalaan dan pemotongan, sehingga ukuran atau rasio gambar yang diperoleh tidak sama dengan yang tampil di layar adalah hal yang normal.
Selain itu, perlu diperhatikan bahwa data gambar yang dikembalikan oleh InputFrame.image() dapat dibaca CPU, bukan tekstur GPU. Jika Anda perlu memakai data gambar di GPU, Anda harus mengunggah data gambar ke tekstur GPU, atau langsung memperoleh tekstur GPU melalui antarmuka CameraImageRenderer.RequestTargetTexture(Action<Camera, RenderTexture>).
[Opsional] Mencegat render gambar kamera fisik
Anda dapat menggunakan ARAssembly.CameraImageRenderer untuk mengontrol gambar kamera fisik yang dirender.
Kode berikut dapat menghentikan render gambar kamera fisik:
if (Session.Assembly != null && Session.Assembly.CameraImageRenderer.OnSome)
{
Session.Assembly.CameraImageRenderer.Value.enabled = false;
}
Perlu dicatat, di sini harus terlebih dahulu memeriksa apakah ARAssembly.CameraImageRenderer ada.
Catatan
Hanya pada session yang gambar kameranya digambar oleh EasyAR, cara di atas dapat menghentikan pembaruan gambar. Umumnya ini tidak berlaku saat menggunakan AR Foundation atau headset, dan saat itu perlu memakai metode yang disediakan library pihak ketiga tersebut untuk mewujudkan fungsi yang sesuai.
Setelah render gambar kamera fisik dihentikan, aplikasi dapat memperoleh data gambar kamera fisik melalui InputFrame dan memakai data tersebut untuk render kustom.
Mendapatkan pembaruan transform
Anda dapat memperoleh data transform objek di scene setelah setiap pembaruan session melalui event PostSessionUpdate.
Catatan
Untuk beberapa fitur (misalnya Mega), meskipun gambar tidak berubah dan tidak ada permintaan pembaruan layanan yang terlihat, perhitungan AR tetap berjalan pada setiap frame render. Karena itu, jika Anda perlu mendapatkan semua perubahan transform, Anda harus mengambil data transform setiap frame, bukan hanya pada beberapa frame.
Mendapatkan transform kamera virtual
Anda dapat memperoleh transform kamera di scene melalui ARAssembly.Camera.
Session.PostSessionUpdate += () =>
{
var position = Session.Assembly.Camera.transform.position;
var rotation = Session.Assembly.Camera.transform.rotation;
};
Mendapatkan transform target
Anda dapat memperoleh transform target di scene melalui objek target yang dipakai. Misalnya, untuk image tracking, target itu adalah objek yang berisi komponen ImageTargetController.
Session.PostSessionUpdate += () =>
{
var position = target.transform.position;
var rotation = target.transform.rotation;
};
[Opsional] Mendapatkan pose
pose adalah struktur data untuk menjelaskan posisi dan orientasi objek, biasanya terdiri dari position dan rotation. Dalam aplikasi AR, pose biasanya dipakai untuk menjelaskan posisi dan orientasi kamera fisik atau target tracking terhadap suatu sistem referensi.
Unity tidak menyediakan data pose mentah, karena pose umumnya dipakai untuk menggerakkan objek di scene, dan itu memang sudah dilakukan otomatis oleh session. Untuk perhitungan dan render konten, transform sudah cukup.
Penting
Sebelum membaca metode di bawah ini, pikirkan lagi apakah data transform kamera, target tracking, dan objek lain sudah memenuhi kebutuhan Anda. Biasanya data pose tambahan tidak diperlukan.
Jika memang ada alasan tertentu dan Anda membutuhkan data pose, Anda bisa menghitungnya dari transform pada event PostSessionUpdate. Umumnya, transform relatif antara target dan camera yang didapat di PostSessionUpdate sudah menjadi pose.
Kode berikut menunjukkan cara mendapatkan transform camera dan target, lalu menghitung pose relatif di antara keduanya:
Session.PostSessionUpdate += () =>
{
Pose cameraToWorld = new(Session.Assembly.Camera.transform.position, Session.Assembly.Camera.transform.rotation);
Pose targetToWorld = new(target.transform.position, target.transform.rotation);
Pose worldToTarget = new()
{
position = Quaternion.Inverse(targetToWorld.rotation) * (-targetToWorld.position),
rotation = Quaternion.Inverse(targetToWorld.rotation)
};
Pose cameraToTarget = cameraToWorld.GetTransformedBy(worldToTarget);
};
Hati-Hati
Jika Anda juga menggunakan AR Foundation, headset, atau library pihak ketiga lain yang sedang berjalan, library tersebut mungkin juga mengubah transform kamera di scene. Pastikan logika pembaruan library tersebut selesai terlebih dahulu sebelum melakukan perhitungan pose terkait, jika tidak hasil perhitungan bisa tidak benar. Dalam skenario seperti ini, pose relatif antara target dan origin di PostSessionUpdate tetap akurat.
[Opsional] Mencegat pembaruan transform
Saat fitur AR berjalan, transform kamera, target tracking, dan objek lain di Unity biasanya diperbarui secara otomatis oleh session. Proses pembaruan ini menjamin kebenaran dan konsistensi render AR, jadi tidak ada cara untuk mencegat pembaruan ini secara langsung.
Namun jika Anda perlu logika pembaruan transform objek yang kustom, Anda bisa mewujudkannya dengan mendengarkan event PostSessionUpdate. Di sini perlu memakai cara yang agak rumit:
- Walaupun biasanya konten render seharusnya dipasang sebagai child atau komponen tambahan di bawah objek yang dikendalikan session, jika Anda perlu mengkustomisasi pembaruan transform objek, objek tersebut harus dikeluarkan dari hierarki objek yang dikendalikan session. Artinya, objek tersebut tidak boleh menjadi child dari objek yang dikendalikan session.
- Pada event PostSessionUpdate, catat transform objek yang ingin Anda perbarui secara kustom.
- Terakhir, pada event PostSessionUpdate, gunakan logika kustom untuk memperbarui transform objek tersebut berdasarkan data yang disediakan session.
Catatan
Penggunaan event PostSessionUpdate diperlukan, karena hanya setelah waktu itu session tidak lagi memanipulasi objek di scene.
Perlu dicatat bahwa cara ini tidak dapat dipakai untuk mengubah camera, dan membutuhkan logika yang lebih kompleks untuk menangani pembaruan kamera kustom.
Selain itu, cara ini hanya dapat dipakai untuk memperbarui transform objek secara kustom, bukan untuk mengubah transform objek yang dikendalikan session. Jika transform objek yang dikendalikan session diubah dari luar, session tetap akan menimpa perubahan itu pada pembaruan frame berikutnya, yang bisa memengaruhi akurasi beberapa perhitungan.
Hati-Hati
Memakai cara ini mengharuskan Anda menjamin kebenaran transform objek, jika tidak dapat menyebabkan kesalahan render AR.
Jika Anda juga menggunakan AR Foundation, headset, atau library pihak ketiga lain, library tersebut mungkin juga mengubah transform objek di scene. Pastikan logika pembaruan library tersebut tidak bertabrakan dengan logika kustom Anda; jika tidak, hasil yang tidak terduga bisa terjadi.
Topik terkait
- Mode center membatasi objek mana yang akan dimodifikasi session melalui transform
- Pengenalan komponen dasar AR