Прежде чем настраивать 3D-модель, ее нужно добавить в приложение. После этого вы сможете улучшить визуальное и интерактивное восприятие, изменив внешний вид и движения модели.
Например, вы можете воспроизводить и контролировать встроенные анимации glTF, получать доступ к узлам, составляющим модель, и перемещать их, а также загружать собственные текстуры и определять свойства материалов, чтобы переопределять внутренние сетки. Эти возможности позволяют динамически изменять внешний вид и поведение объекта во время выполнения.
3D-объекты в Android XR
Jetpack XR SDK поддерживает открытый стандарт glTF 2.0 от Khronos Group для 3D-моделей и отрисовывает эти объекты с помощью физически корректной визуализации (PBR), описанной в стандарте glTF 2.0 (вместе с поддерживаемыми расширениями). glTF (Graphics Library Transmission Format) – это стандартный формат файлов для передачи и загрузки 3D-сцен и моделей. Модель glTF состоит из иерархической структуры внутренних компонентов.
Вот основные компоненты, которые вам нужно знать:
- Узлы. Определяют структуру и иерархию модели. У каждого узла могут быть собственные значения положения, поворота и масштаба.
- Сетки. Трехмерная геометрия, которая формирует форму 3D-объекта.
- Материалы. Они определяют внешний вид сеток, например их цвет, шероховатость или реакцию на освещение.
- Текстуры. Объект изображения, например файл PNG, который можно применить к поверхности 3D-модели, чтобы создать пользовательские узоры, цвет, детализацию или другие визуальные эффекты.
В Jetpack Compose для XR эти файлы можно отрисовать с помощью SpatialGltfModel и отслеживать статус загрузки с помощью SpatialGltfModelState.
Подробнее о том, как добавить 3D-модели в приложение…
Как управлять узлами: позы и поворот
Чтобы управлять отдельными частями модели и изменять ее свойства, например поворот или позу, вам нужно запросить внутренний объект nodes модели GLTF с помощью SpatialGltfModelState.
// Retrieve the list of nodes (individual components/meshes) defined within the glTF model. val entityNodes = modelState.nodes // Find a specific node by name to apply modifications, such as material overrides. val node = entityNodes.find { it.name == "node_name" }
После того как вы найдете нужный узел, вы можете задать его параметр localPose, чтобы изменить его трехмерное положение и поворот относительно родительского узла GltfModelNode, или использовать параметр modelPose, чтобы задать положение относительно корневого узла GltfModelEntity. Аналогичным образом можно использовать localScale/modelScale, чтобы изменить масштаб модели относительно родительского объекта или корня.
LaunchedEffect(node, degrees) { val rotation = Quaternion.fromEulerAngles(degrees, 0f, degrees) node?.let { it.localPose = Pose(it.localPose.translation, rotation) } }
Как настроить свойства материалов 3D-модели
Вы можете изменять атрибуты материалов во время выполнения, чтобы динамически менять внешний вид объекта в зависимости от действий пользователя или текущего состояния приложения.
В Jetpack XR для создания и обработки этих материалов используются классы KhronosPbrMaterial и KhronosUnlitMaterial. Как следует из названия, KhronosUnlitMaterials не освещаются и не зависят от освещения сцены.
KhronosPbrMaterial позволяет настраивать больше свойств, например цвет блеска, степень металличности или шероховатости объекта, а также излучает ли он свет.
Подробнее о поддерживаемых свойствах и настраиваемых параметрах Android XR можно узнать в справочной документации. Чтобы лучше понять эти свойства, ознакомьтесь с глоссарием Khronos.
Чтобы настроить свойства материала 3D-модели, сначала создайте новый материал с помощью KhronosPbrMaterial. Вам нужно задать подходящее значение AlphaMode, чтобы добиться нужного внешнего вида:
Затем укажите свойства, которые нужно изменить. В примере ниже интерфейс setBaseColorFactor используется для изменения основного цвета сетки на фиолетовый. Для этого метода требуется Vector4, где компоненты x, y, z и w соответствуют значениям RGBA (красный, зеленый, синий и альфа-канал):
// Maintain a reference to the custom material to avoid re-creating it on every recomposition. var pbrMaterial by remember { mutableStateOf<KhronosPbrMaterial?>(null) } // Create and apply the custom material once the session is ready and the target node is available. LaunchedEffect(node) { val material = KhronosPbrMaterial.create( session = xrSession, alphaMode = AlphaMode.OPAQUE ).also { pbrMaterial = it // Apply a base color factor (RGBA) to change the color of the model. it.setBaseColorFactor( Vector4( x = 0.5f, y = 0.0f, z = 0.5f, w = 1.0f ) ) }
Как загрузить пользовательские текстуры для 3D-модели
Texture – это объект изображения, который можно применить к поверхности 3D-модели, чтобы добавить цвет, детали или другую информацию о поверхности. Jetpack XR Texture API позволяет асинхронно загружать данные изображений, например файлы PNG, из папки /assets/ приложения.
При загрузке текстуры можно указать TextureSampler, который определяет, как она будет отрисовываться. Сэмплер определяет свойства фильтрации (для случаев, когда текстура выглядит меньше или больше исходного размера) и режимы переноса (для обработки координат за пределами стандартного диапазона [0, 1]). Texture должен быть назначен KhronosPbrMaterial, чтобы оказывать визуальный эффект на 3D-модель.
Чтобы загрузить собственную текстуру, сначала сохраните файл изображения в папку /assets/. Рекомендуем также создать в этой папке подкаталог textures.
После того как вы сохраните файл в нужном каталоге, создайте текстуру с помощью API Texture. Здесь же можно при необходимости добавить необязательный параметр TextureSampler.
В этом примере применяется текстура окклюзии и задается ее интенсивность:
LaunchedEffect(node) { val material = KhronosPbrMaterial.create( session = xrSession, alphaMode = AlphaMode.OPAQUE ).also { pbrMaterial = it // Load a texture val texture = Texture.create( session = xrSession, path = Path("textures/texture_name.png") ) // Set the texture and configure occlusion to define how the material surface handles ambient lighting. it.setOcclusionTexture( texture = texture, strength = 1.0f ) } node?.setMaterialOverride( material = material ) }
Как применять материалы и текстуры к 3D-объектам
Чтобы применить новый материал или текстуру, переопределите существующий материал для определенного узла в файле glTF node. Для этого вызовите метод setMaterialOverride:
node?.setMaterialOverride( material = material )
Чтобы удалить созданные материалы, вызовите метод clearMaterialOverride для узла, который был переопределен ранее. 3D-модель вернется к настройкам по умолчанию:
if (removeMaterial) { node?.clearMaterialOverride() }
Как анимировать 3D-модели
В трехмерные модели можно встраивать анимацию. Внутренние анимации используют сэмплеры, чтобы задавать время и значения движения, и каналы, чтобы связывать эти движения с отдельными узлами и сетками. В Jetpack XR SDK поддерживаются скелетная анимация и анимация материалов, созданные с помощью KHR_animation_pointer расширения glTF.
Анимацией можно управлять только с помощью GltfAnimation SceneCore с GltfModelEntity. Чтобы добавить этот объект в макет Compose для XR, вам нужно использовать SceneCoreEntity вместо SpatialGltfModel.
Укажите название нужного трека из списка animations в файле GltfModelEntity. Используйте GltfAnimationStartOptions, чтобы управлять воспроизведением анимации. При необходимости вы можете указать скорость, время поиска и то, должна ли анимация повторяться:
val animation = gltfEntity.getAnimations().find { it.name == "Walk" } animation?.start(GltfAnimationStartOptions(shouldLoop = true))
glTF и логотип glTF являются товарными знаками Khronos Group Inc.