Renderable
— это 3D-модель, состоящая из вершин, материалов, текстур и многого другого. Его можно прикрепить к Node
и визуализировать как часть сцены. На этой странице описывается, как создавать и изменять Renderable
s.
Создание из виджетов Android
Вы можете создать ViewRenderable
из стандартных виджетов Android. Они визуализируются как плоские карты в сцене.
Чтобы создать один:
Создайте файл макета в 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" />
Создайте
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));