Создать визуализацию

Renderable — это 3D-модель, состоящая из вершин, материалов, текстур и многого другого. Его можно прикрепить к Node и визуализировать как часть сцены. На этой странице описывается, как создавать и изменять Renderable s.

Создание из виджетов Android

Вы можете создать ViewRenderable из стандартных виджетов Android. Они визуализируются как плоские карты в сцене.

Чтобы создать один:

  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() принимает идентификатор ресурса незаполненного файла макета. Вы также можете вызвать setView(View) для создания визуализируемого объекта из программно созданных представлений.

Все методы build() в Sceneform возвращают CompletableFuture . Объект создается в отдельном потоке, а функция обратного вызова выполняется в основном потоке.

Размер визуализируемого объекта зависит от размера объекта View . По умолчанию каждые 250 dp для вида становятся 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, FBX, glTF) в бинарные активы Sceneform (SFB), которые затем можно встроить в ModelRenderable .

Дополнительные сведения см. в разделе Импорт и предварительный просмотр 3D-объектов .

Создавайте простые фигуры во время выполнения

Простые формы, такие как кубы, сферы и цилиндры, можно создавать с помощью ShapeFactory и MaterialFactory , позволяющих создавать визуализируемые объекты из простых форм и материалов.

Вот как создать красную сферу:

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-модели во время выполнения

3D-модели, хранящиеся в виде файлов glTF или glb , можно загружать во время выполнения без преобразования. Это значительно повышает гибкость моделей, отображаемых в вашем приложении, но компромисс заключается в том, что модель считывается во время выполнения и не получает преимуществ от оптимизации, выполняемой во время преобразования времени сборки в 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));