Acompanhamento da mão – MRTK3

Visão geral

Os dados conjuntos da articulação manual são uma das únicas partes dos dados de entrada que ainda não foram tratadas nativamente pelo Sistema de Entrada do Unity, eles são tratados pelos nossos subsistemas.

Observação

Se você não estiver familiarizado com os subsistemas do MRTK3 e as diferenças deles em relação aos serviços MRTK 2.x, consulte a documentação de arquitetura de subsistemas do MRTK3 para um aprofundamento em nossa filosofia e design.

Nossos subsistemas ingerem dados de articulação da mão de várias fontes e os agregam em uma API central que funciona entre dispositivos e contextos de simulação. Os subsistemas abaixo são implementações do HandsSubsystem:

  • O OpenXRHandsSubsystem recebe os dados da mão diretamente do plug-in OpenXR.
  • O XRSDKHandsSubsystem recebe os dados da mão da camada de abstração do SDK XR do Unity (que, por sua vez, pode estar fornecendo seus dados do OpenXR ou outra fonte).
  • O SyntheticHandsSubsystem sintetiza articulações da mão falsas com base nas ações de entrada provenientes do sistema (como devicePosition, deviceRotation etc). Esse subsistema fornece as junções que você vê ao usar a simulação de entrada no editor.

O HandsAggregatorSubsystem é um subsistema que combina todas as fontes de dados de mão em uma API central. Ele extrai dados de articulação esquelética de todos os que executam HandsSubsystemsativamente . A implementação do MRTK de um HandsAggregatorSubsystem é MRTKHandsAggregatorSubsystem, que dá suporte ao carregamento lento e à reutilização de dados de mão por quadro.

Importante

Ao consultar diretamente os dados da articulação da mão, sempre prefira consultar do Agregador, não de nenhum subsistema de mão individual. Dessa forma, seu código funcionará para qualquer fonte de dados da mão, incluindo dados simulados.

O agregador e os subsistemas de mãos avaliam lentamente as solicitações de dados da mão. Os dados da mão não serão consultados até que um script "cliente" os solicite. Se o aplicativo solicitar apenas uma articulação individual, os subsistemas de mãos serão avaliados lentamente e só consultarão uma única articulação das APIs subjacentes. Além disso, se um "cliente" solicitar um valor completo de dados conjuntos, as chamadas subsequentes no mesmo quadro reutilizarão os mesmos dados, reduzindo o custo de consultar muitas articulações no mesmo quadro. Em cada novo quadro, o cache será alterado e liberado e as chamadas subsequentes começarão a recarregar o cache.

Como resultado, ao criar o perfil do aplicativo, a primeira consulta conjunta em um quadro pode levar mais tempo do que as consultas subsequentes. Isso ocorre devido ao custo amortizado associado à primeira consulta e ao desempenho relativo dos "acertos de cache" subsequentes.

Características de pinçagem

O Agregador calcula várias medidas relacionadas ao gesto de pinçamento, com base nos dados conjuntos que consulta de cada subsistema de mãos específico. Essas medidas são configuradas na definição do subsistema do Agregador.

Configuração do subsistema agregador do Hands

O Limite Aberto de Pinçamento e o Limite Fechado de Pinçamento controlam a distância absoluta entre o polegar e o dedo indicador usada para normalizar o progresso da pinça. Quando a distância for igual ao limite fechado, o progresso da pinça será 1,0 e, quando a distância for igual ao limite aberto, será 0,0. (Esses limites estão atualmente em unidades mundiais, mas em breve serão normalizados para o tamanho da mão do usuário.)

O FOV da Câmera de Aumento de Mão controla o quão perto do centro da exibição do usuário a mão deve ser considerada válida para pinçagem. A Tolerância da Mão para o Lado Oposto controla a tolerância para medir a rotação das mãos do usuário. Ela determina quando a mão do usuário está voltada para o lado oposto.

Exemplos de agregador de mãos

