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 .
Допустимое использование (неявное)
- Расширение
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_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должен быть указателем на массив значенийpersistenceScopeCapacityInputXrSpatialPersistenceScopeEXT.
Коды возврата
-
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);
Описание параметров
-
session— это объект XrSession, ранее переданный в функцию xrCreateSpatialPersistenceContextAsyncEXT ::session. -
future— это объектXrFutureEXT, полученный из функции xrCreateSpatialPersistenceContextAsyncEXT . -
completion— это указатель на объект XrCreateSpatialPersistenceContextCompletionEXT .
Функция xrCreateSpatialPersistenceContextCompleteEXT завершает асинхронную операцию, начатую функцией xrCreateSpatialPersistenceContextAsyncEXT . Если future не находится в состоянии готовности, среда выполнения должна вернуть XR_ERROR_FUTURE_PENDING_EXT . Если future уже завершен или отменен, среда выполнения должна вернуть XR_ERROR_FUTURE_INVALID_EXT .
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_persistenceнеобходимо включить перед вызовом функции xrCreateSpatialPersistenceContextCompleteEXT. -
sessionдолжна быть действительным дескриптором XrSession. -
completionдолжна быть указателем на структуру XrCreateSpatialPersistenceContextCompletionEXT.
Коды возврата
-
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 имеет код успешного выполнения.
Допустимое использование (неявное)
- Расширение
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_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);
Описание параметров
-
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_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
Допустимое использование (неявное)
- Расширение
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 .
Если persistDataCount меньше, чем XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput , среда выполнения должна возвращать XR_ERROR_SIZE_INSUFFICIENT из xrQuerySpatialComponentDataEXT .
В отличие от других компонентов, среда выполнения должна устанавливать данные для XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT независимо от XrSpatialEntityTrackingStateEXT .
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_persistenceнеобходимо включить перед использованием XrSpatialComponentPersistenceListEXT. -
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должен быть указателем на массив допустимых дескрипторов XrSpatialPersistenceContextEXT, содержащихpersistenceContextCount. - Параметр
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 отсутствует в её хранилище (независимо от того, был ли этот 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_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)
- Первоначальное описание расширения