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.

Profil de suivi de la main

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
Articulations des mains articulées Jointures de main d’entrée

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.

Maillage de main d’entrée

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 MixedRealityPoseque .

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.GetObjectForIUnknownde . 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;
    }
}