Suivi des mains — MRTK2
Profil de suivi de la main
Le profil Suivi des mains se trouve sous le profil Système d’entrée. Il contient des paramètres pour la personnalisation de la représentation manuelle.
Préfabriqués joints
Les préfabriqués joints sont visualisées à l’aide de préfabriqués simples. Les articulations palmaire et index sont d’une importance particulière et ont leur propre préfabriqué, tandis que toutes les autres articulations partagent le même préfabriqué.
Par défaut, les préfabriqués à joint de main sont de simples primitives géométriques. Vous pouvez les remplacer si vous le souhaitez. Si aucun préfabriqué n’est spécifié, des GameObjects vides sont créés à la place.
Avertissement
Évitez d’utiliser des scripts complexes ou un rendu coûteux dans les préfabriqués joints, car les objets joints sont transformés sur chaque image et peuvent avoir un coût de performances important !
Représentation conjointe de la main par défaut | Étiquettes conjointes |
---|---|
Préfabriqué à mailles manuelles
Le maillage de main est utilisé si des données de maillage entièrement définies sont fournies par l’appareil de suivi des mains. Le maillage pouvant être rendu dans le préfabriqué est remplacé par les données de l’appareil, de sorte qu’un maillage factice tel qu’un cube est suffisant. Le matériau du préfabriqué est utilisé pour le maillage à main.
L’affichage du maillage de main peut avoir un impact notable sur les performances. Pour cette raison, il peut être entièrement désactivé en décochant l’option Activer la visualisation de maillage de main .
Paramètres de visualisation manuelle
Les visualisations de maillage de main et de jointure de main peuvent être désactivées ou activées via le paramètre Modes de visualisation de maillage de la main et modes de visualisation de jointure de main respectivement. Ces paramètres sont spécifiques au mode application, ce qui signifie qu’il est possible d’activer certaines fonctionnalités dans l’éditeur (pour voir les jointures avec la simulation dans l’éditeur, par exemple) tout en ayant les mêmes fonctionnalités désactivées lorsqu’elles sont déployées sur l’appareil (dans les builds du lecteur).
Notez qu’il est généralement recommandé d’activer la visualisation conjointe des mains dans l’éditeur (afin que la simulation dans l’éditeur montre où se trouvent les articulations de la main), et d’avoir à la fois la visualisation des articulations de main et la visualisation du maillage de main désactivée dans le lecteur (car elles entraînent un impact sur les performances).
Scripts
La position et la rotation peuvent être demandées à partir du système d’entrée pour chaque jointure de main individuelle en tant MixedRealityPose
que .
Le système autorise également l’accès aux GameObjects qui suivent les articulations. Cela peut être utile si un autre GameObject doit suivre une jointure en continu.
Les jointures disponibles sont répertoriées dans l’énumération TrackedHandJoint
.
Notes
Les objets joints sont détruits quand le suivi de la main est perdu! Assurez-vous que tous les scripts utilisant l’objet joint gèrent correctement le null
cas afin d’éviter les erreurs !
Accès à un contrôleur de main donné
Un contrôleur de main spécifique est souvent disponible, par exemple lors de la gestion des événements d’entrée. Dans ce cas, les données conjointes peuvent être demandées directement à partir de l’appareil, à l’aide de l’interface IMixedRealityHand
.
Interrogation d’une pose commune à partir du contrôleur
La TryGetJoint
fonction retourne false
si la jointure demandée n’est pas disponible pour une raison quelconque. Dans ce cas, la pose résultante sera MixedRealityPose.ZeroIdentity
.
public void OnSourceDetected(SourceStateEventData eventData)
{
var hand = eventData.Controller as IMixedRealityHand;
if (hand != null)
{
if (hand.TryGetJoint(TrackedHandJoint.IndexTip, out MixedRealityPose jointPose)
{
// ...
}
}
}
Transformation conjointe à partir du visualiseur de main
Des objets joints peuvent être demandés auprès du visualiseur du contrôleur.
public void OnSourceDetected(SourceStateEventData eventData)
{
var handVisualizer = eventData.Controller.Visualizer as IMixedRealityHandVisualizer;
if (handVisualizer != null)
{
if (handVisualizer.TryGetJointTransform(TrackedHandJoint.IndexTip, out Transform jointTransform)
{
// ...
}
}
}
Accès aux données conjoint simplifié
Si aucun contrôleur spécifique n’est fourni, des classes d’utilitaire sont fournies pour un accès pratique aux données conjointes manuelles. Ces fonctions demandent des données conjointes à partir du premier appareil à main disponible actuellement suivi.
Interrogation d’une pose conjointe à partir de HandJointUtils
HandJointUtils
est une classe statique qui interroge le premier appareil de main actif.
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, Handedness.Right, out MixedRealityPose pose))
{
// ...
}
Transformation conjointe à partir d’un service conjoint de main
IMixedRealityHandJointService
conserve un ensemble persistant de GameObjects pour le suivi des jointures.
var handJointService = CoreServices.GetInputSystemDataProvider<IMixedRealityHandJointService>();
if (handJointService != null)
{
Transform jointTransform = handJointService.RequestJointTransform(TrackedHandJoint.IndexTip, Handedness.Right);
// ...
}
Événements de suivi de la main
Le système d’entrée fournit également des événements, si l’interrogation des données des contrôleurs directement n’est pas souhaitable.
Événements conjoints
IMixedRealityHandJointHandler
gère les mises à jour des positions conjointes.
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))
{
// ...
}
}
}
}
Événements de maillage
IMixedRealityHandMeshHandler
gère les modifications du maillage de main articulé.
Notez que les maillages de main ne sont pas activés par défaut.
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;
}
// ...
}
}
}
Problèmes connus
.NET Native
Il existe actuellement un problème connu avec les builds master qui utilisent le back-end .NET. Dans .NET Native, IInspectable
les pointeurs ne peuvent pas être marshalés du code natif au code managé à l’aide Marshal.GetObjectForIUnknown
de . MRTK l’utilise pour obtenir le afin de recevoir des SpatialCoordinateSystem
données de main et d’œil à partir de la plateforme.
Nous avons fourni la source DLL comme solution de contournement pour ce problème, dans le référentiel natif Mixed Reality Toolkit. Suivez les instructions du fichier README et copiez les fichiers binaires résultants dans un dossier Plug-ins dans vos ressources Unity. Après cela, le script WindowsMixedRealityUtilities fourni dans MRTK résout la solution de contournement pour vous.
Si vous souhaitez créer votre propre DLL ou inclure cette solution de contournement dans une dll existante, le cœur de la solution de contournement est :
extern "C" __declspec(dllexport) void __stdcall MarshalIInspectable(IUnknown* nativePtr, IUnknown** inspectable)
{
*inspectable = nativePtr;
}
Et son utilisation dans votre code Unity C# :
[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;
}
}