Controlo manual — MRTK2
Perfil de controlo manual
O perfil Controlo de Mãos encontra-se no perfil do Sistema de Entrada. Contém definições para personalizar a representação manual.
Pré-fabricados conjuntos
Os pré-fabricados conjuntos são visualizados através de pré-fabricados simples. As juntas De Dedo De Palma e Índice são de especial importância e têm a sua própria pré-fabricada, enquanto todas as outras articulações partilham a mesma pré-fabricada.
Por predefinição, os prefáculos da articulação manual são primitivos geométricos simples. Estes podem ser substituídos se assim o desejarem. Se não for especificado qualquer prefáb, são criados gameObjects vazios .
Aviso
Evite utilizar scripts complexos ou composição dispendiosa em prefabs articulares, uma vez que os objetos de articulação são transformados em cada frame e podem ter um custo de desempenho significativo!
Representação Predefinida da Articulação Manual | Etiquetas Conjuntas |
---|---|
Pré-fabricada de malha manual
A malha manual é utilizada se os dados de malha totalmente definidos forem fornecidos pelo dispositivo de controlo manual. A malha renderizável na pré-fabricada é substituída por dados do dispositivo, pelo que uma malha fictícia, como um cubo, é suficiente. O material da pré-fabricada é utilizado para a malha manual.
O ecrã de malha manual pode ter um impacto de desempenho notável, pelo que pode ser totalmente desativado ao desmarcar a opção Ativar Visualização do Hand Mesh .
Definições de visualização manual
As visualizações de malha manual e articulação manual podem ser desativadas ou ativadas através da definição Modos de Visualização do Hand Mesh e dos Modos de Visualização Articular Manual , respetivamente. Estas definições são específicas do modo de aplicação, o que significa que é possível ativar algumas funcionalidades enquanto estiver no editor (para ver articulações com a simulação no editor, por exemplo) ao mesmo tempo que tem as mesmas funcionalidades desativadas quando implementadas no dispositivo (em compilações de leitores).
Tenha em atenção que é geralmente recomendado ter a visualização articular manual ativada no editor (para que a simulação no editor mostre onde estão as articulações da mão) e que a visualização da articulação manual e a visualização da malha manual sejam desativadas no leitor (porque incorrem num impacto no desempenho).
Scripting
A posição e a rotação podem ser pedidas no sistema de entrada para cada articulação manual individual como um MixedRealityPose
.
Em alternativa, o sistema permite o acesso a GameObjects que seguem as articulações. Isto pode ser útil se outro GameObject tiver de controlar continuamente uma articulação.
As juntas disponíveis estão listadas no TrackedHandJoint
enum.
Nota
O objeto da articulação é destruído quando o controlo manual é perdido! Certifique-se de que os scripts que utilizam o objeto de articulação processam o null
caso corretamente para evitar erros!
Aceder a um determinado controlador manual
Um controlador manual específico está muitas vezes disponível, por exemplo, ao processar eventos de entrada. Neste caso, os dados conjuntos podem ser pedidos diretamente a partir do dispositivo, utilizando a IMixedRealityHand
interface.
Pose da junta de consulta do controlador
A TryGetJoint
função devolve false
se a articulação pedida não estiver disponível por algum motivo. Nesse caso, a pose resultante será MixedRealityPose.ZeroIdentity
.
public void OnSourceDetected(SourceStateEventData eventData)
{
var hand = eventData.Controller as IMixedRealityHand;
if (hand != null)
{
if (hand.TryGetJoint(TrackedHandJoint.IndexTip, out MixedRealityPose jointPose)
{
// ...
}
}
}
Transformação conjunta do visualizador manual
Os objetos conjuntos podem ser pedidos ao visualizador do controlador.
public void OnSourceDetected(SourceStateEventData eventData)
{
var handVisualizer = eventData.Controller.Visualizer as IMixedRealityHandVisualizer;
if (handVisualizer != null)
{
if (handVisualizer.TryGetJointTransform(TrackedHandJoint.IndexTip, out Transform jointTransform)
{
// ...
}
}
}
Acesso a dados conjuntos simplificados
Se não for fornecido nenhum controlador específico, as classes de utilitários são fornecidas para acesso conveniente a dados conjuntos de mãos. Estas funções solicitam dados conjuntos do primeiro dispositivo manual disponível atualmente controlado.
Pose de conjunto de sondagens da HandJointUtils
HandJointUtils
é uma classe estática que consulta o primeiro dispositivo ativo.
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, Handedness.Right, out MixedRealityPose pose))
{
// ...
}
Transformação conjunta do serviço conjunto manual
IMixedRealityHandJointService
mantém um conjunto persistente de GameObjects para controlar as articulações.
var handJointService = CoreServices.GetInputSystemDataProvider<IMixedRealityHandJointService>();
if (handJointService != null)
{
Transform jointTransform = handJointService.RequestJointTransform(TrackedHandJoint.IndexTip, Handedness.Right);
// ...
}
Eventos de controlo manual
O sistema de entrada também fornece eventos, se os dados de consulta diretamente dos controladores não forem desejáveis.
Eventos conjuntos
IMixedRealityHandJointHandler
processa atualizações de posições conjuntas.
public class MyHandJointEventHandler : IMixedRealityHandJointHandler
{
public Handedness myHandedness;
void IMixedRealityHandJointHandler.OnHandJointsUpdated(InputEventData<IDictionary<TrackedHandJoint, MixedRealityPose>> eventData)
{
if (eventData.Handedness == myHandedness)
{
if (eventData.InputData.TryGetValue(TrackedHandJoint.IndexTip, out MixedRealityPose pose))
{
// ...
}
}
}
}
Eventos de malha
IMixedRealityHandMeshHandler
processa as alterações da malha manual articulada.
Tenha em atenção que as malhas mano não estão ativadas por predefinição.
public class MyHandMeshEventHandler : IMixedRealityHandMeshHandler
{
public Handedness myHandedness;
public Mesh myMesh;
public void OnHandMeshUpdated(InputEventData<HandMeshInfo> eventData)
{
if (eventData.Handedness == myHandedness)
{
myMesh.vertices = eventData.InputData.vertices;
myMesh.normals = eventData.InputData.normals;
myMesh.triangles = eventData.InputData.triangles;
if (eventData.InputData.uvs != null && eventData.InputData.uvs.Length > 0)
{
myMesh.uv = eventData.InputData.uvs;
}
// ...
}
}
}
Problemas conhecidos
.NET Native
Atualmente, existe um problema conhecido com as compilações mestras com o back-end do .NET. No .NET Native, IInspectable
os ponteiros não podem ser geridos de nativo para código gerido com Marshal.GetObjectForIUnknown
. O MRTK utiliza esta opção para obter os SpatialCoordinateSystem
dados manos e oculares da plataforma.
Fornecemos a origem DLL como solução para este problema, no repositório Mixed Reality Toolkit nativo. Siga as instruções no README e copie os binários resultantes para uma pasta Plug-ins nos seus recursos do Unity. Depois disso, o script WindowsMixedRealityUtilities fornecido no MRTK resolverá a solução para si.
Se quiser criar a sua própria DLL ou incluir esta solução numa existente, o núcleo da solução é:
extern "C" __declspec(dllexport) void __stdcall MarshalIInspectable(IUnknown* nativePtr, IUnknown** inspectable)
{
*inspectable = nativePtr;
}
E a sua utilização no código C# Unity:
[DllImport("DotNetNativeWorkaround.dll", EntryPoint = "MarshalIInspectable")]
private static extern void GetSpatialCoordinateSystem(IntPtr nativePtr, out SpatialCoordinateSystem coordinateSystem);
private static SpatialCoordinateSystem GetSpatialCoordinateSystem(IntPtr nativePtr)
{
try
{
GetSpatialCoordinateSystem(nativePtr, out SpatialCoordinateSystem coordinateSystem);
return coordinateSystem;
}
catch
{
UnityEngine.Debug.LogError("Call to the DotNetNativeWorkaround plug-in failed. The plug-in is required for correct behavior when using .NET Native compilation");
return Marshal.GetObjectForIUnknown(nativePtr) as SpatialCoordinateSystem;
}
}