Extensão OpenXR XR_ANDROID_hand_mesh

String de nome

XR_ANDROID_hand_mesh

Tipo de extensão

Extensão de instância

Número de extensão registrado

704

Revisão

1

Dependências de extensão e versão

OpenXR 1.0

Data da última modificação

2024-09-10

Status do IP

Nenhuma reivindicação de IP conhecida.

Colaboradores

Nihav Jain, Google

Cairn Overturf, Google

Spencer Quin, Google

Levana Chen, Google

Visão geral

Essa extensão permite o rastreamento de mãos representado como uma malha dinâmica.

Essa extensão tem como objetivo fornecer buffers de vértice e índice para a malha de uma representação personalizada das mãos do usuário. Ele pode ser usado para oclusão e visualização.

Essa extensão não deve ser usada para outros fins de rastreamento de mão.

Os dados de rastreamento de mãos podem ser informações pessoais sensíveis e estão intimamente ligados à privacidade e integridade pessoal. É altamente recomendável que os aplicativos que armazenam ou transferem dados de rastreamento de mãos sempre peçam ao usuário uma aceitação ativa e específica para fazer isso.

Inspecionar o capability do sistema

Um aplicativo pode inspecionar se o sistema é capaz de rastrear malhas de mãos encadeando uma estrutura XrSystemHandMeshTrackingPropertiesANDROID ao XrSystemProperties ao chamar xrGetSystemProperties.

typedef struct XrSystemHandMeshTrackingPropertiesANDROID {
  XrStructureType    type;
  void*              next;
  XrBool32           supportsHandMeshTracking;
  XrBool32           supportsTextureUV;
  XrBool32           supportsVertexNormal;
} XrSystemHandMeshTrackingPropertiesANDROID;

Descrições dos participantes

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma dessas estruturas é definida no núcleo do OpenXR ou nesta extensão.
  • supportsHandMeshTracking é um XrBool32, indicando se o XrSystemId selecionado oferece suporte ao rastreamento de malha de mão.
  • supportsTextureUV é um XrBool32, indicando se o XrSystemId selecionado oferece suporte a UVs de textura para os vértices da malha.
  • supportsVertexNormal é um XrBool32, indicando se o XrSystemId selecionado oferece suporte a normais de vértices para os vértices da malha.

O aplicativo deve evitar o uso de recursos de malha de mão quando supportsHandMeshTracking é XR_FALSE, já que isso significa que o sistema não oferece suporte ao rastreamento de malha de mão. Nesse caso, xrCreateHandMeshTrackerANDROID vai retornar XR_ERROR_FEATURE_UNSUPPORTED.

Se supportsHandMeshTracking retornar XR_TRUE, o sistema oferecerá suporte ao rastreamento de malha de mão. Um aplicativo deve usar XrHandMeshANDROID::indexCount e XrHandMeshANDROID::vertexCount para acessar e reutilizar os buffers de malha de mão no loop de renderização ao chamar xrGetHandMeshANDROID em cada frame.

Se supportsTextureUV retornar XR_FALSE, o sistema não oferecerá suporte a UVs de textura para os vértices da malha. Portanto, um aplicativo vai receber XrHandMeshANDROID::textureUVs NULL ao chamar xrGetHandMeshANDROID.

Se supportsVertexNormal retornar XR_FALSE, o sistema não oferecerá suporte a normais de vértices para os vértices da malha. Portanto, um aplicativo receberia XrHandMeshANDROID::normals NULL ao chamar xrGetHandMeshANDROID.

Uso válido (implícito)

Criar um identificador de rastreador de malha de mão

XR_DEFINE_HANDLE(XrHandMeshTrackerANDROID)

O gerenciador XrHandMeshTrackerANDROID representa um rastreador de malha de mão para o rastreamento de malha de mão e o gerenciamento dos recursos relacionados.

Esse identificador pode ser usado para acessar buffers de malha de mão usando outras funções nesta extensão.

Um aplicativo pode criar um identificador XrHandMeshTrackerANDROID usando a função xrCreateHandMeshTrackerANDROID.

XrResult xrCreateHandMeshTrackerANDROID(
    XrSession                                   session,
    const XrHandMeshTrackerCreateInfoANDROID*   createInfo,
    XrHandMeshTrackerANDROID*                   handMeshTracker);