// Get a reference to the aggregator.
var aggregator = XRSubsystemHelpers.GetFirstRunningSubsystem<HandsAggregatorSubsystem>();
// Wait until an aggregator is available.
IEnumerator EnableWhenSubsystemAvailable()
{
    yield return new WaitUntil(() => XRSubsystemHelpers.GetFirstRunningSubsystem<HandsAggregatorSubsystem>() != null);
    GoAhead();
}
// Get a single joint (Index tip, on left hand, for example)
bool jointIsValid = aggregator.TryGetJoint(TrackedHandJoint.IndexTip, XRNode.LeftHand, out HandJointPose jointPose);
// Get an entire hand's worth of joints from the left hand.
bool allJointsAreValid = aggregator.TryGetEntireHand(XRNode.LeftHand, out IReadOnlyList<HandJointPose> joints)
// Check whether the user's left hand is facing away (commonly used to check "aim" intent)
// This is adjustable with the HandFacingAwayTolerance option in the Aggregator configuration.
// "handIsValid" represents whether there was valid hand data in the first place!
bool handIsValid = aggregator.TryGetPalmFacingAway(XRNode.LeftHand, out bool isLeftPalmFacingAway)
// Query pinch characteristics from the left hand.
// pinchAmount is [0,1], normalized to the open/closed thresholds specified in the Aggregator configuration.
// "isReadyToPinch" is adjusted with the HandRaiseCameraFOV and HandFacingAwayTolerance settings in the configuration.
bool handIsValid = aggregator.TryGetPinchProgress(XRNode.LeftHand, out bool isReadyToPinch, out bool isPinching, out float pinchAmount)

Pré-fabricados do controlador de mão

Os MRTK LeftHand Controller pré-fabricados e MRTK RightHand Controller permitem que você use controladores de mão em seu projeto. Esses pré-fabricados podem funcionar com controladores de mão articulados e não articulados. Eles têm interatores para ações de cutucar, agarrar, raio distante e pinçar olhar. Além disso, esses pré-fabricados mostram os visuais apropriados e manipulam as ações de entrada do dispositivo usando componentes do controlador e do interagente anexados a eles. Esses componentes, por sua vez, consomem os mapeamentos de ação de entrada do Unity, que declaram associações de entrada. Os pré-fabricados, por padrão, usam os mapeamentos de ação de entrada definidos no ativo incluído MRTK Default Input Actions .

Observe que os pré-fabricados do controlador manual já estão incluídos no MRTK XR Rig pré-fabricado, consulte criando uma nova cena para obter mais detalhes. Se a plataforma XR do MRTK3 já estiver sendo usada, nenhuma ação adicional será necessária para dar suporte aos controladores de mão.

A hierarquia do prefab do Controlador LeftHand do MRTK unity.

Importante

Se as ações de entrada na plataforma XR do MRTK3 forem modificadas e usarem ações definidas fora do ativo, atualize o MRTK Default Input Actions gerenciador de ações de entrada do MRT3 para que ele aponte para o novo ativo de ação de entrada. Não fazer isso pode resultar em um comportamento indefinido.

Os pré-fabricados do controlador esquerdo e direito do MRTK3 contêm todos os componentes necessários para dar suporte à entrada manual. Um desses componentes é o do ArticulatedHandControllerMRTK, que é uma versão especializada da entrada XR do ActionBasedControllerUnity. Esse script do controlador MRTK3 usa o subsistema agregador de mãos do MRTK3 para expor vários eventos de entrada manual. Por exemplo, o controlador expõe o evento de seleção de pinçagem.

Os pré-fabricados de mão também têm scripts para habilitar a visualização do controlador manual. O HandJointVisualizer componente destina-se à depuração e desenha uma malha em instâncias em cada articulação manual. Embora o ControllerVisualizer componente seja destinado a cenários de produção e, quando um controlador é detectado, renderiza o modelo de controlador correspondente. A malha do controlador da plataforma é usada quando disponível, caso contrário, um modelo de controlador genérico, o especificado no fallbackControllerModel campo, é usado.

