XR_EXT_spatial_persistence

Строка имени

XR_EXT_spatial_persistence

Тип расширения

Расширение экземпляра

Зарегистрированный добавочный номер

764

Пересмотр

1

Статус ратификации

Ратифицирован

Зависимости расширений и версий

XR_EXT_spatial_entity
и
XR_EXT_future

Авторы

Нихав Джайн, Google
Джаред Финдер, Google
Натали Флери, Мета
Юичи Тагучи, Мета
Рон Бессемс, Мета
Инь Ли, Microsoft
Джимми Алампарамбил, ByteDance
Чжипен Лю, ByteDance
Джун Ян, ByteDance

Обзор

Это расширение позволяет приложениям обнаруживать и сопоставлять пространственные объекты в рамках сессий приложения, сессий OpenXR и нескольких пространственных контекстов OpenXR в рамках одной сессии. Расширение XR_EXT_spatial_entity установило, что объект в XrSpatialContextEXT представляется объектом XrSpatialEntityIdEXT . Это расширение развивает эту концепцию, устанавливая, что объект, если он сохранен, представляется объектом XrUuid в рамках сессий приложения и OpenXR, то есть приложение может использовать XrUuid, предоставляемый этим расширением, для идентификации объекта в разных сессиях. Это расширение также обеспечивает полезные возможности пересечения с расширением XR_EXT_spatial_entity для обнаружения сохраненных объектов в среде пользователя и возможности запроса данных об их компонентах.

Контекст пространственной устойчивости

Создайте контекст пространственной персистентности.

XR_DEFINE_HANDLE(XrSpatialPersistenceContextEXT)

Дескриптор XrSpatialPersistenceContextEXT представляет собой соединение с постоянным хранилищем пространственных сущностей.

Функция xrCreateSpatialPersistenceContextAsyncEXT определена следующим образом:

XrResult xrCreateSpatialPersistenceContextAsyncEXT(
    XrSession                                   session,
    const XrSpatialPersistenceContextCreateInfoEXT* createInfo,
    XrFutureEXT*                                future);

Описание параметров

  • session — это объект XrSession , в котором будет активен контекст пространственной персистентности.
  • createInfo — это объект XrSpatialPersistenceContextCreateInfoEXT, используемый для указания параметров контекста пространственной персистентности.
  • future — это указатель на объект XrFutureEXT .

Приложение может создать дескриптор XrSpatialPersistenceContextEXT с помощью функции xrCreateSpatialPersistenceContextAsyncEXT и настроить область действия контекста персистентности в createInfo .

Если scope XrSpatialPersistenceContextCreateInfoEXT :: не перечисляется в xrEnumerateSpatialPersistenceScopesEXT , среда выполнения должна вернуть XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT .

Если среда выполнения использует систему разрешений для управления доступом приложения к хранилищу данных, представленному XrSpatialPersistenceContextEXT , то среда выполнения должна вернуть XR_ERROR_PERMISSION_INSUFFICIENT если эти разрешения не были предоставлены данному приложению.

Допустимое использование (неявное)

  • Расширение XR_EXT_spatial_persistence необходимо включить перед вызовом функции xrCreateSpatialPersistenceContextAsyncEXT.
  • session должна быть действительным дескриптором XrSession.
  • createInfo должна быть указателем на допустимую структуру XrSpatialPersistenceContextCreateInfoEXT.
  • future должен быть указателем на значение XrFutureEXT

Коды возврата

Успех

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Отказ

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • XR_ERROR_VALIDATION_FAILURE

Структура XrSpatialPersistenceContextCreateInfoEXT определяется следующим образом:

typedef struct XrSpatialPersistenceContextCreateInfoEXT {
    XrStructureType                 type;
    const void*                     next;
    XrSpatialPersistenceScopeEXT    scope;
} XrSpatialPersistenceContextCreateInfoEXT;

Описание участников

  • type — это XrStructureType данной структуры.
  • next равно NULL или указателю на следующую структуру в цепочке структур. В ядре OpenXR и в этом расширении такие структуры не определены.
  • scope — это объект XrSpatialPersistenceScopeEXT, определяющий область хранения контекста постоянного хранения.

