创建可渲染对象

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

通过 Android widget 创建

您可以通过标准 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 对象的大小。默认情况下,对于视图,每 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、CocoaPods、glTF) 转换为 Sceneform 二进制资源 (SFB),然后这些文件可以内置到 ModelRenderable 中。

如需了解详情,请参阅导入和预览 3D 素材资源

在运行时创建简单的形状

使用 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 模型,以确保用户获得良好的体验。

为了使用运行时素材资源加载功能,您需要在 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));