名称字符串
XR_ANDROID_hand_mesh
扩展程序类型
实例扩展
已注册的扩展号码
704
修订版本
1
扩展程序和版本依赖项
上次修改日期
2024-09-10
IP 状态
没有已知的 IP 版权主张。
创作贡献者
Nihav Jain,Google
Cairn Overturf,Google
Spencer Quin,Google
Levana Chen,Google
概览
此扩展程序支持以动态手部网格表示的手部跟踪。
此扩展旨在为用户手部个性化表示的网格提供顶点和索引缓冲区。它可用于遮挡和可视化。
此扩展程序不应用于其他手部跟踪用途。
- 如需进行互动,可以使用
XR_EXT_hand_interaction
。 - 对于骨骼关节,可以使用
XR_EXT_hand_tracking
。
手部跟踪数据可能属于敏感个人信息,与个人隐私和完整性密切相关。强烈建议存储或传输手部跟踪数据的应用始终征求用户明确的积极同意。
检查系统功能
应用可以在调用 xrGetSystemProperties 时将 XrSystemHandMeshTrackingPropertiesANDROID 结构链接到 XrSystemProperties,以检查系统是否能够跟踪手部网格。
typedef struct XrSystemHandMeshTrackingPropertiesANDROID {
XrStructureType type;
void* next;
XrBool32 supportsHandMeshTracking;
XrBool32 supportsTextureUV;
XrBool32 supportsVertexNormal;
} XrSystemHandMeshTrackingPropertiesANDROID;
成员说明
type
是此结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展中未定义任何此类结构。supportsHandMeshTracking
是一个XrBool32
,用于指示所选XrSystemId
是否支持手部网格跟踪。supportsTextureUV
是一个XrBool32
,用于指示所选XrSystemId
是否支持网格顶点的纹理 UV。supportsVertexNormal
是一个XrBool32
,用于指示所选的XrSystemId
是否支持网格顶点的顶点法线。
当 supportsHandMeshTracking
为 XR_FALSE
时,应用应避免使用手部网格功能,因为这意味着系统不支持手部网格跟踪。在这种情况下,xrCreateHandMeshTrackerANDROID 将返回 XR_ERROR_FEATURE_UNSUPPORTED
。
如果 supportsHandMeshTracking
返回 XR_TRUE
,则表示系统支持手部网格跟踪。应用应使用 XrHandMeshANDROID::indexCount 和 XrHandMeshANDROID::vertexCount 访问手部网格缓冲区,并在每次调用 xrGetHandMeshANDROID 时在其渲染循环中重复使用这些缓冲区。
如果 supportsTextureUV
返回 XR_FALSE
,则系统不支持网格顶点的纹理 UV,因此应用在调用 xrGetHandMeshANDROID 时会收到 XrHandMeshANDROID::textureUVs NULL
。
如果 supportsVertexNormal
返回 XR_FALSE
,则系统不支持网格顶点的顶点法线,因此应用在调用 xrGetHandMeshANDROID 时会收到 XrHandMeshANDROID::normals NULL
。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能使用 XrSystemHandMeshTrackingPropertiesANDROID type
必须为XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID
next
必须为NULL
,或指向结构链中的下一个结构的有效指针
创建手部网格跟踪器手柄
XR_DEFINE_HANDLE(XrHandMeshTrackerANDROID)
XrHandMeshTrackerANDROID 句柄表示用于手部网格跟踪和管理相关资源的手部网格跟踪器。
此句柄可用于使用此扩展程序中的其他函数访问手部网格缓冲区。
应用可以使用 xrCreateHandMeshTrackerANDROID 函数创建 XrHandMeshTrackerANDROID 句柄。
XrResult xrCreateHandMeshTrackerANDROID(
XrSession session,
const XrHandMeshTrackerCreateInfoANDROID* createInfo,
XrHandMeshTrackerANDROID* handMeshTracker);
参数说明
session
是一个 XrSession,其中手部网格跟踪器将处于活动状态。createInfo
是用于指定手部网格跟踪器的 XrHandMeshTrackerCreateInfoANDROID。handMeshTracker
是返回的 XrHandMeshTrackerANDROID 句柄。
如果系统不支持手部网格跟踪,xrCreateHandMeshTrackerANDROID 将返回 XR_ERROR_FEATURE_UNSUPPORTED
。
XrHandMeshTrackerANDROID 句柄拥有手部网格跟踪的所有资源。在完成手部网格跟踪体验后,应用必须使用 xrDestroyHandMeshTrackerANDROID 函数销毁句柄。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能调用 xrCreateHandMeshTrackerANDROID session
必须是有效的 XrSession 句柄createInfo
必须是指向有效 XrHandMeshTrackerCreateInfoANDROID 结构的指针handMeshTracker
必须是指向 XrHandMeshTrackerANDROID 句柄的指针
返回代码
XR_SUCCESS
XR_SESSION_LOSS_PENDING
XR_ERROR_FEATURE_UNSUPPORTED
XR_ERROR_FUNCTION_UNSUPPORTED
XR_ERROR_RUNTIME_FAILURE
XR_ERROR_INSTANCE_LOST
XR_ERROR_SESSION_LOST
XR_ERROR_OUT_OF_MEMORY
XR_ERROR_HANDLE_INVALID
XR_ERROR_LIMIT_REACHED
XrHandMeshTrackerCreateInfoANDROID 结构描述了用于创建 XrHandMeshTrackerANDROID 句柄的信息。
typedef struct XrHandMeshTrackerCreateInfoANDROID {
XrStructureType type;
const void* next;
} XrHandMeshTrackerCreateInfoANDROID;
成员说明
type
是此结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展中未定义任何此类结构。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能使用 XrHandMeshTrackerCreateInfoANDROID type
必须为XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
next
必须为NULL
,或指向结构链中的下一个结构的有效指针
xrDestroyHandMeshTrackerANDROID 函数会在手部网格跟踪体验结束时释放 handMeshTracker
和底层资源。
XrResult xrDestroyHandMeshTrackerANDROID(
XrHandMeshTrackerANDROID handMeshTracker);
参数说明
handMeshTracker
是之前通过 xrCreateHandMeshTrackerANDROID 创建的 XrHandMeshTrackerANDROID。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能调用 xrDestroyHandMeshTrackerANDROID handMeshTracker
必须是有效的 XrHandMeshTrackerANDROID 句柄
线程安全
- 对
handMeshTracker
和任何子句柄的访问必须在外部进行同步
返回代码
XR_SUCCESS
XR_ERROR_FUNCTION_UNSUPPORTED
XR_ERROR_HANDLE_INVALID
查找手网格
应用可以使用 xrGetHandMeshANDROID 函数检索给定时间戳的手部网格。调用 xrGetHandMeshANDROID 时,手网格的顶点位置和法线表示在 XrHandMeshGetInfoANDROID::baseSpace 指定的空间中。
XrResult xrGetHandMeshANDROID(
XrHandMeshTrackerANDROID handMeshTracker,
const XrHandMeshGetInfoANDROID* getInfo,
XrHandTrackingMeshesANDROID* handMeshes);
参数说明
handMeshTracker
是之前使用 xrCreateHandMeshTrackerANDROID 创建的 XrHandMeshTrackerANDROID 句柄。getInfo
是一个 XrHandMeshGetInfoANDROID 结构,其中包含用于查询手部网格数据的信息。handMeshes
是指向 XrHandTrackingMeshesANDROID 结构的指针,该结构将填充手网格数据。
应用可以使用 xrGetHandMeshANDROID 函数访问运行时生成的手部网格缓冲区。
在首次调用 xrGetHandMeshANDROID 之前,应用应在会话期间至少调用一次 xrBeginFrame。
应用应使用 XrHandMeshANDROID::indexCount 和 XrHandMeshANDROID::vertexCount 访问手部网格缓冲区,并在每次调用 xrGetHandMeshANDROID 时在其渲染循环中重复使用这些缓冲区。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能调用 xrGetHandMeshANDROID handMeshTracker
必须是有效的 XrHandMeshTrackerANDROID 句柄getInfo
必须是指向有效 XrHandMeshGetInfoANDROID 结构的指针handMeshes
必须是指向 XrHandTrackingMeshesANDROID 结构的指针
返回代码
XR_SUCCESS
XR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTED
XR_ERROR_RUNTIME_FAILURE
XR_ERROR_INSTANCE_LOST
XR_ERROR_SESSION_LOST
XR_ERROR_HANDLE_INVALID
XR_ERROR_SIZE_INSUFFICIENT
XR_ERROR_TIME_INVALID
XrHandMeshGetInfoANDROID 介绍了获取手部网格数据所需的信息。
typedef struct XrHandMeshGetInfoANDROID {
XrStructureType type;
const void* next;
XrSpace baseSpace;
XrTime time;
} XrHandMeshGetInfoANDROID;
成员说明
type
是此结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展中未定义任何此类结构。baseSpace
是一个 XrSpace,用于定义在time
中放置顶点的转换的参考空间。time
是XrTime
,用于描述应用希望查询手部网格的时刻。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能使用 XrHandMeshGetInfoANDROID type
必须为XR_TYPE_HAND_MESH_GET_INFO_ANDROID
next
必须为NULL
,或指向结构链中的下一个结构的有效指针baseSpace
必须是有效的 XrSpace 句柄
XrHandTrackingMeshesANDROID 结构包含双手的网格数据。
typedef struct XrHandTrackingMeshesANDROID {
XrStructureType type;
void* next;
XrHandMeshANDROID leftHandMesh;
XrHandMeshANDROID rightHandMesh;
} XrHandTrackingMeshesANDROID;
成员说明
type
是此结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展中未定义任何此类结构。leftHandMesh
是左手的 XrHandMeshANDROID。rightHandMesh
是右手的 XrHandMeshANDROID。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能使用 XrHandTrackingMeshesANDROID type
必须为XR_TYPE_HAND_TRACKING_MESHES_ANDROID
next
必须为NULL
,或指向结构链中的下一个结构的有效指针leftHandMesh
必须是有效的 XrHandMeshANDROID 结构rightHandMesh
必须是有效的 XrHandMeshANDROID 结构
XrHandMeshANDROID 结构包含数据和缓冲区,用于接收一只手的 xrGetHandMeshANDROID 函数的掌纹追踪数据。
typedef struct XrHandMeshANDROID {
XrBool32 isActive;
XrTime dynamicLastUpdateTime;
uint32_t indexCount;
uint32_t vertexCount;
const uint32_t* indices;
const XrVector2f* textureUVs;
const XrVector3f* positions;
const XrVector3f* normals;
XrPosef baseSpaceFromVertexSpace;
} XrHandMeshANDROID;
成员说明
type
是此结构的 XrStructureType。next
是NULL
或指向结构链中下一个结构的指针。核心 OpenXR 或此扩展中未定义任何此类结构。isActive
是一个XrBool32
,用于指示当前的手部网格跟踪器是否处于活动状态以及网格数据是否有效。dynamicLastUpdateTime
是XrTime
,用于指定上次更新动态缓冲区的时间。indexCount
是一个uint32_t
,用作手网格的indices
数量。vertexCount
是一个uint32_t
,用作手部网格的positions
数量。当系统支持textureUVs
或normals
时,还可以将其用于textureUVs
或normals
。indices
是一个uint32_t
数组,表示三角形的网格索引,顺序为逆时针。指向的值的数量为indexCount
。textureUVs
是NULL
或表示顶点纹理坐标的XrVector2f
数组。所指向的值的数量为vertexCount
。positions
是一个XrVector3f
数组,表示baseSpaceFromVertexSpace
中的顶点位置。所指向的值的数量为vertexCount
。normals
是NULL
或XrVector3f
数组,表示baseSpaceFromVertexSpace
中的顶点法向量。所指向的值的数量为vertexCount
。baseSpaceFromVertexSpace
是调用 xrGetHandMeshANDROID 时位于 XrHandMeshGetInfoANDROID::baseSpace 中的顶点 XrSpace。应用可以使用它在渲染期间转换网格顶点和法线的坐标空间。
手部网格以三角形列表的形式表示,从手部外侧观察时,每个三角形的顶点均按逆时针顺序排列。
如果返回的 isActive
值为 XR_FALSE
,则表示系统未主动跟踪手部;例如,手部超出传感器的范围、输入焦点已从应用移开,或者应用无权访问手部跟踪数据。
当返回的 isActive
值为 XR_TRUE
时,indices
和 positions
中表示的手部跟踪网格(包括 textureUVs
和 normals
,如果系统支持的话)会更新为给定 xrGetHandMeshANDROID 函数的 XrHandMeshGetInfoANDROID::time 的最新数据。
XrHandMeshANDROID 中返回的手部网格缓冲区指向的内存归运行时所有,并与应用共享。在下次调用 xrBeginFrame 之前,只要 XrHandMeshTrackerANDROID 句柄有效,就可以从任何线程安全地访问内存。
indices
和textureUVs
指向的值不是动态- 指针以及
positions
和normals
指向的值都是动态的,在对 xrBeginFrame 的调用之间,这两个值都可能会发生变化。应用可以使用dynamicLastUpdateTime
检查值自上一个帧以来是否发生了变化,并在没有变化时避免不必要的数据处理。
有效用法(隐式)
- 必须先启用
XR_ANDROID_hand_mesh
扩展程序,然后才能使用 XrHandMeshANDROID indices
必须是指向有效uint32_t
值的指针textureUVs
必须是指向有效 XrVector2f 结构的指针positions
必须是指向有效 XrVector3f 结构的指针normals
必须是指向有效 XrVector3f 结构的指针
手部网格跟踪的示例代码
以下示例代码演示了如何访问手部网格缓冲区以进行渲染。
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_xrCreateHandMeshTrackerANDROID xrCreateHandMeshTrackerANDROID; // previously initialized
PFN_xrDestroyHandMeshTrackerANDROID xrDestroyHandMeshTrackerANDROID; // previously initialized
PFN_xrGetHandMeshANDROID xrGetHandMeshANDROID; // previously initialized
// Inspect system capability
XrSystemHandMeshTrackingPropertiesANDROID handMeshTrackingProps = {
.type = XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID,
};
XrSystemProperties sysProps = {
.type = XR_TYPE_SYSTEM_PROPERTIES,
.next = &handMeshTrackingProps
};
CHK_XR(xrGetSystemProperties(instance, systemId, &sysProps));
if (!handMeshTrackingProps.supportsHandMeshTracking) {
// hand mesh tracking is not supported.
return;
}
XrHandMeshTrackerCreateInfoANDROID trackerCreateInfo = {
.type = XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
};
XrHandMeshTrackerANDROID handMeshTracker = XR_NULL_HANDLE;
CHK_XR(xrCreateHandMeshTrackerANDROID(
session, &trackerCreateInfo, &handMeshTracker));
// app update loop
while (true) {
// ...
// For every frame in frame loop
// ...
XrFrameState frameState; // previously returned from xrWaitFrame
const XrTime time = frameState.predictedDisplayTime;
// ...
XrHandMeshGetInfoANDROID getInfo = {
.type = XR_TYPE_HAND_MESH_GET_INFO_ANDROID,
.baseSpace = appPlaySpace,
.time = time,
};
XrHandTrackingMeshesANDROID handMeshes = {
.type = XR_TYPE_HAND_TRACKING_MESHES_ANDROID
};
CHK_XR(xrGetHandMeshANDROID(handMeshTracker, &getInfo, &handMeshes));
if (handMeshes.leftHandMesh.isActive) {
// access vertex/index buffers for rendering.
}
// ...
// Finish frame loop
// ...
}
CHECK_XR(xrDestroyHandMeshTracker(handMeshTracker));
新的对象类型
新的枚举常量
XrObjectType 枚举已扩展为:
XR_OBJECT_TYPE_HAND_MESH_TRACKER_ANDROID
XrStructureType 枚举已扩展为:
XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID
XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
XR_TYPE_HAND_MESH_GET_INFO_ANDROID
XR_TYPE_HAND_TRACKING_MESHES_ANDROID
新枚举
新结构
- XrSystemHandMeshTrackingPropertiesANDROID
- XrHandMeshTrackerCreateInfoANDROID
- XrHandMeshGetInfoANDROID
- XrHandMeshANDROID
- XrHandTrackingMeshesANDROID
新函数
问题
版本历史记录
- 修订版 1,2024 年 9 月 10 日(Levana Chen)
- 初始扩展程序说明