XR_EXT_spatial_anchor
Строка имени
XR_EXT_spatial_anchor
Тип расширения
Расширение экземпляра
Зарегистрированный добавочный номер
763
Пересмотр
1
Статус ратификации
Ратифицирован
Зависимости расширений и версий
XR_EXT_spatial_entity
Авторы
Нихав Джайн, Google
Натали Флери, Мета
Юичи Тагучи, Мета
Рон Бессемс, Мета
Инь Ли, Microsoft
Джимми Алампарамбил, ByteDance
Чжипен Лю, ByteDance
Джун Ян, ByteDance
Обзор
Это расширение основано на XR_EXT_spatial_entity и позволяет приложениям создавать пространственные якоря — произвольные точки в физическом окружении пользователя, которые затем будут отслеживаться средой выполнения. Затем среда выполнения должна корректировать положение и ориентацию начала координат якоря с течением времени по мере необходимости, независимо от всех других пространств и якорей, чтобы обеспечить сохранение его исходного соответствия реальному миру.
Якорь, отслеживающий заданное положение и ориентацию в пределах XrSpatialContextEXT , представляется как пространственный объект, имеющий (или "обладающий") компонент XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT .
Преимущества использования анкеров
Поскольку понимание средой выполнения физической среды пользователя обновляется на протяжении всего времени существования XrSpatialContextEXT , виртуальные объекты могут смещаться относительно своих мест размещения приложением, что влияет на реализм приложения и качество пользовательского опыта. Создав якорь рядом с местом размещения виртуального объекта и всегда отображая этот виртуальный объект относительно якоря, приложение может гарантировать, что каждый виртуальный объект будет выглядеть так, будто он остается в одном и том же положении и ориентации в физической среде. Кроме того, в отличие от некоторых пространств отсчета, якоря не подвержены влиянию перецентрирования на системном уровне.
Поддержка во время выполнения
Если среда выполнения поддерживает пространственные привязки, она должна указать это, перечислив XR_SPATIAL_CAPABILITY_ANCHOR_EXT в xrEnumerateSpatialCapabilitiesEXT .
Конфигурация
Структура XrSpatialCapabilityConfigurationAnchorEXT определяется следующим образом:
typedef struct XrSpatialCapabilityConfigurationAnchorEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationAnchorEXT;
Описание участников
-
type— это XrStructureType данной структуры. -
next— этоNULLили указатель на следующую структуру в цепочке структур. -
capabilityпредставляет собой XrSpatialCapabilityEXT . -
enabledComponentCount— это типuint32_t, описывающий количество элементов в массивеenabledComponents. -
enabledComponents— это указатель на массив XrSpatialComponentTypeEXT .
Приложения могут включить пространственную возможность XR_SPATIAL_CAPABILITY_ANCHOR_EXT , добавив указатель на структуру XrSpatialCapabilityConfigurationAnchorEXT в XrSpatialContextCreateInfoEXT :: capabilityConfigs .
Если capability XR_SPATIAL_CAPABILITY_ANCHOR_EXT не равно XR_SPATIAL_CAPABILITY_ANCHOR_EXT , среда выполнения должна вернуть XR_ERROR_VALIDATION_FAILURE .
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_anchorнеобходимо включить перед использованием XrSpatialCapabilityConfigurationAnchorEXT. -
typeдолжен бытьXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT -
nextдолжно бытьNULLили допустимым указателем на следующую структуру в цепочке структур. - Значение
capabilityдолжно быть допустимым значением XrSpatialCapabilityEXT. -
enabledComponentsдолжен быть указателем на массив допустимых значений XrSpatialComponentTypeEXT, равныхenabledComponentCount. - Параметр
enabledComponentCountдолжен быть больше0
Гарантированные компоненты
Среда выполнения, поддерживающая XR_SPATIAL_CAPABILITY_ANCHOR_EXT , должна предоставлять следующие пространственные компоненты в качестве гарантированных компонентов всех сущностей, созданных или обнаруженных с помощью этой возможности, и должна перечислять их в xrEnumerateSpatialCapabilityComponentTypesEXT :
-
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
Якорный компонент
Данные компонентов
В качестве данных для XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT используется XrPosef , который определяет положение и ориентацию якоря.
Структура списка компонентов для запроса данных
Структура XrSpatialComponentAnchorListEXT определяется следующим образом:
typedef struct XrSpatialComponentAnchorListEXT {
XrStructureType type;
void* next;
uint32_t locationCount;
XrPosef* locations;
} XrSpatialComponentAnchorListEXT;
Описание участников
-
type— это XrStructureType данной структуры. -
next— этоNULLили указатель на следующую структуру в цепочке структур. -
locationCount— это тип данныхuint32_t, описывающий количество элементов в массивеlocations. -
locations— это массив объектов XrPosef .
Среда выполнения должна возвращать XR_ERROR_VALIDATION_FAILURE из xrQuerySpatialComponentDataEXT , если XrSpatialComponentAnchorListEXT находится в цепочке XrSpatialComponentDataQueryResultEXT :: next , но XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT не включен в XrSpatialComponentDataQueryConditionEXT :: componentTypes .
Если locationCount меньше, чем XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput , среда выполнения должна возвращать XR_ERROR_SIZE_INSUFFICIENT из xrQuerySpatialComponentDataEXT .
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_anchorнеобходимо включить перед использованием XrSpatialComponentAnchorListEXT. -
typeдолжен бытьXR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT -
nextдолжно бытьNULLили допустимым указателем на следующую структуру в цепочке структур. -
locationsдолжны быть указателями на массив структурlocationCountXrPosef. - Параметр
locationCountдолжен быть больше0
Конфигурация
Если для какой-либо возможности перечислен XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT в XrSpatialCapabilityComponentTypesEXT :: componentTypes , приложение может включить её, включив этот перечисленный параметр в список XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents производной структуры XrSpatialCapabilityConfigurationBaseHeaderEXT , поддерживающей этот компонент.
Для этого компонента не требуется включать какую-либо специальную конфигурацию в цепочку XrSpatialCapabilityConfigurationBaseHeaderEXT :: next .
Создание пространственной привязки
Функция xrCreateSpatialAnchorEXT определена следующим образом:
XrResult xrCreateSpatialAnchorEXT(
XrSpatialContextEXT spatialContext,
const XrSpatialAnchorCreateInfoEXT* createInfo,
XrSpatialEntityIdEXT* anchorEntityId,
XrSpatialEntityEXT* anchorEntity);
Описание параметров
-
spatialContext— это объект XrSpatialContextEXT, созданный ранее с помощью xrCreateSpatialContextAsyncEXT . -
createInfo— это указатель на объект XrSpatialAnchorCreateInfoEXT . -
anchorEntityId— это указатель на объектXrSpatialEntityIdEXTв котором возвращается идентификатор якорного объекта. -
anchorEntity— это указатель на объект XrSpatialEntityEXT, в котором возвращается дескриптор якорного объекта.
Приложение может создать пространственную привязку с помощью функции xrCreateSpatialAnchorEXT .
Чтобы получить обновленные данные компонента для привязки, передайте значение, заполненное в anchorEntity в метод XrSpatialUpdateSnapshotCreateInfoEXT :: entities при создании снимка. Приложение может использовать anchorEntityId для уникальной идентификации этой привязки в массиве XrSpatialComponentDataQueryResultEXT :: entityIds при использовании xrQuerySpatialComponentDataEXT .
Если для spatialContext не был настроен параметр XR_SPATIAL_CAPABILITY_ANCHOR_EXT , среда выполнения должна вернуть XR_ERROR_VALIDATION_FAILURE из xrCreateSpatialAnchorEXT . См. раздел «Конфигурация» для получения информации о том, как настроить XrSpatialContextEXT для параметра XR_SPATIAL_CAPABILITY_ANCHOR_EXT .
Якорь, представленный anchorEntity , действителен только в течение времени существования spatialContext или до тех пор, пока приложение не вызовет метод xrDestroySpatialEntityEXT для него, в зависимости от того, что произойдет раньше. Другие расширения могут предлагать функции для сохранения этого вновь созданного якоря в нескольких сессиях XrSession или для его совместного использования между процессами с другими приложениями.
Вновь созданный якорь, до его уничтожения, должен быть обнаруживаем в родительском пространственном контексте. Это означает, что среда выполнения должна включать anchorEntityId в снимок, созданный с помощью xrCreateSpatialDiscoverySnapshotAsyncEXT для spatialContext , если якорь соответствует критериям обнаружения, заданным в XrSpatialDiscoverySnapshotCreateInfoEXT . Вновь созданный якорь также может быть обнаружен в других пространственных контекстах, настроенных с помощью XR_SPATIAL_CAPABILITY_ANCHOR_EXT , хотя и с другим XrSpatialEntityIdEXT , поскольку конкретный XrSpatialEntityIdEXT уникален для своего XrSpatialContextEXT .
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_anchorнеобходимо включить перед вызовом функции xrCreateSpatialAnchorEXT. -
spatialContextдолжен быть допустимым дескриптором XrSpatialContextEXT. -
createInfoдолжна быть указателем на допустимую структуру XrSpatialAnchorCreateInfoEXT. -
anchorEntityIdдолжен быть указателем на значениеXrSpatialEntityIdEXT -
anchorEntityдолжен быть указателем на дескриптор XrSpatialEntityEXT.
Коды возврата
-
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_POSE_INVALID -
XR_ERROR_RUNTIME_FAILURE -
XR_ERROR_SESSION_LOST -
XR_ERROR_TIME_INVALID -
XR_ERROR_VALIDATION_FAILURE -
XR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID(если включенаXR_ANDROID_spatial_entity_bound_anchor) -
XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT(если включена опцияXR_ANDROID_spatial_entity_bound_anchor)
Структура XrSpatialAnchorCreateInfoEXT определяется следующим образом:
typedef struct XrSpatialAnchorCreateInfoEXT {
XrStructureType type;
const void* next;
XrSpace baseSpace;
XrTime time;
XrPosef pose;
} XrSpatialAnchorCreateInfoEXT;
Описание участников
-
type— это XrStructureType данной структуры. -
next— этоNULLили указатель на следующую структуру в цепочке структур. -
baseSpace— это XrSpace, в котором применяетсяpose. -
time— это значениеXrTime, в которое находитсяbaseSpace(и применяетсяpose). -
pose— это местоположение опорного объекта.
Допустимое использование (неявное)
- Расширение
XR_EXT_spatial_anchorнеобходимо включить перед использованием XrSpatialAnchorCreateInfoEXT. -
typeдолжен бытьXR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT -
nextдолжен бытьNULLили являться допустимым указателем на следующую структуру в цепочке структур . См. также: XrSpatialAnchorParentANDROID -
baseSpaceдолжен быть допустимым дескриптором XrSpace.
Поза опорного элемента запроса
После создания якоря среда выполнения должна корректировать его положение и ориентацию во времени относительно других пространств, чтобы поддерживать наилучшее возможное выравнивание с его исходным местоположением в реальном мире, даже если это изменяет отношение якоря к исходному XrSpatialAnchorCreateInfoEXT :: baseSpace использованному для его инициализации.
Приложение может использовать xrCreateSpatialUpdateSnapshotEXT с XrSpatialEntityEXT якоря для создания нового XrSpatialSnapshotEXT , а затем запросить компонент XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT из этого снимка с помощью xrQuerySpatialComponentDataEXT . Приложение может добавить XrSpatialComponentAnchorListEXT в XrSpatialComponentDataQueryResultEXT :: next для получения последних данных о местоположении якорей.
Среда выполнения может установить состояние отслеживания вновь созданного якоря в значение XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT . Приложение должно считывать состояние сущности якоря, предоставленное в XrSpatialComponentDataQueryResultEXT :: entityStates , и данные компонента якоря сущности только в том случае, если состояние отслеживания равно XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT .
Рекомендации по использованию анкеров
- Положение каждого якорного объекта изменяется независимо от любого другого якорного объекта или пространства. Отдельно привязанные виртуальные объекты могут смещаться или вращаться относительно друг друга, нарушая пространственную иерархию в тех случаях, когда ожидается, что эти виртуальные объекты будут оставаться на месте относительно друг друга. В таких случаях приложение должно использовать один и тот же якорный объект для всех виртуальных объектов, которые не перемещаются относительно друг друга.
- Приложение должно уничтожить все дескрипторы XrSpatialEntityEXT для якорей, которые больше не используются, чтобы освободить ресурсы, которые среда выполнения может использовать для отслеживания этих якорей.
Пример кода
Настройка возможностей привязки
В следующем примере показано, как настроить параметры привязки при создании пространственного контекста.
// Create a spatial spatial context
XrSpatialContextEXT spatialContext{};
{
std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_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();
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;
}
// ...
// Create spatial anchors and get their latest pose in the frame loop.
// ...
CHK_XR(xrDestroySpatialContextEXT(spatialContext));
Создать пространственную привязку и определить её местоположение
В следующем примере показано, как создать пространственную привязку и получить её положение в каждом кадре.
XrSpatialAnchorCreateInfoEXT createInfo{XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT};
createInfo.baseSpace = localSpace;
createInfo.time = predictedDisplayTime;
createInfo.pose = {{0, 0, 0, 1}, {1, 1, 1}};
XrSpatialEntityIdEXT spatialAnchorEntityId;
XrSpatialEntityEXT spatialAnchorEntity;
CHK_XR(xrCreateSpatialAnchorEXT(spatialContext, &createInfo, &spatialAnchorEntityId, &spatialAnchorEntity));
auto updateAnchorLocation = [&](XrTime time) {
// We want to get updated data for all components of the entities, so skip specifying componentTypes.
XrSpatialUpdateSnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT};
snapshotCreateInfo.entityCount = 1;
snapshotCreateInfo.entities = &spatialAnchorEntity;
snapshotCreateInfo.baseSpace = localSpace;
snapshotCreateInfo.time = time;
XrSpatialSnapshotEXT snapshot;
CHK_XR(xrCreateSpatialUpdateSnapshotEXT(spatialContext, &snapshotCreateInfo, &snapshot));
// Query for the entities that have the anchor component on them.
std::array<XrSpatialComponentTypeEXT, 1> componentsToQuery {XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT};
XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
queryCond.componentTypeCount = componentsToQuery.size();
queryCond.componentTypes = componentsToQuery.data();
XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
CHK_XR(xrQuerySpatialComponentDataEXT(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();
// query for the pose data
std::vector<XrPosef> locations(queryResult.entityIdCountOutput);
XrSpatialComponentAnchorListEXT locationList{XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT};
locationList.locationCount = locations.size();
locationList.locations = locations.data();
queryResult.next = &locationList;
CHK_XR(xrQuerySpatialComponentDataEXT(snapshot, &queryCond, &queryResult));
for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
if (entityStates[i] == XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
// Pose for entity entityIds[i] is locations[i].
}
}
CHK_XR(xrDestroySpatialSnapshotEXT(snapshot));
};
while (1) {
// ...
// For every frame in frame loop
// ...
XrFrameState frameState; // previously returned from xrWaitFrame
const XrTime time = frameState.predictedDisplayTime;
updateAnchorLocation(time);
// ...
// Finish frame loop
// ...
}
CHK_XR(xrDestroySpatialEntityEXT(spatialAnchorEntity));
Новые команды
Новые сооружения
- XrSpatialAnchorCreateInfoEXT
- XrSpatialCapabilityConfigurationAnchorEXT
Расширение XrSpatialComponentDataQueryResultEXT :
Новые константы перечислений
-
XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAME -
XR_EXT_spatial_anchor_SPEC_VERSION Расширение XrSpatialCapabilityEXT :
-
XR_SPATIAL_CAPABILITY_ANCHOR_EXT
-
Расширение XrSpatialComponentTypeEXT :
-
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
-
Расширение XrStructureType :
-
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT -
XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT -
XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT
-
Проблемы
Почему функция xrCreateSpatialAnchorEXT выводит не только идентификатор сущности, но и её дескриптор?
- Решено
- Ответ: Функция xrCreateSpatialAnchorEXT вполне могла бы выдавать в качестве результата только идентификатор объекта, и приложения могли бы создать дескриптор объекта для этого идентификатора с помощью xrCreateSpatialEntityFromIdEXT . Однако, учитывая типичное использование якоря, когда приложения запрашивают положение якоря каждый кадр, он становится хорошим кандидатом для использования в «снимке обновления», который требует в качестве входных данных дескрипторов объектов. Предвидя этот типичный сценарий использования, xrCreateSpatialAnchorEXT выполняет xrCreateSpatialEntityFromIdEXT от имени приложения и предоставляет ему дескриптор объекта для использования с xrCreateSpatialUpdateSnapshotEXT .
История версий
Редакция 1, 10.07.2024 (Нихав Джайн, Google)
- Первоначальное описание расширения