Пространственные контейнеры добавляют в OpenXR объемные окна. Пространственный контейнер – это определяемая расширениями XR_EXT_spatial_container и XR_EXT_spatial_container_self_rendering в OpenXR 1.1 управляемая системой трехмерная область в пространстве пользователя, в которой приложение отрисовывает 3D-контент с помощью стандартных слоев композиции OpenXR.
Обычно сеанс OpenXR запрашивает эксклюзивный доступ ко всей зоне обзора пользователя. Пространственные контейнеры позволяют приложению отображать 3D-контент OpenXR в ограниченном трехмерном поле в среде пользователя или в любой момент переходить в неограниченный полноэкранный режим с эффектом присутствия.
О пространственных контейнерах
Пространственный контейнер – это ограниченная или неограниченная трехмерная область, которая управляется системой Android XR и отрисовывается приложением OpenXR.
- Ограниченный режим. Приложение предлагает размеры 3D-объекта (ширину, высоту и глубину в метрах), а система выделяет для него трехмерную ограничительную рамку в окружении пользователя. Приложение отрисовывает стереоскопический 3D-контент внутри объема, а система обрезает его по границам 3D-области.
- Режим погружения. Пространственный контейнер расширяется до бесконечных границ, предоставляя приложению всю зону обзора пользователя, как в традиционном полноэкранном режиме OpenXR.
Как пользователи взаимодействуют с пространственными контейнерами
Система Android XR управляет элементами управления окном пространственного контейнера и его размещением в физическом пространстве, обеспечивая согласованную модель взаимодействия между приложениями:
- Перемещение и изменение положения. Пользователи могут перемещать пространственный контейнер в 3D-пространстве, используя системный маркер и жесты руками (например, сведение пальцев) или контроллеры движения.
- Сворачивание и закрытие. Элементы управления системными окнами позволяют пользователям сворачивать или закрывать отдельные пространственные контейнеры. Когда пользователь закрывает контейнер, система уведомляет об этом приложение, чтобы оно могло освободить ресурсы.
- Привязка к полу с помощью распознавания сцены. Когда приложение запрашивает разрешение
android.permission.SCENE_UNDERSTANDING_COARSE, система автоматически включает привязку к поверхности, чтобы пользователи могли размещать и закреплять пространственный контейнер на физическом полу без дополнительной настройки приложения, как показано на рисунке 1. - Прямое взаимодействие с 3D-контентом. Когда контейнер находится в фокусе и интерактивен, пользователи могут напрямую взаимодействовать с 3D-контентом внутри него, используя отслеживание рук, взгляд или контроллеры 6DoF.
- Переход между ограниченным и иммерсивным режимами. Пользователь или приложение может переключать контейнер между ограниченным трехмерным окном и неограниченным полноэкранным иммерсивным режимом без перезапуска сеанса OpenXR.
- Режим следования в движении Поскольку система управляет положением координатного пространства каждого пространственного контейнера (
xrCreateSpatialContainerSpaceEXT), пользователи могут включить режим следования в элементах управления системным окном. В результате ограниченный 3D-контейнер будет автоматически следовать за ними и оставаться в зоне обзора, когда они перемещаются. Дополнительная настройка в приложении не требуется.
Как использовать пространственные контейнеры в Android XR
При создании приложения с пространственными контейнерами проектируйте сцену с учетом границ контейнера, изменений состояния и режима смешивания фона.
Как адаптировать 3D-контент к границам контейнера
В ограниченном режиме начало координат (0, 0, 0) пространства пространственного контейнера (xrCreateSpatialContainerSpaceEXT) находится в центре трехмерной ограничивающей рамки.
Поскольку система управляет положением контейнера в пространстве пользователя, ваше приложение отображает 3D-контент относительно (0, 0, 0), а система обрабатывает перемещение пользователя и режим следования. Система обрезает любую геометрию, отображаемую за пределами ширины, высоты или глубины поля, чтобы контент оставался в пределах назначенного ему объема.
Приложение должно отслеживать события изменения границ от среды выполнения и масштабировать или перемещать 3D-сцену так, чтобы ключевой контент помещался в текущие размеры контейнера. Когда контейнер переходит в режим погружения, границы становятся бесконечными и вы можете восстановить сцену в полном масштабе 1:1.
Как реагировать на изменения состояния контейнера
Вместо того чтобы управлять видимостью и фокусом только на уровне приложения, каждый пространственный контейнер сообщает о своем состоянии, чтобы приложение могло реагировать соответствующим образом:
- Видимость. Показывает, виден ли контейнер в данный момент. Приостанавливайте анимацию, аудио и симуляции, когда контейнер скрыт. Приложение также может запрашивать показ или скрытие контейнера.
- Интерактивность. Указывает, находится ли контейнер в фокусе и получает ли он пользовательский ввод от отслеживания рук, контроллеров или взгляда. Включите или отключите интерактивные выделения и обработку ввода при изменении фокуса.
- Режим границ. Показывает, в каком режиме находится контейнер:
XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT(ограничен трехмерным полем) илиXR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT(неограниченный полноэкранный режим). Обновляйте масштаб сцены и переключайте визуальные эффекты окружения (например, скайбоксы или сквозной режим) при изменении режима. Приложение также может в любой момент запросить переход между ограниченным режимом и режимом погружения.
Использовать альфа-смешивание в ограниченном режиме
В ограниченном режиме прозрачный фон позволяет пользователю видеть физическое окружение и другие окна вокруг ваших 3D-моделей. Настройте камеру или область просмотра с прозрачным фоном и используйте режим смешивания среды alpha-blend. При переходе в режим погружения вы можете оставить сквозную камеру включенной или переключиться на непрозрачный скайбокс.
Проверьте доступность функций и настройте манифест
Для пространственных контейнеров требуется устройство Android XR, поддерживающее Spatial API уровня 4 или выше. Вместо того чтобы напрямую проверять уровень API Android, запросите среду выполнения OpenXR, чтобы определить, поддерживаются ли пространственные контейнеры. Для этого вызовите xrEnumerateInstanceExtensionProperties, чтобы проверить, доступны ли XR_EXT_spatial_container и XR_EXT_spatial_container_self_rendering, и вызовите xrGetSystemProperties с XrSystemSpatialContainerPropertiesEXT, чтобы проверить supportsBounded и supportsImmersive.
Прежде чем создавать приложение, использующее пространственные контейнеры, настройте режим запуска действий и разрешения для отдельных функций в файле AndroidManifest.xml.
Как включить режим полного пространства в AndroidManifest.xml
Для пространственных контейнеров требуется режим управляемого полного пространства, даже для автономных приложений OpenXR. Традиционные полноэкранные приложения OpenXR объявляют XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED, чтобы получить эксклюзивный контроль над экраном без управления системными окнами. Приложение, использующее пространственные контейнеры, полагается на системный компоновщик Android XR для управления ограниченными 3D-объемами, элементами управления окнами и пространственным размещением в режиме полного пространства. В этом случае необходимо задать для android.window.PROPERTY_XR_ACTIVITY_START_MODE значение XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application ...>
<!-- Spatial Containers require Full Space Managed mode -->
<property
android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED" />
<activity android:name=".MainActivity" ...>
<!-- Optional hint declaring which bounds modes the activity uses -->
<property
android:name="org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_USED_BOUNDS_MODES"
android:value="XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT|XR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT" />
</activity>
</application>
</manifest>
Объявление и запрос разрешений для определенных функций
Для создания и отрисовки базового пространственного контейнера не требуются опасные динамические разрешения. Однако для некоторых функций необходимо объявить и запросить соответствующие разрешения Android XR:
- Чтобы закрепить пространственный контейнер на физическом полу с помощью распознавания сцены, объявите и запросите опасное разрешение
android.permission.SCENE_UNDERSTANDING_COARSEво время выполнения. - Чтобы отслеживать положение головы пользователя в OpenXR, объявите и запросите
android.permission.HEAD_TRACKING.
<uses-permission android:name="android.permission.HEAD_TRACKING" />
<uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />
Подробнее о том, как объявлять и запрашивать опасные разрешения XR во время выполнения, рассказывается в статье Разрешения для XR.
Как включить пространственные контейнеры в проекте
Вы можете создавать пространственные контейнеры с помощью Unity, Godot или непосредственно с помощью OpenXR на C++. Выберите вкладку, чтобы увидеть предварительные требования, настройку редактора и пример кода для предпочитаемой вами среды:
Unity
Требования
- Версия Unity: Unity 6 версии 6000.0.58f2 или выше.
- Настройка проекта. Выполните все шаги, описанные в руководстве по настройке проекта Unity.
- Пакеты Unity. Установите пакет Android XR Extensions for Unity версии 1.5.0 или более поздней.
Настройте проект
- Выберите Edit (Редактировать) > Project Settings (Настройки проекта) > XR Plug-in Management (Управление плагинами XR) > OpenXR.
- Нажмите Настройки рядом с пунктом Android XR (Extensions): Session Management (Android XR (расширения): управление сеансами) и снимите флажок Immersive XR (XR с эффектом присутствия).
- В списке OpenXR Feature Groups (Группы функций OpenXR) включите Spatial Container (Пространственный контейнер).
Используйте XRSpatialContainerFeature в C#, чтобы запрашивать границы, реагировать на события контейнера и переключаться между ограниченным режимом и режимом погружения.
void OnEnable()
{
XRSpatialContainerFeature.OnSpatialContainerBoundsChanged += OnBoundsChanged;
}
private void OnBoundsChanged(Vector3 bounds, bool infiniteBounds)
{
float minScale = Mathf.Min(bounds.x, bounds.y, bounds.z);
transform.localScale = infiniteBounds ? Vector3.one : Vector3.one * minScale;
}
public void SetImmersiveMode(bool immersive)
{
XRSpatialContainerFeature.TryRequestBoundsMode(immersive);
}
Полные инструкции по настройке проекта, конфигурации манифеста и обработке разрешений приведены в статье Как использовать пространственные контейнеры в Unity.
Godot
Требования
- Версия Godot: Godot 4.8-dev или более поздняя.
- Настройка проекта. Выполните все шаги из руководства по настройке проекта Godot Engine.
- Плагин Godot OpenXR Vendors. Установите плагин Godot OpenXR Vendors версии 5.2 или более поздней.
Настройте проект
- Перейдите в раздел Project (Проект) > Project Settings (Настройки проекта), включите Advanced Settings (Расширенные настройки) и выберите General (Общие) > XR > OpenXR > Extensions (Расширения).
- В подразделе Spatial Container (Пространственный контейнер) выберите Enabled (Включено) и настройте Bounds Mode (Режим границ) и Bounds (Границы).
- Выберите Project (Проект) > Export (Экспорт). > Android и в разделе Android XR Features (Функции Android XR) выберите Use Experimental Features (Использовать экспериментальные функции).
Используйте синглтон OpenXRSpatialContainerExtension в GDScript, чтобы реагировать на изменения границ и режима контейнера:
func _ready() -> void:
if OpenXRSpatialContainerExtension.is_enabled():
OpenXRSpatialContainerExtension.spatial_container_bounds_changed.connect(
_on_bounds_changed
)
func _on_bounds_changed(_rid: RID, bounds: Vector3) -> void:
scale = Vector3.ONE * min(bounds.x, bounds.y, bounds.z)
func set_immersive_mode() -> void:
OpenXRSpatialContainerExtension.request_main_spatial_container_bounds_mode(
OpenXRSpatialContainerState.IMMERSIVE
)
Полные настройки проекта, разрешения на экспорт и примеры GDScript можно найти в статье Как использовать пространственные контейнеры в Godot.
OpenXR
Требования
- Версия OpenXR: заголовки OpenXR 1.1 с
XR_EXT_spatial_containerиXR_EXT_spatial_container_self_rendering. - Настройка манифеста. Настройте манифест приложения, как описано в статье Начало работы с OpenXR для Android XR, используя
XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED.
При создании XrInstance включите XR_EXT_spatial_container и XR_EXT_spatial_container_self_rendering, а затем создайте и отрисуйте пространственный контейнер:
// 1. Enable the Spatial Container extensions during xrCreateInstance
const char* enabledExtensions[] = {
XR_EXT_SPATIAL_CONTAINER_EXTENSION_NAME,
XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME,
};
// 2. Configure and create a self-rendering spatial container
XrSpatialContainerConfigurationSelfRenderingEXT selfRenderingConfig{
.type = XR_TYPE_SPATIAL_CONTAINER_CONFIGURATION_SELF_RENDERING_EXT,
.next = nullptr,
.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
.suggestedBounds = {1.5f, 1.5f, 1.5f}, // Width, height, depth in meters
};
XrSpatialContainerCreateInfoEXT createInfo{
.type = XR_TYPE_SPATIAL_CONTAINER_CREATE_INFO_EXT,
.next = &selfRenderingConfig,
.spatialContainerConfig =
reinterpret_cast<const XrSpatialContainerConfigurationBaseHeaderEXT*>(
&selfRenderingConfig),
};
XrSpatialContainerEXT spatialContainer = XR_NULL_HANDLE;
xrCreateSpatialContainerEXT(session, &createInfo, &spatialContainer);
// 3. Request bounded mode and make the container visible
xrRequestSpatialContainerBoundsModeEXT(
spatialContainer, XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT);
xrRequestSpatialContainerVisibilityEXT(spatialContainer, XR_TRUE);
Дополнительная информация
- Как использовать пространственные контейнеры в Unity
- Как использовать пространственные контейнеры в Godot
- Разрешения для XR
OpenXR™ и логотип OpenXR являются товарными знаками, принадлежащими The Khronos Group Inc. и зарегистрированными в Великобритании, Европейском союзе, Китае и Японии.