XR_ANDROID_scene_meshing OpenXR 扩展

名称字符串 XR_ANDROID_scene_meshing

扩展程序类型 实例扩展程序

注册的扩展程序编号 464

修订版本 3

扩展程序和版本依赖项 OpenXR 1.0

上次修改日期 2025 年 5 月 15 日

IP 状态 没有已知的 IP 索赔要求。

贡献者 Spencer Quin,Google Jared Finder,Google Antonio Fontan,Google Cairn Overturf,Google Nihav Jain,Google Salar Khan,Google Sebastian Klose,Google Jürgen Sturm,Google Vinny DaSilva,Google Ricardo Campbell,Google

概览

此扩展程序旨在为大致表示环境中的物理对象的网格提供网格数据。 它可用于在沉浸式应用中直观呈现场景,并允许虚拟对象与物理对象(例如碰撞)进行互动。

场景网格化数据可能属于敏感的个人信息,与个人隐私和完整性密切相关。 强烈建议存储或传输场景网格数据的应用始终要求用户主动明确接受才能执行此操作。

权限

Android 应用必须在其清单中列出 android.permission.SCENE_UNDERSTANDING_FINE 权限。android.permission.SCENE_UNDERSTANDING_FINE 权限被视为敏感权限,因为它允许运行时研究用户环境。

应用必须在运行时请求权限才能使用以下功能:

(保护级别:危险)

检查系统功能

应用可以通过在调用 xrGetSystemProperties 时将 XrSystemSceneMeshingPropertiesANDROID 结构体链接到 XrSystemProperties 来检查系统是否支持场景网格化。

XrSystemSceneMeshingPropertiesANDROID

typedef struct XrSystemSceneMeshingPropertiesANDROID {
    XrStructureType    type;
    void*              next;
    XrBool32           supportsSceneMeshing;
} XrSystemSceneMeshingPropertiesANDROID;

会员说明

  • type 是相应结构的 XrStructureType
  • nextNULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。
  • supportsSceneMeshing 是一个 XrBool32,用于指示系统是否支持场景网格化。

如果 supportsSceneMeshingXR_FALSE,则系统不支持场景网格化。 当 supportsSceneMeshingXR_FALSE 时,应用避免使用场景网格化功能,因为对 xrCreateSceneMeshingTrackerANDROID 的调用会失败。

如果 supportsSceneMeshingXR_TRUE,则系统支持场景网格化。

有效使用情况(隐式)

XrSceneMeshSemanticLabelSetANDROID

XrSceneMeshSemanticLabelSetANDROID 枚举描述了场景网格划分的语义标签集。此枚举中的每个值都表示包含语义标签的另一个枚举。 例如,值 XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID 表示集合 XrSceneMeshSemanticLabelANDROID