Структура XrSpatialPersistenceContextCreateInfoEXT описывает информацию, необходимую для создания дескриптора XrSpatialPersistenceContextEXT .

Допустимое использование (неявное)

typedef enum XrSpatialPersistenceScopeEXT {
    XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT = 1,
    XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT = 1000781000,
    XR_SPATIAL_PERSISTENCE_SCOPE_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceScopeEXT;

Перечисление XrSpatialPersistenceScopeEXT определяет различные типы областей контекста сохранения данных.

Перечисления имеют следующие значения:

Описание перечисления

XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT

Предоставляет приложению доступ только для чтения (т.е. приложение не может изменять хранилище, связанное с этой областью действия) к пространственным сущностям, сохраняемым и управляемым системой. Приложение может использовать UUID в компоненте сохранения данных для этой области действия, чтобы сопоставлять сущности в разных пространственных контекстах и ​​при перезагрузке устройства.

XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT

Операции сохранения данных и доступ к ним ограничены пространственными привязками, на одном и том же устройстве, для одного и того же пользователя и одного и того же приложения (добавлено расширением XR_EXT_spatial_persistence_operations ).

Функция xrEnumerateSpatialPersistenceScopesEXT определена следующим образом:

XrResult xrEnumerateSpatialPersistenceScopesEXT(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    uint32_t                                    persistenceScopeCapacityInput,
    uint32_t*                                   persistenceScopeCountOutput,
    XrSpatialPersistenceScopeEXT*               persistenceScopes);

Описание параметров

  • instance — это дескриптор объекта XrInstance .
  • systemId — это XrSystemId , для которого будут перечислены области пространственного сохранения.
  • persistenceScopeCapacityInput — это емкость массива persistenceScopes , или 0, указывающее на запрос на получение требуемой емкости.
  • persistenceScopeCountOutput — это количество областей сохранения данных или требуемая емкость в случае, если persistenceScopeCapacityInput недостаточна.
  • persistenceScopes — это массив объектов XrSpatialPersistenceScopeEXT . Он может быть NULL если persistenceScopeCapacityInput равен 0.
  • Подробное описание получения необходимого размера persistenceScopes см. в главе « Параметры размера буфера» .

Приложение может перечислить список областей пространственной персистентности, поддерживаемых заданным XrSystemId , используя xrEnumerateSpatialPersistenceScopesEXT .

Допустимое использование (неявное)

  • Расширение XR_EXT_spatial_persistence необходимо включить перед вызовом функции xrEnumerateSpatialPersistenceScopesEXT.
  • instance должен быть допустимым дескриптором XrInstance.
  • persistenceScopeCountOutput должен быть указателем на значение типа uint32_t
  • Если persistenceScopeCapacityInput не равно 0 , persistenceScopes должен быть указателем на массив значений persistenceScopeCapacityInput XrSpatialPersistenceScopeEXT.

Коды возврата

Успех

  • XR_SUCCESS

Отказ

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SIZE_INSUFFICIENT
  • XR_ERROR_SYSTEM_INVALID
  • XR_ERROR_VALIDATION_FAILURE

Функция xrCreateSpatialPersistenceContextCompleteEXT определена следующим образом:

XrResult xrCreateSpatialPersistenceContextCompleteEXT(
    XrSession                                   session,
    XrFutureEXT                                 future,
    XrCreateSpatialPersistenceContextCompletionEXT* completion);

Описание параметров

Функция xrCreateSpatialPersistenceContextCompleteEXT завершает асинхронную операцию, начатую функцией xrCreateSpatialPersistenceContextAsyncEXT . Если future не находится в состоянии готовности, среда выполнения должна вернуть XR_ERROR_FUTURE_PENDING_EXT . Если future уже завершен или отменен, среда выполнения должна вернуть XR_ERROR_FUTURE_INVALID_EXT .

Допустимое использование (неявное)

Коды возврата

Успех

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Отказ

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_FUTURE_INVALID_EXT
  • XR_ERROR_FUTURE_PENDING_EXT
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_VALIDATION_FAILURE

Структура XrCreateSpatialPersistenceContextCompletionEXT определяется следующим образом:

typedef struct XrCreateSpatialPersistenceContextCompletionEXT {
    XrStructureType                         type;
    void*                                   next;
    XrResult                                futureResult;
    XrSpatialPersistenceContextResultEXT    createResult;
    XrSpatialPersistenceContextEXT          persistenceContext;
} XrCreateSpatialPersistenceContextCompletionEXT;

Описание участников

  • type — это XrStructureType данной структуры.
  • next — это NULL или указатель на следующую структуру в цепочке структур.
  • futureResult — это результат операции создания контекста пространственной персистентности (XrResult) .
  • createResult — это объект XrSpatialPersistenceContextResultEXT операции создания пространственного контекста.
  • persistenceContext — это объект XrSpatialPersistenceContextEXT , созданный с использованием данных и конфигурации из xrCreateSpatialPersistenceContextAsyncEXT :: createInfo .

Будущие коды возврата

Значения futureResult :

Успех

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Отказ

  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_PERMISSION_INSUFFICIENT

Если futureResult и createResult оба являются кодами успешного выполнения, persistenceContext должен быть действительным. Если persistenceContext действителен, он должен оставаться таковым в течение жизненного цикла xrCreateSpatialPersistenceContextAsyncEXT :: session или до тех пор, пока приложение не использует xrDestroySpatialPersistenceContextEXT с persistenceContext , в зависимости от того, что произойдет раньше.

В среде выполнения параметр createResult необходимо устанавливать только в том случае, если futureResult имеет код успешного выполнения.

Допустимое использование (неявное)

typedef enum XrSpatialPersistenceContextResultEXT {
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT = 0,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT = -1000781001,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT = -1000781002,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceContextResultEXT;

Перечисление XrSpatialPersistenceContextResultEXT определяет различные типы кодов результатов для операции сохранения данных. Сбои во время операций сохранения данных не всегда контролируются приложением, и это перечисление используется для описания таких случаев. Аналогично XrResult , коды успеха в перечислении XrSpatialPersistenceContextResultEXT являются неотрицательными значениями, а коды сбоя — отрицательными.

Перечисления имеют следующие значения:

Описание перечисления

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT

Операция сохранения контекста прошла успешно.

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT

Операция сохранения данных завершилась неудачей, поскольку среда выполнения не смогла отследить объект. (Добавлено расширением XR_EXT_spatial_persistence_operations )

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT

Предоставленный UUID для сохранения данных не найден в хранилище. (Добавлено расширением XR_EXT_spatial_persistence_operations )

Разрушьте контекст пространственной устойчивости.

Функция xrDestroySpatialPersistenceContextEXT определена следующим образом:

XrResult xrDestroySpatialPersistenceContextEXT(
    XrSpatialPersistenceContextEXT              persistenceContext);

Описание параметров

Приложение может использовать xrDestroySpatialPersistenceContextEXT для освобождения дескриптора persistenceContext после завершения задач, связанных с сохранением пространственной информации.

В среде выполнения не следует уничтожать базовые ресурсы для persistenceContext при вызове xrDestroySpatialPersistenceContextEXT , если существуют допустимые дескрипторы XrSpatialContextEXT , к которым persistenceContext был привязан через XrSpatialContextPersistenceConfigEXT . Это связано с тем, что ресурсы контекста персистентности по-прежнему используются пространственным контекстом для обнаружения персистентных сущностей. Уничтожение дескриптора контекста персистентности в такой ситуации лишь прекращает доступ приложения к этим ресурсам.

Ресурсы для уничтоженного объекта XrSpatialPersistenceContextEXT должны быть освобождены, когда будут уничтожены все дескрипторы XrSpatialContextEXT , к которым был привязан контекст персистентности.

Допустимое использование (неявное)

Безопасность резьбы

  • Доступ к persistenceContext и любым дочерним элементам должен синхронизироваться извне.

Коды возврата

Успех

  • XR_SUCCESS

Отказ

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE

Обнаружение постоянно сохраняемых сущностей

Компонент сохранения

Сохраняемые пространственные объекты имеют компонент сохранения, который среда выполнения должна включать в снимки обнаружения и обновления, если параметр XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT включен при создании XrSpatialContextEXT и включен в XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes или XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes .

Данные компонентов

Структура XrSpatialPersistenceDataEXT определяется следующим образом:

typedef struct XrSpatialPersistenceDataEXT {
    XrUuid                          persistUuid;
    XrSpatialPersistenceStateEXT    persistState;
} XrSpatialPersistenceDataEXT;

Описание участников

  • persistUuid — это XrUuid .
  • persistState — это объект XrSpatialPersistenceStateEXT , представляющий состояние персистентности persistUuid

Допустимое использование (неявное)

typedef enum XrSpatialPersistenceStateEXT {
    XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT = 1,
    XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT = 2,
    XR_SPATIAL_PERSISTENCE_STATE_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceStateEXT;

Перечисление XrSpatialPersistenceStateEXT идентифицирует различные состояния сохраненного UUID.

Перечисления имеют следующие значения:

Описание перечисления

XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT

Сохраненный UUID успешно загружен из хранилища.

XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT

Сохраненный UUID не был обнаружен в хранилище и либо был удален из него, либо никогда в нем не содержался.

Структура списка компонентов для запроса данных

Структура XrSpatialComponentPersistenceListEXT определяется следующим образом:

typedef struct XrSpatialComponentPersistenceListEXT {
    XrStructureType                 type;
    void*                           next;
    uint32_t                        persistDataCount;
    XrSpatialPersistenceDataEXT*    persistData;
} XrSpatialComponentPersistenceListEXT;

Описание участников

  • type — это XrStructureType данной структуры.
  • next равно NULL или указателю на следующую структуру в цепочке структур. В ядре OpenXR и в этом расширении такие структуры не определены.
  • persistDataCount — это тип uint32_t , описывающий количество элементов в массиве persistData .
  • persistData — это массив объектов XrSpatialPersistenceDataEXT .

Среда выполнения должна возвращать XR_ERROR_VALIDATION_FAILURE из xrQuerySpatialComponentDataEXT , если XrSpatialComponentPersistenceListEXT находится в следующей цепочке XrSpatialComponentDataQueryResultEXT :: next , но XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT не включен в XrSpatialComponentDataQueryConditionEXT :: componentTypes .

Если persistDataCount меньше, чем XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput , среда выполнения должна возвращать XR_ERROR_SIZE_INSUFFICIENT из xrQuerySpatialComponentDataEXT .

В отличие от других компонентов, среда выполнения должна устанавливать данные для XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT независимо от XrSpatialEntityTrackingStateEXT .

Допустимое использование (неявное)

Конфигурация

Если для какой-либо возможности перечислен XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT в XrSpatialCapabilityComponentTypesEXT :: componentTypes , приложение может включить её, добавив перечисление в список XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents . Для этого компонента не требуется специальная конфигурация, которая должна быть включена в следующую цепочку XrSpatialCapabilityConfigurationBaseHeaderEXT . Если приложение включает XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT в список включенных компонентов, оно также должно включить XrSpatialContextPersistenceConfigEXT в следующую цепочку XrSpatialContextCreateInfoEXT, в противном случае среда выполнения должна вернуть XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT из xrCreateSpatialContextAsyncEXT .

Настройка пространственного контекста с помощью контекстов сохранения данных.

Структура XrSpatialContextPersistenceConfigEXT определяется следующим образом:

typedef struct XrSpatialContextPersistenceConfigEXT {
    XrStructureType                          type;
    const void*                              next;
    uint32_t                                 persistenceContextCount;
    const XrSpatialPersistenceContextEXT*    persistenceContexts;
} XrSpatialContextPersistenceConfigEXT;

Описание участников

  • type — это XrStructureType данной структуры.
  • next равно NULL или указателю на следующую структуру в цепочке структур. В ядре OpenXR и в этом расширении такие структуры не определены.
  • persistenceContextCount — это тип uint32_t , описывающий количество элементов в массиве persistenceContexts .
  • persistenceContexts — это массив объектов XrSpatialPersistenceContextEXT .

Приложение может добавить XrSpatialContextPersistenceConfigEXT в следующую цепочку XrSpatialContextCreateInfoEXT . Это позволит настроить созданный XrSpatialContextEXT с помощью persistenceContexts и даст приложению возможность обнаруживать пространственные сущности, сохраненные в хранилище, представленном дескрипторами XrSpatialPersistenceContextEXT в persistenceContexts .

Допустимое использование (неявное)

Создать снимок обнаружения

Обнаружение объектов с определенными UUID.

Структура XrSpatialDiscoveryPersistenceUuidFilterEXT определяется следующим образом:

typedef struct XrSpatialDiscoveryPersistenceUuidFilterEXT {
    XrStructureType    type;
    const void*        next;
    uint32_t           persistedUuidCount;
    const XrUuid*      persistedUuids;
} XrSpatialDiscoveryPersistenceUuidFilterEXT;

Описание участников

  • type — это XrStructureType данной структуры.
  • next равно NULL или указателю на следующую структуру в цепочке структур. В ядре OpenXR и в этом расширении такие структуры не определены.
  • persistedUuidCount — это тип uint32_t , описывающий количество элементов в массиве persistedUuids
  • persistedUuids — это массив объектов XrUuid .

Приложение может использовать XrSpatialDiscoveryPersistenceUuidFilterEXT в следующей цепочке XrSpatialDiscoverySnapshotCreateInfoEXT, чтобы ограничить операцию обнаружения только теми сущностями, чьи сохраненные UUID входят в набор UUID, предоставленных в persistedUuids .

Если приложение добавляет XrSpatialDiscoveryPersistenceUuidFilterEXT в следующую цепочку XrSpatialDiscoverySnapshotCreateInfoEXT , но xrCreateSpatialDiscoverySnapshotAsyncEXT :: spatialContext не был сконфигурирован с использованием XrSpatialPersistenceContextEXT с помощью XrSpatialContextPersistenceConfigEXT , среда выполнения должна вернуть XR_ERROR_VALIDATION_FAILURE из xrCreateSpatialDiscoverySnapshotAsyncEXT .

Среда выполнения должна рассматривать фильтр XrSpatialDiscoveryPersistenceUuidFilterEXT как условие «И» с любыми другими фильтрами, предоставленными в XrSpatialDiscoverySnapshotCreateInfoEXT или его следующей цепочке. Сам массив persistedUuids должен рассматриваться средой выполнения как условие «ИЛИ», то есть фильтр для сущностей, имеющих любой из UUID, предоставленных в этом массиве.

В созданном снимке среды выполнения должна содержаться одна запись для каждого из UUID в persistedUuids , для которых в данный момент удалось определить состояние XrSpatialPersistenceStateEXT .

  • Если среда выполнения успешно обнаружила UUID в своем хранилище, то -

    • В среде выполнения необходимо установить значение XrSpatialPersistenceStateEXT в XrSpatialPersistenceDataEXT этого объекта равным XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT .
    • В созданном снимке среды выполнения для данного объекта должен присутствовать действительный идентификатор XrSpatialEntityIdEXT .
    • Если объект активно отслеживается и для его компонентов имеются действительные данные, среда выполнения должна установить значение XrSpatialEntityTrackingStateEXT для этой сущности в значение XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT . В противном случае среда выполнения должна установить значение XrSpatialEntityTrackingStateEXT в значение XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT .
  • Если среда выполнения определила, что UUID отсутствует в её хранилище (независимо от того, был ли этот UUID в хранилище изначально или присутствовал однажды, но впоследствии был удалён), то -

    • Среда выполнения должна установить значение XrSpatialPersistenceStateEXT в XrSpatialPersistenceDataEXT этого объекта равным XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT , чтобы сообщить приложению, что этот UUID больше не присутствует в хранилище.
    • В среде выполнения для данного объекта в созданном снимке необходимо установить значение XrSpatialEntityIdEXT равным XR_NULL_SPATIAL_ENTITY_ID_EXT .
    • В среде выполнения необходимо установить для объекта XrSpatialEntityTrackingStateEXT значение XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT чтобы указать приложению, что отслеживание этого объекта никогда не будет осуществляться.
  • Если среда выполнения не смогла определить, присутствует ли UUID в её хранилище, она не должна включать его в снимок.

Приложение также может использовать XrSpatialDiscoveryPersistenceUuidFilterEXT в следующей цепочке XrSpatialComponentDataQueryConditionEXT для запроса сущностей с определенными UUID в существующих снимках. При использовании с XrSpatialComponentDataQueryConditionEXT , если XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids содержит какой-либо XrUuid , отсутствующий в XrSpatialSnapshotEXT , среда выполнения не должна включать запись для этого XrUuid в результат запроса. Кроме того, порядок (последовательность) сущностей в результате запроса может не совпадать с порядком UUID, предоставленных в XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids . Приложение должно включить XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT в XrSpatialComponentDataQueryConditionEXT :: componentTypes и XrSpatialComponentPersistenceListEXT в следующую цепочку XrSpatialComponentDataQueryResultEXT , а затем проверить XrSpatialPersistenceDataEXT :: persistUuid каждого индекса результатов запроса, чтобы понять, какому UUID соответствует текущий индекс результатов.

Допустимое использование (неявное)

Обнаружить все сохраненные сущности

Если приложение использует xrCreateSpatialDiscoverySnapshotAsyncEXT без XrSpatialDiscoveryPersistenceUuidFilterEXT и с XrSpatialContextEXT , который был настроен с использованием XrSpatialPersistenceContextEXT , то среда выполнения должна включать в созданный снимок те сущности, которые сохраняются в хранилище, представленном XrSpatialPersistenceContextEXT , и удовлетворяют фильтрам, предоставленным в XrSpatialDiscoverySnapshotCreateInfoEXT . Для этих сущностей -

  • В среде выполнения необходимо установить значение XrSpatialPersistenceStateEXT в XrSpatialPersistenceDataEXT этого объекта равным XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT .
  • В созданном снимке среды выполнения для данного объекта должен присутствовать действительный идентификатор XrSpatialEntityIdEXT .
  • Если объект активно отслеживается и для его компонентов имеются действительные данные, среда выполнения должна установить значение XrSpatialEntityTrackingStateEXT для этой сущности в значение XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT . В противном случае среда выполнения должна установить значение XrSpatialEntityTrackingStateEXT в значение XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT .

Новые типы объектов

Новые команды

Новые сооружения

Новые перечисления

Новые константы перечислений

  • XR_EXT_SPATIAL_PERSISTENCE_EXTENSION_NAME
  • XR_EXT_spatial_persistence_SPEC_VERSION
  • Расширение XrObjectType :

    • XR_OBJECT_TYPE_SPATIAL_PERSISTENCE_CONTEXT_EXT
  • Расширение XrResult :

    • XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • Расширение XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT
  • Расширение XrStructureType :

    • XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT
    • XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT
    • XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT
    • XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT
    • XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT

Пример кода

Создание контекста сохранения

// Check if the required persistence scope supported
uint32_t scopeCount;
CHK_XR(xrEnumerateSpatialPersistenceScopesEXT(instance, systemId, 0, &scopeCount, nullptr));
std::vector<XrSpatialPersistenceScopeEXT> persistenceScopes(scopeCount);
CHK_XR(xrEnumerateSpatialPersistenceScopesEXT(instance, systemId, scopeCount, &scopeCount, persistenceScopes.data()));

if (std::find(persistenceScopes.begin(), persistenceScopes.end(), XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT) == persistenceScopes.end()) {
  return;
}

XrSpatialPersistenceContextEXT persistenceContext{};

XrSpatialPersistenceContextCreateInfoEXT persistenceContextCreateInfo{XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT};
persistenceContextCreateInfo.scope = XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT;
XrFutureEXT createContextFuture;
CHK_XR(xrCreateSpatialPersistenceContextAsyncEXT(session, &persistenceContextCreateInfo, &createContextFuture));

waitUntilReady(createContextFuture);

XrCreateSpatialPersistenceContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT};
CHK_XR(xrCreateSpatialPersistenceContextCompleteEXT(session, createContextFuture, &completion));
if (completion.futureResult != XR_SUCCESS || completion.createResult != XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT) {
  return;
}

persistenceContext = completion.persistenceContext;

// ...
// Connect persistence context to a spatial context and discover persisted entities.
// ...

CHK_XR(xrDestroySpatialPersistenceContextEXT(persistenceContext));

Свяжите контекст сохранения данных с пространственным контекстом.

// Note: Anchor capability is just used as an example here. Persistence can be
// supported by other capabilities too. xrEnumerateSpatialCapabilityComponentTypesEXT() can
// be used to check if a certain capability supports persistence.
if (!isSpatialCapabilitySupported(instance, systemId, XR_SPATIAL_CAPABILITY_ANCHOR_EXT)) {
  return;
}

const bool supportsPersistenceComponent = isSpatialComponentSupported(instance, systemId, XR_SPATIAL_CAPABILITY_ANCHOR_EXT, XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT);

// Create a spatial spatial context
XrSpatialContextEXT spatialContext{};
{

  std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
    XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT,
  };

  if (supportsPersistenceComponent) {
    enabledComponents.push_back(XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT);
  }

  XrSpatialCapabilityConfigurationAnchorEXT anchorConfig{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT};
  anchorConfig.capability = XR_SPATIAL_CAPABILITY_ANCHOR_EXT;
  anchorConfig.enabledComponentCount = enabledComponents.size();
  anchorConfig.enabledComponents = enabledComponents.data();

  std::array<XrSpatialCapabilityConfigurationBaseHeaderEXT*, 1> capabilityConfigs = {
    reinterpret_cast<XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&anchorConfig),
  };

  XrSpatialContextCreateInfoEXT spatialContextCreateInfo{XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT};
  spatialContextCreateInfo.capabilityConfigCount = capabilityConfigs.size();
  spatialContextCreateInfo.capabilityConfigs = capabilityConfigs.data();

  XrSpatialContextPersistenceConfigEXT persistenceConfig{XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT};
  persistenceConfig.persistenceContextCount = 1;
  persistenceConfig.persistenceContexts = &persistenceContext;

  if (supportsPersistenceComponent) {
    spatialContextCreateInfo.next = &persistenceConfig;
  }

  XrFutureEXT createContextFuture;
  CHK_XR(xrCreateSpatialContextAsyncEXT(session, &spatialContextCreateInfo, &createContextFuture));

  waitUntilReady(createContextFuture);

  XrCreateSpatialContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialContextCompleteEXT(session, createContextFuture, &completion));
  if (completion.futureResult != XR_SUCCESS) {
    return;
  }

  spatialContext = completion.spatialContext;
}