Plataformas não HoloLens podem usar o RiggedHandMeshVisualizer para visualizar a mão. Conforme indicado pelo nome, esse visualizador usa uma malha fraudada para renderizar modelos de mão de alta qualidade e não é recomendado para plataformas AR como o HoloLens, tanto por motivos de desempenho quanto de design. Observe que esse visualizador não está configurado nos pré-fabricados do controlador manual padrão.

Observação

Para plataformas de realidade aumentada, como o HoloLens, recomendamos não usar nenhuma visualização manual. O conflito entre a mão real do usuário e a visualização holográfica ligeiramente atrasada pode ser mais perturbador do que vale a pena. No entanto, para plataformas opacas, essa é uma ótima solução.

Os pré-fabricados do controlador de mão padrão também hospedam um conjunto de componentes do interagente. Elas incluem PokeInteractor, MRTKRayInteractor, GrabInteractor e GrabInteractor. Para obter mais informações sobre esses interagentes, visite Arquitetura do Interator — MRTK3.

Por fim, os pré-fabricados do controlador também contêm componentes do detector, IInteractionModeDetectore NearInteractionModeDetectorInteractionDetector. Esses componentes informam ao gerenciador de modo de interação do aplicativo quais interagentes devem ser habilitados. Para obter mais informações sobre os detectores do MRTK3, visite Gerenciador de Modo de Interação — MRTK3.

Fontes de pose

Todos os interatores de mão do MRTK3 exigem uma pose do controlador (ou pose de mão). O tipo de pose de mão pode variar de interagente para interator. Por exemplo, alguns usam ações de entrada do Unity para obter posição e rotação, enquanto outros usam a pose do dedo indicador, alguns usam a pose de palma. A origem da pose da mão de cada interagente é definida por uma classe que implementa a interface do IPoseSource MRTK3. Essa interface declara o seguinte:

  • TryGetPose. Este método tenta obter uma pose de mão no espaço mundial. Por exemplo, a pose retornada pode corresponder a uma pose de articulação de mão obtida do subsistema agregador de mão do MRTK3. Esse método retornará se a recuperação da pose tiver sido bem-sucedida. Alguma implementação desse método, como recuperar a pose de dados de articulação manual, poderá falhar se os dados não estiverem disponíveis.

O tipo de IPoseSource um interagente é especificado por meio do inspetor do Unity e pode ser um dos seguintes tipos:

  • FallbackCompositePoseSource. Uma fonte de pose composta por uma lista ordenada de fontes de pose. Retorna o resultado da primeira origem da pose que retorna com êxito uma pose.
  • HandBasedPoseSource. Uma classe abstrata que ajuda a definir uma fonte de pose baseada em uma entrega específica com acesso ao subsistema agregador de mãos do MRTK3.
  • HandJointPoseSource. Uma origem colocada que estende HandBasedPoseSource e rastreia uma articulação de mão específica em uma mão específica.
  • InputActionPoseSource. Uma origem de pose que obtém uma pose composta por uma posição controlada e rotação das ações de entrada do Unity especificadas. As ações de entrada padrão podem ser encontradas no ativo do MRTK Default Input Actions Unity.
  • PinchPoseSource. Uma fonte de pose que estende HandBasedPoseSource e obtém a pose de pinçagem de uma mão específica do subsistema agregador de mão do MRTK3.
  • PolyfillHandRayPoseSource. Uma origem de pose que estende HandBasedPoseSource e representa um raio de mão. Esse raio de mão é construído derivando das posições da palma e da mão do subsistema agregador de mãos do MRTK3.

Os tipos de origem de pose para interagentes muados já estão especificados nos pré-fabricados do controlador padrão do MRTK3. Não é recomendável modificar as configurações de origem de pose padrão do prefab.