名称字符串
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
权限被视为敏感权限,因为它允许运行时研究用户环境。
应用必须在运行时请求权限才能使用以下功能:
- xrCreateSceneMeshingTrackerANDROID
- xrDestroySceneMeshingTrackerANDROID
- xrCreateSceneMeshSnapshotANDROID
- xrDestroySceneMeshSnapshotANDROID
- xrGetAllSubmeshStatesANDROID
- xrGetSubmeshDataANDROID
(保护级别:危险)
检查系统功能
应用可以通过在调用 xrGetSystemProperties 时将 XrSystemSceneMeshingPropertiesANDROID 结构体链接到 XrSystemProperties 来检查系统是否支持场景网格化。
XrSystemSceneMeshingPropertiesANDROID
typedef struct XrSystemSceneMeshingPropertiesANDROID {
XrStructureType type;
void* next;
XrBool32 supportsSceneMeshing;
} XrSystemSceneMeshingPropertiesANDROID;
会员说明
type
是相应结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。supportsSceneMeshing
是一个 XrBool32,用于指示系统是否支持场景网格化。
如果 supportsSceneMeshing
为 XR_FALSE
,则系统不支持场景网格化。
当 supportsSceneMeshing
为 XR_FALSE
时,应用应避免使用场景网格化功能,因为对 xrCreateSceneMeshingTrackerANDROID 的调用会失败。
如果 supportsSceneMeshing
为 XR_TRUE
,则系统支持场景网格化。
有效使用情况(隐式)
- 必须先启用
XR_ANDROID_scene_meshing
扩展程序,然后才能使用 XrSystemSceneMeshingPropertiesANDROID type
必须为XR_TYPE_SYSTEM_SCENE_MESHING_PROPERTIES_ANDROID
next
必须为NULL
或指向结构链中下一个结构的有效指针
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。supportedSemanticLabelSetsInputCapacity
是supportedSemanticLabelSets
的长度。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);
参数说明
session
是场景网格化跟踪器将处于活动状态的 XrSession。createInfo
是一个指向 XrSceneMeshingTrackerCreateInfoANDROID 结构的指针,用于描述要创建的场景网格化跟踪器。tracker
是返回的 XrSceneMeshingTrackerANDROID 句柄。
如果系统不支持场景网格化,xrCreateSceneMeshingTrackerANDROID 将返回 XR_ERROR_FEATURE_UNSUPPORTED
。应用可以通过使用 XrSystemSceneMeshingPropertiesANDROID 结构调用 xrGetSystemProperties 来检查系统支持情况。
创建场景网格化跟踪器时,XrSceneMeshingTrackerCreateInfoANDROID::semanticLabelSet 中只能使用系统支持的语义标签集。 函数 xrEnumerateSupportedSemanticLabelSetsANDROID 可用于获取支持的语义标签集列表。
如果应用请求不受支持的 semanticLabelSet
,xrCreateSceneMeshingTrackerANDROID 将返回 XR_ERROR_FEATURE_UNSUPPORTED
。
xrCreateSceneMeshingTrackerANDROID 句柄拥有场景网格化的所有资源。 完成场景网格化体验后,应用必须通过 xrDestroySceneMeshingTrackerANDROID 函数销毁句柄。
XrSceneMeshingTrackerCreateInfoANDROID
XrSceneMeshingTrackerCreateInfoANDROID 结构描述了用于创建 XrSceneMeshingTrackerANDROID 句柄的信息。
typedef struct XrSceneMeshingTrackerCreateInfoANDROID {
XrStructureType type;
const void* next;
XrSceneMeshSemanticLabelSetANDROID semanticLabelSet;
XrBool32 enableNormals;
} XrSceneMeshingTrackerCreateInfoANDROID;
会员说明
type
是相应结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。semanticLabelSet
是一个 XrSceneMeshSemanticLabelSetANDROID,用于指定场景网格化要使用的语义标签集。如果此值设置为XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID
,运行时将忽略 XrSceneSubmeshDataANDROID::vertexSemantics 缓冲区字段。enableNormals
是一个 XrBool32,用于指定在获取场景网格数据时是否在场景网格缓冲区中包含网格顶点的顶点法线。
xrDestroySceneMeshingTrackerANDROID
xrDestroySceneMeshingTrackerANDROID 函数会在完成场景网格化体验后释放 tracker
和底层资源。
XrResult xrDestroySceneMeshingTrackerANDROID(
XrSceneMeshingTrackerANDROID tracker);
参数说明
tracker
是之前由 xrCreateSceneMeshingTrackerANDROID 创建的 XrSceneMeshingTrackerANDROID。
创建场景网格快照句柄
XrSceneMeshSnapshotANDROID
XR_DEFINE_HANDLE(XrSceneMeshSnapshotANDROID)
XrSceneMeshSnapshotANDROID 句柄表示场景网格快照。这是使用 xrCreateSceneMeshSnapshotANDROID 创建的,该函数本质上是在调用时获取场景网格数据的快照。
此句柄可用于通过 xrGetAllSubmeshStatesANDROID 和 xrGetSubmeshDataANDROID 检索子网格信息和数据。
XrSceneMeshSnapshotCreateInfoANDROID
XrSceneMeshSnapshotCreateInfoANDROID 结构描述了用于创建 XrSceneMeshSnapshotANDROID 句柄的信息
typedef struct XrSceneMeshSnapshotCreateInfoANDROID {
XrStructureType type;
const void* next;
XrSpace baseSpace;
XrTime time;
XrBoxf boundingBox;
} XrSceneMeshSnapshotCreateInfoANDROID;
会员说明
type
是相应结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 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;
会员说明
type
是相应结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。snapshot
是由运行时创建的 XrSceneMeshSnapshotANDROID 句柄。trackingState
是一个 XrSceneMeshTrackingStateANDROID,用于描述创建快照时场景网格化跟踪器的状态。
xrCreateSceneMeshSnapshotANDROID
应用可以使用 xrCreateSceneMeshSnapshotANDROID 函数从场景网格化跟踪器创建场景网格快照。此函数会返回一个 XrSceneMeshSnapshotANDROID 句柄,以及封装在 XrSceneMeshSnapshotCreationResultANDROID 结构中的 XrSceneMeshTrackingStateANDROID。 从技术上讲,句柄是创建时场景网格数据的快照。 此句柄可用于分别使用 xrGetAllSubmeshStatesANDROID 和 xrGetSubmeshDataANDROID 查询场景网格信息和数据。
XrResult xrCreateSceneMeshSnapshotANDROID(
XrSceneMeshingTrackerANDROID tracker,
const XrSceneMeshSnapshotCreateInfoANDROID* createInfo,
XrSceneMeshSnapshotCreationResultANDROID* outSnapshotCreationResult);
参数说明
tracker
是之前使用 xrCreateSceneMeshingTrackerANDROID 创建的 XrSceneMeshingTrackerANDROID 句柄。createInfo
是指向 XrSceneMeshSnapshotCreateInfoANDROID 结构的指针,该结构包含创建场景网格快照所需的必要信息。outSnapshotCreationResult
是指向 XrSceneMeshSnapshotCreationResultANDROID 对象的指针,该对象由运行时填充快照创建结果。
从场景网格快照获取场景网格数据
XrSceneSubmeshStateANDROID
XrSceneSubmeshStateANDROID 描述子网格。 它包含有关子网格的基本信息(ID、姿势、边界、上次更新时间)。
typedef struct XrSceneSubmeshStateANDROID {
XrStructureType type;
void* next;
XrUuid submeshId;
XrTime lastUpdatedTime;
XrPosef submeshPoseInBaseSpace;
XrExtent3Df bounds;
} XrSceneSubmeshStateANDROID;
会员说明
type
是相应结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。submeshId
是用于标识子网格的 XrUuid。lastUpdatedTime
是一个 XrTime,表示子网格上次更新的时间。submeshPoseInBaseSpace
是一个 XrPosef,表示用于创建场景网格快照的基础空间中子网格的姿势。这也是子网格边界框中心的姿势。bounds
是一个 XrExtent3Df,用于描述封装子网格的边界框的尺寸。 此边界位于用于创建场景网格句柄的基础空间中。
xrGetAllSubmeshStatesANDROID
应用可以使用 xrGetAllSubmeshStatesANDROID 函数来获取场景网格中所有子网格的状态。此结构包含基本信息,可让应用选择需要数据的子网格。 此函数可以在 2 调用惯用法中使用。
XrResult xrGetAllSubmeshStatesANDROID(
XrSceneMeshSnapshotANDROID snapshot,
uint32_t submeshStateCapacityInput,
uint32_t* submeshStateCountOutput,
XrSceneSubmeshStateANDROID* submeshStates);
参数说明
snapshot
是之前使用 xrCreateSceneMeshSnapshotANDROID 创建的 XrSceneMeshSnapshotANDROID 句柄。submeshStateCapacityInput
是submeshStates
的长度。submeshStateCountOutput
是submeshStates
中从数组开头开始由运行时修改的元素数量。submeshStates
是一个 XrSceneSubmeshStateANDROID 结构体数组,运行时会将场景网格中所有子网格的状态输出到该数组。
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。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展程序中未定义此类结构。submeshId
是用于标识子网格的 XrUuid。vertexCapacityInput
是vertexPositions
、vertexNormals
和vertexSemantics
的长度。vertexCountOutput
是vertexPositions
、vertexNormals
和vertexSemantics
中从数组开头开始已被运行时修改的元素数量。vertexPositions
是一个 XrVector3f 数组,运行时将向其中输出子网格的顶点位置。vertexNormals
是一个 XrVector3f 数组,运行时将向其中输出子网格的顶点法线。 如果应用创建的跟踪器的法线处于停用状态,则此字段可以留空 (NULL
)。vertexSemantics
是一个uint8_t
数组,运行时会将子网格的顶点语义输出到该数组中。如果应用创建的跟踪器的语义标签已设置,此字段可以留空。NULL
XR_SCENE_MESH_SEMANTIC_LABEL_SET_NONE_ANDROID
indexCapacityInput
是indices
的长度。indexCountOutput
是indices
中从数组开头开始已被运行时修改的元素数量。indices
是一个uint32_t
数组,运行时会将子网格的索引输出到该数组。
xrGetSubmeshDataANDROID
应用可以使用 xrGetSubmeshDataANDROID 函数获取所选子网格列表的数据。此函数可以在 2 调用惯用法中使用。在第一次调用中,应用必须为所选子网格列表中的每个元素设置有效的子网格 ID(即,可从 xrGetAllSubmeshStatesANDROID 中检索到,且具有相同的场景网格快照)和零容量,以获取子网格数据所需的缓冲区大小。 在第二次调用中,应用必须将缓冲区指针设置为所选子网格列表中的每个元素的已分配缓冲区,同时设置缓冲区的容量,以获取子网格的数据。
XrResult xrGetSubmeshDataANDROID(
XrSceneMeshSnapshotANDROID snapshot,
uint32_t submeshDataCount,
XrSceneSubmeshDataANDROID* inoutSubmeshData);
参数说明
snapshot
是之前使用 xrCreateSceneMeshSnapshotANDROID 创建的 XrSceneMeshSnapshotANDROID 句柄。submeshDataCount
是inoutSubmeshData
的长度。inoutSubmeshData
是一个 XrSceneSubmeshDataANDROID 数组,其中每个元素都将由运行时根据子网格 ID 填充网格数据。
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);
参数说明
snapshot
是之前使用 xrCreateSceneMeshSnapshotANDROID 创建的 XrSceneMeshSnapshotANDROID 句柄,将由此函数销毁。
场景网格化示例代码
以下示例代码演示了如何访问场景网格数据以进行渲染。
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
新枚举
新结构
- XrSystemSceneMeshingPropertiesANDROID
- XrSceneMeshingTrackerCreateInfoANDROID
- XrSceneMeshSnapshotCreateInfoANDROID
- XrSceneMeshSnapshotCreationResultANDROID
- XrSceneSubmeshStateANDROID
- XrSceneSubmeshDataANDROID
新函数
- xrCreateSceneMeshingTrackerANDROID
- xrDestroySceneMeshingTrackerANDROID
- xrEnumerateSupportedSemanticLabelSetsANDROID
- xrCreateSceneMeshSnapshotANDROID
- xrDestroySceneMeshSnapshotANDROID
- xrGetAllSubmeshStatesANDROID
- xrGetSubmeshDataANDROID
问题
版本历史记录
- 修订版 3,2025-05-15 (Salar Khan) ** 初始扩展程序说明
OpenXR™ 和 OpenXR 徽标是 The Khronos Group Inc. 拥有的商标,已在中国、欧盟、日本和英国注册为商标。