1. Ringkasan
ARCore adalah platform untuk mem-build aplikasi augmented reality di Android. Gambar Augmented memberi Anda kemampuan untuk membuat aplikasi AR yang dapat mengenali gambar 2D yang telah didaftarkan sebelumnya di dunia nyata dan menambatkan konten virtual ke atasnya.
Codelab ini memandu Anda dalam memodifikasi aplikasi contoh ARCore yang ada untuk memasukkan Gambar Augmented yang bergerak atau diam di tempat.
Yang akan Anda build
Dalam codelab ini, Anda akan mem-build dari aplikasi contoh ARCore yang sudah ada. Di akhir codelab, aplikasi Anda akan dapat:
- Mendeteksi target gambar dan menambatkan labirin virtual pada target
- Melacak target yang bergerak selama berada dalam tampilan kamera
Apakah ini pertama kalinya Anda membuat aplikasi ARCore?
Apakah Anda berencana untuk menulis kode contoh dalam codelab ini atau hanya ingin membaca halaman ini?
Yang akan Anda pelajari
- Cara menggunakan Gambar Augmented di ARCore di Java
- Cara mengukur kemampuan gambar untuk dikenali oleh ARCore
- Cara menambatkan konten virtual pada gambar dan melacak gerakannya
Prasyarat
Anda membutuhkan hardware dan software tertentu untuk menyelesaikan codelab ini.
Persyaratan hardware
- Perangkat yang mendukung ARCore yang terhubung melalui kabel USB ke mesin pengembangan Anda
Persyaratan software
- ARCore APK 1.9.0 atau yang lebih baru. APK ini biasanya diinstal secara otomatis di perangkat melalui Play Store
- Mesin pengembangan dengan Android Studio (v3.1 atau yang lebih baru)
- Akses ke Internet, karena Anda perlu mendownload library selama pengembangan
Setelah semuanya siap, mari kita mulai.
2. Menyiapkan lingkungan pengembangan
Mendownload SDK
Kita akan mulai dengan mendownload ARCore Android SDK terbaru dari GitHub. Ekstrak file zip ke lokasi pilihan Anda. Untuk codelab ini, versi SDK paling awal adalah 1.18.1. Folder ini akan disebut arcore-android-sdk-x.xx.x
, nilai persisnya adalah versi SDK yang Anda gunakan.
Luncurkan Android Studio, dan klik Open an existing Android Studio project.
Buka folder yang diekstrak:
arcore-android-sdk-x.xx.x/samples/augmented_image_java
Klik Buka.
Tunggu sampai Android Studio menyelesaikan sinkronisasi project. Jika Android Studio tidak memiliki komponen yang diperlukan, prosesnya mungkin akan gagal dengan pesan Install missing platform and sync project
. Ikuti petunjuk untuk memperbaiki masalah.
Menjalankan aplikasi contoh
Setelah Anda memiliki project aplikasi ARCore yang berfungsi, mari kita coba menjalankannya.
Hubungkan perangkat ARCore ke mesin pengembangan, lalu gunakan menu Run > Run 'app' untuk menjalankan versi debug pada perangkat. Pada dialog yang meminta Anda memilih dari perangkat mana aplikasi dijalankan, pilih perangkat yang terhubung dan klik OK.
Project contoh ini menggunakan targetSdkVersion 28
. Jika Anda mengalami error build seperti Failed to find Build Tools revision 28.0.3
, ikuti petunjuk yang dijelaskan di Android Studio untuk mendownload dan menginstal versi Android Build Tools yang diperlukan.
Jika semuanya berhasil, aplikasi contoh akan diluncurkan di perangkat dan meminta izin kepada Anda untuk mengizinkan Gambar Augmented mengambil gambar dan video. Ketuk ALLOW untuk memberikan izin.
Menguji dengan gambar sampel
Kini setelah menyiapkan lingkungan pengembangan, Anda dapat menguji aplikasi dengan memberinya gambar untuk dilihat.
Kembali ke Android Studio, di jendela Project, buka app > assets, lalu klik dua kali file default.jpg
untuk membukanya.
Arahkan kamera perangkat ke gambar Bumi di layar, lalu ikuti petunjuk untuk menyesuaikan gambar yang Anda pindai ke dalam garis bidik.
Bingkai gambar akan diletakkan di atas gambar, seperti ini:
Selanjutnya, kita akan melakukan sedikit peningkatan pada aplikasi contoh.
3. Menampilkan model labirin pada Gambar 2D
Anda dapat mulai menggunakan Gambar Augmented dengan menampilkan model 3D di atasnya.
Mendownload model 3D
Untuk codelab ini, kita akan menggunakan "Circle Maze - Green" oleh Evol, dan berlisensi CC-BY 3.0. Saya menyimpan salinan model 3D ini di repositori github dari codelab ini, yang dapat Anda temukan di sini.
Ikuti langkah-langkah ini untuk mendownload model dan memasukkannya ke Android Studio.
- Buka repositori GitHub di codelab ini, direktori third_party.
- Klik GreenMaze_obj.zip, lalu klik tombol Download.
Tindakan ini akan mendownload file bernama GreenMaze_obj.zip
.
- Di Android studio, buat direktori
green-maze
di app > assets > models - Ekstrak zip
GreenMaze_obj.zip
dan salin konten ke lokasi ini:arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/assets/models/green-maze
- Di Android Studio, buka app > assets > models > green-maze.
Harus ada dua file dalam folder ini: GreenMaze.obj
dan GreenMaze.mtl
.
Merender model labirin
Ikuti langkah-langkah berikut untuk menampilkan model 3D GreenMaze.obj
di atas gambar 2D yang ada.
Di AugmentedImageRenderer.java
, tambahkan variabel anggota yang disebut mazeRenderer
untuk merender model labirin. Karena labirin harus ditambatkan ke gambar, sebaiknya tempatkan mazeRenderer
ke dalam class AugmentedImageRenderer
.
AugmentedImageRenderer.java
// Add a member variable to hold the maze model.
private final ObjectRenderer mazeRenderer = new ObjectRenderer();
Pada fungsi createOnGlThread()
, muat GreenMaze.obj
. Agar mudah, gunakan tekstur bingkai yang sama dengan teksturnya.
AugmentedImageRenderer.java
// Replace the definition of the createOnGlThread() function with the
// following code, which loads GreenMaze.obj.
public void createOnGlThread(Context context) throws IOException {
mazeRenderer.createOnGlThread(
context, "models/green-maze/GreenMaze.obj", "models/frame_base.png");
mazeRenderer.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);
}
Ganti definisi fungsi draw()
dengan kode berikut. Tindakan ini akan menyesuaikan ukuran labirin ke ukuran gambar yang terdeteksi, dan merendernya di layar.
AugmentedImageRenderer.java
// Adjust size of detected image and render it on-screen
public void draw(
float[] viewMatrix,
float[] projectionMatrix,
AugmentedImage augmentedImage,
Anchor centerAnchor,
float[] colorCorrectionRgba) {
float[] tintColor =
convertHexToColor(TINT_COLORS_HEX[augmentedImage.getIndex() % TINT_COLORS_HEX.length]);
final float mazeEdgeSize = 492.65f; // Magic number of maze size
final float maxImageEdgeSize = Math.max(augmentedImage.getExtentX(), augmentedImage.getExtentZ()); // Get largest detected image edge size
Pose anchorPose = centerAnchor.getPose();
float mazeScaleFactor = maxImageEdgeSize / mazeEdgeSize; // scale to set Maze to image size
float[] modelMatrix = new float[16];
// OpenGL Matrix operation is in the order: Scale, rotation and Translation
// So the manual adjustment is after scale
// The 251.3f and 129.0f is magic number from the maze obj file
// You mustWe need to do this adjustment because the maze obj file
// is not centered around origin. Normally when you
// work with your own model, you don't have this problem.
Pose mazeModelLocalOffset = Pose.makeTranslation(
-251.3f * mazeScaleFactor,
0.0f,
129.0f * mazeScaleFactor);
anchorPose.compose(mazeModelLocalOffset).toMatrix(modelMatrix, 0);
mazeRenderer.updateModelMatrix(modelMatrix, mazeScaleFactor, mazeScaleFactor/10.0f, mazeScaleFactor); // This line relies on a change in ObjectRenderer.updateModelMatrix later in this codelab.
mazeRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
}
Sekarang, labirin akan ditampilkan di atas gambar default.jpg
Bumi.
Catatan: Karena Anda tidak memiliki kontrol penuh atas model 3D sampel ini, kode di atas menggunakan beberapa angka "ajaib". Dimensi model labirin adalah 492.65 x 120 x 492.65, dengan pusat di (251.3, 60, -129.0). Rentang nilai koordinat X, Y, dan Z verteksnya masing-masing adalah [5.02, 497.67], [0, 120], dan [-375.17, 117.25]. Dengan demikian, skala model labirin harus image_size / 492.65
. mazeModelLocalOffset
diterapkan karena model 3D labirin tidak berpusat pada asal (0, 0, 0).
Dinding labirin masih terlalu tinggi untuk diletakkan di atas gambar. Buat fungsi bantuan updateModelMatrix()
yang dapat menskalakan X, Y, Z secara tidak rata untuk menskalakan tinggi Labirin sebesar 0,1. Perlu diperhatikan bahwa Anda harus mempertahankan updateModelMatrix(float[] modelMatrix, float scaleFactor)
yang ada dan menambahkan overload fungsi updateModelMatrix(float[] modelMatrix, float scaleFactorX, float scaleFactorY, float scaleFactorZ)
sebagai fungsi baru.
common/rendering/ObjectRenderer.java
// Scale X, Y, Z coordinates unevenly
public void updateModelMatrix(float[] modelMatrix, float scaleFactorX, float scaleFactorY, float scaleFactorZ) {
float[] scaleMatrix = new float[16];
Matrix.setIdentityM(scaleMatrix, 0);
scaleMatrix[0] = scaleFactorX;
scaleMatrix[5] = scaleFactorY;
scaleMatrix[10] = scaleFactorZ;
Matrix.multiplyMM(this.modelMatrix, 0, modelMatrix, 0, scaleMatrix, 0);
}
Jalankan kode. Labirin sekarang seharusnya pas di atas gambar.
4. Menambahkan Andy ke labirin
Sekarang setelah Anda memiliki labirin, tambahkan karakter untuk bergerak di dalamnya. Gunakan file andy.obj
yang disertakan dalam ARCore Android SDK. Pastikan tekstur bingkai gambar sebagai teksturnya, karena terlihat berbeda dari labirin hijau yang dirender di bagian atas gambar.
Di AugmentedImageRenderer.java
, tambahkan ObjectRenderer
pribadi untuk merender Andy.
AugmentedImageRenderer.java
// Render for Andy
private final ObjectRenderer andyRenderer = new ObjectRenderer();
Berikutnya, lakukan inisialisasi andyRenderer
di akhir createOnGlThread()
.
AugmentedImageRenderer.java
public void createOnGlThread(Context context) throws IOException {
// Initialize andyRenderer
andyRenderer.createOnGlThread(
context, "models/andy.obj", "models/andy.png");
andyRenderer.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);
}
Terakhir, render Andy di atas labirin di akhir fungsi draw()
.
AugmentedImageRenderer.java
public void draw(
float[] viewMatrix,
float[] projectionMatrix,
AugmentedImage augmentedImage,
Anchor centerAnchor,
float[] colorCorrectionRgba) {
// Render Andy, standing on top of the maze
Pose andyModelLocalOffset = Pose.makeTranslation(
0.0f,
0.1f,
0.0f);
anchorPose.compose(andyModelLocalOffset).toMatrix(modelMatrix, 0);
andyRenderer.updateModelMatrix(modelMatrix, 0.05f); // 0.05f is a Magic number to scale
andyRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
}
Jalankan kode. Anda akan melihat Andy yang berdiri di atas labirin.
Menentukan kualitas gambar target
ARCore bergantung pada fitur visual untuk mengenali gambar. Karena perbedaan kualitas, tidak semua gambar dapat dikenali dengan mudah.
arcoreimg
adalah alat command line yang membuat Anda dapat menentukan seberapa dikenali sebuah gambar oleh ARCore. Alat ini menampilkan angka antara 0 hingga 100, dengan 100 sebagai yang paling mudah dikenali.
. Berikut contohnya:
arcore-android-sdk-x.xx.x/tools/arcoreimg/macos$
$ ./arcoreimg eval-img --input_image_path=/Users/username/maze.jpg
100
maze.jpg
memiliki nilai 100, sehingga mudah dikenali oleh ARCore.
5. Opsional: Membuat Andy bergerak di dalam labirin
Terakhir, Anda dapat menambahkan beberapa kode untuk membuat Andy bergerak di labirin. Misalnya, gunakan mesin Fisika open source, jBullet untuk menangani simulasi fisika. Tidak masalah jika Anda melewatkan bagian ini.
Download PhysicsController.java
dan tambahkan ke project Anda di direktori
arcore-android-sdk-x.xx.x/samples/augmented_image_java/app/src/main/java/com/google/ar/core/examples/java/augmentedimage/
Di Android Studio, Tambahkan GreenMaze.obj ke direktori project assets, sehingga dapat dimuat pada runtime. Salin GreenMaze.obj
dari app > assets > models > green-maze ke app > assets.
Tambahkan dependensi berikut ke file build.gradle
aplikasi.
app/build.gradle
// jbullet library
implementation 'cz.advel.jbullet:jbullet:20101010-1'
// Obj - a simple Wavefront OBJ file loader
// https://github.com/javagl/Obj
implementation 'de.javagl:obj:0.2.1'
Tentukan variabel andyPose
untuk menyimpan posisi pose Andy saat ini.
AugmentedImageRenderer.java
// Create a new pose for the Andy
private Pose andyPose = Pose.IDENTITY;
Ubah AugmentedImageRenderer.java
untuk merender Andy menggunakan variabel andyPose
yang baru.
AugmentedImageRenderer.java
public void draw(
float[] viewMatrix,
float[] projectionMatrix,
AugmentedImage augmentedImage,
Anchor centerAnchor,
float[] colorCorrectionRgba) {
// Use these code to replace previous code for rendering the Andy object
//
// Adjust the Andy's rendering position
// The Andy's pose is at the maze's vertex's coordinate
Pose andyPoseInImageSpace = Pose.makeTranslation(
andyPose.tx() * mazeScaleFactor,
andyPose.ty() * mazeScaleFactor,
andyPose.tz() * mazeScaleFactor);
anchorPose.compose(andyPoseInImageSpace).toMatrix(modelMatrix, 0);
andyRenderer.updateModelMatrix(modelMatrix, 0.05f);
andyRenderer.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, tintColor);
}
Tambahkan fungsi utilitas baru, updateAndyPose()
, untuk menerima update pose Andy.
AugmentedImageRenderer.java
// Receive Andy pose updates
public void updateAndyPose(Pose pose) {
andyPose = pose;
}
Di AugmentedImageActivity.java
, buat objek PhysicsController
yang menggunakan mesin fisika JBullet untuk mengelola semua fungsi terkait fisika.
AugmentedImageActivity.java
import com.google.ar.core.Pose;
// Declare the PhysicsController object
private PhysicsController physicsController;
Di mesin Fisika, sebenarnya kita menggunakan bola kaku untuk merepresentasikan Andy dan memperbarui pose Andy menggunakan pose bola. Panggil PhysicsController
untuk memperbarui sifat fisika setiap kali aplikasi mengenali gambar. Untuk menggerakkan bola seolah-olah di dunia nyata, terapkan gravitasi dunia nyata untuk menggerakkan bola dalam labirin.
AugmentedImageActivity.java
// Update the case clause for TRACKING to call PhysicsController
// whenever the app recognizes an image
private void drawAugmentedImages(
...
case TRACKING:
// Switch to UI Thread to update View
this.runOnUiThread(
new Runnable() {
@Override
public void run() {
fitToScanView.setVisibility(View.GONE);
}
});
// Create a new anchor for newly found images
if (!augmentedImageMap.containsKey(augmentedImage.getIndex())) {
Anchor centerPoseAnchor = augmentedImage.createAnchor(augmentedImage.getCenterPose());
augmentedImageMap.put(
augmentedImage.getIndex(), Pair.create(augmentedImage, centerPoseAnchor));
physicsController = new PhysicsController(this);
} else {
Pose ballPose = physicsController.getBallPose();
augmentedImageRenderer.updateAndyPose(ballPose);
// Use real world gravity, (0, -10, 0), as gravity
// Convert to Physics world coordinate(maze mesh has to be static)
// Use the converted coordinate as a force to move the ball
Pose worldGravityPose = Pose.makeTranslation(0, -10f, 0);
Pose mazeGravityPose = augmentedImage.getCenterPose().inverse().compose(worldGravityPose);
float mazeGravity[] = mazeGravityPose.getTranslation();
physicsController.applyGravityToBall(mazeGravity);
physicsController.updatePhysics();
}
break;
Jalankan aplikasi. Andy kini seharusnya bergerak secara realistis saat Anda memiringkan gambar.
Contoh di bawah ini menggunakan ponsel lain untuk menampilkan gambar. Anda bebas menggunakan perangkat atau alat apa pun yang nyaman bagi Anda, seperti tablet, atau sampul buku cetak, atau sekadar kertas cetak yang ditempelkan pada objek datar.
Selesai. Bersenang-senanglah saat Anda mencoba membuat Andy melewati labirin. Petunjuk: Lebih mudah menemukan titik keluar saat Anda menahan gambar target secara terbalik.
6. Selamat
Selamat, Anda telah mencapai bagian akhir codelab ini, dan dengan demikian Anda telah:
- Membuat dan menjalankan contoh AugmentedImage Java ARCore.
- Memperbarui contoh untuk menampilkan model labirin pada gambar, pada skala yang sesuai.
- Memanfaatkan pose gambar untuk melakukan hal menyenangkan.
Jika ingin membaca ke kode lengkapnya, Anda dapat mendownloadnya di sini.