Renderable
是 3D 模型,由頂點、材質、紋理等組成。可以附加至 Node
,並作為場景的一部分進行轉譯。本頁面說明如何建立及修改 Renderable
。
透過 Android 小工具建立
您可以從標準 Android 小工具建立 ViewRenderable
。這些場景會在場景中以平面資訊卡的形式呈現。
如何建立:
建立採用 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" />
建構
ViewRenderable
。ViewRenderable.builder() .setView(this, R.layout.test_view) .build() .thenAccept(renderable -> testViewRenderable = renderable);
這個版本的
setView()
會使用未加載的版面配置檔案資源 ID。您也可以呼叫setView(View)
,透過程式輔助建立的檢視畫面建立可轉譯內容。
場景中的所有 build()
方法都會傳回 CompletableFuture
。物件會建構在另一個執行緒上,並在主執行緒上執行回呼函式。
可轉譯的大小取決於 View
物件的大小。根據預設,檢視畫面每 250dp 就會變為可轉譯的 1 公尺。使用 setSizer(ViewSizer)
變更檢視畫面大小的計算方式。
基礎檢視的變更會影響算繪的顯示方式。附加可顯示檢視畫面的節點會傳送觸控事件給檢視畫面,因此您可以回應按下按鈕的動作。
// update button text when the renderable's node is tapped
Button button = (Button) renderable.getView();
button.setOnClickListener((button) -> button.setText("clicked"));
從 3D 資產建立
Sceneform 提供的工具和外掛程式可將 3D 素材資源檔案 (OBJ、FBX、glTF) 轉換為 Sceneform 二進位檔素材資源 (SFB),然後將其整合至 ModelRenderable
中。
詳情請參閱匯入並預覽 3D 素材資源。
在執行階段建立簡易形狀
您可以使用 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); });
在執行階段載入 3D 模型
儲存為 glTF
或 glb
檔案的 3D 模型可在執行階段載入,無需轉換。這可大幅提高應用程式顯示模型的彈性,但缺點是系統會在執行階段讀取模型,無法對建構期間轉換為 sfb
的最佳化作業有益。因此,建議您在各種裝置和網路條件下測試應用程式和 3D 模型,確保使用者享有絕佳體驗。
如要使用執行階段資產載入功能,您必須在 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));