XR_EXT_spatial_persistence

Name String

XR_EXT_spatial_persistence

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

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

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

764

Revision

1

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

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

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

XR_EXT_spatial_entity
и
XR_EXT_future

Авторы

Нихав Джайн (Nihav Jain), Google
Джаред Финдер (Jared Finder), Google
Натали Флери (Natalie Fleury), Meta
Юичи Тагучи (Yuichi Taguchi), Meta
Рон Бессемс (Ron Bessems), Meta
Инь Ли (Yin Li), Microsoft
Джимми Алампарамбил (Jimmy Alamparambil), ByteDance
Чжипэн Лю (Zhipeng Liu), ByteDance
Цзюнь Янь (Jun Yan), 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 .

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

Если среда выполнения применяет систему разрешений для управления доступом приложения к постоянному хранилищу, представленному 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_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1 = 1000808000,
    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).

XR_SPATIAL_PERSISTENCE_SCOPE_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1

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

Функция 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 . Среда выполнения должна возвращать XR_ERROR_FUTURE_PENDING_EXT, если future не находится в состоянии готовности. Среда выполнения должна возвращать XR_ERROR_FUTURE_INVALID_EXT, если future уже завершено или отменено.

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

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

Выполнено

  • 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_LOCALIZATION_FAILURE_ANDROIDX1 = -1000808000,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1 = -1000808001,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1 = -1000808002,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1 = -1000808003,
    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)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_LOCALIZATION_FAILURE_ANDROIDX1

Не удалось выполнить операцию сохранения, так как не удалось выполнить локализацию. (Добавлено расширением XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1

Не удалось выполнить операцию сохранения, так как функция карты локализации недостаточна. (Добавлено расширением XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1

Не удалось выполнить операцию сохранения из-за ошибки сетевого подключения. (Добавлено расширением XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1

Операция сохранения не выполнена из-за истечения времени ожидания сети. (Добавлено расширением XR_ANDROIDX1_spatial_anchor_cloud_sharing)

Удалить контекст сохранения пространственных данных

Функция 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 .

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

В отличие от других компонентов, среда выполнения должна задавать данные для 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 .

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

  • Расширение XR_EXT_spatial_persistence должно быть включено до использования XrSpatialContextPersistenceConfigEXT.
  • type должно быть XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT
  • next должно быть NULL или действительным указателем на следующую структуру в цепочке структур.
  • persistenceContexts должен быть указателем на массив из persistenceContextCount действительных дескрипторов XrSpatialPersistenceContextEXT.
  • Значение параметра persistenceContextCount должно быть больше 0.

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

Как найти объекты с определенными 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 отсутствует в ее хранилище (независимо от того, не было ли его там никогда или он был, но затем был удален), то:

    • Среда выполнения должна задать для 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 соответствует текущий индекс.

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

  • Расширение XR_EXT_spatial_persistence должно быть включено до использования XrSpatialDiscoveryPersistenceUuidFilterEXT.
  • type должно быть XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT
  • next должно быть NULL или действительным указателем на следующую структуру в цепочке структур.
  • persistedUuids должен быть указателем на массив структур persistedUuidCount XrUuid.
  • Значение параметра persistedUuidCount должно быть больше 0.
Посмотреть все сохраненные объекты

Если приложение использует 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 августа 2024 г. (Нихав Джайн, Google)

    • Описание расширения