// ...
// Discover persisted anchors.
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

Обнаружить все сохраненные сущности

XrFutureEXT future = XR_NULL_FUTURE_EXT;

// We want to look for entities that have the following components.
std::vector<XrSpatialComponentTypeEXT> snapshotComponents = {
  XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT,
};

auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &snapshotCreateInfo, &future));

  waitUntilReady(future);

  XrCreateSpatialDiscoverySnapshotCompletionInfoEXT completionInfo{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT};
  completionInfo.baseSpace = localSpace;
  completionInfo.time = time;
  completionInfo.future = future;

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(spatialContext, &completionInfo, &completion));
  if (completion.futureResult == XR_SUCCESS) {

    // Query for the semantic label component data
    XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
    queryCond.componentTypeCount = snapshotComponents.size();
    queryCond.componentTypes = snapshotComponents.data();

    XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
    std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
    queryResult.entityIdCapacityInput = entityIds.size();
    queryResult.entityIds = entityIds.data();
    queryResult.entityStateCapacityInput = entityStates.size();
    queryResult.entityStates = entityStates.data();

    std::vector<XrSpatialPersistenceDataEXT> persistenceData(queryResult.entityIdCountOutput);
    XrSpatialComponentPersistenceListEXT persistenceDataList{XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT};
    persistenceDataList.persistDataCount = persistenceData.size();
    persistenceDataList.persistData = persistenceData.data();
    queryResult.next = &persistenceDataList;

    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      // persistenceData[i].persistUuid is the UUID of the persisted entity whose entity ID is entityIds[i].
      // The persistenceData array is essentially the uuids persisted in the scope that the current
      // XrSpatialPersistenceContextEXT is configured with.
    }

    CHK_XR(xrDestroySpatialSnapshotEXT(completion.snapshot));
  }
};