Descrições dos parâmetros

Se o sistema não oferecer suporte ao rastreamento de malha de mão, xrCreateHandMeshTrackerANDROID vai retornar XR_ERROR_FEATURE_UNSUPPORTED.

O gerenciador XrHandMeshTrackerANDROID tem todos os recursos para o rastreamento de malha de mão. Depois de terminar as experiências de rastreamento de malha de mão, o aplicativo precisa destruir o identificador usando a função xrDestroyHandMeshTrackerANDROID.

Uso válido (implícito)

Códigos de retorno

Sucesso

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Falha

  • 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

A estrutura XrHandMeshTrackerCreateInfoANDROID descreve as informações para criar um identificador XrHandMeshTrackerANDROID.

typedef struct XrHandMeshTrackerCreateInfoANDROID {
    XrStructureType    type;
    const void*        next;
} XrHandMeshTrackerCreateInfoANDROID;

Descrições dos participantes

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma dessas estruturas é definida no núcleo do OpenXR ou nesta extensão.

Uso válido (implícito)

A função xrDestroyHandMeshTrackerANDROID libera o handMeshTracker e os recursos subjacentes quando as experiências de rastreamento de malha de mão são concluídas.

XrResult xrDestroyHandMeshTrackerANDROID(
    XrHandMeshTrackerANDROID handMeshTracker);

Descrições dos parâmetros

Uso válido (implícito)

Segurança da linha de execução

  • O acesso a handMeshTracker e a qualquer identificador filho precisa ser sincronizado externamente.

Códigos de retorno

Sucesso

  • XR_SUCCESS

Falha

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID

Localizar malhas de mão

O aplicativo pode usar a função xrGetHandMeshANDROID para extrair a malha da mão em um determinado carimbo de data/hora. A posição e a normal dos vértices da malha da mão são representadas no espaço especificado por XrHandMeshGetInfoANDROID::baseSpace ao chamar xrGetHandMeshANDROID.

XrResult xrGetHandMeshANDROID(
    XrHandMeshTrackerANDROID                    handMeshTracker,
    const XrHandMeshGetInfoANDROID*             getInfo,
    XrHandTrackingMeshesANDROID*                handMeshes);

Descrições dos parâmetros

O aplicativo pode usar a função xrGetHandMeshANDROID para acessar os buffers de malha de mão gerados pelo ambiente de execução.

O aplicativo precisa chamar xrBeginFrame pelo menos uma vez durante a sessão antes da primeira chamada para xrGetHandMeshANDROID.

Um aplicativo deve usar XrHandMeshANDROID::indexCount e XrHandMeshANDROID::vertexCount para acessar e reutilizar buffers de malha de mão no loop de renderização ao chamar xrGetHandMeshANDROID em cada frame.

Uso válido (implícito)

Códigos de retorno

Sucesso

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Falha

  • 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

Um XrHandMeshGetInfoANDROID descreve as informações necessárias para receber dados de mesh de mão.

typedef struct XrHandMeshGetInfoANDROID {
    XrStructureType    type;
    const void*        next;
    XrSpace            baseSpace;
    XrTime             time;
} XrHandMeshGetInfoANDROID;

Descrições dos participantes

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma dessas estruturas é definida no núcleo do OpenXR ou nesta extensão.
  • baseSpace é um XrSpace que define o espaço de referência em que localizar a transformação dos vértices em time.
  • time é o XrTime que descreve o momento em que o aplicativo quer consultar a malha da mão.

Uso válido (implícito)

A estrutura XrHandTrackingMeshesANDROID contém dados de malha para as duas mãos.

typedef struct XrHandTrackingMeshesANDROID {
    XrStructureType      type;
    void*                next;
    XrHandMeshANDROID    leftHandMesh;
    XrHandMeshANDROID    rightHandMesh;
} XrHandTrackingMeshesANDROID;

Descrições dos participantes

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma dessas estruturas é definida no núcleo do OpenXR ou nesta extensão.
  • leftHandMesh é o XrHandMeshANDROID para a mão esquerda.
  • rightHandMesh é o XrHandMeshANDROID para a mão direita.

