Membuat Renderable

Renderable adalah model 3D dan terdiri dari vertex, material, tekstur, dan lainnya. Ini dapat dilampirkan ke Node dan dirender sebagai bagian dari scene. Halaman ini menjelaskan cara membuat dan mengubah Renderable.

Membuat dari widget Android

Anda dapat membuat ViewRenderable dari widget Android standar. Ini dirender sebagai kartu datar dalam tampilan.

Untuk membuatnya:

  1. Buat file tata letak dalam res > layout. Contoh:

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
       android:id="@+id/planetInfoCard"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:background="@drawable/rounded_bg"
       android:gravity="center"
       android:orientation="vertical"
       android:padding="6dp"
       android:text="Test"
       android:textAlignment="center" />
    
  2. Build ViewRenderable.

    ViewRenderable.builder()
        .setView(this, R.layout.test_view)
        .build()
        .thenAccept(renderable -> testViewRenderable = renderable);
    

    Versi setView() ini mengambil ID resource dari file tata letak yang tidak di-inflate. Anda juga dapat memanggil setView(View) untuk membuat render dari tampilan yang dibuat secara terprogram.

Semua metode build() di Sceneform menampilkan CompletableFuture. Objek ini dibuat di thread terpisah dan fungsi callback dieksekusi pada thread utama.

Ukuran render dapat didasarkan pada ukuran objek View. Secara default, setiap 250 dp untuk tampilan menjadi 1 meter untuk dapat dirender. Gunakan setSizer(ViewSizer) untuk mengubah cara penghitungan ukuran tampilan.

Perubahan pada tampilan dasar memengaruhi cara perenderan dapat ditampilkan. Node dengan tampilan yang dapat dirender akan terpasang akan mengirimkan peristiwa sentuh ke tampilan, sehingga Anda dapat, misalnya, merespons penekanan tombol.

// update button text when the renderable's node is tapped
Button button = (Button) renderable.getView();
button.setOnClickListener((button) -> button.setText("clicked"));

Membuat dari aset 3D

Sceneform menyediakan alat dan plugin untuk mengonversi file aset 3D (OBJ, FBX, glTF) menjadi aset biner Sceneform (SFB), yang kemudian dapat di-build menjadi ModelRenderable.

Untuk informasi selengkapnya, lihat Mengimpor dan Melihat Pratinjau Aset 3D.

Membuat bentuk sederhana pada waktu proses

Bentuk sederhana seperti kubus, bola, dan silinder dapat dibuat menggunakan ShapeFactory dan MaterialFactory memungkinkan objek yang dapat dirender dari bentuk dan bahan sederhana.

Berikut cara membuat bola merah:

MaterialFactory.makeOpaqueWithColor(this, new Color(android.graphics.Color.RED))
        .thenAccept(
            material -> {
              redSphereRenderable =
                  ShapeFactory.makeSphere(0.1f, new Vector3(0.0f, 0.15f, 0.0f), material); });

Memuat model 3D pada waktu proses

Model 3D yang disimpan sebagai file glTF atau glb dapat dimuat pada runtime tanpa konversi. Hal ini sangat meningkatkan fleksibilitas model yang dirender di aplikasi Anda, tetapi konsekuensinya adalah model ini dibaca saat runtime dan tidak mendapatkan manfaat dari pengoptimalan yang dilakukan selama konversi waktu build ke sfb. Oleh karena itu, sebaiknya uji aplikasi dan model 3D Anda di berbagai perangkat dan kondisi jaringan untuk memastikan pengguna memiliki pengalaman yang baik.

Untuk menggunakan pemuatan aset runtime, Anda perlu menambahkan dependensi pada library aset di app/build.gradle:

  dependencies {
     implementation 'com.google.ar.sceneform:assets:1.15.0'
  }

Class RenderableSource menangani pemuatan file glTF dan membuat objek sumber untuk ModelRenderable.Builder yang membuat objek yang dapat dirender.

Misalnya, memuat model dari internet akan terlihat seperti ini:

 private static final String GLTF_ASSET =
   "https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF/Duck.gltf";

 /* When you build a Renderable, Sceneform loads model and related resources
 * in the background while returning a CompletableFuture.
 * Call thenAccept(), handle(), or check isDone() before calling get().
 */
 ModelRenderable.builder()
    .setSource(this, RenderableSource.builder().setSource(
            this,
            Uri.parse(GLTF_ASSET),
            RenderableSource.SourceType.GLTF2)
            .setScale(0.5f)  // Scale the original model to 50%.
            .setRecenterMode(RenderableSource.RecenterMode.ROOT)
            .build())
    .setRegistryId(GLTF_ASSET)
    .build()
    .thenAccept(renderable -> duckRenderable = renderable)
    .exceptionally(
        throwable -> {
          Toast toast =
              Toast.makeText(this, "Unable to load renderable " +
              GLTF_ASSET, Toast.LENGTH_LONG);
          toast.setGravity(Gravity.CENTER, 0, 0);
          toast.show();
          return null;
        });

Catatan: Untuk mengakses resource dari jarak jauh, Anda perlu menyertakan izin Internet di AndroidManifest.xml:

    <manifest …>
      <!-- Needed to load a glTF from the internet. -->
        <uses-permission android:name="android.permission.INTERNET"/>

    </manifest>

Mengubah render pada waktu proses

Jika beberapa node menggunakan renderable, perubahan pada render tersebut akan berlaku untuk semua node. Untuk menghindari perilaku tersebut, panggil makeCopy() untuk membuat instance yang dapat dirender terpisah. Perhatikan bahwa ini juga memanggil makeCopy() pada setiap materi dalam dapat di-render.

blueSphereRenderable = redSphereRenderable.makeCopy();
blueSphereRenderable.getMaterial().setFloat3(
                  MaterialFactory.MATERIAL_COLOR, new Color(android.graphics.Color.BLUE));