OpenXR-Handtracking

Einführung

Bemerkung

Diese Seite konzentriert sich speziell auf den Funktionsumfang, der durch OpenXR verfügbar gemacht wird. Teile der hier vorgestellten Funktionalität gelten auch für WebXR und können von anderen XR-Schnittstellen bereitgestellt werden.

Bei der Diskussion über Handtracking ist es wichtig zu wissen, dass es unterschiedliche Meinungen darüber gibt, wo die Grenzen gezogen werden. In der Praxis hat dies zur Folge, dass es Unterschiede in der Implementierung zwischen den verschiedenen OpenXR-Laufzeiten gibt. Möglicherweise finden Sie sich in einer Situation wieder, in der die ausgewählte Hardware ein Teil des Puzzles nicht unterstützt oder die Dinge so anders macht als die anderen Plattformen, dass Sie zusätzliche Arbeit leisten müssen.

Allerdings schließen die jüngsten Verbesserungen der OpenXR-Spezifikation diese Lücken und da die Plattformen diese Verbesserungen implementieren, kommen wir einer Zukunft näher, in der wir entweder über vollständige Portabilität zwischen Plattformen verfügen oder zumindest eine klare Möglichkeit, die Fähigkeiten einer Plattform zu erkennen.

Wenn wir uns die Anfänge von VR ansehen, lag der Fokus der großen Plattformen auf der Verfolgung von Controller-basierten Eingaben. Hier verfolgen wir ein physisches Gerät, das auch Tasten für weitere Eingaben hat. Aus den Tracking-Daten können wir auf die Position der Hände des Spielers schließen, aber es sind keine weiteren Informationen bekannt. Traditionell wurde es dem Spiel überlassen, einen Mechanismus zu implementieren, um die Hand des Spielers anzuzeigen und die Finger basierend auf weiteren Eingaben vom Controller zu animieren, sei es durch gedrückte Tasten oder durch Näherungssensoren. Oft werden Finger auch kontextabhängig platziert, je nachdem, was der Benutzer hält und welche Aktion er ausführt.

In jüngerer Zeit ist optisches Handtracking eine beliebte Lösung geworden, bei dem Kameras die Hände des Benutzers verfolgen und vollständige Trackingdaten für die Hand- und Fingerpositionen verfügbar werden. Viele Anbieter betrachteten dies als völlig unabhängig vom Controller-Tracking und führten unabhängige APIs ein, um auf Hand- und Fingerpositionen sowie Orientierungsdaten zuzugreifen. Bei der Verarbeitung von Eingaben war es Sache des Spieleentwicklers, einen Mechanismus zur Gestenerkennung zu implementieren.

Diese Trennung besteht auch in OpenXR, wo das Controller-Tracking hauptsächlich vom Action-Map-System übernommen wird, während das optische Hand-Tracking hauptsächlich von der Hand-Tracking-API-Erweiterung übernommen wird.

Allerdings ist die Welt nicht ganz so schwarz und weiß und wir erleben eine Reihe von Szenarien, in denen wir Grenzen überschreiten:

  • Geräte, die in beide Kategorien passen, wie getrackte Handschuhe und Controller wie der Index-Controller, die auch Finger-Tracking durchführen.

  • XR-Laufzeitumgebungen, die abgeleitetes Hand-Tracking aus Controllerdaten implementieren, um die richtige Fingerplatzierung für mehrere Controller zu ermitteln.

  • XR-Anwendungen, die nahtlos zwischen Controller- und Hand-Tracking wechseln möchten und unabhängig vom verwendeten Ansatz dasselbe Benutzererlebnis bieten möchten.

OpenXR reagiert auf diesen Aufruf, indem es weitere Erweiterungen einführt, mit denen wir die Fähigkeiten der XR-Laufzeit/Hardware abfragen oder über diese Kluft hinweg weitere Funktionen hinzufügen können. Das derzeit noch bestehende Problem besteht darin, dass es Lücken bei der Übernahme dieser Erweiterungen gibt, da einige Plattformen die Fähigkeiten daher nicht in vollem Umfang melden. Daher müssen Sie möglicherweise die auf bestimmter Hardware verfügbaren Funktionen testen und Ihren Ansatz entsprechend anpassen.

Demo-Projekt

Die auf dieser Seite dargestellten Informationen wurden zum Erstellen eines Demoprojekts verwendet, das Sie hier finden.

