Criar um Renderable

Um Renderable é um modelo 3D e consiste em vértices, materiais, texturas e muito mais. Ele pode ser anexado a uma Node e renderizado como parte de uma cena. Nesta página, descrevemos como criar e modificar Renderables.

Criar a partir de widgets do Android

Você pode criar um ViewRenderable usando widgets padrão do Android. Eles são renderizados como cards planos na cena.

Para criar uma, faça o seguinte:

  1. Crie um arquivo de layout em res > layout. Exemplo:

    <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. Crie a ViewRenderable.

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

    Esta versão da setView() usa o ID do recurso do arquivo de layout não inflado. Você também pode chamar setView(View) para criar um elemento de renderização a partir de visualizações criadas de maneira programática.

Todos os métodos build() no Sceneform retornam um CompletableFuture. O objeto é criado em uma linha de execução separada e a função de callback é executada na linha de execução principal.

O tamanho do renderable é baseado no tamanho do objeto View. Por padrão, cada 250 dp da visualização se torna 1 m para a renderização. Use setSizer(ViewSizer) para mudar o tamanho da visualização.

As mudanças na visualização subjacente afetam a forma como o elemento de renderização é exibido. Os nós com uma visualização renderizada anexada enviam eventos de toque para a visualização. Assim, você pode, por exemplo, responder a um botão.

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

Criar usando um recurso 3D

O Sceneform fornece ferramentas e plug-ins para converter arquivos de recursos 3D (OBJ, KTX, glTF) em recursos binários de cenário (SFB, na sigla em inglês), que podem ser integrados a um ModelRenderable.

Para mais informações, consulte Importar e visualizar recursos 3D.

Criar formas simples no ambiente de execução

Formas simples, como cubos, esferas e cilindros, podem ser criadas usando ShapeFactory e MaterialFactory. Permitem que você crie objetos renderizáveis de formas e materiais simples.

Veja como criar uma esfera vermelha:

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

Carregar modelos 3D no momento da execução

Os modelos 3D armazenados como arquivos glTF ou glb podem ser carregados no momento da execução sem conversão. Isso melhora muito a flexibilidade dos modelos renderizados no aplicativo, mas a desvantagem é que o modelo é lido no momento da execução e não se beneficia da otimização feita durante a conversão do tempo de compilação para sfb. Por esse motivo, é recomendável testar seu aplicativo e seus modelos 3D em uma grande variedade de dispositivos e condições de rede para garantir que os usuários tenham uma ótima experiência.

Para usar o carregamento de recursos de ambiente de execução, você precisa adicionar a dependência à biblioteca de recursos no app/build.gradle:

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

A classe RenderableSource processa o carregamento do arquivo glTF e a criação de um objeto de origem para ModelRenderable.Builder, que cria o objeto renderizável.

Por exemplo, o carregamento de um modelo pela Internet tem esta aparência:

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

Observação: para acessar recursos remotamente, inclua a permissão de Internet no seu AndroidManifest.xml:

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

   
</manifest>

Modificar renderizações no ambiente de execução

Se vários nós usarem o renderable, as alterações nele poderão ser aplicadas a todos os nós. Para evitar esse comportamento, chame makeCopy() para criar uma instância renderizável separada. Isso também chama makeCopy() em todos os materiais no renderizador.

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