XR_ANDROID_spatial_object_tracking

Строка имени

XR_ANDROID_spatial_object_tracking

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

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

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

786

Пересмотр

2

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

Не ратифицировано

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

XR_EXT_spatial_entity

Дата последнего изменения

2025-06-25

Статус IP

Известных претензий на интеллектуальную собственность нет.

Авторы

Кайл Чен, Google
Нихав Джайн, Google
Левана Чен, Google
Спенсер Куин, Google

Обзор

Это расширение основано на XR_EXT_spatial_entity и определяет пространственные возможности для отслеживания набора предопределенных физических объектов без необходимости ввода данных из приложения. Например, система может отслеживать клавиатуры, мыши и другие объекты в окружающей среде, а затем сообщать приложению их положение и размеры.

Разрешения

В манифесте Android-приложений должно быть указано разрешение android.permission.SCENE_UNDERSTANDING_COARSE, поскольку это расширение зависит от геометрии окружающей среды. Разрешение android.permission.SCENE_UNDERSTANDING_COARSE считается опасным.

(Уровень защиты: опасный)

Поддержка во время выполнения

Если среда выполнения поддерживает отслеживание объектов, она должна указать это, перечислив переменную XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID в переменной xrEnumerateSpatialCapabilitiesEXT .

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

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

typedef struct XrSpatialCapabilityConfigurationObjectTrackingANDROID {
    XrStructureType                               type;
    const void*                                   next;
    XrSpatialCapabilityEXT                        capability;
    uint32_t                                      enabledComponentCount;
    const XrSpatialComponentTypeEXT*              enabledComponents;
    uint32_t                                      activeSemanticLabelCount;
    const XrSpatialObjectSemanticLabelANDROID*    activeSemanticLabels;
} XrSpatialCapabilityConfigurationObjectTrackingANDROID;

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

  • type — это XrStructureType данной структуры.
  • next — это NULL или указатель на следующую структуру в цепочке структур.
  • capability представляет собой XrSpatialCapabilityEXT и должна быть XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID .
  • enabledComponentCount — это тип uint32_t , описывающий количество элементов в массиве enabledComponents . Он должен быть больше 0.
  • enabledComponents — это указатель на массив XrSpatialComponentTypeEXT .
  • activeSemanticLabelCount — это тип данных uint32_t , описывающий количество элементов в массиве activeSemanticLabels . Он может быть равен 0, что означает, что все семантические метки активны, или больше 0, в этом случае массив activeSemanticLabels используется для определения того, какие семантические метки активны.
  • activeSemanticLabels — это указатель на массив XrSpatialObjectSemanticLabelANDROID , указывающий на активные объекты в отслеживании. Он должен быть равен null, если activeSemanticLabelCount равен 0. И он должен быть ненулевым, если activeSemanticLabelCount больше 0, что означает, что он используется для определения того, какие семантические метки являются активными.

Приложения могут включить пространственную возможность XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID , добавив указатель на структуру XrSpatialCapabilityConfigurationObjectTrackingANDROID в XrSpatialContextCreateInfoEXT :: capabilityConfigs .

Если capability не равна XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID , среда выполнения должна вернуть XR_ERROR_VALIDATION_FAILURE .

Приложения могут указать желаемые семантические метки в activeSemanticLabels , которые они предпочитают отслеживать. Если в activeSemanticLabels не указаны семантические метки и activeSemanticLabelCount равно 0, по умолчанию отслеживаются все семантические метки.

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

  • Расширение XR_ANDROID_spatial_object_tracking необходимо включить перед использованием XrSpatialCapabilityConfigurationObjectTrackingANDROID.
  • type должен быть XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID
  • next должно быть NULL или допустимым указателем на следующую структуру в цепочке структур.
  • Значение capability должно быть допустимым значением XrSpatialCapabilityEXT.
  • enabledComponents должен быть указателем на массив допустимых значений XrSpatialComponentTypeEXT, равных enabledComponentCount .
  • activeSemanticLabels должен быть указателем на массив допустимых значений XrSpatialObjectSemanticLabelANDROID, равных activeSemanticLabelCount
  • Параметр enabledComponentCount должен быть больше 0
  • Параметр activeSemanticLabelCount должен быть больше 0

