Tracciamento della mano - MRTK2
Profilo di tracciamento della mano
Il profilo di rilevamento della mano si trova nel profilo del sistema di input. Contiene le impostazioni per la personalizzazione della rappresentazione manuale.
Prefab comuni
I prefab comuni vengono visualizzati usando prefab semplici. Le articolazioni palmo e indice sono di particolare importanza e hanno il proprio prefab, mentre tutte le altre articolazioni condividono lo stesso prefab.
Per impostazione predefinita, i prefab delle articolazioni della mano sono semplici primitive geometriche. Queste possono essere sostituite, se necessario. Se non viene specificato alcun prefab, vengono creati invece gameobject vuoti.
Avviso
Evitare di usare script complessi o un rendering costoso nei prefab comuni, poiché gli oggetti joint vengono trasformati in ogni frame e possono avere un costo significativo per le prestazioni.
Rappresentazione congiunta manuale predefinita | Etichette comuni |
---|---|
Prefab mesh a mano
La mesh manuale viene utilizzata se i dati mesh completamente definiti vengono forniti dal dispositivo di tracciamento della mano. Il rendering della mesh nel prefab viene sostituito dai dati del dispositivo, quindi è sufficiente una mesh fittizia, ad esempio un cubo. Il materiale del prefab viene usato per la mesh a mano.
La visualizzazione mesh a mano può avere un impatto notevole sulle prestazioni, per questo motivo può essere disabilitata completamente deselezionando l'opzione Abilita visualizzazione mesh manuale .
Impostazioni di visualizzazione della mano
Le visualizzazioni della mesh a mano e delle mani possono essere disattivate o attivate rispettivamente tramite l'impostazione Modalità di visualizzazione Mesh mano e Le modalità di visualizzazione delle mani. Queste impostazioni sono specifiche della modalità applicazione, ovvero è possibile attivare alcune funzionalità durante l'editor (per visualizzare le articolazioni con simulazione nell'editor, ad esempio) con le stesse funzionalità disattivate quando vengono distribuite nel dispositivo (nelle build del lettore).
Si noti che in genere è consigliabile attivare la visualizzazione delle articolazioni della mano nell'editor (in modo che la simulazione nell'editor mostri dove si trovano le articolazioni della mano) e di avere sia la visualizzazione delle articolazioni della mano che la visualizzazione della mesh della mano disattivata nel giocatore (perché comportano un riscontro delle prestazioni).
Scripting
La posizione e la rotazione possono essere richieste dal sistema di input per ogni singola articolazione della mano come .MixedRealityPose
In alternativa, il sistema consente l'accesso a GameObjects che seguono le articolazioni. Ciò può essere utile se un altro GameObject deve tenere traccia di un'articolazione in modo continuo.
Le articolazioni disponibili sono elencate nell'enumerazione TrackedHandJoint
.
Nota
L'oggetto giunto viene distrutto quando si perde il tracciamento della mano! Assicurarsi che tutti gli script che usano l'oggetto comune gestiscono normalmente il null
caso per evitare errori.
Accesso a un determinato controller della mano
Un controller della mano specifico è spesso disponibile, ad esempio quando si gestiscono gli eventi di input. In questo caso i dati comuni possono essere richiesti direttamente dal dispositivo, usando l'interfaccia IMixedRealityHand
.
Polling joint pose from controller
La TryGetJoint
funzione restituisce false
se il giunto richiesto non è disponibile per qualche motivo. In tal caso la posa risultante sarà MixedRealityPose.ZeroIdentity
.
public void OnSourceDetected(SourceStateEventData eventData)
{
var hand = eventData.Controller as IMixedRealityHand;
if (hand != null)
{
if (hand.TryGetJoint(TrackedHandJoint.IndexTip, out MixedRealityPose jointPose)
{
// ...
}
}
}
Trasformazione congiunta dal visualizzatore a mano
Gli oggetti joint possono essere richiesti dal visualizzatore controller.
public void OnSourceDetected(SourceStateEventData eventData)
{
var handVisualizer = eventData.Controller.Visualizer as IMixedRealityHandVisualizer;
if (handVisualizer != null)
{
if (handVisualizer.TryGetJointTransform(TrackedHandJoint.IndexTip, out Transform jointTransform)
{
// ...
}
}
}
Accesso semplificato ai dati comuni
Se non viene fornito alcun controller specifico, vengono fornite classi di utilità per un accesso pratico ai dati comuni. Queste funzioni richiedono dati comuni dal primo dispositivo a mano attualmente monitorato.
Polling joint pose from HandJointUtils
HandJointUtils
è una classe statica che esegue una query sul primo dispositivo a mano attiva.
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, Handedness.Right, out MixedRealityPose pose))
{
// ...
}
Trasformazione congiunta dal servizio congiunto a mano
IMixedRealityHandJointService
mantiene un set persistente di GameObjects per tenere traccia delle articolazioni.
var handJointService = CoreServices.GetInputSystemDataProvider<IMixedRealityHandJointService>();
if (handJointService != null)
{
Transform jointTransform = handJointService.RequestJointTransform(TrackedHandJoint.IndexTip, Handedness.Right);
// ...
}
Eventi di rilevamento della mano
Anche il sistema di input fornisce eventi, se non è consigliabile eseguire direttamente il polling dei dati dai controller.
Eventi comuni
IMixedRealityHandJointHandler
gestisce gli aggiornamenti delle posizioni comuni.
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))
{
// ...
}
}
}
}
Eventi mesh
IMixedRealityHandMeshHandler
gestisce le modifiche della mesh a mano articolata.
Si noti che le mesh a mano non sono abilitate per impostazione predefinita.
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;
}
// ...
}
}
}
Problemi noti
.NET Native
Esiste attualmente un problema noto con le compilazioni master che usano il back-end .NET. In .NET Native non IInspectable
è possibile effettuare il marshalling dei puntatori dal codice nativo al codice gestito usando Marshal.GetObjectForIUnknown
. MRTK usa questa opzione per ottenere l'oggetto SpatialCoordinateSystem
per ricevere dati di mano e occhio dalla piattaforma.
L'origine DLL è stata fornita come soluzione alternativa per questo problema, nel repository nativo di Realtà mista Toolkit. Seguire le istruzioni nel file LEGGIMI e copiare i file binari risultanti in una cartella Plugins negli asset di Unity. Successivamente, lo script WindowsMixedRealityUtilities fornito in MRTK risolverà automaticamente la soluzione alternativa.
Se si vuole creare una DLL personalizzata o includere questa soluzione alternativa in una soluzione esistente, il nucleo della soluzione alternativa è:
extern "C" __declspec(dllexport) void __stdcall MarshalIInspectable(IUnknown* nativePtr, IUnknown** inspectable)
{
*inspectable = nativePtr;
}
E il relativo uso nel codice 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;
}
}