Name String
XR_ANDROID_hand_mesh
Extension Type
Instance extension
Registered Extension Number
704
Revision
1
Extension and Version Dependencies
Last Modified Date
2024-09-10
IP Status
No known IP claims.
Contributors
Nihav Jain, Google
Cairn Overturf, Google
Spencer Quin, Google
Levana Chen, Google
Overview
This extension enables hand tracking represented as a dynamic hand mesh.
This extension is intended to provide vertex and index buffers for the mesh of a personalized representation of the user's hands. It can be used for occlusion and visualization.
This extension should not be used for other hand tracking purposes.
- For interaction, XR_EXT_hand_interactioncan be used.
- For skeletal joints, XR_EXT_hand_trackingcan be used.
Hand tracking data can be sensitive personal information and is closely linked to personal privacy and integrity. It is strongly recommended that applications that store or transfer hand tracking data always ask the user for active and specific acceptance to do so.
Inspect system capability
An application can inspect whether the system is capable of hand tracking meshes by chaining an XrSystemHandMeshTrackingPropertiesANDROID structure to the XrSystemProperties when calling xrGetSystemProperties.
typedef struct XrSystemHandMeshTrackingPropertiesANDROID {
  XrStructureType    type;
  void*              next;
  XrBool32           supportsHandMeshTracking;
  XrBool32           supportsTextureUV;
  XrBool32           supportsVertexNormal;
} XrSystemHandMeshTrackingPropertiesANDROID;
Member Descriptions
- typeis the XrStructureType of this structure.
- nextis- NULLor a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR or this extension.
- supportsHandMeshTrackingis an- XrBool32, indicating if the selected- XrSystemIdsupports hand mesh tracking.
- supportsTextureUVis an- XrBool32, indicating if the selected- XrSystemIdsupports texture UVs for the mesh vertices.
- supportsVertexNormalis an- XrBool32, indicating if the selected- XrSystemIdsupports vertex normals for the mesh vertices.
The application should avoid using hand mesh capabilities when
supportsHandMeshTracking is XR_FALSE, since this means the system does not
support hand mesh tracking. In this case, xrCreateHandMeshTrackerANDROID
will return XR_ERROR_FEATURE_UNSUPPORTED.
If supportsHandMeshTracking returns XR_TRUE, the system
supports hand mesh tracking. An application should use
XrHandMeshANDROID::indexCount and XrHandMeshANDROID::vertexCount to
access hand mesh buffers and reuse them in their render loop when calling
xrGetHandMeshANDROID every frame.
If supportsTextureUV returns XR_FALSE, the system does not
support texture UVs for the mesh vertices, and therefore an application would
receive XrHandMeshANDROID::textureUVs NULL when calling
xrGetHandMeshANDROID.
If supportsVertexNormal returns XR_FALSE, the system does not
support vertex normals for the mesh vertices, and therefore an application would
receive XrHandMeshANDROID::normals NULL when calling
xrGetHandMeshANDROID.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to using XrSystemHandMeshTrackingPropertiesANDROID
- typemust be- XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID
- nextmust be- NULLor a valid pointer to the next structure in a structure chain
Create a hand mesh tracker handle
XR_DEFINE_HANDLE(XrHandMeshTrackerANDROID)
The XrHandMeshTrackerANDROID handle represents a hand mesh tracker for hand mesh tracking and managing the related resources.
This handle can be used to access hand mesh buffers using other functions in this extension.
An application can create an XrHandMeshTrackerANDROID handle using xrCreateHandMeshTrackerANDROID function.
XrResult xrCreateHandMeshTrackerANDROID(
    XrSession                                   session,
    const XrHandMeshTrackerCreateInfoANDROID*   createInfo,
    XrHandMeshTrackerANDROID*                   handMeshTracker);
