创建可渲染对象

可渲染对象是一种 3D 模型,包含顶点、材料和纹理,等等。 它可以连接到 Node 并作为场景的一部分渲染。 本页将介绍如何创建和修改可渲染对象。

从 Android 微件创建

您可以从标准的 Android 微件创建 ViewRenderable。 它们将在场景中渲染为平坦的卡片。

要创建可渲染对象,请执行以下操作:

  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() 将获取未抬高的布局文件的资源 ID。 您还可以调用 setView(View),从通过编程方式创建的视图创建可渲染对象。

Sceneform 中的所有 build() 函数都可以返回 CompletableFuture。 此对象在单独的线程上构建,回调函数在主线程上执行。

可渲染对象的大小基于 View 对象的大小。 默认情况下,视图的每 10px 代表可渲染对象的 1cm。 调用 setPixelsToMeters() 可以更改转换比率。

对底层视图的更改会影响可渲染对象的显示方式。 连接了视图可渲染对象的节点会将触摸事件分派给视图,以便让您响应按钮按下操作。

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

从 3D asset 创建

Sceneform 提供了多种工具和插件,用于将 3D asset 文件(OBJ、FBX、glTF)转换成 Sceneform 二进制 asset (SFB),此 asset 随后可以构建到 ModelRenderable 中。

如需了解详细信息,请参阅导入和预览 3D asset

在运行时创建简单的形状

可以使用 ShapeFactoryMaterialFactory 创建立方体、球体和圆柱体等简单的形状,这些形状让您可以从简单的形状和材料创建可渲染对象。

以下代码可以创建一个红色的球体:

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 模型

运行时,无需转换即可加载以 glTFglb 文件形式存储的 3D 模型。 这大大提升了您的应用中渲染的模型的灵活性,但不利的一点是,模型将在运行时读取,并且不会受益于构建时转换成 sfb 期间进行的优化。 因此,建议您在各种设备和网络条件下测试您的应用和 3D 模型,以便确保您的用户获得出色的体验。

要使用运行时 asset 加载,您需要在 asset 库的 app/build.gradle 中添加依赖项:

  dependencies {
     implementation 'com.google.ar.sceneform:assets:1.5.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));