Cómo crear un Renderable

Un Renderable es un modelo 3D y consta de vértices, materiales, texturas y mucho más. Se puede adjuntar a un objeto Node y renderizar como parte de una escena. En esta página, se describe cómo crear y modificar Renderable.

Crear a partir de widgets de Android

Puedes crear una ViewRenderable a partir de widgets estándar de Android. Estos se representan como tarjetas planas en la escena.

Para crear una, sigue estos pasos:

  1. Crea un archivo de diseño en res > layout. Por ejemplo:

    <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. Compila el ViewRenderable.

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

    Esta versión de setView() toma el ID de recurso del archivo de diseño aumentado. También puedes llamar a setView(View) para crear un renderizado a partir de vistas creadas de manera programática.

Todos los métodos build() en Sceneform muestran un CompletableFuture. El objeto se compila en un subproceso independiente y la función de devolución de llamada se ejecuta en el subproceso principal.

El tamaño del renderizado se basa en el tamaño del objeto View. De forma predeterminada, cada 250 dp de la vista se convierte en 1 metro para el elemento que se puede renderizar. Usa setSizer(ViewSizer) para cambiar la forma en que se calcula el tamaño de la vista.

Los cambios en la vista subyacente afectan la forma en que se muestra. Los nodos con una vista procesable adjunta enviarán eventos táctiles a la vista, por lo que puedes, por ejemplo, responder cuando se presiona un botón.

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

Crear a partir de un elemento 3D

Sceneform proporciona herramientas y complementos para convertir archivos 3D de elementos (OBJ, FBX y glTF) en elementos binarios de Sceneform (SFB), que luego se pueden compilar en un objeto ModelRenderable.

Para obtener más información, consulta Importar y obtener vista previa de elementos 3D.

Crea formas simples en el tiempo de ejecución

Las formas simples, como cubos, esferas y cilindros, se pueden crear con ShapeFactory y MaterialFactory te permiten crear objetos renderizados a partir de formas y materiales simples.

Para crear una esfera roja, sigue estos pasos:

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

Cargar modelos 3D durante el tiempo de ejecución

Los modelos en 3D almacenados como archivos glTF o glb se pueden cargar en el entorno de ejecución sin conversión. Esto mejora en gran medida la flexibilidad de los modelos procesados en tu aplicación, pero la desventaja es que el modelo se lee en el entorno de ejecución y no se beneficia de la optimización que se realiza durante la conversión del tiempo de compilación a sfb. Debido a esto, se recomienda que pruebes tu aplicación y tus modelos 3D en una amplia variedad de dispositivos y condiciones de red para asegurarte de que tus usuarios tengan una gran experiencia.

Para usar la carga de elementos del entorno de ejecución, debes agregar la dependencia en la biblioteca de elementos en app/build.gradle:

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

La clase RenderableSource controla la carga del archivo glTF y la creación de un objeto de origen para ModelRenderable.Builder que crea el objeto que se puede renderizar.

Por ejemplo, cargar un modelo desde Internet tiene el siguiente aspecto:

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

Nota: Para acceder a los recursos de forma remota, debes incluir el permiso de Internet en el archivo AndroidManifest.xml:

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

    </manifest>

Modifica los elementos que se pueden renderizar durante el tiempo de ejecución

Si varios nodos usan el elemento que se puede renderizar, los cambios se aplicarán a todos ellos. Para evitar ese comportamiento, llama a makeCopy() a fin de crear una instancia de procesamiento separada. Ten en cuenta que esto también llama a makeCopy() en todos los materiales del renderizado.

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