Die Hand Tracking API

Wie in unserer Einleitung erwähnt, wird die Hand-Tracking-API hauptsächlich mit optischem Hand-Tracking verwendet und funktioniert auf vielen Plattformen nur, wenn der Benutzer keinen Controller hält. Einige Plattformen unterstützen vom Controller abgeleitetes Hand-Tracking, was bedeutet, dass Sie Hand-Tracking-Daten erhalten, auch wenn der Benutzer einen Controller hält. Dazu gehören SteamVR, Meta Quest (derzeit nur nativ, aber Meta-Link-Unterstützung kommt wahrscheinlich) und hoffentlich bald auch andere.

Die Implementierung der Handverfolgung in Godot wurde auf der Grundlage des Godot Humanoid Skeleton standardisiert und funktioniert sowohl in OpenXR als auch in WebXR. Die folgenden Anweisungen funktionieren daher in beiden Umgebungen.

Um die Hand-Tracking-API mit OpenXR zu verwenden, müssen Sie sie zuerst aktivieren. Dies kann in den Projekteinstellungen erfolgen:

../../_images/xr_enable_handtracking.webp

Für einige eigenständige XR-Geräte müssen Sie auch die Handverfolgungserweiterung in den Exporteinstellungen konfigurieren, beispielsweise für Meta Quest:

../../_images/openxr_enable_hand_tracking_meta.webp

Jetzt müssen Sie für jede Hand drei Komponenten zu Ihrer Szene hinzufügen:

  • Ein verfolgter Knoten zum Positionieren der Hand.

  • Ein richtig geskinntes Handmesh mit Skelett.

  • Ein Skelett-Modifier, der Finger-Tracking-Daten auf das Skelett anwendet.

../../_images/openxr_hand_tracking_nodes.webp

Handtrackingnodes

Das Handtrackingsystem verwendet separate Handtracker, um die Position der Hände des Spielers in unserem Verfolgungsraum zu verfolgen.

Diese Informationen wurden für die folgenden Anwendungsfälle herausgefiltert:

  • Die Verfolgung erfolgt im lokalen Bereich des Knotens XROrigin3D. Dieser Knoten muss ein untergeordneter Knoten des Knotens XROrigin3D sein, um korrekt platziert zu werden.

  • Dieser Knoten kann als IK-Ziel verwendet werden, wenn anstelle von separaten Handnetzen ein Oberkörpernetz mit Armen verwendet wird.

  • Die tatsächliche Platzierung der Hände kann in Szenarien wie Benutzeroberflächen zur Avatar-Erstellung, falschen Spiegeln oder ähnlichen Situationen lose an die Verfolgung gebunden sein, was dazu führt, dass das Handmesh und das Fingertracking an einer anderen Stelle lokalisiert werden.

Wir konzentrieren uns nur auf den ersten Anwendungsfall.

Dazu müssen Sie Ihrem XROrigin3D-Knoten einen XRNode3D-Knoten hinzufügen.

  • Auf diesem Knoten sollte der Tracker auf /user/hand_tracker/left oder /user/hand_tracker/right für die linke bzw. rechte Hand eingestellt werden.

  • Die Pose sollte auf Standard eingestellt bleiben, eine andere Option funktioniert hier nicht.

  • Das Kontrollkästchen Bei Verfolgung anzeigen blendet diesen Knoten automatisch aus, wenn keine Verfolgungsdaten verfügbar sind, oder macht diesen Knoten sichtbar, wenn Verfolgungsdaten verfügbar sind.

Rigged-Handmesh

Um unsere Hand anzuzeigen, benötigen wir ein Handnetz, das entsprechend ausgerüstet und geskinnt ist. Hierzu verwendet Godot die Handknochenstruktur, wie sie für den Godot Humanoid definiert ist, unterstützt aber optional einen zusätzlichen Spitzenknochen für jeden Finger.

The OpenXR hand tracking demo contains example glTF files of properly rigged hands.

Wir werden diese hier verwenden und sie als untergeordnetes Element zu unserem Knoten XRNode3D hinzufügen. Wir müssen auch bearbeitbare untergeordnete Elemente aktivieren, um Zugriff auf unseren Knoten Skeleton3D zu erhalten.

Der Handskelett-Modifikator

Finally we need to add an XRHandModifier3D node as a child to our Skeleton3D node. This node will obtain the finger tracking data from OpenXR and apply it the hand model.

