Contrôleurs, pointeurs et focus — MRTK2

Les contrôleurs, les pointeurs et le focus sont des concepts de niveau supérieur qui s’appuient sur les bases établies par le système d’entrée principal. Ensemble, ils fournissent une grande partie du mécanisme d’interaction avec les objets de la scène.

Controllers

Les contrôleurs sont des représentations d’un contrôleur physique (6 degrés de liberté, main articulée, etc.). Ils sont créés par les gestionnaires d’appareils et sont chargés de communiquer avec le système sous-jacent correspondant et de traduire ces données en données et événements en forme de MRTK.a

Par exemple, sur la plateforme Windows Mixed Reality, le WindowsMixedRealityArticulatedHand est un contrôleur qui est responsable de l’interfaçage avec les API de suivi des mains Windows sous-jacentes pour obtenir des informations sur les articulations, la pose et d’autres propriétés de la main. Il est responsable de la transformation de ces données en événements MRTK pertinents (par exemple, en appelant RaisePoseInputChanged ou RaiseHandJointsUpdated) et en mettant à jour son propre état interne afin que les requêtes pour TryGetJointPose retournent des données correctes.

En règle générale, le cycle de vie d’un contrôleur implique :

  1. Un contrôleur est créé par un gestionnaire de périphériques lors de la détection d’une nouvelle source (par exemple, le gestionnaire de périphériques détecte et commence à suivre une main).

  2. Dans la boucle Update() du contrôleur, il appelle son système d’API sous-jacent.

  3. Dans la même boucle de mise à jour, il déclenche des modifications d’événement d’entrée en appelant directement dans le système d’entrée principal lui-même (par exemple, le déclenchement de HandMeshUpdated ou HandJointsUpdated).

Pointeurs et focus

Les pointeurs sont utilisés pour interagir avec des objets de jeu. Cette section décrit comment les pointeurs sont créés, comment ils sont mis à jour et comment ils déterminent le ou les objets qui sont en focus. Il couvre également les différents types de pointeurs qui existent et les scénarios dans lesquels ils sont actifs.

Catégories de pointeurs

Les pointeurs appartiennent généralement à l’une des catégories suivantes :

  • Pointeurs lointains

    Ces types de pointeurs sont utilisés pour interagir avec des objets qui sont loin de l’utilisateur (la distance est définie comme simplement « pas proche »). Ces types de pointeurs castent généralement des lignes qui peuvent aller loin dans le monde et permettre à l’utilisateur d’interagir et de manipuler des objets qui ne sont pas immédiatement à côté d’eux.

  • Pointeurs proches

    Ces types de pointeurs sont utilisés pour interagir avec des objets suffisamment proches de l’utilisateur pour saisir, toucher et manipuler. En règle générale, ces types de pointeurs interagissent avec des objets en recherchant des objets dans le voisinage proche (soit en effectuant des diffusions de rayons à de petites distances, en effectuant un casting sphérique à la recherche d’objets à proximité, soit en énumérant des listes d’objets qui sont considérés comme pouvant être saisis/tactiles).

  • Pointeurs de téléportation

    Ces types de pointeurs se connectent au système de téléportation pour gérer le déplacement de l’utilisateur vers l’emplacement ciblé par le pointeur.

Médiation de pointeur

Étant donné qu’un seul contrôleur peut avoir plusieurs pointeurs (par exemple, la main articulée peut avoir à la fois des pointeurs d’interaction proche et éloigné), il existe un composant qui est responsable de la médiatation du pointeur qui doit être actif.

Par exemple, lorsque la main de l’utilisateur s’approche d’un bouton appuyable, le ShellHandRayPointer doit cesser de s’afficher et le PokePointer doit être engagé.

Cela est géré par le DefaultPointerMediator, qui est chargé de déterminer quels pointeurs sont actifs, en fonction de l’état de tous les pointeurs. L’une des principales opérations consiste à désactiver les pointeurs éloignés lorsqu’un pointeur proche est proche d’un objet (voir DefaultPointerMediator).

Il est possible de fournir une autre implémentation du médiateur de pointeur en modifiant la PointerMediator propriété sur le profil du pointeur.

Comment désactiver les pointeurs

Étant donné que le médiateur de pointeur exécute chaque image, il finit par contrôler l’état actif/inactif de tous les pointeurs. Par conséquent, si vous définissez la propriété IsInteractionEnabled d’un pointeur dans le code, elle sera remplacée par le médiateur du pointeur chaque image. Au lieu de cela, vous pouvez spécifier le PointerBehavior pour contrôler si les pointeurs doivent être activés ou désactivés vous-même. Notez que cela fonctionne uniquement si vous utilisez la valeur par défaut FocusProvider et DefaultPointerMediator dans MRTK.

Exemple : Désactiver les rayons de la main dans MRTK

Le code suivant désactive les rayons de la main dans MRTK :

// Turn off all hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Turn off hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

Le code suivant retourne aux rayons des mains leur comportement par défaut dans MRTK :

PointerUtils.SetHandRayPointerBehavior(PointerBehavior.Default);

Le code suivant force les rayons de la main à être activés, qu’ils soient proches d’une capture :

// Turn off all hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOn);

Consultez PointerUtils et TurnPointersOnOff pour plus d’exemples.

FocusProvider

Est FocusProvider le cheval de travail qui est chargé d’itérer sur la liste de tous les pointeurs et de déterminer quel est l’objet ciblé pour chaque pointeur.

Dans chaque Update() appel, cela permet de :

  1. Mettez à jour tous les pointeurs, en effectuant un raycasting et en effectuant une détection d’accès telle que configurée par le pointeur lui-même (par exemple, le pointeur de sphère peut spécifier le raycastMode SphereOverlap, afin que FocusProvider effectue une collision basée sur une sphère)

  2. Mettez à jour l’objet ciblé sur une base par pointeur (c’est-à-dire, si un objet a obtenu le focus, il déclencherait également des événements sur cet objet, si un objet perdait le focus, il déclencherait le focus perdu, etc.).

Configuration et cycle de vie du pointeur

Les pointeurs peuvent être configurés dans la section Pointeurs du profil système d’entrée.

La durée de vie d’un pointeur est généralement la suivante :

  1. Un gestionnaire de périphériques détecte la présence d’un contrôleur. Ce gestionnaire de périphériques crée ensuite l’ensemble de pointeurs associés au contrôleur via un appel à RequestPointers.

  2. FocusProvider, dans sa boucle Update(), itérera sur tous les pointeurs valides et effectuera la logique de détection de raycast ou d’accès associée. Cela permet de déterminer l’objet qui est concentré par chaque pointeur particulier.

    • Étant donné qu’il est possible d’avoir plusieurs sources d’entrée actives en même temps (par exemple, deux mains actives sont présentes), il est également possible d’avoir plusieurs objets qui ont le focus en même temps.
  3. Le gestionnaire de périphériques, lorsqu’il découvre qu’une source de contrôleur a été perdue, supprime les pointeurs associés au contrôleur perdu.