XR_EXT_spatial_object_tracking

名称字符串

XR_EXT_spatial_object_tracking

扩展程序类型

实例扩展程序

已注册的扩展程序编号

745

修订版本

1

批准状态

未批准

扩展程序和版本依赖项

XR_EXT_spatial_entity

IP 状态

没有已知的 IP 权利主张。

创作贡献者

Nihav Jain,Google
Natalie Fleury,Meta
Yuichi Taguchi,Meta
Ron Bessems,Meta
Yin Li,Microsoft
Jimmy Alamparambil,字节跳动
Zhipeng Liu,字节跳动
Jun Yan,字节跳动
Andy Biar,Unity Technologies
Rebecca Nordhauser,Unity Technologies

概览

此扩展程序基于 XR_EXT_spatial_entity 构建,并定义了一项空间功能,用于跟踪一组预定义的对象,而无需应用提供输入数据集。

运行时支持

如果运行时支持对象跟踪,则必须通过在 xrEnumerateSpatialCapabilitiesEXT 中枚举 XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT 来表明这一点。

配置

XrSpatialCapabilityConfigurationObjectTrackingEXT 结构的定义如下:

typedef struct XrSpatialCapabilityConfigurationObjectTrackingEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
} XrSpatialCapabilityConfigurationObjectTrackingEXT;

成员说明

  • type 是此结构的 XrStructureType。
  • next 是 NULL 或指向结构链中下一个结构的指针。
  • capability 是一个 XrSpatialCapabilityEXT,必须为 XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT。
  • enabledComponentCount 是一个 uint32_t,用于描述 enabledComponents 数组中的元素数量。
  • enabledComponents 是一个指向 XrSpatialComponentTypeEXT 数组的指针。

应用可以通过在 XrSpatialContextCreateInfoEXT :: capabilityConfigs 中添加指向 XrSpatialCapabilityConfigurationObjectTrackingEXT 结构的指针,来启用 XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT 空间功能。

如果 capability 不是 XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT,则运行时必须返回 XR_ERROR_VALIDATION_FAILURE。

有效用法(隐式)

保证型组件

支持 XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT 的运行时必须支持以下空间组件,作为此功能发现的实体的保证组件,并且必须在 xrEnumerateSpatialCapabilityComponentTypesEXT 中枚举这些组件:

  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_3D_EXT
  • 至少一个组件类型,用于为跟踪的对象提供一组语义标签。如果没有语义标签组件,对象跟踪功能就毫无意义。虽然此扩展程序将 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT 和 XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT 定义为运行时可能支持的语义标签组件,但其他扩展程序可以定义新的组件类型,以提供描述被跟踪对象的不同类别的语义标签。如需详细了解语义标签集和组件类型设计,请参阅 [ext_spatial_semantic_labels_guidelines]。运行时可以不支持 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT 或 XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT 的对象跟踪功能,但必须支持至少一种提供语义标签的组件类型。

有界 3D 组件

有界 3D 组件提供其所在实体所代表对象的中心和范围。如需了解详情,请参阅有界 3D。

可选组件

除了保证组件部分中列出的组件之外,支持 XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT 的运行时可能还支持空间组件。应用可以使用 xrEnumerateSpatialCapabilityComponentTypesEXT 获取运行时支持的组件的完整列表,然后可以在创建空间上下文时配置其感兴趣的组件。

对象语义标签

组件数据