Parameter Descriptions
- sessionis an XrSession in which the hand mesh tracker will be active.
- createInfois the XrHandMeshTrackerCreateInfoANDROID used to specify the hand mesh tracker.
- handMeshTrackeris the returned XrHandMeshTrackerANDROID handle.
If the system does not support hand mesh tracking,
xrCreateHandMeshTrackerANDROID will return XR_ERROR_FEATURE_UNSUPPORTED.
The XrHandMeshTrackerANDROID handle owns all the resources for hand mesh tracking. After finishing with hand mesh tracking experiences, the application must destroy the handle using the xrDestroyHandMeshTrackerANDROID function.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to calling xrCreateHandMeshTrackerANDROID
- sessionmust be a valid XrSession handle
- createInfomust be a pointer to a valid XrHandMeshTrackerCreateInfoANDROID structure
- handMeshTrackermust be a pointer to an XrHandMeshTrackerANDROID handle
Return Codes
- 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
The XrHandMeshTrackerCreateInfoANDROID structure describes the information to create an XrHandMeshTrackerANDROID handle.
typedef struct XrHandMeshTrackerCreateInfoANDROID {
    XrStructureType    type;
    const void*        next;
} XrHandMeshTrackerCreateInfoANDROID;
Member Descriptions
- typeis the XrStructureType of this structure.
- nextis- NULLor a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR or this extension.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to using XrHandMeshTrackerCreateInfoANDROID
- typemust be- XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
- nextmust be- NULLor a valid pointer to the next structure in a structure chain
xrDestroyHandMeshTrackerANDROID function releases the handMeshTracker
and the underlying resources when finished with hand mesh tracking experiences.
XrResult xrDestroyHandMeshTrackerANDROID(
    XrHandMeshTrackerANDROID handMeshTracker);
Parameter Descriptions
- handMeshTrackeris an XrHandMeshTrackerANDROID previously created by xrCreateHandMeshTrackerANDROID.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to calling xrDestroyHandMeshTrackerANDROID
- handMeshTrackermust be a valid XrHandMeshTrackerANDROID handle
Thread Safety
- Access to handMeshTracker, and any child handles, must be externally synchronized
Return Codes
- XR_SUCCESS
- XR_ERROR_FUNCTION_UNSUPPORTED
- XR_ERROR_HANDLE_INVALID
Locate hand meshes
The application can use the xrGetHandMeshANDROID function to retrieve the hand mesh at a given timestamp. The hand mesh's vertices' position and normal are represented in the space specified by XrHandMeshGetInfoANDROID::baseSpace when calling xrGetHandMeshANDROID.
XrResult xrGetHandMeshANDROID(
    XrHandMeshTrackerANDROID                    handMeshTracker,
    const XrHandMeshGetInfoANDROID*             getInfo,
    XrHandTrackingMeshesANDROID*                handMeshes);