Sie müssen die Eigenschaft Hand Tracker entweder auf /user/hand_tracker/left oder /user/hand_tracker/right setzen, je nachdem, ob wir die Tracking-Daten der linken oder rechten Hand anwenden.

Sie können für diesen Knoten auch den Modus Bone Update einstellen.

  • Vollständig wendet die Handverfolgungsdaten vollständig an. Dies bedeutet, dass die Skelettpositionierung möglicherweise die Größe der tatsächlichen Hand des Benutzers widerspiegelt. Dies kann zu einem Scrunching-Effekt führen, wenn die Meshes nicht richtig gewichtet sind, um dies zu berücksichtigen. Stellen Sie sicher, dass Sie Ihr Spiel mit Spielern aller Größen testen, wenn optische Handverfolgung verwendet wird!

  • Nur Rotation wendet nur die Rotation auf die Knochen der Hände an und behält die Knochenlänge bei. In diesem Modus ändert sich die Größe des Handmeshes nicht.

Wenn dies hinzugefügt wurde, sollte beim Ausführen des Projekts die Hand korrekt angezeigt werden, sofern das Handtracking unterstützt wird.

Die Hand-Tracking-Datenquelle

Dies ist eine OpenXR-Erweiterung, die Informationen über die Quelle der Handverfolgungsdaten bereitstellt. Derzeit implementieren nur wenige Laufzeiten sie, aber wenn sie verfügbar ist, wird Godot sie aktivieren.

Wenn diese Erweiterung nicht unterstützt wird und daher „unknown“ zurückgegeben wird, können Sie von folgenden Annahmen ausgehen:

  • Wenn Sie SteamVR (einschließlich Steam-Link) verwenden, wird nur das Controller-basierte Handtracking unterstützt.

  • Für alle anderen Laufzeitumgebungen gilt: Sofern Handverfolgung unterstützt wird, wird nur optisches Handverfolgung unterstützt (Hinweis: Metalinks fallen derzeit in diese Kategorie).

  • In allen anderen Fällen wird überhaupt kein Hand-Tracking unterstützt.

Sie können auf diese Informationen über den Code zugreifen:

var hand_tracker : XRHandTracker = XRServer.get_tracker('/user/hand_tracker/left')
if hand_tracker:
    if hand_tracker.has_tracking_data:
        if hand_tracker.hand_tracking_source == XRHandTracker.HAND_TRACKING_SOURCE_UNKNOWN:
            print("Hand tracking source unknown")
        elif hand_tracker.hand_tracking_source == XRHandTracker.HAND_TRACKING_SOURCE_UNOBSTRUCTED:
            print("Hand tracking source is optical hand tracking")
        elif hand_tracker.hand_tracking_source == XRHandTracker.HAND_TRACKING_SOURCE_CONTROLLER:
            print("Hand tracking data is inferred from controller data")
        else:
            print("Unknown hand tracking source ", hand_tracker.hand_tracking_source)
    else:
        print("Hand is currently not being tracked")
else:
    print("No hand tracker registered")

This example logs the state for the left hand.

Wenn in diesem Beispiel kein Hand-Tracker von get_tracker zurückgegeben wird, bedeutet dies, dass die Hand-Tracking-API von der XR-Laufzeitumgebung überhaupt nicht unterstützt wird.

Wenn ein Tracker vorhanden ist, aber has_tracking_data falsch ist, wird die Hand des Benutzers derzeit nicht verfolgt. Dies hat wahrscheinlich einen der folgenden Gründe:

  • Die Hand des Spielers ist für keine der Tracking-Kameras am Headset sichtbar

  • Der Spieler verwendet derzeit einen Controller und das Headset unterstützt nur optisches Handtracking

  • Der Controller ist ausgeschaltet und es wird nur das Handtracking des Controllers unterstützt.

Verarbeiten von Benutzereingaben

Das Reagieren auf vom Benutzer ausgeführte Aktionen wird bei Verwendung von Controllern über Das XR-Action-Mapping abgewickelt. In der Aktionskarte können Sie verschiedene Eingaben wie den Auslöser oder den Joystick auf dem Controller einer Aktion zuordnen. Dies kann dann die Logik in Ihrem Spiel steuern.

