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 Renderable
s.
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:
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" />
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 chamarsetView(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));