Гарантированные компоненты

Среда выполнения, поддерживающая XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID , должна поддерживать следующие пространственные компоненты в качестве гарантированных компонентов объектов, обнаруженных с помощью этой возможности, и должна перечислять их в xrEnumerateSpatialCapabilityComponentTypesEXT -

  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_3D_EXT
  • XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_ANDROID Возможность отслеживания объектов бессмысленна без компонента семантической метки. Хотя это расширение определяет XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_ANDROID как один из возможных компонентов семантической метки, поддерживаемых средами выполнения, другие расширения могут определять новые типы компонентов для предоставления различных классов семантических меток, описывающих отслеживаемый объект.

Ограниченный 3D-компонент

Компонент «Ограниченное 3D» определяет центр и границы объекта, представленного сущностью, на которой он расположен. Более подробную информацию см. в разделе «Ограниченное 3D» .

Компонент семантической метки объекта

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

typedef enum XrSpatialObjectSemanticLabelANDROID {
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_UNCATEGORIZED_ANDROID = 0,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_KEYBOARD_ANDROID = 1,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MOUSE_ANDROID = 2,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_LAPTOP_BASE_ANDROID = 3,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrSpatialObjectSemanticLabelANDROID;

Перечисление XrSpatialObjectSemanticLabelANDROID описывает набор семантических меток для объекта.

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

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_UNCATEGORIZED_ANDROID

Программа выполнения не смогла классифицировать этот объект.

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_KEYBOARD_ANDROID

Данный объект — клавиатура.

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MOUSE_ANDROID

Объект — мышь.

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_LAPTOP_BASE_ANDROID

Предметом является ноутбук.

Пространственная ориентация объекта

Ориентация объектов показана на следующем изображении (где xyz = rgb), начиная с нижней центральной части объектов.

Трехмерная ориентация мыши совпадает с трехмерной ориентацией опорной плоскости. Границы охватывают клавиатуру и мышь, а также основание ноутбука.

XR ANDROID пространственная ориентация объектов

Рисунок 34. Пример ориентации объекта.

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

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

typedef struct XrSpatialComponentObjectSemanticLabelListANDROID {
    XrStructureType                         type;
    void*                                   next;
    uint32_t                                semanticLabelCount;
    XrSpatialObjectSemanticLabelANDROID*    semanticLabels;
} XrSpatialComponentObjectSemanticLabelListANDROID;

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

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

Приложение может запрашивать компонент семантической метки пространственных объектов в XrSpatialSnapshotEXT , добавив XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_ANDROID в XrSpatialComponentDataQueryConditionEXT :: componentTypes и добавив XrSpatialComponentObjectSemanticLabelListANDROID в следующую цепочку указателей XrSpatialComponentDataQueryResultEXT .

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

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

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

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

Если для какой-либо возможности в XrSpatialCapabilityComponentTypesEXT :: componentTypes перечислено XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_ANDROID , приложение может включить эту возможность, включив перечисление в список XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents структуры, производной от XrSpatialCapabilityConfigurationBaseHeaderEXT , которая поддерживает этот компонент.

Для включения этого компонента в следующую цепочку XrSpatialCapabilityConfigurationBaseHeaderEXT не требуется никакой специальной конфигурации.

Пример кода

Настройка функции отслеживания объектов

Приведенный ниже пример кода демонстрирует, как настроить отслеживание объектов при создании пространственного контекста.

// Check if object tracking capability is supported
uint32_t capabilityCount = 0;
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, 0, &capabilityCount, nullptr));
std::vector<XrSpatialCapabilityEXT> capabilities(capabilityCount);
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, capabilityCount, &capabilityCount, capabilities.data()));

if (std::find(capabilities.begin(), capabilities.end(), XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID) == capabilities.end()) {
  return;
}

// Enumerate supported components for object tracking capability
XrSpatialCapabilityComponentTypesEXT objectComponents{
  .type = XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT,
};
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID, &objectComponents));
std::vector<XrSpatialComponentTypeEXT> objectCapabilityComponents(objectComponents.componentTypeCountOutput);
objectComponents.componentTypeCapacityInput = objectCapabilityComponents.size();
objectComponents.componentTypes = objectCapabilityComponents.data();
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID, &objectComponents));

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