typedef enum XrSpatialObjectSemanticLabelEXT {
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_UNCATEGORIZED_EXT = 1,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_SOFA_EXT = 2,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_BED_EXT = 3,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_CHAIR_EXT = 4,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_TABLE_EXT = 5,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_LAMP_EXT = 6,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_PLANT_EXT = 7,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_DISPLAY_SCREEN_EXT = 8,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_WALL_ART_EXT = 9,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_CABINET_EXT = 10,
    XR_SPATIAL_OBJECT_SEMANTIC_LABEL_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialObjectSemanticLabelEXT;

XrSpatialObjectSemanticLabelEXT 枚举描述了一组对象的语义标签。

对于带有 XR_SPATIAL_OBJECT_SEMANTIC_LABEL_DISPLAY_SCREEN_EXT 标签的实体,Bounded 3D 组件的 +Z 轴必须大致与屏幕的表面法线一致。

对于带有 XR_SPATIAL_OBJECT_SEMANTIC_LABEL_WALL_ART_EXT 标签的实体,Bounded 3D 组件的 +Z 轴必须与发现艺术品的墙壁的表面法线一致。

对于带有 XR_SPATIAL_OBJECT_SEMANTIC_LABEL_TABLE_EXT 标签的实体,Bounded 3D 组件的 +Z 轴必须与桌面的表面法线一致。

对于 XrSpatialObjectSemanticLabelEXT 中的所有其他标签,应用不得对实体上 Bounded 3D 组件提供的 XrBoxf :: center :: orientation 如何与该对象的物理属性对齐做出任何假设。

枚举值具有以下含义:

枚举说明

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_UNCATEGORIZED_EXT

运行时无法对此实体进行分类。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_SOFA_EXT

实体是沙发。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_BED_EXT

实体是床。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_CHAIR_EXT

该实体是一把椅子。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_TABLE_EXT

实体是一个表。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_LAMP_EXT

实体是一盏灯。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_PLANT_EXT

该实体是一种植物。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_DISPLAY_SCREEN_EXT

实体是显示屏,例如显示器或电视。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_WALL_ART_EXT

实体是墙面艺术。

XR_SPATIAL_OBJECT_SEMANTIC_LABEL_CABINET_EXT

实体是柜子。

用于查询数据的组件列表结构

XrSpatialComponentObjectSemanticLabelListEXT 结构的定义如下:

typedef struct XrSpatialComponentObjectSemanticLabelListEXT {
    XrStructureType                     type;
    void*                               next;
    uint32_t                            semanticLabelCount;
    XrSpatialObjectSemanticLabelEXT*    semanticLabels;
} XrSpatialComponentObjectSemanticLabelListEXT;

成员说明

  • type 是此结构的 XrStructureType。
  • next 是 NULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义任何此类结构。
  • semanticLabelCount 是一个 uint32_t,用于描述 semanticLabels 数组中的元素数量。
  • semanticLabels 是一个 XrSpatialObjectSemanticLabelEXT 数组。

如需查询 XrSpatialSnapshotEXT 中空间实体的对象语义标签组件,请在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中添加 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT,并将 XrSpatialComponentObjectSemanticLabelListEXT 添加到 XrSpatialComponentDataQueryResultEXT :: next 链中。

如果 XrSpatialComponentObjectSemanticLabelListEXT 位于 XrSpatialComponentDataQueryResultEXT :: next 链中,但 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT 未包含在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中,则运行时必须从 xrQuerySpatialComponentDataEXT 返回 XR_ERROR_VALIDATION_FAILURE。

如果 semanticLabelCount 小于 XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput,则运行时必须从 xrQuerySpatialComponentDataEXT 返回 XR_ERROR_SIZE_INSUFFICIENT。

有效用法(隐式)

配置

如果 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT 在 XrSpatialCapabilityComponentTypesEXT :: componentTypes 中针对某项功能进行了枚举,则应用可以通过将该枚举项包含在支持此组件的功能的 XrSpatialCapabilityConfigurationBaseHeaderEXT 派生结构的 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 列表中来启用该功能。

此组件不需要任何特殊配置即可包含在 XrSpatialCapabilityConfigurationBaseHeaderEXT :: next 链中,但确实提供了可选配置供应用提供。

XrSpatialFeatureObjectSemanticLabelSubsetEXT 结构的定义如下:

typedef struct XrSpatialFeatureObjectSemanticLabelSubsetEXT {
    XrStructureType                           type;
    const void*                               next;
    uint32_t                                  semanticLabelCount;
    const XrSpatialObjectSemanticLabelEXT*    semanticLabels;
} XrSpatialFeatureObjectSemanticLabelSubsetEXT;

成员说明

  • type 是此结构的 XrStructureType。
  • next 是 NULL 或指向结构链中下一个结构的指针。
  • semanticLabelCount 是一个 uint32_t,用于描述 semanticLabels 数组中的元素数量。
  • semanticLabels 是一个 XrSpatialObjectSemanticLabelEXT 数组。

如果运行时针对给定功能从 xrEnumerateSpatialCapabilityComponentTypesEXT 枚举 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT,则它必须针对同一功能从 xrEnumerateSpatialCapabilityFeaturesEXT 枚举 XR_SPATIAL_CAPABILITY_FEATURE_OBJECT_SEMANTIC_LABEL_SUBSET_EXT。如果应用在配置该功能时启用了 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT,则可以将 XrSpatialFeatureObjectSemanticLabelSubsetEXT 链接到该功能的相应配置结构,以便为运行时提供 XrSpatialObjectSemanticLabelEXT 中定义的标签子集。运行时可能会使用此标签子集来优化其跟踪流水线。

如果 semanticLabels 包含任何未在 XrSpatialObjectSemanticLabelEXT 中定义的标签,或者 semanticLabels 包含 XR_SPATIAL_OBJECT_SEMANTIC_LABEL_UNCATEGORIZED_EXT,则运行时必须从 xrCreateSpatialContextAsyncEXT 返回 XR_ERROR_VALIDATION_FAILURE。

如果应用在 semanticLabels 中提供了有效的标签列表,但 XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT 未包含在 XrSpatialFeatureObjectSemanticLabelSubsetEXT 链接到的配置结构的 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 数组中,则运行时必须从 xrCreateSpatialContextAsyncEXT 返回 XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT。

如果应用使用有效的 XrSpatialFeatureObjectSemanticLabelSubsetEXT 配置功能,则运行时不得在为配置的空间上下文创建的任何发现快照中包含具有未在 semanticLabels 中列出的语义标签的实体。

有效用法(隐式)

键盘语义标签

组件数据

typedef enum XrSpatialKeyboardSemanticLabelEXT {
    XR_SPATIAL_KEYBOARD_SEMANTIC_LABEL_UNCATEGORIZED_EXT = 1,
    XR_SPATIAL_KEYBOARD_SEMANTIC_LABEL_KEYBOARD_EXT = 2,
    XR_SPATIAL_KEYBOARD_SEMANTIC_LABEL_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialKeyboardSemanticLabelEXT;

XrSpatialKeyboardSemanticLabelEXT 枚举描述了键盘的语义标签。

XR_SPATIAL_KEYBOARD_SEMANTIC_LABEL_KEYBOARD_EXT 的范围和方向由同一实体上的有界 3D 组件表示,如下图所示(其中 xyz = rgb),源自对象的中心。

ext spatial object tracking keyboard orientation

图 30. 键盘方向。

枚举说明

XR_SPATIAL_KEYBOARD_SEMANTIC_LABEL_UNCATEGORIZED_EXT

运行时无法对此实体进行分类。

XR_SPATIAL_KEYBOARD_SEMANTIC_LABEL_KEYBOARD_EXT

实体是键盘。

用于查询数据的组件列表结构体

XrSpatialComponentKeyboardSemanticLabelListEXT 结构的定义如下:

typedef struct XrSpatialComponentKeyboardSemanticLabelListEXT {
    XrStructureType                       type;
    void*                                 next;
    uint32_t                              semanticLabelCount;
    XrSpatialKeyboardSemanticLabelEXT*    semanticLabels;
} XrSpatialComponentKeyboardSemanticLabelListEXT;

成员说明

  • type 是此结构的 XrStructureType。
  • next 是 NULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义任何此类结构。
  • semanticLabelCount 是一个 uint32_t,用于描述 semanticLabels 数组中的元素数量。
  • semanticLabels 是一个 XrSpatialKeyboardSemanticLabelEXT 数组。

如需查询 XrSpatialSnapshotEXT 中空间实体的键盘语义标签组件,请在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中添加 XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT,并将 XrSpatialComponentKeyboardSemanticLabelListEXT 添加到 XrSpatialComponentDataQueryResultEXT :: next 链中。

如果 XrSpatialComponentKeyboardSemanticLabelListEXT 位于 XrSpatialComponentDataQueryResultEXT :: next 链中,但 XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT 未包含在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中,则运行时必须从 xrQuerySpatialComponentDataEXT 返回 XR_ERROR_VALIDATION_FAILURE。

如果 semanticLabelCount 小于 XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput,则运行时必须从 xrQuerySpatialComponentDataEXT 返回 XR_ERROR_SIZE_INSUFFICIENT。

有效用法(隐式)

配置

如果 XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT 在 XrSpatialCapabilityComponentTypesEXT :: componentTypes 中针对某项功能进行了枚举,则应用可以通过将该枚举项包含在支持此组件的功能的 XrSpatialCapabilityConfigurationBaseHeaderEXT 派生结构的 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 列表中来启用该功能。

此组件不需要任何特殊配置即可包含在 XrSpatialCapabilityConfigurationBaseHeaderEXT :: next 链中。

鼠标语义标签

组件数据

typedef enum XrSpatialMouseSemanticLabelEXT {
    XR_SPATIAL_MOUSE_SEMANTIC_LABEL_UNCATEGORIZED_EXT = 1,
    XR_SPATIAL_MOUSE_SEMANTIC_LABEL_MOUSE_EXT = 2,
    XR_SPATIAL_MOUSE_SEMANTIC_LABEL_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialMouseSemanticLabelEXT;

XrSpatialMouseSemanticLabelEXT 枚举描述了鼠标的语义标签。

枚举说明

XR_SPATIAL_MOUSE_SEMANTIC_LABEL_UNCATEGORIZED_EXT

运行时无法对此实体进行分类。

XR_SPATIAL_MOUSE_SEMANTIC_LABEL_MOUSE_EXT

实体是鼠标。

用于查询数据的组件列表结构体

XrSpatialComponentMouseSemanticLabelListEXT 结构的定义如下:

typedef struct XrSpatialComponentMouseSemanticLabelListEXT {
    XrStructureType                    type;
    void*                              next;
    uint32_t                           semanticLabelCount;
    XrSpatialMouseSemanticLabelEXT*    semanticLabels;
} XrSpatialComponentMouseSemanticLabelListEXT;

成员说明

  • type 是此结构的 XrStructureType。
  • next 是 NULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义任何此类结构。
  • semanticLabelCount 是一个 uint32_t,用于描述 semanticLabels 数组中的元素数量。
  • semanticLabels 是一个 XrSpatialMouseSemanticLabelEXT 数组。

如需查询 XrSpatialSnapshotEXT 中空间实体的鼠标语义标签组件,请在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中添加 XR_SPATIAL_COMPONENT_TYPE_MOUSE_SEMANTIC_LABEL_EXT,并将 XrSpatialComponentMouseSemanticLabelListEXT 添加到 XrSpatialComponentDataQueryResultEXT :: next 链中。

如果 XrSpatialComponentMouseSemanticLabelListEXT 位于 XrSpatialComponentDataQueryResultEXT :: next 链中,但 XR_SPATIAL_COMPONENT_TYPE_MOUSE_SEMANTIC_LABEL_EXT 未包含在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中,则运行时必须从 xrQuerySpatialComponentDataEXT 返回 XR_ERROR_VALIDATION_FAILURE。

如果 semanticLabelCount 小于 XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput,则运行时必须从 xrQuerySpatialComponentDataEXT 返回 XR_ERROR_SIZE_INSUFFICIENT。

有效用法(隐式)

配置

如果 XR_SPATIAL_COMPONENT_TYPE_MOUSE_SEMANTIC_LABEL_EXT 在 XrSpatialCapabilityComponentTypesEXT :: componentTypes 中针对某项功能进行了枚举,则应用可以通过将该枚举项包含在支持此组件的功能的 XrSpatialCapabilityConfigurationBaseHeaderEXT 派生结构的 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 列表中来启用该功能。

此组件不需要任何特殊配置即可包含在 XrSpatialCapabilityConfigurationBaseHeaderEXT :: next 链中。

示例代码

配置对象跟踪功能

以下示例代码演示了如何在创建空间上下文时配置对象跟踪功能。

// Check if object tracking capability is supported
uint32_t capabilityCount;
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_EXT) == capabilities.end()) {
  return;
}

// Enumerate supported components for object tracking capability
XrSpatialCapabilityComponentTypesEXT objectComponents{XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT};
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT, &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_EXT, &objectComponents));

