ARCore для Jetpack XR позволяет приложениям работать с базовыми концепциями дополненной реальности (AR), используя низкоуровневые примитивы понимания сцены и отслеживание движения. Используйте ARCore для Jetpack XR при создании AR-приложений, и вам необходимо использовать плоские данные или привязывать контент к фиксированному местоположению в пространстве.
Понимание жизненного цикла сеанса
Доступ ко всем объектам, отслеживаемым ARCore для Jetpack XR, должен осуществляться через сеанс . Подобно жизненному циклу Activity , объекты Session также имеют жизненный цикл, который должен поддерживаться в соответствии с использованием вашим приложением функций объекта Session. Если ваше приложение содержит одно действие с поддержкой XR, рассмотрите возможность управления жизненным циклом сеанса с помощью компонента, поддерживающего жизненный цикл .
Создать сеанс
Прежде чем использовать сеанс, его необходимо создать. Для создания сеанса пользователю необходимо предоставить разрешение android.permission.SCENE_UNDERSTANDING
вашему приложению .
Чтобы создать сеанс:
when (val result = Session.create(owner)) {
is SessionCreateSuccess -> {
session = result.session
}
is SessionCreatePermissionsNotGranted -> {
// Request android.permission.SCENE_UNDERSTANDING.
}
}
См. SessionCreateResult
чтобы узнать, почему сеанс не может быть создан.
Возобновить сеанс
Возобновление сеанса следует выполнять, когда ваше приложение готово обрабатывать изменения состояния из ARCore для Jetpack XR. Во многих случаях это делается в обратном вызове onResume()
вашего Activity, но ваше приложение может захотеть отложить обработку до взаимодействия с пользователем.
В следующем фрагменте кода показан пример возобновления сеанса.
when (val result = session.resume()) {
is SessionResumeSuccess -> {
// Session has been created successfully.
// Attach any successful handlers here.
}
is SessionResumePermissionsNotGranted -> {
// Request android.permission.SCENE_UNDERSTANDING.
}
См. SessionResumeResult
, чтобы узнать, почему сеанс может не возобновиться.
Приостановить сеанс
Когда ваша активность переходит в фоновый режим, приостановите сеанс с помощью Session.pause()
. Приостановка сеанса временно прекращает отслеживание до возобновления сеанса, сохраняя состояние системы восприятия.
Уничтожить сеанс
Чтобы навсегда удалить сеанс, используйте Session.destroy()
. Это освобождает ресурсы, используемые сеансом, и уничтожает все состояния сеанса.
Получить состояние воспринимаемых плоскостей
ARCore для Jetpack XR предоставляет состояние самолетов через StateFlow
, который генерирует состояние самолетов. Подписка на самолеты в сеансе уведомляет ваше приложение о добавлении, обновлении или удалении самолетов.
Plane.subscribe(session).collect { planes ->
// Planes have changed; update plane rendering
}
Плоскость обладает следующими свойствами:
-
label
: семантическое описание данногоPlane
. Это может бытьWall
,Floor
,Ceiling
илиTable
. -
centerPose
: Поза центра обнаруженной плоскости. -
extents
: Размеры обнаруженной плоскости в метрах. -
vertices
: список вершин выпуклого многоугольника, аппроксимирующего плоскость.
Проведите тест на попадание в самолеты
Хит-тест — метод расчета пересечения луча с объектами, отслеживаемыми сеансом. Обычное применение проверки нажатия — указать на стол и разместить в этом месте объект. Результатом проверки попадания является список объектов попадания. Другими словами, проверка попадания не останавливается при первом попадании в объект. Однако часто вас может интересовать только первое попадание объекта данного типа.
Чтобы выполнить проверку попадания, используйте Interaction.hitTest()
с Ray
:
val results = Interaction.hitTest(session, ray)
// When interested in the first Table hit:
val tableHit = results.firstOrNull {
val trackable = it.trackable
trackable is Plane && trackable.state.value.label == Plane.Label.Table
}
Привязывайте контент к фиксированному местоположению в пространстве
Чтобы придать виртуальным объектам положение в реальном мире, используйте Anchor
. Объект Anchor помогает вашему приложению отслеживать фиксированное местоположение в физическом пространстве.
Привязка создается с использованием Pose
, которую можно интерпретировать относительно существующего Trackable
или нет.
Создайте привязку относительно Trackable
Когда привязка создается относительно Trackable
, например Plane
, которая заставляет привязку следовать за прикрепленным Trackable
при его перемещении в пространстве.
val anchor = trackable.createAnchor(pose)
Создайте якорь без Trackable
Чтобы создать привязку, которая не прикреплена к Trackable
:
when (val result = Anchor.create(session, pose)) {
is AnchorCreateSuccess -> // ...
else -> // handle failure
}
Прикрепите объект к якорю
Чтобы визуализировать модель в этом месте, создайте GltfModel
и установите его позу в положение якоря. Убедитесь, что модель скрыта, когда TrackingState
Anchor Stopped
.
// renderSession is androidx.xr.core.Session
anchor.state.collect { state ->
if (state.trackingState == TrackingState.Tracking) {
gltfEntity.setPose(
renderSession.perceptionSpace.transformPoseTo(state.pose, renderSession.activitySpace)
)
} else if (state.trackingState == TrackingState.Stopped) {
entity.setHidden(true)
}
}
Понимание состояния отслеживания
Каждый Trackable
имеет TrackingState
, который следует проверить перед использованием. У Trackable
, у которого есть TrackableState
Tracking
система активно обновляет свою Pose
. Trackable
, который находится Paused
может стать Tracking
в будущем, тогда как тот, который Stopped
никогда не станет Tracking
.
Сохраняйте привязку на протяжении всего сеанса
Якорь, который не сохраняется, исчезает после уничтожения сеанса. Сохраняя привязку, ваше приложение запоминает положение этой привязки в своих личных данных приложения. Этот якорь можно получить в следующем сеансе, и он закреплен в том же месте в мире.
Чтобы сохранить привязку, используйтеnchor.persist anchor.persist()
как показано здесь:
val uuid = anchor.persist()
Ваше приложение может получить привязку, используя UUID
в будущем сеансе:
when (val result = Anchor.load(session, uuid)) {
is AnchorCreateSuccess -> // Loading was successful. The anchor is stored in result.anchor.
else -> // handle failure
}
Если вам больше не нужен якорь, вызовите unpersist()
. Это удалит привязку из хранилища вашего приложения и сделает невозможным получение данного UUID для вызовов Anchor.load()
.
Anchor.unpersist(session, uuid)
Ваше приложение также может запросить список всех сохраненных привязок, которые все еще присутствуют в хранилище вашего приложения:
val uuids = Anchor.getPersistedAnchorUuids(session)