Delen via


Handtracering — MRTK2

Handtraceringsprofiel

Het profiel Handtracering vindt u onder het profiel Invoersysteem. Het bevat instellingen voor het aanpassen van handweergave.

Handtraceringsprofiel

Gezamenlijke prefabs

Gezamenlijke prefabs worden gevisualiseerd met behulp van eenvoudige prefabs. De palm - en wijsvingerverbindingen zijn van bijzonder belang en hebben hun eigen prefab, terwijl alle andere verbindingen dezelfde prefab delen.

Standaard zijn de handgewrichte prefabs eenvoudige geometrische primitieven. Deze kunnen desgewenst worden vervangen. Als er helemaal geen prefab is opgegeven, worden in plaats daarvan lege GameObjects gemaakt.

Waarschuwing

Vermijd het gebruik van complexe scripts of dure rendering in gezamenlijke prefabs, omdat gezamenlijke objecten op elk frame worden getransformeerd en aanzienlijke prestatiekosten kunnen hebben.

Standaardhandgezame weergave Gezamenlijke labels
Gelede handgewrichten Invoerhandverbindingen

Prefab van handgaas

Het handgaas wordt gebruikt als volledig gedefinieerde mesh-gegevens worden geleverd door het handtraceringsapparaat. De mesh die in de prefab kan worden weergegeven, wordt vervangen door gegevens van het apparaat, zodat een dummy-mesh zoals een kubus voldoende is. Het materiaal van de prefab wordt gebruikt voor het handgaas.

Invoer hand mesh

Hand mesh-weergave kan een merkbare invloed hebben op de prestaties. Daarom kan het volledig worden uitgeschakeld door de optie Visualisatie van handgaas inschakelen uit te schakelen.

Instellingen voor handvisualisatie

De visualisaties van handgaas en handgewrichten kunnen worden in- of uitgeschakeld via respectievelijk de instelling Visualisatiemodi hand mesh en handgezame visualisatiemodi . Deze instellingen zijn specifiek voor de toepassingsmodus, wat betekent dat het mogelijk is om bepaalde functies in de editor in te schakelen (om bijvoorbeeld combinaties met in-editorsimulatie te zien) terwijl dezelfde functies zijn uitgeschakeld wanneer deze worden geïmplementeerd op het apparaat (in speler-builds).

Houd er rekening mee dat het over het algemeen wordt aanbevolen om handgemeenschappelijke visualisatie in de editor in te schakelen (zodat simulatie in de editor laat zien waar de handverbindingen zich bevinden), en om zowel handgewrichten als visualisatie met handgaas uit te schakelen in de speler (omdat ze een prestatietreffer hebben).

Scripting

Positie en draaiing kunnen worden aangevraagd vanuit het invoersysteem voor elke afzonderlijke handverbinding als een MixedRealityPose.

Het systeem staat ook toegang toe tot GameObjects die de verbindingen volgen. Dit kan handig zijn als een ander GameObject continu een joint moet bijhouden.

Beschikbare verbindingen worden vermeld in de TrackedHandJoint opsomming.

Opmerking

Het gezamenlijke object wordt vernietigd wanneer handtracering verloren gaat! Zorg ervoor dat scripts die gebruikmaken van het gezamenlijke object de null case correct verwerken om fouten te voorkomen.

Toegang krijgen tot een bepaalde handcontroller

Een specifieke handcontroller is vaak beschikbaar, bijvoorbeeld bij het verwerken van invoer gebeurtenissen. In dit geval kunnen de gezamenlijke gegevens rechtstreeks vanaf het apparaat worden opgevraagd via de IMixedRealityHand interface.

Polling joint pose van controller

De TryGetJoint functie retourneert false als de aangevraagde verbinding om een of andere reden niet beschikbaar is. In dat geval is MixedRealityPose.ZeroIdentityde resulterende houding .

public void OnSourceDetected(SourceStateEventData eventData)
{
  var hand = eventData.Controller as IMixedRealityHand;
  if (hand != null)
  {
    if (hand.TryGetJoint(TrackedHandJoint.IndexTip, out MixedRealityPose jointPose)
    {
      // ...
    }
  }
}

Gezamenlijke transformatie van hand visualiseren

Gezamenlijke objecten kunnen worden aangevraagd bij de visualisatiefunctie van de controller.

public void OnSourceDetected(SourceStateEventData eventData)
{
  var handVisualizer = eventData.Controller.Visualizer as IMixedRealityHandVisualizer;
  if (handVisualizer != null)
  {
    if (handVisualizer.TryGetJointTransform(TrackedHandJoint.IndexTip, out Transform jointTransform)
    {
      // ...
    }
  }
}

Vereenvoudigde gezamenlijke toegang tot gegevens

Als er geen specifieke controller wordt gegeven, worden er hulpprogrammaklassen geboden voor gemakkelijke toegang tot hand-gezamenlijke gegevens. Deze functies vragen om gezamenlijke gegevens van het eerste beschikbare handapparaat dat momenteel wordt bijgehouden.

Polling joint pose van HandJointUtils

HandJointUtils is een statische klasse die een query uitvoert op het eerste actieve apparaat.

if (HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, Handedness.Right, out MixedRealityPose pose))
{
    // ...
}

Gezamenlijke transformatie van hand gezamenlijke service

IMixedRealityHandJointService behoudt een permanente set GameObjects voor het bijhouden van verbindingen.

var handJointService = CoreServices.GetInputSystemDataProvider<IMixedRealityHandJointService>();
if (handJointService != null)
{
    Transform jointTransform = handJointService.RequestJointTransform(TrackedHandJoint.IndexTip, Handedness.Right);
    // ...
}

Handtraceringsevenementen

Het invoersysteem biedt ook gebeurtenissen als het rechtstreeks pollen van gegevens van controllers niet wenselijk is.

Gezamenlijke gebeurtenissen

IMixedRealityHandJointHandler verwerkt updates van gemeenschappelijke standpunten.

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))
            {
                // ...
            }
        }
    }
}

Mesh-gebeurtenissen

IMixedRealityHandMeshHandler verwerkt wijzigingen van het gearticuleerde handgaas.

Houd er rekening mee dat handgaas niet standaard is ingeschakeld.

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

            // ...
        }
    }
}

Bekende problemen

systeemeigen .NET

Er is momenteel een bekend probleem met hoofdbuilds die de .NET-back-end gebruiken. In systeemeigen .NET IInspectable kunnen aanwijzers niet worden weergegeven van systeemeigen naar beheerde code met behulp van Marshal.GetObjectForIUnknown. MRTK gebruikt deze om de SpatialCoordinateSystem te verkrijgen om hand- en ooggegevens van het platform te ontvangen.

Als tijdelijke oplossing voor dit probleem hebben we een DLL-bron verstrekt in de systeemeigen Mixed Reality Toolkit-opslagplaats. Volg de instructies in de README daar en kopieer de resulterende binaire bestanden naar een map Plugins in uw Unity-assets. Daarna wordt de tijdelijke oplossing opgelost met het script WindowsMixedRealityUtilities in MRTK.

Als u uw eigen DLL wilt maken of deze tijdelijke oplossing wilt opnemen in een bestaande, is de kern van de tijdelijke oplossing:

extern "C" __declspec(dllexport) void __stdcall MarshalIInspectable(IUnknown* nativePtr, IUnknown** inspectable)
{
    *inspectable = nativePtr;
}

En het gebruik ervan in uw C#Unity-code:

[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;
    }
}