Bei der Verwendung von Handtracking gab es ursprünglich keine solchen Eingaben. Die Eingaben werden durch Gesten des Benutzers gesteuert, z. B. durch das Ballen einer Faust zum Greifen oder das Zusammenziehen von Daumen und Zeigefinger zum Auswählen von etwas. Es war Sache des Spieleentwicklers, dies umzusetzen.

Angesichts der zunehmenden Nachfrage nach Anwendungen, die nahtlos zwischen Controller- und Hand-Tracking wechseln können und eine gewisse grundlegende Eingabefähigkeit erfordern, wurden der Spezifikation einige Erweiterungen hinzugefügt, die eine grundlegende Gestenerkennung ermöglichen und mit der Aktionskarte verwendet werden können.

Das Hand-Interaktionsprofil

Die Handinteraktionsprofilerweiterung ist eine neue Kernerweiterung, die Pinch-, Greif- und Poke-Gesten und damit verbundene Posen unterstützt. Diese Erweiterung wird derzeit noch nur eingeschränkt unterstützt, sollte aber in naher Zukunft in weiteren Laufzeiten verfügbar sein.

../../_images/openxr_hand_interaction_profile.webp

Die Pinch-Geste wird durch Zusammenziehen von Daumen und Zeigefinger ausgelöst. Dies wird häufig als Auswahlgeste für Menüsysteme verwendet, ähnlich wie wenn Sie mit Ihrem Controller auf ein Objekt zeigen und den Auslöser drücken, um es auszuwählen, und wird daher häufig als solche abgebildet.

  • Bei der Pinch-Pose handelt es sich um eine Pose, die in der Mitte zwischen der Spitze des Daumens und der Spitze des Zeigefingers positioniert und so ausgerichtet ist, dass ein Ray Cast zur Identifizierung eines Ziels verwendet werden kann.

  • Der Float-Eingang Pinch ist ein Wert zwischen 0,0 (die Spitzen von Daumen und Zeigefinger sind auseinander) und 1,0 (die Spitzen von Daumen und Zeigefinger berühren sich).

  • Die Eingabe Pinch Ready ist wahr, wenn sich die Fingerspitzen (fast) berühren.

Die Greifgeste wird durch das Ballen einer Faust ausgelöst und wird oft verwendet, um Gegenstände aufzuheben, ähnlich wie die Quetscheingabe auf Controllern.

  • Der Float-Input Greifen ist ein Wert zwischen 0.0 (offene Hand) und 1.0 (Faust).

  • Die Eingabe Greifen bereit ist wahr, wenn der Benutzer eine Faust gemacht hat.

Die Anstupsgeste wird durch Ausstrecken des Zeigefingers ausgelöst. Dies ist eine kleine Ausnahme, da die Pose an der Spitze des Zeigefingers häufig verwendet wird, um ein interaktives Objekt anzustupsen. Die Anstupspose ist eine Pose, die auf der Spitze des Zeigefingers positioniert ist.

Schließlich wird die Eingabe Ziel aktivieren (bereit) als eine Eingabe definiert, die 1.0/wahr ist, wenn der Zeigefinger ausgestreckt ist und auf ein Ziel zeigt, das aktiviert werden kann. Wie Laufzeiten dies interpretieren, ist nicht klar.

Bei diesem Setup werden die normalen left_hand- und right_hand-Tracker verwendet und man kann somit nahtlos zwischen Controller- und Hand-Tracking-Eingabe wechseln.

Bemerkung

Sie müssen die Handinteraktionsprofilerweiterung in den OpenXR-Projekteinstellungen aktivieren.

Microsoft-Handinteraktionsprofil

Die „Microsoft hand interaction profile extension <https://github.khronos.org/OpenXR-Inventory/extension_support.html#XR_MSFT_hand_interaction>“_ wurde von Microsoft eingeführt und imitiert grob das einfache Controller-Profil. Meta hat auch Unterstützung für diese Erweiterung hinzugefügt, allerdings nur auf ihrem nativen OpenXR-Client. Sie ist derzeit nicht über Meta Link verfügbar.

../../_images/openxr_msft_hand_interaction_profile.webp

Die Pinch-Unterstützung wird über die Eingabe select verfügbar gemacht. Der Wert beträgt 0.0, wenn die Spitzen von Daumen und Zeigefinger auseinander liegen, und 1.0, wenn sie zusammen liegen.

Beachten Sie, dass in diesem Profil die Zielpose als Pose zwischen Daumen und Zeigefinger neu definiert wird, die so ausgerichtet ist, dass ein Ray Cast zum Identifizieren eines Ziels verwendet werden kann.

