Handtracering — MRTK2

Profiel voor handtracering

Het profiel Voor handtracering vindt u onder het invoersysteemprofiel. Het bevat instellingen voor het aanpassen van de handweergave.

Profiel voor handtracering

Gezamenlijke prefabs

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

Standaard zijn de handgevoegde 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!

Standaardgemeenschappelijke weergave van hand Gezamenlijke labels
Gelekte handverbindingen Invoerhandverbindingen

Handmaas prefab

De hand-mesh 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, dus een dummy mesh zoals een kubus is voldoende. Het materiaal van de prefab wordt gebruikt voor het handgaas.

Hand-mesh-invoer

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

Instellingen voor handvisualisatie

De hand-mesh- en handvisualisaties kunnen worden uitgeschakeld of ingeschakeld via respectievelijk de instelling Hand Mesh-visualisatiemodi en handgemeenschappelijke visualisatiemodi . Deze instellingen zijn toepassingsmodusspecifiek, wat betekent dat het mogelijk is om bepaalde functies in te schakelen in de editor (om verbindingen met simulatie in de editor te bekijken, bijvoorbeeld) terwijl dezelfde functies zijn uitgeschakeld wanneer ze worden geïmplementeerd op het apparaat (in speler-builds).

Houd er rekening mee dat het over het algemeen wordt aanbevolen om gezamenlijke handvisualisatie in de editor in te schakelen (zodat in-editorsimulatie wordt aangegeven waar de handkoppelingen zijn) en dat zowel handgemeenschappelijke visualisatie als handmaasvisualisatie zijn uitgeschakeld in de speler (omdat er een prestatietreffer optreedt).

Uitvoeren van scripts

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

Het systeem biedt ook toegang tot GameObjects die de gewrichten volgen. Dit kan handig zijn als een ander GameObject continu een gezamenlijke moet bijhouden.

Beschikbare gewrichten worden vermeld in de TrackedHandJoint opsomming.

Notitie

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

Toegang tot een bepaalde handcontroller

Een specifieke handcontroller is vaak beschikbaar, bijvoorbeeld bij het verwerken van invoergebeurtenissen. In dit geval kunnen de gezamenlijke gegevens rechtstreeks vanaf het apparaat worden aangevraagd met behulp van de IMixedRealityHand interface.

De gezamenlijke houding van de controller peilen

De TryGetJoint functie retourneert false als de aangevraagde joint om een of andere reden niet beschikbaar is. In dat geval zal de resulterende houding zijn MixedRealityPose.ZeroIdentity.

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 visualisatie 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 gegevenstoegang

Als er geen specifieke controller wordt gegeven, worden er hulpprogrammaklassen verstrekt voor handige toegang tot handgemeenschappelijke gegevens. Deze functies vragen gezamenlijke gegevens aan van het eerste beschikbare apparaat dat momenteel wordt bijgehouden.

Polling joint pose van HandJointUtils

HandJointUtils is een statische klasse waarmee een query wordt uitgevoerd op het eerste actieve apparaat.

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

Gezamenlijke transformatie van handgemeenschappelijke service

IMixedRealityHandJointService houdt een permanente set GameObjects voor het bijhouden van joints.

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

Gebeurtenissen voor handtracering

Het invoersysteem biedt ook gebeurtenissen, als pollinggegevens van controllers rechtstreeks niet wenselijk zijn.

Gezamenlijke gebeurtenissen

IMixedRealityHandJointHandler verwerkt updates van gezamenlijke posities.

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 hand meshes niet standaard zijn 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 master-builds met behulp van de .NET-back-end. In systeemeigen .NET IInspectable kunnen pointers niet worden marshaled van systeemeigen naar beheerde code met behulp van Marshal.GetObjectForIUnknown. MRTK gebruikt dit om de SpatialCoordinateSystem hand- en ooggegevens van het platform te ontvangen.

We hebben een DLL-bron opgegeven als tijdelijke oplossing voor dit probleem, in de systeemeigen opslagplaats Mixed Reality Toolkit. Volg de instructies in de README daar en kopieer de resulterende binaire bestanden naar een map Plugins in uw Unity-assets. Daarna lost het Script WindowsMixedRealityUtilities in MRTK de tijdelijke oplossing voor u op.

Als u uw eigen DLL wilt maken of deze tijdelijke oplossing in een bestaande wilt opnemen, 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;
    }
}