// Check if the object & keyboard semantic labels component is supported
const auto supportsComponent = [&objectCapabilityComponents](XrSpatialComponentTypeEXT component) {
  return std::find(objectCapabilityComponents.begin(), objectCapabilityComponents.end(), component) != objectCapabilityComponents.end();
};

const bool supportsObjectSemanticLabel = supportsComponent(XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT);
const bool supportsKeyboardSemanticLabel = supportsComponent(XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT);

// Enumerate supported features for object tracking capability
uint32_t featureCount;
CHK_XR(xrEnumerateSpatialCapabilityFeaturesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT, 0, &featureCount, nullptr));
std::vector<XrSpatialCapabilityFeatureEXT> features(featureCount);
CHK_XR(xrEnumerateSpatialCapabilityFeaturesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT, featureCount, &featureCount, features.data()));

const bool supportsObjectSemanticLabelSubsetFeature = std::find(features.begin(), features.end(), XR_SPATIAL_CAPABILITY_FEATURE_OBJECT_SEMANTIC_LABEL_SUBSET_EXT) != features.end();

// Create a spatial context
XrSpatialContextEXT spatialContext{};

// Enable the guaranteed components of the object tracking capability
std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_3D_EXT,
};
// Optionally enable the supported semantic labels
if (supportsObjectSemanticLabel) {
  enabledComponents.push_back(XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT);
}
if (supportsKeyboardSemanticLabel) {
  enabledComponents.push_back(XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT);
}