Uso válido (implícito)

Uma estrutura XrHandMeshANDROID contém dados e buffers para receber dados de rastreamento de malha de mão da função xrGetHandMeshANDROID para uma mão.

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;

Descrições dos participantes

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma dessas estruturas é definida no núcleo do OpenXR ou nesta extensão.
  • isActive é um XrBool32 que indica se o rastreador de malha de mão atual está ativo e se os dados da malha são válidos.
  • dynamicLastUpdateTime é o XrTime que especifica a hora em que os buffers dinâmicos foram atualizados pela última vez.
  • indexCount é um uint32_t que serve como o número de indices da malha da mão.
  • vertexCount é um uint32_t que serve como o número de positions da malha da mão. Ele pode ser usado para textureUVs ou normals quando eles têm suporte do sistema.
  • indices é uma matriz de uint32_t que representa os índices de malha para triângulos na ordem de sentido anti-horário. O número de valores apontados é indexCount.
  • textureUVs é NULL ou uma matriz de XrVector2f que representa as coordenadas da textura do vértice. O número de valores apontados é vertexCount.
  • positions é uma matriz de XrVector3f que representa as posições dos vértices em baseSpaceFromVertexSpace. O número de valores apontados é vertexCount.
  • normals é um NULL ou uma matriz de XrVector3f que representa as normais de vértices em baseSpaceFromVertexSpace. O número de valores apontados é vertexCount.
  • baseSpaceFromVertexSpace é o vértice XrSpace localizado em XrHandMeshGetInfoANDROID::baseSpace ao chamar xrGetHandMeshANDROID. Os aplicativos podem usar isso para transformar o espaço de coordenadas dos vértices e das normais da malha durante a renderização.

A malha da mão é representada em listas de triângulos, e os vértices de cada triângulo estão na ordem anti-horária quando vistos de fora da mão.

Quando o valor isActive retornado é XR_FALSE, isso indica que a mão não está sendo rastreada ativamente. Por exemplo, a mão está fora do alcance do sensor, o foco de entrada foi removido do aplicativo ou o aplicativo não tem as permissões para acessar os dados de rastreamento de mão.

Quando o valor isActive retornado é XR_TRUE, a malha de rastreamento de mãos representada em indices e positions, incluindo textureUVs e normals se o sistema oferece suporte a eles, são atualizados para os dados mais recentes do XrHandMeshGetInfoANDROID::time fornecidos à função xrGetHandMeshANDROID.

A memória apontada pelos buffers de malha de mão retornados em XrHandMeshANDROID é de propriedade do ambiente de execução e compartilhada com o aplicativo. O acesso à memória é seguro de qualquer linha de execução até a próxima chamada para xrBeginFrame enquanto o gerenciador XrHandMeshTrackerANDROID for válido.

  • Os valores apontados por indices e textureUVs não são dinâmicos
  • O ponteiro e os valores apontados por positions e normals são dinâmicos e podem mudar entre as chamadas para xrBeginFrame. O aplicativo pode usar dynamicLastUpdateTime para verificar se os valores mudaram desde o último frame e evitar o processamento de dados desnecessário quando não há mudanças.

Uso válido (implícito)

  • A extensão XR_ANDROID_hand_mesh precisa ser ativada antes de usar XrHandMeshANDROID.
  • indices precisa ser um ponteiro para um valor uint32_t válido
  • textureUVs precisa ser um ponteiro para uma estrutura XrVector2f válida
  • positions precisa ser um ponteiro para uma estrutura XrVector3f válida
  • normals precisa ser um ponteiro para uma estrutura XrVector3f válida

Exemplo de código para rastreamento de malha de mão

O código de exemplo a seguir demonstra como acessar buffers de malha de mão para renderização.

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));

Novos tipos de objeto

Novas constantes de tipo enumerado

A enumeração XrObjectType é estendida com:

  • XR_OBJECT_TYPE_HAND_MESH_TRACKER_ANDROID

A enumeração XrStructureType é ampliada com:

  • 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

Novos tipos enumerados

Novas estruturas

Novas funções

Problemas

Histórico de versões

  • Revisão 1, 10-09-2024 (Levana Chen)
    • Descrição inicial da extensão