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_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_LIMIT_REACHEDXR_ERROR_OUT_OF_MEMORYXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXTXR_ERROR_VALIDATION_FAILURE
Структура XrSpatialPersistenceContextCreateInfoEXT определяется следующим образом:
typedef struct XrSpatialPersistenceContextCreateInfoEXT {
XrStructureType type;
const void* next;
XrSpatialPersistenceScopeEXT scope;
} XrSpatialPersistenceContextCreateInfoEXT;
Описания участников
type– это XrStructureType этой структуры.next– этоNULLили указатель на следующую структуру в цепочке. Такие структуры не определены в ядре OpenXR или этом расширении.scope– это XrSpatialPersistenceScopeEXT, определяющий область хранения контекста сохраняемости.
Структура XrSpatialPersistenceContextCreateInfoEXT описывает информацию, необходимую для создания дескриптора XrSpatialPersistenceContextEXT.
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_persistenceдолжно быть включено до использования XrSpatialPersistenceContextCreateInfoEXT. -
typeдолжно бытьXR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT -
nextдолжно бытьNULLили действительным указателем на следующую структуру в цепочке структур. -
scopeдолжно быть действительным значением XrSpatialPersistenceScopeEXT.
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должен быть указателем на массив значенийpersistenceScopeCapacityInputXrSpatialPersistenceScopeEXT.
Коды возврата
XR_SUCCESS
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SIZE_INSUFFICIENTXR_ERROR_SYSTEM_INVALIDXR_ERROR_VALIDATION_FAILURE
Функция xrCreateSpatialPersistenceContextCompleteEXT определяется следующим образом:
XrResult xrCreateSpatialPersistenceContextCompleteEXT(
XrSession session,
XrFutureEXT future,
XrCreateSpatialPersistenceContextCompletionEXT* completion);
Описание параметров
session– это XrSession, ранее переданный в xrCreateSpatialPersistenceContextAsyncEXT ::session.future– этоXrFutureEXT, полученный от xrCreateSpatialPersistenceContextAsyncEXT .completion– указатель на XrCreateSpatialPersistenceContextCompletionEXT .
xrCreateSpatialPersistenceContextCompleteEXT завершает асинхронную операцию, запущенную xrCreateSpatialPersistenceContextAsyncEXT . Среда выполнения должна возвращать XR_ERROR_FUTURE_PENDING_EXT, если future не находится в состоянии готовности. Среда выполнения должна возвращать XR_ERROR_FUTURE_INVALID_EXT, если future уже завершено или отменено.
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_persistenceдолжно быть включено до вызова xrCreateSpatialPersistenceContextCompleteEXT. -
sessionдолжен быть действительным дескриптором XrSession. -
completionдолжен быть указателем на структуру XrCreateSpatialPersistenceContextCompletionEXT.
Коды возврата
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_FUTURE_INVALID_EXTXR_ERROR_FUTURE_PENDING_EXTXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_LIMIT_REACHEDXR_ERROR_OUT_OF_MEMORYXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_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_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_RUNTIME_FAILUREXR_ERROR_INSTANCE_LOSTXR_ERROR_SESSION_LOSTXR_ERROR_OUT_OF_MEMORYXR_ERROR_LIMIT_REACHEDXR_ERROR_PERMISSION_INSUFFICIENT
Если futureResult и createResult – коды успешного выполнения, то persistenceContext должен быть действительным. Если persistenceContext действителен, он должен оставаться таковым в течение жизненного цикла xrCreateSpatialPersistenceContextAsyncEXT :: session или до тех пор, пока приложение не использует xrDestroySpatialPersistenceContextEXT с persistenceContext (в зависимости от того, что произойдет раньше).
Среда выполнения должна задавать createResult, только если futureResult – код успешного выполнения.
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_persistenceдолжно быть включено до использования XrCreateSpatialPersistenceContextCompletionEXT. -
typeдолжно бытьXR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT -
nextдолжно бытьNULLили действительным указателем на следующую структуру в цепочке структур. -
futureResultдолжно быть действительным значением XrResult. -
createResultдолжно быть допустимым значением XrSpatialPersistenceContextResultEXT. -
persistenceContextдолжен быть действительным дескриптором XrSpatialPersistenceContextEXT.
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);
Описание параметров
persistenceContext– это XrSpatialPersistenceContextEXT, ранее созданный с помощью xrCreateSpatialPersistenceContextAsyncEXT .
Приложение может использовать xrDestroySpatialPersistenceContextEXT, чтобы освободить дескриптор persistenceContext, когда задачи пространственного сохранения будут выполнены.
Среда выполнения не должна уничтожать базовые ресурсы для persistenceContext при вызове xrDestroySpatialPersistenceContextEXT, если есть действительные дескрипторы XrSpatialContextEXT, с которыми persistenceContext был связан через XrSpatialContextPersistenceConfigEXT . Это связано с тем, что ресурсы контекста сохраняемости по-прежнему используются пространственным контекстом для обнаружения сохраненных объектов. Удаление дескриптора контекста сохраняемости в такой ситуации только лишает приложение доступа к этим ресурсам.
Ресурсы для уничтоженного XrSpatialPersistenceContextEXT должны быть освобождены, когда все дескрипторы XrSpatialContextEXT, с которыми был связан контекст сохраняемости, будут уничтожены.
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_persistenceдолжно быть включено до вызова xrDestroySpatialPersistenceContextEXT. -
persistenceContextдолжен быть действительным дескриптором XrSpatialPersistenceContextEXT.
Потокобезопасность
- Доступ к
persistenceContextи любым дочерним дескрипторам должен быть синхронизирован извне.
Коды возврата
XR_SUCCESS
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_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.
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_persistenceдолжно быть включено до использования XrSpatialPersistenceDataEXT. -
persistStateдолжно быть допустимым значением XrSpatialPersistenceStateEXT.
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 .
Допустимое использование (неявное)
- Перед использованием XrSpatialComponentPersistenceListEXT необходимо включить расширение
XR_EXT_spatial_persistence. -
typeдолжно бытьXR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT -
nextдолжно бытьNULLили действительным указателем на следующую структуру в цепочке структур. -
persistDataдолжен быть указателем на массив структурpersistDataCountXrSpatialPersistenceDataEXT. - Значение параметра
persistDataCountдолжно быть больше0.
Конфигурация
Если 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.
- Среда выполнения должна задать для XrSpatialPersistenceStateEXT в XrSpatialPersistenceDataEXT этого объекта значение
Если среда выполнения определила, что 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, чтобы сообщить приложению, что объект никогда не будет отслеживаться.
- Среда выполнения должна задать для XrSpatialPersistenceStateEXT в XrSpatialPersistenceDataEXT этого объекта значение
Если среда выполнения не смогла определить, есть ли 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должен быть указателем на массив структурpersistedUuidCountXrUuid. - Значение параметра
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.
Новые типы объектов
Новые команды
- xrCreateSpatialPersistenceContextAsyncEXT
- xrCreateSpatialPersistenceContextCompleteEXT
- xrDestroySpatialPersistenceContextEXT
- xrEnumerateSpatialPersistenceScopesEXT
Новые структуры
- XrCreateSpatialPersistenceContextCompletionEXT
- XrSpatialPersistenceContextCreateInfoEXT
- XrSpatialPersistenceDataEXT
Расширение XrSpatialComponentDataQueryResultEXT :
Расширение XrSpatialContextCreateInfoEXT :
Расширение XrSpatialDiscoverySnapshotCreateInfoEXT , XrSpatialComponentDataQueryConditionEXT :
Новые перечисления
Новые константы перечисления
XR_EXT_SPATIAL_PERSISTENCE_EXTENSION_NAMEXR_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_EXTXR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXTXR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXTXR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXTXR_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)
- Описание расширения