Utwórz szablon do renderowania

Renderable to model 3D składający się z wierzchołków, materiałów, tekstur i innych elementów. Można go dołączyć do elementu Node i renderować jako część sceny. Na tej stronie opisaliśmy, jak tworzyć i modyfikować Renderable.

Twórz widżety na Androidzie

ViewRenderable możesz utworzyć ze standardowych widżetów na Androida. Są one renderowane jako płaskie karty w scenie.

Aby to zrobić:

  1. Utwórz plik układu w res > układ. Przykład:

    <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. Utwórz ViewRenderable.

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

    Ta wersja narzędzia setView() pobiera identyfikator zasobu nierozszerzonego pliku układu. Możesz też wywołać metodę setView(View), aby utworzyć renderowanie w widokach utworzonych automatycznie.

Wszystkie metody build() w Sceneform zwracają CompletableFuture. Obiekt jest oparty na oddzielnym wątku, a funkcja wywołania zwrotnego jest wykonywana w głównym wątku.

Rozmiar renderowanego elementu zależy od rozmiaru obiektu View. Domyślnie każde 250 dp w widoku wynosi 1 metr na możliwość renderowania. Kliknij setSizer(ViewSizer), aby zmienić sposób obliczania rozmiaru widoku danych.

Zmiany w widoku bazowym wpływają na sposób renderowania renderowania. Węzły z załączonym widokiem renderują zdarzenia dotknięcia do widoku, dzięki czemu możesz na przykład odpowiedzieć na naciśnięcie przycisku.

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

Tworzenie na podstawie zasobu 3D

Sceneform udostępnia narzędzia i wtyczki do konwertowania plików zasobów 3D (OBJ, Anthos, glTF) na zasoby binarne Sceneform, które można następnie umieścić w narzędziu ModelRenderable.

Więcej informacji znajdziesz w artykule o importowaniu i wyświetlaniu podglądu zasobów 3D.

Tworzenie prostych kształtów w czasie działania

Proste kształty, takie jak sześciany, sfery i cylindry, można tworzyć za pomocą ShapeFactory i MaterialFactory, tworząc bezpretensjonalne obiekty z prostych kształtów i materiałów.

Jak utworzyć czerwoną sferę:

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

Wczytywanie modeli 3D podczas działania

Modele 3D przechowywane jako glTF lub glb mogą być ładowane w czasie działania bez konwersji. Znacznie zwiększa to elastyczność modeli renderowanych w aplikacji, ale kompromis polega na tym, że model jest odczytywany w czasie działania i nie przynosi korzyści z optymalizacji wykonywanej podczas konwersji w czasie kompilacji do sfb. Dlatego zalecamy przetestowanie aplikacji i modeli 3D na różnych urządzeniach i w różnych warunkach sieciowych, aby mieć pewność, że będą one wygodne dla użytkowników.

Aby korzystać z wczytywania zasobów środowiska wykonawczego, musisz dodać zależność do biblioteki zasobów w interfejsie app/build.gradle:

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

Klasa RenderableSource wczytuje plik glTF i tworzy obiekt źródłowy dla ModelRenderable.Builder, który tworzy obiekt z możliwością renderowania.

Na przykład załadowanie modelu z internetu wygląda tak:

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

Uwaga: aby uzyskać dostęp zdalny do zasobów, musisz uwzględnić uprawnienie Internet w pliku AndroidManifest.xml:

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

   
</manifest>

Modyfikowanie renderowania w czasie działania

Jeśli renderowanych jest wiele węzłów, zmiany wprowadzone w tym mechanizmie będą stosowane do wszystkich węzłów. Aby uniknąć tego problemu, wywołaj makeCopy(), aby utworzyć oddzielną instancję do renderowania. Spowoduje to też wywołanie metody makeCopy() w przypadku wszystkich materiałów w renderowaniu.

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