// We only want to track sofa and table.
std::vector<XrSpatialObjectSemanticLabelEXT> objectSemanticLabelSubset = {
  XR_SPATIAL_OBJECT_SEMANTIC_LABEL_SOFA_EXT,
  XR_SPATIAL_OBJECT_SEMANTIC_LABEL_TABLE_EXT
};
XrSpatialFeatureObjectSemanticLabelSubsetEXT subsetFeature{XR_TYPE_SPATIAL_FEATURE_OBJECT_SEMANTIC_LABEL_SUBSET_EXT};
subsetFeature.semanticLabelCount = objectSemanticLabelSubset.size();
subsetFeature.semanticLabels = objectSemanticLabelSubset.data();

XrSpatialCapabilityConfigurationObjectTrackingEXT objectTrackingConfig{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_EXT};
objectTrackingConfig.capability = XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT;
objectTrackingConfig.enabledComponentCount = enabledComponents.size();
objectTrackingConfig.enabledComponents = enabledComponents.data();
if (supportsObjectSemanticLabelSubsetFeature) {
  objectTrackingConfig.next = &subsetFeature;
}

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

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;

// ...
// Discovery entities with the spatial context
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

发现空间实体和查询组件数据

以下示例代码演示了如何发现为配置了 XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT 的上下文创建的空间实体,并查询其组件数据。

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,
};
if (supportsKeyboardSemanticLabel) {
  snapshotComponents.push_back(XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_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<XrBoxf> bounded3D(queryResult.entityIdCountOutput);
    XrSpatialComponentBounded3DListEXT bounded3DList{XR_TYPE_SPATIAL_COMPONENT_BOUNDED_3D_LIST_EXT};
    bounded3DList.boundCount = bounded3D.size();
    bounded3DList.bounds = bounded3D.data();
    queryResult.next = &bounded3DList;

    std::vector<XrSpatialKeyboardSemanticLabelEXT> semanticLabels;
    XrSpatialComponentKeyboardSemanticLabelListEXT semanticLabelsList{XR_TYPE_SPATIAL_COMPONENT_KEYBOARD_SEMANTIC_LABEL_LIST_EXT};
    if (supportsKeyboardSemanticLabel) {
      semanticLabels.resize(queryResult.entityIdCountOutput);
      semanticLabelsList.semanticLabelCount = semanticLabels.size();
      semanticLabelsList.semanticLabels = semanticLabels.data();
      semanticLabelsList.next = queryResult.next;
      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.

      if (supportsKeyboardSemanticLabel) {
        // 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 = {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
  // ...
}

新结构

新枚举

新枚举常量

  • XR_EXT_SPATIAL_OBJECT_TRACKING_EXTENSION_NAME
  • XR_EXT_spatial_object_tracking_SPEC_VERSION
  • 扩展 XrSpatialCapabilityEXT:

    • XR_SPATIAL_CAPABILITY_OBJECT_TRACKING_EXT
  • 扩展 XrSpatialCapabilityFeatureEXT:

    • XR_SPATIAL_CAPABILITY_FEATURE_OBJECT_SEMANTIC_LABEL_SUBSET_EXT
  • 扩展 XrSpatialComponentTypeEXT:

    • XR_SPATIAL_COMPONENT_TYPE_KEYBOARD_SEMANTIC_LABEL_EXT
    • XR_SPATIAL_COMPONENT_TYPE_MOUSE_SEMANTIC_LABEL_EXT
    • XR_SPATIAL_COMPONENT_TYPE_OBJECT_SEMANTIC_LABEL_EXT
  • 扩展 XrStructureType:

    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_OBJECT_TRACKING_EXT
    • XR_TYPE_SPATIAL_COMPONENT_KEYBOARD_SEMANTIC_LABEL_LIST_EXT
    • XR_TYPE_SPATIAL_COMPONENT_MOUSE_SEMANTIC_LABEL_LIST_EXT
    • XR_TYPE_SPATIAL_COMPONENT_OBJECT_SEMANTIC_LABEL_LIST_EXT
    • XR_TYPE_SPATIAL_FEATURE_OBJECT_SEMANTIC_LABEL_SUBSET_EXT

问题

版本历史记录

  • 修订版本 1,2025 年 6 月 3 日(Nihav Jain,Google)

    • 初始扩展程序说明