Jetpack XR SDK позволяет использовать Jetpack SceneCore для создания, контроля и управления экземплярами Entity
, такими как 3D-модели , стереоскопическое видео и PanelEntity
, с помощью Jetpack SceneCore.
Jetpack SceneCore использует два распространенных архитектурных шаблона для поддержки 3D-разработки: граф сцены и систему сущностей-компонентов (ECS).
Используйте граф сцены для создания объектов и управления ими.
Чтобы создавать объекты в трехмерном пространстве и управлять ими, вы должны использовать API сеанса Jetpack SceneCore, чтобы получить доступ к графу сцены. Граф сцены соответствует реальному миру пользователя и позволяет организовывать 3D-объекты, такие как панели и 3D-модели, в иерархическую структуру и сохранять состояние этих объектов.
Получив доступ к графу сцены, вы можете использовать API в Jetpack Compose для XR для создания пространственного пользовательского интерфейса (например, SpatialPanel
и Orbiter
) в графе сцены. Для 3D-контента, такого как 3D-модели, вы можете получить прямой доступ к сеансу. Дополнительную информацию см. в разделе «О ActivitySpace» на этой странице.
Система компонентов сущности
Система «сущность-компонент» следует принципу композиции, а не наследования. Вы можете расширить поведение сущностей, присоединив компоненты, определяющие поведение, что позволяет применять одно и то же поведение к различным типам сущностей. Дополнительные сведения см. в разделе Добавление общего поведения к сущностям на этой странице.
О ActivitySpace
Каждый Session
имеет ActivitySpace
, который автоматически создается с помощью Session
. ActivitySpace
— это Entity
верхнего уровня в графе сцены.
ActivitySpace представляет собой трехмерное пространство с правосторонней системой координат (ось X указывает вправо, ось Y указывает вверх, а ось Z назад относительно начала координат) и счетчиками для единиц измерения, соответствующих реальный мир. Происхождение ActivitySpace
несколько произвольно (поскольку пользователи могут сбросить положение ActivitySpace
в реальном мире), поэтому рекомендуется располагать контент относительно друг друга, а не относительно источника.
Работа с сущностями
Сущности занимают центральное место в SceneCore. Почти все, что пользователь видит и с чем взаимодействует, — это объекты, представляющие панели, 3D-модели и многое другое.
Поскольку ActivitySpace
является узлом верхнего уровня графа сцены, по умолчанию все новые сущности помещаются непосредственно в ActivitySpace
. Вы можете перемещать объекты по графу сцены, вызывая setParent
или addChild
.
У сущностей есть некоторые варианты поведения по умолчанию, которые являются универсальными для всех сущностей, например изменение положения, поворот или видимость. Определенные подклассы Entity
, такие как GltfEntity
, имеют дополнительное поведение, поддерживающее подкласс.
Манипулировать сущностями
Когда вы вносите изменение в свойство Entity
, принадлежащее базовому классу Entity
, это изменение будет распространяться на все его дочерние элементы. Например, корректировка Pose
родительской Entity
приводит к тому, что все ее дочерние элементы имеют одинаковую настройку. Внесение изменений в дочернюю Entity
не влияет на ее родительскую сущность.
Pose
представляет расположение и вращение Сущности в трехмерном пространстве. Местоположение представляет собой Vector3
состоящий из числовых позиций x, y, z. Вращение представлено Quaternion
. Положение Entity
всегда относительно ее родительской сущности. Другими словами, Entity
, позиция которого равна (0, 0, 0), будет помещен в начало координат его родительского объекта.
//place the entity forward 2 meters
val modelPosition = Vector3(0f, 0f, -2f)
//rotate the entity by 180 degrees on the up axis (upside-down)
val newOrientation = Quaternion.fromEulerAngles(0f, 0f, 180f)
//update the position and rotation on the entity
entity.setPose(Pose(newPosition, newOrientation))
Чтобы изменить видимость Entity
, используйте setHidden
.
//hide the entity
entity.setHidden(true)
Чтобы изменить размер Entity
, сохраняя при этом ее общую форму, используйте setScale
.
//double the size of the entity
entity.setScale(2f)
Добавьте общее поведение к сущностям
Чтобы добавить к сущностям общее поведение, можно использовать следующие компоненты:
-
MovableComponent
: позволяет пользователю перемещать объекты. -
ResizableComponent
: позволяет пользователю изменять размер объектов в соответствии с шаблонами пользовательского интерфейса. -
InteractableComponent
: позволяет захватывать события ввода для пользовательских взаимодействий.
Создание экземпляров компонентов должно выполняться с помощью соответствующего метода создания в классе Session
. Например, чтобы создать ResizableComponent
, вызовите session.createResizableComponent()
.
Чтобы добавить определенное поведение компонента к Entity
используйте метод addComponent()
.
Используйте MovableComponent, чтобы сделать Entity перемещаемым пользователем.
MovableComponent
позволяет пользователю перемещать Entity
. Вы также можете указать, может ли объект быть привязан к типу поверхности, например, к горизонтальным или вертикальным поверхностям, или к определенным семантическим поверхностям, например к столу, стене или потолку. Чтобы указать параметры привязки, укажите набор AnchorPlacement
при создании MovableComponent
.
Вот пример объекта, который можно перемещать и привязывать к любой вертикальной поверхности и только к горизонтальным поверхностям пола и потолка.
val anchorPlacement = AnchorPlacement.createForPlanes(
planeTypeFilter = setOf(PlaneSemantic.FLOOR, PlaneSemantic.TABLE),
planeSemanticFilter = setOf(PlaneType.VERTICAL))
val movableComponent = xrSession.createMovableComponent(
systemMovable = false,
scaleInZ = false,
anchorPlacement = setOf(anchorPlacement)
)
entity.addComponent(movableComponent)
Используйте ResizableComponent, чтобы сделать Entity изменяемым пользователем.
ResizableComponent
позволяет пользователям изменять размер Entity
. ResizableComponent
включает в себя подсказки визуального взаимодействия, которые предлагают пользователю изменить размер Entity
. При создании ResizeableComponent
вы можете указать минимальный или максимальный размер (в метрах). У вас также есть возможность указать фиксированное соотношение сторон при изменении размера, чтобы ширина и высота изменялись пропорционально друг другу.
Вот пример использования ResizableComponent
с фиксированным соотношением сторон:
val resizableComponent = xrSession.createResizableComponent()
resizableComponent.minimumSize = Dimensions(177f, 100f, 1f )
resizableComponent.fixedAspectRatio = 16f / 9f //Specify a 16:9 aspect ratio
entity.addComponent(resizableComponent)
Используйте InteractableComponent для захвата событий ввода пользователя.
InteractableComponent
позволяет захватывать события ввода от пользователя, например, когда пользователь взаимодействует с Entity
или наводит на него курсор. При создании InteractableComponent
вы должны указать InputEventListener
для получения входных событий. Когда пользователь выполняет какое-либо действие ввода, метод onInputEvent
вызывается с конкретной входной информацией, указанной в параметре InputEvent
.
-
InputEvent.action
указывает тип ввода, например наведение или нажатие (ACTION_DOWN) на объекте. -
InputEvent.source
указывает, откуда поступил ввод, например ввод от руки или контроллера. -
InputEvent.pointerType
указывает, поступил ли ввод от правой или левой руки.
Полный список всех констант InputEvent
смотрите в справочной документации .
В следующем фрагменте кода показан пример использования InteractableComponent
для увеличения размера сущности правой рукой и уменьшения левой рукой.
private val executor by lazy { Executors.newSingleThreadExecutor() }
val interactableComponent = xrSession.createInteractableComponent(executor) {
//when the user disengages with the entity with their hands
if (it.source == InputEvent.SOURCE_HANDS && it.action == InputEvent.ACTION_UP) {
// increase size with right hand and decrease with left
if (it.pointerType == InputEvent.POINTER_TYPE_RIGHT){
entity.setScale(1.5f)
} else if (it.pointerType == InputEvent.POINTER_TYPE_LEFT){
entity.setScale(0.5f)
}
}
}
entity.addComponent(interactableComponent)