// Enable the 2 guaranteed components (bounded 3D, semantic label) of the object tracking capability
std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_3D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_ANDROID,
};

// Specify some semantic labels to be active and tracked
std::vector<XrSpatialObjectSemanticLabelANDROID> activeSemanticLabels =
{
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_KEYBOARD_ANDROID,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MOUSE_ANDROID,
};

XrSpatialCapabilityConfigurationObjectTrackingANDROID objectTrackingConfig{
  .type = XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID,
  .capability = XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID,
  .enabledComponentCount = static_cast<uint32_t>(enabledComponents.size()),
  .enabledComponents = enabledComponents.data(),
  // Specify the count of active semantic labels and the pointer to the array of
  // active semantic labels.
  // If the `activeSemanticLabelCount` is 0 and `activeSemanticLabels` is NULL,
  // all labels will be set to active by default.
  .activeSemanticLabelCount = static_cast<uint32_t>(activeSemanticLabels.size()),
  .activeSemanticLabels = activeSemanticLabels.data(),
};

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

XrSpatialContextCreateInfoEXT spatialContextCreateInfo{
  .type = XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT,
  .capabilityConfigCount = capabilityConfigs.size(),
  .capabilityConfigs = capabilityConfigs.data(),
};
XrFutureEXT createContextFuture {XR_NULL_FUTURE_EXT};
CHK_XR(xrCreateSpatialContextAsyncEXT(session, &spatialContextCreateInfo, &createContextFuture));

waitUntilReady(createContextFuture);

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

spatialContext = completion.spatialContext;

// ...
// Discover entities with the spatial context
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

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

Приведенный ниже пример кода демонстрирует, как обнаруживать пространственные объекты для контекста, настроенного с XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_ANDROID , и запрашивать данные его компонентов.

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_BOUNDED_3D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_ANDROID,
};

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

  waitUntilReady(future);

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

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{
    .type = 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{
      .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT,
      .componentTypeCount = static_cast<uint32_t>(snapshotComponents.size()),
      .componentTypes = snapshotComponents.data(),
    };

    XrSpatialComponentDataQueryResultEXT queryResult{
      .type = 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<XrBoxf> bounded3D(queryResult.entityIdCountOutput);
    XrSpatialComponentBounded3DListEXT bounded3DList{
      .type = XR_TYPE_SPATIAL_COMPONENT_BOUNDED_3D_LIST_EXT,
      .boundCount = static_cast<uint32_t>(bounded3D.size()),
      .bounds = bounded3D.data(),
    };
    queryResult.next = &bounded3DList;

    std::vector<XrSpatialObjectSemanticLabelANDROID> semanticLabels(queryResult.entityIdCountOutput);
    XrSpatialComponentObjectSemanticLabelListANDROID semanticLabelsList{
      .type = XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_ANDROID,
      .semanticLabelCount = static_cast<uint32_t>(semanticLabels.size()),
      .semanticLabels = semanticLabels.data(),
    };
    queryResult.next = &semanticLabelsList;

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

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      if (entityStates[i] != XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
        continue;
      }

      // 3D bounds for entity entityIds[i] is bounded3D[i].extents centered on bounded3D[i].center.

      // semantic label for entity entityIds[i] is semanticLabels[i].

    }

    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 = {
    .type = XR_TYPE_EVENT_DATA_BUFFER,
  };
  XrResult result = xrPollEvent(instance, &event);
  if (result == XR_SUCCESS) {
    if (event.type == 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);
    }
  }

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

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

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

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

  • XR_ANDROID_SPATIAL_OBJECT_TRACKING_EXTENSION_NAME
  • XR_ANDROID_spatial_object_tracking_SPEC_VERSION
  • Расширение XrSpatialCapabilityEXT :

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

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

    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_ANDROID
    • XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_ANDROID

Проблемы

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

  • Редакция 1, 26.06.2025 (Кайл Чен)

    • Первоначальное описание расширения.
  • Редакция 2, 04.12.2025 (Кайл Чен)

    • Обновите формат примера в соответствии с новым стилем.