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

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