Controller, puntatori e messa a fuoco — MRTK2

I controller, i puntatori e lo stato attivo sono concetti di livello superiore che si basano sulla base stabilita dal sistema di input principale. Insieme, forniscono una grande parte del meccanismo per interagire con oggetti nella scena.

Controllers

I controller sono rappresentazioni di un controller fisico (6 gradi di libertà, mano articolata e così via). Vengono creati dai responsabili dei dispositivi e sono responsabili della comunicazione con il sistema sottostante corrispondente e la traduzione dei dati in dati e eventi con forma MRTK.

Ad esempio, sulla piattaforma Windows Mixed Reality, è WindowsMixedRealityArticulatedHand un controller responsabile dell'interfacciamento con le API di rilevamento delle mani sottostanti Windows per ottenere informazioni sulle articolazioni, la posa e altre proprietà della mano. È responsabile della trasformazione di questi dati in eventi MRTK pertinenti,ad esempio chiamando RaisePoseInputChanged o RaiseHandJointsUpdated, e aggiornando lo stato interno in modo che le query per TryGetJointPose restituiranno dati corretti.

In genere, il ciclo di vita di un controller comporta:

  1. Un controller viene creato da un gestore dispositivi al momento del rilevamento di una nuova origine, ad esempio il gestore dispositivi rileva e avvia il rilevamento di una mano.

  2. Nel ciclo update() del controller chiama nel sistema API sottostante.

  3. Nello stesso ciclo di aggiornamento genera modifiche all'evento di input chiamando direttamente nel sistema di input principale stesso (ad esempio, aumentando HandMeshUpdated o HandJointsUpdated).

Puntatori e messa a fuoco

I puntatori vengono usati per interagire con gli oggetti del gioco. Questa sezione descrive come vengono creati puntatori, come vengono aggiornati e come determinano gli oggetti che si trovano nello stato attivo. Verranno inoltre illustrati i diversi tipi di puntatori esistenti e gli scenari in cui sono attivi.

Categorie puntatore

I puntatori in genere rientrano in una delle categorie seguenti:

  • Puntatori lontani

    Questi tipi di puntatori vengono usati per interagire con oggetti che sono lontani dall'utente (lontano è definito semplicemente "non vicino"). Questi tipi di puntatori in genere esegue il cast di linee che possono andare lontano nel mondo e consentire all'utente di interagire con e modificare gli oggetti che non sono immediatamente accanto a loro.

  • Puntatori vicino

    Questi tipi di puntatori vengono usati per interagire con oggetti che sono abbastanza vicini all'utente per afferrare, toccare e modificare. In genere, questi tipi di puntatori interagiscono con oggetti cercando oggetti nella vicinanza vicina (eseguendo il raycasting a piccole distanze, eseguendo il cast sferico cercando oggetti nella vicinanza o enumerando elenchi di oggetti considerati afferrabili/toccabili).

  • Puntatori teleporti

    Questi tipi di puntatori si collegano al sistema di teleportazione per gestire lo spostamento dell'utente nella posizione di destinazione del puntatore.

Mediazione puntatore

Poiché un singolo controller può avere più puntatori (ad esempio, la mano articolata può avere puntatori sia vicino che lontano), esiste un componente responsabile della mediazione del puntatore che deve essere attivo.

Ad esempio, quando la mano dell'utente si avvicina a un pulsante premuto, deve ShellHandRayPointer essere interrotta e deve PokePointer essere attivata.

Viene gestito da DefaultPointerMediator, che è responsabile della determinazione dei puntatori attivi, in base allo stato di tutti i puntatori. Uno degli elementi chiave che esegue questa operazione è disabilitare i puntatori lontani quando un puntatore vicino è vicino a un oggetto (vedere DefaultPointerMediator).

È possibile fornire un'implementazione alternativa del mediatore puntatore modificando la PointerMediator proprietà nel profilo del puntatore.

Come disabilitare i puntatori

Poiché il mediatore puntatore esegue ogni frame, termina il controllo dello stato attivo/inattivo di tutti i puntatori. Pertanto, se si imposta la proprietà IsInteractionEnabled di un puntatore nel codice, verrà sovrascritto dal mediatore puntatore ogni fotogramma. È invece possibile specificare l'oggetto PointerBehavior per controllare se i puntatori devono essere attiva o disattivati autonomamente. Si noti che questo funzionerà solo se si usa il valore predefinito FocusProvider e DefaultPointerMediator in MRTK.

Esempio: Disabilitare i raggi della mano in MRTK

Il codice seguente disattiva i raggi della mano in 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);

Il codice seguente restituirà i raggi di mano al comportamento predefinito in MRTK:

PointerUtils.SetHandRayPointerBehavior(PointerBehavior.Default);

Il codice seguente forza i raggi della mano da attivare, indipendentemente dal fatto che in prossimità di un oggetto afferrabile:

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

Per altri esempi, vedere PointerUtils e TurnPointersOnOff per altri esempi.

FocusProvider

Il FocusProvider cavallo di cavallo che è responsabile dell'iterazione sull'elenco di tutti i puntatori e capire qual è l'oggetto incentrato per ogni puntatore.

In ogni Update() chiamata, questa operazione:

  1. Aggiornare tutti i puntatori, eseguendo raycasting e eseguendo il rilevamento degli hit configurati dal puntatore stesso (ad esempio, il puntatore a sfera potrebbe specificare sphereOverlap raycastMode, quindi FocusProvider eseguirà una collisione basata su sfera)

  2. Aggiornare l'oggetto incentrato su base a puntatore (ad esempio, se un oggetto ha ottenuto lo stato attivo, viene attivato anche gli eventi a tale oggetto, se un oggetto perde lo stato attivo, lo stato attivo viene perso e così via).

Configurazione e ciclo di vita del puntatore

I puntatori possono essere configurati nella sezione Puntatori del profilo di sistema di input.

La durata di un puntatore è generalmente la seguente:

  1. Un gestore dispositivi rileverà la presenza di un controller. Questa gestione dispositivi creerà quindi il set di puntatori associati al controller tramite una chiamata a RequestPointers.

  2. Lo FocusProvider, nel ciclo Update(), eseguirà l'iterazione su tutti i puntatori validi e eseguirà la logica di rilevamento dei raggi associata o di hit. Questa operazione viene usata per determinare l'oggetto incentrato su ogni particolare puntatore.

    • Poiché è possibile avere più origini di input attive contemporaneamente (ad esempio due mani attive), è anche possibile avere più oggetti che hanno lo stato attivo contemporaneamente.
  3. Il gestore dispositivi, dopo aver scoperto che un'origine controller è stata persa, elimina i puntatori associati al controller perso.