สร้างการแสดงผลได้

A Renderable คือโมเดล 3 มิติและประกอบด้วยจุดยอดมุม วัสดุ พื้นผิว และอื่นๆ และสามารถแนบไว้กับ Node และแสดงผลเป็นส่วนหนึ่งของฉาก หน้านี้จะอธิบายวิธีสร้างและแก้ไข Renderable

สร้างจากวิดเจ็ต Android

คุณสามารถสร้าง ViewRenderable ได้จากวิดเจ็ต Android มาตรฐาน ซึ่งจะแสดงผลเป็นการ์ดแบนในฉาก

วิธีสร้างลิงก์

  1. สร้างไฟล์เลย์เอาต์ใน res >Layout เช่น

    <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. สร้าง ViewRenderable

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

    setView() เวอร์ชันนี้ใช้รหัสทรัพยากรของไฟล์เลย์เอาต์ที่ไม่สูงกว่าความเป็นจริง หรือจะเรียก setView(View) เพื่อสร้างการแสดงภาพจากมุมมองแบบเป็นโปรแกรมก็ได้

เมธอด build() ทั้งหมดใน Sceneform จะแสดงผล CompletableFuture ออบเจ็กต์สร้างขึ้นในเทรดแยกต่างหากและมีการเรียกใช้ฟังก์ชันเรียกกลับในเทรดหลัก

ขนาดของการแสดงผลได้จะขึ้นอยู่กับขนาดของออบเจ็กต์ View โดยค่าเริ่มต้น ทุกๆ 250 dp สําหรับมุมมองจะกลายเป็น 1 เมตรสําหรับการแสดงผล ใช้ setSizer(ViewSizer) เพื่อเปลี่ยนแปลงวิธีคํานวณขนาดมุมมอง

การเปลี่ยนแปลงมุมมองที่สําคัญจะมีผลต่อวิธีแสดงผล โหนดที่มีการดูการแสดงผลซึ่งแนบได้จะส่งเหตุการณ์การแตะไปยังมุมมอง เพื่อให้คุณสามารถ เช่น ตอบสนองต่อการกดปุ่ม

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

สร้างจากเนื้อหา 3 มิติ

Sceneform ให้บริการเครื่องมือและปลั๊กอินสําหรับแปลงไฟล์เนื้อหา 3D (OBJ, FBX, glTF) เป็นเนื้อหาไบนารีของ Sceneform (SFB) ซึ่งจะสร้างลงใน ModelRenderable ได้

สําหรับข้อมูลเพิ่มเติม โปรดดูที่นําเข้าและดูตัวอย่างเนื้อหา 3 มิติ

สร้างรูปร่างง่ายๆ ในช่วงรันไทม์

คุณสามารถสร้างรูปร่างง่ายๆ เช่น ลูกบาศก์ ทรงกลม และทรงกระบอกโดยใช้ ShapeFactory และ MaterialFactory ให้สร้างวัตถุที่แสดงผลได้จากรูปร่างและวัสดุที่ไม่ซับซ้อน

วิธีสร้างวงกลมสีแดงมีดังนี้

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

โหลดโมเดล 3 มิติขณะรันไทม์

โมเดล 3 มิติที่จัดเก็บเป็นไฟล์ glTF หรือ glb สามารถโหลดได้ขณะรันไทม์โดยไม่มีการแปลง การดําเนินการนี้จะช่วยเพิ่มความยืดหยุ่นของโมเดลที่แสดงในแอปพลิเคชันได้อย่างมาก แต่ข้อดีคือระบบจะอ่านโมเดลในช่วงรันไทม์และไม่ได้รับประโยชน์จากการเพิ่มประสิทธิภาพที่เกิดขึ้นระหว่างการแปลงเวลาบิลด์เป็น sfb เราจึงขอแนะนําให้ทดสอบแอปพลิเคชันและโมเดล 3 มิติบนอุปกรณ์และสภาพเครือข่ายที่หลากหลายเพื่อให้มั่นใจว่าผู้ใช้จะได้รับประสบการณ์การใช้งานที่ยอดเยี่ยม

หากต้องการใช้การโหลดเนื้อหารันไทม์ คุณต้องเพิ่มทรัพยากร Dependency ในไลบรารีชิ้นงานใน app/build.gradle ดังนี้

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

คลาส RenderableSource จะจัดการการโหลดไฟล์ glTF และสร้างออบเจ็กต์ต้นทางสําหรับ ModelRenderable.Builder ซึ่งสร้างออบเจ็กต์ที่แสดงผลได้

เช่น การโหลดโมเดลจากอินเทอร์เน็ตจะมีลักษณะดังนี้

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

หมายเหตุ: หากต้องการเข้าถึงทรัพยากรจากระยะไกล คุณต้องรวมสิทธิ์อินเทอร์เน็ตใน AndroidManifest.xml ของคุณดังนี้

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

    </manifest>

แก้ไขการแสดงภาพได้ในรันไทม์

หากโหนดหลายรายการใช้การแสดงผลได้ การเปลี่ยนแปลงที่แสดงได้จะมีผลกับโหนดทั้งหมด เพื่อหลีกเลี่ยงพฤติกรรมดังกล่าว ให้เรียกใช้ makeCopy() เพื่อสร้างอินสแตนซ์ที่แสดงผลได้แยกต่างหาก โปรดทราบว่าโค้ดนี้เรียก makeCopy() บนทุกเนื้อหาที่แสดงผลได้

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