while (1) {
  // ...
  // For every frame in frame loop
  // ...

  XrFrameState frameState;  // previously returned from xrWaitFrame
  const XrTime time = frameState.predictedDisplayTime;

  // Poll for the XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT event
  XrEventDataBuffer event = {XR_TYPE_EVENT_DATA_BUFFER};
  XrResult result = xrPollEvent(instance, &event);
  if (result == XR_SUCCESS) {
      switch (event.type) {
          case XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT: {
              const XrEventDataSpatialDiscoveryRecommendedEXT& eventdata =
                  *reinterpret_cast<XrEventDataSpatialDiscoveryRecommendedEXT*>(&event);
              // Discover spatial entities for the context that we received the "discovery
              // recommended" event for.
              discoverSpatialEntities(eventdata.spatialContext, time);
              break;
          }
      }
  }

  // ...
  // Finish frame loop
  // ...
}

Обнаружение объектов с определенными UUID.

XrFutureEXT future = XR_NULL_FUTURE_EXT;

// Load up the uuids that the app has stored on its own i.e. the uuids it is interested in.
std::vector<XrUuid> uuidsStoredByApp = loadPersistedUuids();

// We want to look for entities that have the following components.
std::vector<XrSpatialComponentTypeEXT> snapshotComponents = {
  XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT,
};

auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
  XrSpatialDiscoveryPersistenceUuidFilterEXT persistenceFilter{XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT};
  persistenceFilter.persistedUuidCount = uuidsStoredByApp.size();
  persistenceFilter.persistedUuids = uuidsStoredByApp.data();

  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  snapshotCreateInfo.next = &persistenceFilter;

  CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &snapshotCreateInfo, &future));

  waitUntilReady(future);

  XrCreateSpatialDiscoverySnapshotCompletionInfoEXT completionInfo{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT};
  completionInfo.baseSpace = localSpace;
  completionInfo.time = time;
  completionInfo.future = future;

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(spatialContext, &completionInfo, &completion));
  if (completion.futureResult == XR_SUCCESS) {

    // Query for the semantic label component data
    XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
    queryCond.componentTypeCount = snapshotComponents.size();
    queryCond.componentTypes = snapshotComponents.data();

    XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
    std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
    queryResult.entityIdCapacityInput = entityIds.size();
    queryResult.entityIds = entityIds.data();
    queryResult.entityStateCapacityInput = entityStates.size();
    queryResult.entityStates = entityStates.data();

    std::vector<XrSpatialPersistenceDataEXT> persistenceData(queryResult.entityIdCountOutput);
    XrSpatialComponentPersistenceListEXT persistenceDataList{XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT};
    persistenceDataList.persistDataCount = persistenceData.size();
    persistenceDataList.persistData = persistenceData.data();
    queryResult.next = &persistenceDataList;

    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      if (persistenceData[i].persistState == XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT) {
        // persistenceData[i].persistUuid, requested by the app, is present in the persistence scope
        // and its corresponding entity ID and state are entityIds[i] & entityStates[i] respectively.
      } else if (persistenceData[i].persistState == XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT) {
        // persistenceData[i].persistUuid, requested by the app, is NOT present in the persistence scope
        // and its corresponding entity ID (entityIds[i]) would be XR_NULL_SPATIAL_ENTITY_ID_EXT
        // and tracking state (entityStates[i]) would be XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT.
      }
    }

    CHK_XR(xrDestroySpatialSnapshotEXT(completion.snapshot));
  }
};

while (1) {
  // ...
  // For every frame in frame loop
  // ...

  XrFrameState frameState;  // previously returned from xrWaitFrame
  const XrTime time = frameState.predictedDisplayTime;

  // Poll for the XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT event
  XrEventDataBuffer event = {XR_TYPE_EVENT_DATA_BUFFER};
  XrResult result = xrPollEvent(instance, &event);
  if (result == XR_SUCCESS) {
      switch (event.type) {
          case XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT: {
              const XrEventDataSpatialDiscoveryRecommendedEXT& eventdata =
                  *reinterpret_cast<XrEventDataSpatialDiscoveryRecommendedEXT*>(&event);
              // Discover spatial entities for the context that we received the "discovery
              // recommended" event for.
              discoverSpatialEntities(eventdata.spatialContext, time);
              break;
          }
      }
  }

  // ...
  // Finish frame loop
  // ...
}

Проблемы

История версий

  • Редакция 1, 29.08.2024 (Нихав Джайн, Google)

    • Первоначальное описание расширения