Die Greifunterstützung wird durch die Eingabe Quetschen verfügbar gemacht, deren Wert 0.0 beträgt, wenn die Hand geöffnet ist, und 1.0, wenn die Faust geballt ist.

Bei diesem Setup werden die normalen left_hand- und right_hand-Tracker verwendet und man kann somit nahtlos zwischen Controller- und Hand-Tracking-Eingabe wechseln.

HTC-Handinteraktionsprofil

Die htc Hand Interaction Profile Extension wurde von HTC eingeführt und ist ähnlich wie die Microsoft-Erweiterung definiert. Sie wird von HTC nur für die Headsets Focus 3 und Elite XR unterstützt.

../../_images/openxr_htc_hand_interaction_profile.webp

Informationen zur Gestenunterstützung finden Sie im Microsoft-Handinteraktionsprofil.

Der entscheidende Unterschied besteht darin, dass diese Erweiterung zwei neue Tracker einführt: /user/hand_htc/left und /user/hand_htc/right. Dies bedeutet, dass zusätzliche Logik implementiert werden muss, um zwischen den Standard-Trackern und den HTC-spezifischen Trackern zu wechseln, wenn der Benutzer seinen Controller ablegt oder aufnimmt.

Einfaches Controllerprofil

Das einfache Controllerprofil ist ein Standardkernprofil, das als Fallbackprofil definiert ist, wenn ein Controller verwendet wird, für den kein Profil existiert.

Es gibt eine Reihe von OpenXR-Laufzeitumgebungen, die Controller über das einfache Controllerprofil nachahmen, wenn Hand-Tracking verwendet wird.

Leider gibt es keine stichhaltige Möglichkeit, um festzustellen, ob ein unbekannter Controller verwendet wird oder ob das Hand-Tracking über dieses Profil einen Controller emuliert.

../../_images/openxr_simple_controller_hand.webp

XR-Laufzeiten können die Funktionsweise des einfachen Controllerprofils frei definieren, daher besteht auch keine Gewissheit darüber, wie dieses Profil auf Gesten abgebildet wird.

Die gebräuchlichste Zuordnung scheint zu sein, dass Select-Klick wahr ist, wenn sich die Spitzen von Daumen und Zeigefinger berühren und die Handfläche des Benutzers vom Benutzer weg zeigt. Menü-Klick ist wahr, wenn sich die Spitzen von Daumen und Zeigefinger berühren und die Handfläche des Benutzers zum Benutzer zeigt.

Bei diesem Setup werden die normalen left_hand- und right_hand-Tracker verwendet und man kann somit nahtlos zwischen Controller- und Hand-Tracking-Eingabe wechseln.

Bemerkung

Da sich einige dieser Interaktionsprofile überschneiden, ist es wichtig zu wissen, dass Sie jedes Profil zu Ihrer Aktionskarte hinzufügen können und die XR-Laufzeit das am besten passende Profil auswählt.

Beispielsweise unterstützt ein Meta Quest sowohl das Microsoft-Handinteraktionsprofil als auch das einfache Controllerprofil. Wenn beide angegeben sind, hat das Microsoft-Handinteraktionsprofil Vorrang und wird verwendet.

Sobald Meta die Kernprofilerweiterung für Handinteraktion unterstützt, wird erwartet, dass dieses Profil Vorrang vor Microsoft- und einfachen Controllerprofilen hat.

Gestenbasierte Eingabe

Wenn die Plattform bei Verwendung der Handverfolgung keine Interaktionsprofile unterstützt oder Sie eine Anwendung erstellen, für die Sie eine komplexere Gestenunterstützung benötigen, müssen Sie Ihr eigenes Gestenerkennungssystem erstellen.

Sie können die vollständigen Handverfolgungsdaten über die Ressource XRHandTracker für jede Hand abrufen. Sie können den Handtracker abrufen, indem Sie XRServer.get_tracker aufrufen und entweder /user/hand_tracker/left oder /user/hand_tracker/left als Tracker verwenden. Diese Ressource bietet Zugriff auf alle Gelenkinformationen für die jeweilige Hand.

Die detaillierte Beschreibung eines vollständigen Algorithmus zur Gestenerkennung geht über den Rahmen dieses Handbuchs hinaus. Es gibt jedoch eine Reihe von Community-Projekten, die Sie sich ansehen können: