Создание, контроль и управление сущностями

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 смотрите в справочной документации .

В следующем фрагменте кода показан пример использования 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)