Parameter Descriptions
- handMeshTrackeris an XrHandMeshTrackerANDROID handle previously created with xrCreateHandMeshTrackerANDROID.
- getInfois an XrHandMeshGetInfoANDROID structure which contains information to query the hand mesh data.
- handMeshesis a pointer to an XrHandTrackingMeshesANDROID structure which will be populated with the hand mesh data.
The application can use the xrGetHandMeshANDROID function to access the hand mesh buffers generated by the runtime.
The application should call xrBeginFrame at least once during the session before the first call to xrGetHandMeshANDROID.
An application should use XrHandMeshANDROID::indexCount and XrHandMeshANDROID::vertexCount to access hand mesh buffers and reuse them in their render loop when calling xrGetHandMeshANDROID every frame.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to calling xrGetHandMeshANDROID
- handMeshTrackermust be a valid XrHandMeshTrackerANDROID handle
- getInfomust be a pointer to a valid XrHandMeshGetInfoANDROID structure
- handMeshesmust be a pointer to an XrHandTrackingMeshesANDROID structure
Return Codes
- 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
A XrHandMeshGetInfoANDROID describes the information required to get hand mesh data.
typedef struct XrHandMeshGetInfoANDROID {
    XrStructureType    type;
    const void*        next;
    XrSpace            baseSpace;
    XrTime             time;
} XrHandMeshGetInfoANDROID;
Member Descriptions
- typeis the XrStructureType of this structure.
- nextis- NULLor a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR or this extension.
- baseSpaceis an XrSpace defining the reference space in which to locate the transform for the vertices at- time.
- timeis the- XrTimethat describes the time at which the application wishes to query the hand mesh.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to using XrHandMeshGetInfoANDROID
- typemust be- XR_TYPE_HAND_MESH_GET_INFO_ANDROID
- nextmust be- NULLor a valid pointer to the next structure in a structure chain
- baseSpacemust be a valid XrSpace handle
XrHandTrackingMeshesANDROID structure contains mesh data for both hands.
typedef struct XrHandTrackingMeshesANDROID {
    XrStructureType      type;
    void*                next;
    XrHandMeshANDROID    leftHandMesh;
    XrHandMeshANDROID    rightHandMesh;
} XrHandTrackingMeshesANDROID;
Member Descriptions
- typeis the XrStructureType of this structure.
- nextis- NULLor a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR or this extension.
- leftHandMeshis the XrHandMeshANDROID for the left hand.
- rightHandMeshis the XrHandMeshANDROID for the right hand.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to using XrHandTrackingMeshesANDROID
- typemust be- XR_TYPE_HAND_TRACKING_MESHES_ANDROID
- nextmust be- NULLor a valid pointer to the next structure in a structure chain
- leftHandMeshmust be a valid XrHandMeshANDROID structure
- rightHandMeshmust be a valid XrHandMeshANDROID structure
A XrHandMeshANDROID structure contains data and buffers to receive hand mesh tracking data from xrGetHandMeshANDROID function for one hand.
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;
Member Descriptions
- typeis the XrStructureType of this structure.
- nextis- NULLor a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR or this extension.
- isActiveis an- XrBool32indicating if the current hand mesh tracker is active and the mesh data is valid.
- dynamicLastUpdateTimeis the- XrTimespecifying the time at which the dynamic buffers were last updated.
- indexCountis a- uint32_tserving as the number of- indicesof the hand mesh.
- vertexCountis a- uint32_tserving as the number of- positionsof the hand mesh. It can also be used for- textureUVsor- normalswhen they are supported by the system.
- indicesis an array of- uint32_trepresenting the mesh indices for triangles in counter-clockwise winder order. The number of values pointed to is- indexCount.
- textureUVsis- NULLor an array of- XrVector2frepresenting the vertex texture coordinates. The number of values pointed to is- vertexCount.
- positionsis an array of- XrVector3frepresenting the vertex positions in- baseSpaceFromVertexSpace. The number of values pointed to is- vertexCount.
- normalsis an- NULLor an array of- XrVector3frepresenting the vertex normals in- baseSpaceFromVertexSpace. The number of values pointed to is- vertexCount.
- baseSpaceFromVertexSpaceis the vertex XrSpace located in the XrHandMeshGetInfoANDROID::baseSpace when calling xrGetHandMeshANDROID. Applications can use this to transform the coordinate space of the mesh vertices and normals during rendering.
The hand mesh is represented in triangle lists and each triangle's vertices are in counter-clockwise order when looking from outside of the hand.
When the returned isActive value is XR_FALSE, this indicates the hand
is not actively tracked; for example, the hand is outside of sensor's range, the
input focus is taken away from the application, or the application does not have
the permissions to access hand tracking data.
When the returned isActive value is XR_TRUE, the hand tracking mesh
represented in indices and positions, including textureUVs and normals
if they are supported by the system, are updated to the latest data of the
XrHandMeshGetInfoANDROID::time given to the xrGetHandMeshANDROID
function.
The memory pointed to by hand mesh buffers returned in XrHandMeshANDROID is owned by the runtime and shared with the application. The memory is safe to access from any thread until the next call to xrBeginFrame while the XrHandMeshTrackerANDROID handle is valid.
- The values pointed to by indicesandtextureUVsare not dynamic
- The pointer and the values pointed to by positionsandnormalsare dynamic that both may change between calls to xrBeginFrame. The application can usedynamicLastUpdateTimeto check if the values have changed since the last frame and avoid unnecessary data processing when there is no changes.
Valid Usage (Implicit)
- The XR_ANDROID_hand_meshextension must be enabled prior to using XrHandMeshANDROID
- indicesmust be a pointer to a valid- uint32_tvalue
- textureUVsmust be a pointer to a valid XrVector2f structure
- positionsmust be a pointer to a valid XrVector3f structure
- normalsmust be a pointer to a valid XrVector3f structure
Example code for hand mesh tracking
Following example code demonstrates how to access hand mesh buffers for rendering.
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));
New Object Types
New Enum Constants
XrObjectType enumeration is extended with:
- XR_OBJECT_TYPE_HAND_MESH_TRACKER_ANDROID
XrStructureType enumeration is extended with:
- 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
New Enums
New Structures
- XrSystemHandMeshTrackingPropertiesANDROID
- XrHandMeshTrackerCreateInfoANDROID
- XrHandMeshGetInfoANDROID
- XrHandMeshANDROID
- XrHandTrackingMeshesANDROID
New Functions
Issues
Version History
- Revision 1, 2024-09-10 (Levana Chen)
- Initial extension description
 
OpenXR™ and the OpenXR logo are trademarks owned by The Khronos Group Inc. and are registered as a trademark in China, the European Union, Japan and the United Kingdom.