typedef enum XrSceneMeshSemanticLabelSetANDROID {
    XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID = 0,
    XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID = 1,
    XR_SCENE_MESH_SEMANTIC_LABEL_SET_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrSceneMeshSemanticLabelSetANDROID;

xrEnumerateSupportedSemanticLabelSetsANDROID

应用可以使用 xrEnumerateSupportedSemanticLabelSetsANDROID 函数获取系统支持的语义标签集。

XrResult xrEnumerateSupportedSemanticLabelSetsANDROID(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    uint32_t                                    supportedSemanticLabelSetsInputCapacity,
    uint32_t*                                   supportedSemanticLabelSetsOutputCount,
    XrSceneMeshSemanticLabelSetANDROID*         supportedSemanticLabelSets);

参数说明

  • instance 是由应用创建的 XrInstance
  • systemId 是从 xrGetSystem 重试的 XrSystemId
  • supportedSemanticLabelSetsInputCapacitysupportedSemanticLabelSets 的长度。
  • supportedSemanticLabelSetsOutputCount 是运行时从数组开头开始修改的 supportedSemanticLabelSets 中的元素数量。
  • supportedSemanticLabelSets 是一个 XrSceneMeshSemanticLabelSetANDROID 数组,运行时会将支持的语义标签集写入该数组。

预计每个系统至少会支持 XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID,因为此枚举值表示未设置任何语义标签,并且在应用不需要顶点语义的情况下可以使用。

创建场景网格化跟踪器句柄

XrSceneMeshingTrackerANDROID

XR_DEFINE_HANDLE(XrSceneMeshingTrackerANDROID)

XrSceneMeshingTrackerANDROID 句柄表示用于场景网格化和管理相关资源的场景网格化跟踪器。

此句柄可用于使用此扩展程序中的 xrCreateSceneMeshSnapshotANDROID 创建场景网格快照。

xrCreateSceneMeshingTrackerANDROID

应用可以使用 xrCreateSceneMeshingTrackerANDROID 函数创建 XrSceneMeshingTrackerANDROID 句柄。

XrResult xrCreateSceneMeshingTrackerANDROID(
    XrSession                                   session,
    const XrSceneMeshingTrackerCreateInfoANDROID* createInfo,
    XrSceneMeshingTrackerANDROID*               tracker);

参数说明

如果系统不支持场景网格化,xrCreateSceneMeshingTrackerANDROID 将返回 XR_ERROR_FEATURE_UNSUPPORTED。应用可以通过使用 XrSystemSceneMeshingPropertiesANDROID 结构调用 xrGetSystemProperties 来检查系统支持情况。

创建场景网格化跟踪器时,XrSceneMeshingTrackerCreateInfoANDROID::semanticLabelSet 中只能使用系统支持的语义标签集。 函数 xrEnumerateSupportedSemanticLabelSetsANDROID 用于获取支持的语义标签集列表。

如果应用请求不受支持的 semanticLabelSetxrCreateSceneMeshingTrackerANDROID 将返回 XR_ERROR_FEATURE_UNSUPPORTED

xrCreateSceneMeshingTrackerANDROID 句柄拥有场景网格化的所有资源。 完成场景网格化体验后,应用必须通过 xrDestroySceneMeshingTrackerANDROID 函数销毁句柄。

XrSceneMeshingTrackerCreateInfoANDROID

XrSceneMeshingTrackerCreateInfoANDROID 结构描述了用于创建 XrSceneMeshingTrackerANDROID 句柄的信息。

typedef struct XrSceneMeshingTrackerCreateInfoANDROID {
    XrStructureType                       type;
    const void*                           next;
    XrSceneMeshSemanticLabelSetANDROID    semanticLabelSet;
    XrBool32                              enableNormals;
} XrSceneMeshingTrackerCreateInfoANDROID;

会员说明

  • type 是相应结构的 XrStructureType
  • nextNULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。
  • semanticLabelSet 是一个 XrSceneMeshSemanticLabelSetANDROID,用于指定场景网格化要使用的语义标签集。如果此值设置为 XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID,运行时将忽略 XrSceneSubmeshDataANDROID::vertexSemantics 缓冲区字段。
  • enableNormals 是一个 XrBool32,用于指定在获取场景网格数据时是否在场景网格缓冲区中包含网格顶点的顶点法线。

xrDestroySceneMeshingTrackerANDROID

xrDestroySceneMeshingTrackerANDROID 函数会在完成场景网格化体验后释放 tracker 和底层资源。

XrResult xrDestroySceneMeshingTrackerANDROID(
    XrSceneMeshingTrackerANDROID          tracker);

参数说明

创建场景网格快照句柄

XrSceneMeshSnapshotANDROID

XR_DEFINE_HANDLE(XrSceneMeshSnapshotANDROID)

XrSceneMeshSnapshotANDROID 句柄表示场景网格快照。这是使用 xrCreateSceneMeshSnapshotANDROID 创建的,该函数本质上是在调用时获取场景网格数据的快照。

此句柄可用于通过 xrGetAllSubmeshStatesANDROIDxrGetSubmeshDataANDROID 检索子网格信息和数据。

XrSceneMeshSnapshotCreateInfoANDROID

XrSceneMeshSnapshotCreateInfoANDROID 结构描述了用于创建 XrSceneMeshSnapshotANDROID 句柄的信息

typedef struct XrSceneMeshSnapshotCreateInfoANDROID {
    XrStructureType    type;
    const void*        next;
    XrSpace            baseSpace;
    XrTime             time;
    XrBoxf             boundingBox;
} XrSceneMeshSnapshotCreateInfoANDROID;

会员说明

  • type 是相应结构的 XrStructureType
  • nextNULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。
  • baseSpace 是一个 XrSpace,用于描述场景子网格姿势信息表示的参考空间。
  • time 是描述场景网格将被处理或显示的时间的 XrTime
  • boundingBox 是一个 XrBoxf,用于描述获取场景网格的边界框。

XrSceneMeshTrackingStateANDROID

XrSceneMeshTrackingStateANDROID 枚举描述了场景网格化跟踪器的跟踪状态。 此枚举中的每个值都表示场景网格化跟踪器的状态。 此枚举封装在 XrSceneMeshSnapshotCreationResultANDROID 结构中,该结构是从 xrCreateSceneMeshSnapshotANDROID 返回的。

typedef enum XrSceneMeshTrackingStateANDROID {
    XR_SCENE_MESH_TRACKING_STATE_INITIALIZING_ANDROID = 0,
    XR_SCENE_MESH_TRACKING_STATE_TRACKING_ANDROID = 1,
    XR_SCENE_MESH_TRACKING_STATE_WAITING_ANDROID = 2,
    XR_SCENE_MESH_TRACKING_STATE_ERROR_ANDROID = 3,
    XR_SCENE_MESH_TRACKING_STATE_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrSceneMeshTrackingStateANDROID;

XrSceneMeshSnapshotCreationResultANDROID

XrSceneMeshSnapshotCreationResultANDROID 结构用于存储场景网格快照创建的结果,该结果由 xrCreateSceneMeshSnapshotANDROID 返回。结果包括快照句柄和创建快照时场景网格化跟踪器的跟踪状态。

typedef struct XrSceneMeshSnapshotCreationResultANDROID {
    XrStructureType                  type;
    void*                            next;
    XrSceneMeshSnapshotANDROID       snapshot;
    XrSceneMeshTrackingStateANDROID    trackingState;
} XrSceneMeshSnapshotCreationResultANDROID;

会员说明

xrCreateSceneMeshSnapshotANDROID

应用可以使用 xrCreateSceneMeshSnapshotANDROID 函数从场景网格化跟踪器创建场景网格快照。此函数会返回一个 XrSceneMeshSnapshotANDROID 句柄,以及封装在 XrSceneMeshSnapshotCreationResultANDROID 结构中的 XrSceneMeshTrackingStateANDROID。 从技术上讲,句柄是创建时场景网格数据的快照。 此句柄可用于分别使用 xrGetAllSubmeshStatesANDROIDxrGetSubmeshDataANDROID 查询场景网格信息和数据。

XrResult xrCreateSceneMeshSnapshotANDROID(
    XrSceneMeshingTrackerANDROID                tracker,
    const XrSceneMeshSnapshotCreateInfoANDROID* createInfo,
    XrSceneMeshSnapshotCreationResultANDROID*   outSnapshotCreationResult);

参数说明

从场景网格快照获取场景网格数据

XrSceneSubmeshStateANDROID

XrSceneSubmeshStateANDROID 描述子网格。 它包含有关子网格的基本信息(ID、姿势、边界、上次更新时间)。

typedef struct XrSceneSubmeshStateANDROID {
    XrStructureType    type;
    void*              next;
    XrUuid             submeshId;
    XrTime             lastUpdatedTime;
    XrPosef            submeshPoseInBaseSpace;
    XrExtent3Df        bounds;
} XrSceneSubmeshStateANDROID;

会员说明

  • type 是相应结构的 XrStructureType
  • nextNULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。
  • submeshId 是用于标识子网格的 XrUuid
  • lastUpdatedTime 是一个 XrTime,表示子网格上次更新的时间。
  • submeshPoseInBaseSpace 是一个 XrPosef,表示用于创建场景网格快照的基础空间中子网格的姿势。这也是子网格边界框中心的姿势。
  • bounds 是一个 XrExtent3Df,用于描述封装子网格的边界框的尺寸。 此边界位于用于创建场景网格句柄的基础空间中。

xrGetAllSubmeshStatesANDROID

应用可以使用 xrGetAllSubmeshStatesANDROID 函数来获取场景网格中所有子网格的状态。此结构包含基本信息,可让应用选择需要数据的子网格。 此函数可以在 2 调用惯用法中使用。

XrResult xrGetAllSubmeshStatesANDROID(
    XrSceneMeshSnapshotANDROID            snapshot,
    uint32_t                              submeshStateCapacityInput,
    uint32_t*                             submeshStateCountOutput,
    XrSceneSubmeshStateANDROID*           submeshStates);

参数说明

XrSceneSubmeshDataANDROID

XrSceneSubmeshDataANDROID 包含子网格的三角形数据以及子网格 ID。 此结构用于 xrGetSubmeshDataANDROID 以获取子网格的数据。 应用必须设置此结构体的子网格 ID 和指向已分配缓冲区的缓冲区指针,以便在已分配的缓冲区中填充子网格的返回数据。 应用可以使用 xrGetSubmeshDataANDROID 作为一种双调用惯用法,其中第一个调用将要求应用设置子网格 ID 并获取子网格数据所需的缓冲区大小,然后应用可以在第二个调用中分配缓冲区并获取数据。

typedef struct XrSceneSubmeshDataANDROID {
    XrStructureType    type;
    const void*        next;
    XrUuid             submeshId;
    uint32_t           vertexCapacityInput;
    uint32_t           vertexCountOutput;
    XrVector3f*        vertexPositions;
    XrVector3f*        vertexNormals;
    uint8_t*           vertexSemantics;
    uint32_t           indexCapacityInput;
    uint32_t           indexCountOutput;
    uint32_t*          indices;
} XrSceneSubmeshDataANDROID;

会员说明

  • type 是相应结构的 XrStructureType
  • nextNULL 或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。
  • submeshId 是用于标识子网格的 XrUuid
  • vertexCapacityInputvertexPositionsvertexNormalsvertexSemantics 的长度。
  • vertexCountOutputvertexPositionsvertexNormalsvertexSemantics 中从数组开头开始已被运行时修改的元素数量。
  • vertexPositions 是一个 XrVector3f 数组,运行时将向其中输出子网格的顶点位置。
  • vertexNormals 是一个 XrVector3f 数组,运行时将向其中输出子网格的顶点法线。 如果应用创建的跟踪器的法线处于停用状态,则此字段可以留空 (NULL)。
  • vertexSemantics 是一个 uint8_t 数组,运行时会将子网格的顶点语义输出到该数组中。如果应用创建的跟踪器的语义标签已设置,此字段可以留空。NULLXR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID
  • indexCapacityInputindices 的长度。
  • indexCountOutputindices 中从数组开头开始已被运行时修改的元素数量。
  • indices 是一个 uint32_t 数组,运行时会将子网格的索引输出到该数组。

xrGetSubmeshDataANDROID

应用可以使用 xrGetSubmeshDataANDROID 函数获取所选子网格列表的数据。此函数可以在 2 调用惯用法中使用。在第一次调用中,应用必须为所选子网格列表中的每个元素设置有效的子网格 ID(即,可从 xrGetAllSubmeshStatesANDROID 中检索到,且具有相同的场景网格快照)和零容量,以获取子网格数据所需的缓冲区大小。 在第二次调用中,应用必须将缓冲区指针设置为所选子网格列表中的每个元素的已分配缓冲区,同时设置缓冲区的容量,以获取子网格的数据。

XrResult xrGetSubmeshDataANDROID(
    XrSceneMeshSnapshotANDROID            snapshot,
    uint32_t                              submeshDataCount,
    XrSceneSubmeshDataANDROID*            inoutSubmeshData);

参数说明

XrSceneMeshSemanticLabelANDROID

XrSceneMeshSemanticLabelANDROID 枚举是可用于标记网格顶点的默认语义标签集,用于描述网格顶点所在的物理环境表面。此枚举集由 XrSceneMeshSemanticLabelSetANDROID 中的 XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID 值表示。

typedef enum XrSceneMeshSemanticLabelANDROID {
    XR_SCENE_MESH_SEMANTIC_LABEL_OTHER_ANDROID = 0,
    XR_SCENE_MESH_SEMANTIC_LABEL_FLOOR_ANDROID = 1,
    XR_SCENE_MESH_SEMANTIC_LABEL_CEILING_ANDROID = 2,
    XR_SCENE_MESH_SEMANTIC_LABEL_WALL_ANDROID = 3,
    XR_SCENE_MESH_SEMANTIC_LABEL_TABLE_ANDROID = 4,
    XR_SCENE_MESH_SEMANTIC_LABEL_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrSceneMeshSemanticLabelANDROID;

销毁场景网格快照

xrDestroySceneMeshSnapshotANDROID

应用可以使用 xrDestroySceneMeshSnapshotANDROID 函数销毁场景网格快照。销毁句柄后,应用无法再使用该句柄获取子网格信息或数据。 当跟踪器被销毁时,句柄也会自动销毁,因为跟踪器句柄是场景网格快照句柄的父句柄。

XrResult xrDestroySceneMeshSnapshotANDROID(
    XrSceneMeshSnapshotANDROID            snapshot);

参数说明

场景网格化示例代码

以下示例代码演示了如何访问场景网格数据以进行渲染。

XrInstance instance;  // Created at app startup
XrSystemId systemId;  // Received from xrGetSystem() at app startup
XrSession session;    // Created at app startup
XrSpace appPlaySpace; // Created at app startup

// The function pointers are previously initialized using xrGetInstanceProcAddr.
PFN_xrCreateSceneMeshingTrackerANDROID xrCreateSceneMeshingTrackerANDROID;
PFN_xrDestroySceneMeshingTrackerANDROID xrDestroySceneMeshingTrackerANDROID;
PFN_xrEnumerateSupportedSemanticLabelSetsANDROID xrEnumerateSupportedSemanticLabelSetsANDROID;
PFN_xrCreateSceneMeshSnapshotANDROID xrCreateSceneMeshSnapshotANDROID;
PFN_xrDestroySceneMeshSnapshotANDROID xrDestroySceneMeshSnapshotANDROID;
PFN_xrGetAllSubmeshStatesANDROID xrGetAllSubmeshStatesANDROID;
PFN_xrGetSubmeshDataANDROID xrGetSubmeshDataANDROID;

// Inspect system capability
XrSystemSceneMeshingPropertiesANDROID sceneMeshingProps = {
  .type = XR_TYPE_SYSTEM_SCENE_MESHING_PROPERTIES_ANDROID,
};
XrSystemProperties sysProps = {
  .type = XR_TYPE_SYSTEM_PROPERTIES,
  .next = &sceneMeshingProps
};
CHK_XR(xrGetSystemProperties(instance, systemId, &sysProps));
if (!sceneMeshingProps.supportsSceneMeshing) {
    // scene meshing is not supported.
    return;
}

uint32_t supportedsemanticLabelSetsCount = 0;
xrEnumerateSupportedSemanticLabelSetsANDROID(
  instance, systemId, 0, &supportedsemanticLabelSetsCount, nullptr);
std::vector<XrSceneMeshSemanticLabelSetANDROID> supportedSemanticLabelSets(
  supportedsemanticLabelSetsCount);
xrEnumerateSupportedSemanticLabelSetsANDROID(
  instance, systemId, supportedsemanticLabelSetsCount,
  &supportedsemanticLabelSetsCount, supportedSemanticLabelSets.data());

XrSceneMeshSemanticLabelSetANDROID semanticLabelSet = XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID;
// Check if system supports XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID
if (std::find(supportedSemanticLabelSets.begin(), supportedSemanticLabelSets.end(),
              XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID) !=
    supportedSemanticLabelSets.end()) {
  semanticLabelSet = XR_SCENE_MESH_SEMANTIC_LABEL_SET_DEFAULT_ANDROID;
}

XrSceneMeshingTrackerCreateInfoANDROID trackerCreateInfo = {
  .type = XR_TYPE_SCENE_MESHING_TRACKER_CREATE_INFO_ANDROID,
  .semanticLabelSet = semanticLabelSet,
  .enableNormals = XR_TRUE
};

XrSceneMeshingTrackerANDROID tracker = XR_NULL_HANDLE;
CHK_XR(xrCreateSceneMeshingTrackerANDROID(session, &trackerCreateInfo, &tracker));

XrSceneMeshSnapshotCreationResultANDROID snapshotResult = {
  .type = XR_TYPE_SCENE_MESH_SNAPSHOT_CREATION_RESULT_ANDROID,
  .snapshot = XR_NULL_HANDLE
};
XrSceneMeshSnapshotANDROID& snapshot = snapshotResult.snapshot;
XrSceneMeshSnapshotCreateInfoANDROID createInfo = {
  .type = XR_TYPE_SCENE_MESH_SNAPSHOT_CREATE_INFO_ANDROID
};

// app update loop
while (true) {
  // ...
  // For every frame in frame loop
  // ...

  XrFrameState frameState; // previously returned from xrWaitFrame
  const XrTime time = frameState.predictedDisplayTime;
  XrBoxf box; // populated with the bounding box of the camera frustum

  // ...

  createInfo.baseSpace = appPlaySpace;
  createInfo.time = time;
  createInfo.boundingBox = box;

  // Grab the scene mesh snapshot. This way the app can: know all of the submesh infos,
  // choose the appropriate submeshes for which to get data, allocate the necessary
  // buffer for those submeshes, and then get the data.
  CHK_XR(xrCreateSceneMeshSnapshotANDROID(tracker, &createInfo, &snapshotResult));

  // check the tracking state
  if (snapshotResult.trackingState == XR_SCENE_MESH_TRACKING_STATE_ERROR_ANDROID) {
    // unrecoverable error. Exit the app.
    if (snapshot != XR_NULL_HANDLE) {
      CHK_XR(xrDestroySceneMeshSnapshotANDROID(snapshot));
      snapshot = XR_NULL_HANDLE;
    }
    break;
  } else if (snapshotResult.trackingState != XR_SCENE_MESH_TRACKING_STATE_TRACKING_ANDROID) {
    // The tracker is not tracking. Try again later.
    if (snapshot != XR_NULL_HANDLE) {
      CHK_XR(xrDestroySceneMeshSnapshotANDROID(snapshot));
      snapshot = XR_NULL_HANDLE;
    }
    continue;
  }

  // 2-call idiom for getting submesh states
  std::vector<XrSceneSubmeshStateANDROID> states;
  uint32_t submeshCount = 0;
  CHK_XR(xrGetAllSubmeshStatesANDROID(snapshot, 0, &submeshCount, nullptr));
  states.resize(submeshCount);
  for (XrSceneSubmeshStateANDROID& state : states) {
    state = {.type = XR_TYPE_SCENE_SUBMESH_STATE_ANDROID};
  }
  CHK_XR(xrGetAllSubmeshStatesANDROID(snapshot, submeshCount, &submeshCount, states.data()));

  // To store the poses for the selected submeshes
  std::vector<XrPosef> submeshesPoses;
  submeshesPoses.reserve(submeshCount);

  std::vector<XrSceneSubmeshDataANDROID> submeshes;
  submeshes.reserve(submeshCount);
  // Iterate the states and determine which submeshes the app wants data for
  for (XrSceneSubmeshStateANDROID& state : states) {
    // Modify this bool as necessary by looking at states. Maybe state.lastUpdatedTime
    // is below a threshold or maybe the bounding box does not intersect with camera view
    // frustum (The submesh will be culled).
    bool needed;
    if (needed) {
      // Add the selected submesh to the submeshes list. Set the capacity
      // zero for now since the size of the buffer will be determined later.
      XrSceneSubmeshDataANDROID submesh = {
        .type = XR_TYPE_SCENE_SUBMESH_DATA_ANDROID,
        .submeshId = state.submeshId,
        .vertexCapacityInput = 0,
        .vertexCountOutput = 0,
        .vertexPositions = nullptr,
        .vertexNormals = nullptr,
        .vertexSemantics = nullptr,
        .indexCapacityInput = 0,
        .indexCountOutput = 0,
        .indices = nullptr,
      };
      submeshes.push_back(submesh);
      submeshesPoses.push_back(state.submeshPoseInBaseSpace);
    }
  }

  // Grab the data for the selected submeshes using the 2-call idiom.
  CHK_XR(xrGetSubmeshDataANDROID(snapshot, submeshes.size(), submeshes.data()));
  for (XrSceneSubmeshDataANDROID& submesh : submeshes) {
    submesh.vertexCapacityInput = submesh.vertexCountOutput;
    submesh.vertexCountOutput = 0;
    submesh.vertexPositions = new XrVector3f[submesh.vertexCountOutput];
    submesh.vertexNormals = new XrVector3f[submesh.vertexCountOutput];
    submesh.vertexSemantics = new uint8_t[submesh.vertexCountOutput];
    submesh.indexCapacityInput = submesh.indexCountOutput;
    submesh.indexCountOutput = 0;
    submesh.indices = new uint32_t[submesh.indexCountOutput];
  }
  CHK_XR(xrGetSubmeshDataANDROID(snapshot, submeshes.size(), submeshes.data()));

  // Destroy the scene mesh snapshot since we have finally grabbed the submeshes data. In
  // next iteration app can: create a new one to get latest mesh data
  CHK_XR(xrDestroySceneMeshSnapshotANDROID(snapshot));
  snapshot = XR_NULL_HANDLE;

  // Iterate the submeshes and get the vertex positions, vertex normals and
  // vertex semantics data for the selected submeshes
  for (uint32_t i = 0; i < submeshes.size(); i++) {
    XrSceneSubmeshDataANDROID& data = submeshes[i];
    XrVector3f* vertexPositions = data.vertexPositions;
    XrVector3f* vertexNormals = data.vertexNormals;
    XrSceneMeshSemanticLabelANDROID* vertexSemantics =
      reinterpret_cast<XrSceneMeshSemanticLabelANDROID*>(data.vertexSemantics);
    XrPosef pose = submeshesPoses[i];

    // *** Use the data as per needs ***

    // Release the allocated memory for the data buffers when done using
    delete [] data.vertexPositions;
    delete [] data.vertexNormals;
    delete [] data.vertexSemantics;
    delete [] data.indices;
  }

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

CHK_XR(xrDestroySceneMeshingTrackerANDROID(tracker));

新的对象类型

新的枚举常量

XrObjectType 枚举已扩展为包含:

  • XR_OBJECT_TYPE_SCENE_MESHING_TRACKER_ANDROID
  • XR_OBJECT_TYPE_SCENE_MESH_SNAPSHOT_ANDROID

XrStructureType 枚举已扩展为包含以下内容:

  • XR_TYPE_SYSTEM_SCENE_MESHING_PROPERTIES_ANDROID
  • XR_TYPE_SCENE_MESHING_TRACKER_CREATE_INFO_ANDROID
  • XR_TYPE_SCENE_MESH_SNAPSHOT_CREATE_INFO_ANDROID
  • XR_TYPE_SCENE_MESH_SNAPSHOT_CREATION_RESULT_ANDROID
  • XR_TYPE_SCENE_SUBMESH_STATE_ANDROID
  • XR_TYPE_SCENE_SUBMESH_DATA_ANDROID

新枚举

新结构

新函数

问题

版本历史记录

  • 修订版 3,2025-05-15 (Salar Khan) ** 初始扩展程序说明

OpenXR™ 和 OpenXR 徽标是 The Khronos Group Inc. 拥有的商标,已在中国、欧盟、日本和英国注册为商标。