Hände und Motion-Controller in DirectX

Hinweis

Dieser Artikel bezieht sich auf die älteren WinRT-nativen APIs. Für neue native App-Projekte empfehlen wir die Verwendung der OpenXR-API.

In Windows Mixed Reality werden sowohl Hand- als auch Bewegungscontrollereingaben über die räumlichen Eingabe-APIs behandelt, die im Windows gefunden werden. BENUTZEROBERFLÄCHE. Input.Spatial Namespace. Dadurch können Sie allgemeine Aktionen wie Select auf die gleiche Weise sowohl über Hände als auch Bewegungscontroller behandeln.

Erste Schritte

Beginnen Sie mit der SpatialInteractionManager-Schnittstelle, um auf räumliche Eingaben in Windows Mixed Reality zuzugreifen. Sie können auf diese Schnittstelle zugreifen, indem Sie SpatialInteractionManager::GetForCurrentView, normalerweise während des App-Starts, aufrufen.

using namespace winrt::Windows::UI::Input::Spatial;

SpatialInteractionManager interactionManager = SpatialInteractionManager::GetForCurrentView();

Der Auftrag des SpatialInteractionManagers besteht darin, Zugriff auf SpatialInteractionSources bereitzustellen, die eine Quelle von Eingaben darstellen. Es gibt drei Arten von SpatialInteractionSources im System.

  • Hand stellt die erkannte Hand eines Benutzers dar. Handquellen bieten verschiedene Features basierend auf dem Gerät, die von grundlegenden Gesten auf HoloLens bis hin zu voll artikulierter Handverfolgung auf HoloLens 2 reichen.
  • Controller stellt einen gekoppelten Bewegungscontroller dar. Bewegungscontroller können verschiedene Funktionen bieten, z. B. Auswahlauslöser, Menüschaltflächen, Tastenkombinationen, Touchpads und Daumensticks.
  • Voice stellt die Sprachausgabe des Sprachsystems des Benutzers dar. Diese Quelle fügt z. B. eine Select-Veröffentlichung ein, wenn der Benutzer "Auswählen" sagt.

Daten pro Frame für eine Quelle werden durch die SpatialInteractionSourceState-Schnittstelle dargestellt. Es gibt zwei verschiedene Möglichkeiten, auf diese Daten zuzugreifen, je nachdem, ob Sie ein ereignisgesteuertes oder abfragebasiertes Modell in Ihrer Anwendung verwenden möchten.

Ereignisgesteuerte Eingabe

Der SpatialInteractionManager bietet eine Reihe von Ereignissen, die Ihre App hören kann. Einige Beispiele umfassen SourcePressed, [SourceReleased und SourceUpdated.

Der folgende Code hängt beispielsweise einen Ereignishandler namens MyApp::OnSourcePressed mit dem SourcePressed-Ereignis ab. Dies ermöglicht Es Ihrer App, Drücken auf jeder Art von Interaktionsquelle zu erkennen.

using namespace winrt::Windows::UI::Input::Spatial;

auto interactionManager = SpatialInteractionManager::GetForCurrentView();
interactionManager.SourcePressed({ this, &MyApp::OnSourcePressed });

Dieses gedrückte Ereignis wird asynchron an Ihre App gesendet, zusammen mit dem entsprechenden SpatialInteractionSourceState zum Zeitpunkt des Drückens. Ihre App oder Spielmodul kann die Verarbeitung sofort starten oder die Ereignisdaten in Ihrer Eingabeverarbeitungsroutine in Warteschlange stellen. Nachfolgend finden Sie eine Ereignishandlerfunktion für das SourcePressed-Ereignis, das überprüft, ob die Auswahlschaltfläche gedrückt wurde.

using namespace winrt::Windows::UI::Input::Spatial;

void MyApp::OnSourcePressed(SpatialInteractionManager const& sender, SpatialInteractionSourceEventArgs const& args)
{
	if (args.PressKind() == SpatialInteractionPressKind::Select)
	{
		// Select button was pressed, update app state
	}
}

Der obige Code überprüft nur die Drücken "Auswählen", die der primären Aktion auf dem Gerät entspricht. Beispiele sind das Ausführen eines AirTap-Elements HoloLens oder das Ziehen des Triggers auf einem Bewegungscontroller. 'Select' drücken die Absicht des Benutzers, das Hologramm zu aktivieren, auf das sie ausgerichtet sind. Das SourcePressed-Ereignis wird für eine Reihe verschiedener Schaltflächen und Gesten ausgelöst, und Sie können andere Eigenschaften auf der SpatialInteractionSource überprüfen, um für diese Fälle zu testen.

Abfragebasierte Eingabe

Sie können auch SpatialInteractionManager verwenden, um den aktuellen Zustand der Eingabe für jeden Frame zu abfragen. Rufen Sie dazu getDetectedSourcesAtTimestamp jeden Frame auf. Diese Funktion gibt ein Array zurück, das einen SpatialInteractionSourceState für jede aktive SpatialInteractionSource enthält. Dies bedeutet eine für jeden aktiven Bewegungscontroller, eine für jede nachverfolgte Hand und eine für Die Sprache, wenn ein Befehl "auswählen" kürzlich ausgelöst wurde. Anschließend können Sie die Eigenschaften auf jedem SpatialInteractionSourceState überprüfen, um Eingaben in Ihre Anwendung zu steuern.

Hier finden Sie ein Beispiel für die Überprüfung der Aktion "Auswählen" mithilfe der Abfragemethode. Die Vorhersagevariable stellt ein HolographicFramePrediction-Objekt dar, das aus dem HolographicFrame abgerufen werden kann.

using namespace winrt::Windows::UI::Input::Spatial;

auto interactionManager = SpatialInteractionManager::GetForCurrentView();
auto sourceStates = m_spatialInteractionManager.GetDetectedSourcesAtTimestamp(prediction.Timestamp());

for (auto& sourceState : sourceStates)
{
	if (sourceState.IsSelectPressed())
	{
		// Select button is down, update app state
	}
}

Jede SpatialInteractionSource verfügt über eine ID, die Sie verwenden können, um neue Quellen zu identifizieren und vorhandene Quellen von Frame zu Frame zu korrelieren. Hände erhalten eine neue ID jedes Mal, wenn sie den FOV verlassen und eingeben, aber Controller-IDs bleiben für die Dauer der Sitzung statisch. Sie können die Ereignisse auf SpatialInteractionManager wie SourceDetected und SourceLost verwenden, um zu reagieren, wenn Die Hände eingeben oder die Ansicht des Geräts verlassen, oder wenn Bewegungscontroller aktiviert/deaktiviert sind oder gekoppelt/unbezahlt sind.

Vorausgesagte vs. historische Posen

GetDetectedSourcesAtTimestamp verfügt über einen Zeitstempelparameter. Dadurch können Sie Zustands- und Posendaten anfordern, die entweder vorhergesagt oder historisch vorhergesagt oder historisch sind, sodass Sie räumliche Interaktionen mit anderen Eingabequellen korrelieren können. Wenn Sie beispielsweise die Position der Hand im aktuellen Frame rendern, können Sie den vorhergesagten Zeitstempel übergeben, der vom HolographicFrame bereitgestellt wird. Dadurch kann das System die Handposition weiterleiten, um sich eng mit der gerenderten Frameausgabe auszurichten, wodurch die wahrgenommene Latenz minimiert wird.

Eine solche vorhergesagte Pose erzeugt jedoch keinen idealen Zeigerstrahl für das Ziel mit einer Interaktionsquelle. Wenn beispielsweise eine Bewegungscontrollerschaltfläche gedrückt wird, kann es bis zu 20 ms dauern, bis dieses Ereignis bis zu Bluetooth zum Betriebssystem aufblasen kann. Ähnlich kann ein Benutzer, nachdem ein Benutzer eine Handgeste ausführt, einige Zeit übergeben, bevor das System die Geste erkennt und ihre App dann nach ihnen fragt. Wenn Ihre App eine Zustandsänderung abfragt, wird der Kopf und die Hand verwendet, um diese Interaktion tatsächlich in der Vergangenheit zu erreichen. Wenn Sie zielen, indem Sie den Zeitstempel Ihres aktuellen HolographicFrame an GetDetectedSourcesAtTimestamp übergeben, wird die Pose stattdessen an den Zielstrahl weitergeleitet, wenn der Frame angezeigt wird, was in Zukunft mehr als 20 ms sein könnte. Diese zukünftige Pose eignet sich gut für das Rendern der Interaktionsquelle, besteht jedoch das Zeitproblem für die Ausrichtung der Interaktion, da das Ziel des Benutzers in der Vergangenheit aufgetreten ist.

Glücklicherweise stellen die SourcePressed-, [SourceReleased- und SourceUpdated-Ereignisse den historischen Zustand bereit, der jedem Eingabeereignis zugeordnet ist. Dies umfasst direkt den historischen Kopf und die Hand-Posen, die über TryGetPointerPose verfügbar sind, zusammen mit einem historischen Zeitstempel , den Sie an andere APIs übergeben können, um mit diesem Ereignis zu korrelieren.

Das führt zu den folgenden bewährten Methoden beim Rendern und Zielen mit Händen und Controllern für jeden Frame:

  • Für das Rendern jedes Frames sollte Ihre App die vorwärts vorhergesagte Pose jeder Interaktionsquelle zur Photonzeit des aktuellen Frames abfragen. Sie können für alle Interaktionsquellen abfragen, indem Sie getDetectedSourcesAtTimestamp jedes Frame aufrufen, indem Sie den vorhergesagten Zeitstempel übergeben, der von HolographicFrame::CurrentPrediction bereitgestellt wird.
  • Für Hand-/Controller , die auf eine Pressemitteilung oder Veröffentlichung abzielen, sollte Ihre App gedrückte/veröffentlichte Ereignisse behandeln, raycasting basierend auf dem historischen Kopf oder der Hand für dieses Ereignis. Sie erhalten diesen Zielstrahl, indem Sie das SourcePressed - oder SourceReleased-Ereignis behandeln, die State-Eigenschaft aus den Ereignisargumenten abrufen und dann die TryGetPointerPose-Methode aufrufen.

Geräteübergreifende Eingabeeigenschaften

Die SpatialInteractionSource-API unterstützt Controller und Handverfolgungssysteme mit einer vielzahl von Funktionen. Eine Reihe dieser Funktionen ist zwischen Gerätetypen üblich. Beispielsweise bieten Handverfolgungs- und Bewegungscontroller sowohl eine "Auswahl"-Aktion als auch eine 3D-Position. Je nach Möglichkeit zugeordnet die API diese allgemeinen Funktionen den gleichen Eigenschaften auf der SpatialInteractionSource. Dadurch können Anwendungen eine vielzahl von Eingabetypen einfacher unterstützen. In der folgenden Tabelle werden die eigenschaften beschrieben, die unterstützt werden und wie sie über Eingabetypen verglichen werden.

Eigenschaft BESCHREIBUNG geste HoloLens(1. Generation) Bewegungscontroller Artikulierte Hände
SpatialInteractionSource::Handigkeit Rechts oder links / Controller. Nicht unterstützt Unterstützt Unterstützt
SpatialInteractionSourceState::IsSelectPressed Aktueller Zustand der primären Schaltfläche. Luft tippen Trigger Entspannter Luft tippen (nach oben heften)
SpatialInteractionSourceState::IsGrasped Aktueller Zustand der Schaltfläche "Greif". Nicht unterstützt Schaltfläche "Suchen" Anheften oder Schließen der Hand
SpatialInteractionSourceState::IsMenuPressed Aktueller Status der Menüschaltfläche. Nicht unterstützt Menüschaltfläche Nicht unterstützt
SpatialInteractionSourceLocation::Position XYZ-Position der Hand- oder Griffposition auf dem Controller. Palmstandort Grip-Posenposition Palmstandort
SpatialInteractionSourceLocation::Orientation Quaternion, die die Ausrichtung der Hand- oder Griffpose auf dem Controller darstellt. Nicht unterstützt Griff-Posenausrichtung Palmausrichtung
SpatialPointerInteractionSourcePose::Position Ursprung des Zeigestrahls. Nicht unterstützt Unterstützt Unterstützt
SpatialPointerInteractionSourcePose::ForwardDirection Richtung des Zeigestrahls. Nicht unterstützt Unterstützt Unterstützt

Einige der obigen Eigenschaften sind auf allen Geräten nicht verfügbar, und die API bietet eine Möglichkeit, dies zu testen. Sie können beispielsweise die SpatialInteractionSource::IsGraspSupported-Eigenschaft überprüfen, um zu bestimmen, ob die Quelle eine Greifaktion bereitstellt.

Griffpose vs. Zeigepose

Windows Mixed Reality unterstützt Bewegungscontroller in verschiedenen Formfaktoren. Es unterstützt auch artikulierte Handverfolgungssysteme. Alle diese Systeme haben unterschiedliche Beziehungen zwischen der Handposition und der natürlichen "Vorwärtsrichtung", die Apps zum Zeigen oder Rendern von Objekten in der Hand des Benutzers verwenden sollten. Um all dies zu unterstützen, gibt es zwei Arten von 3D-Posen, die sowohl für die Handverfolgung als auch für Bewegungscontroller bereitgestellt werden. Die erste ist Griffposition, die die Handposition des Benutzers darstellt. Die zweite ist zeigende Pose, die einen Zeigerstrahl darstellt, der von der Hand oder dem Controller des Benutzers stammt. Wenn Sie also die Hand des Benutzers oder ein Objekt rendern möchten, das in der Hand des Benutzers gehalten wird, z. B. ein Schwert oder eine Waffe, verwenden Sie die Griffpose. Wenn Sie einen Raycast vom Controller oder der Hand ausstrahlen möchten, z. B. wenn der Benutzer auf der Benutzeroberfläche auf **zeigt, verwenden Sie die zeigende Pose.

Sie können über SpatialInteractionSourceState::P roperties::TryGetLocation(...)auf die Griffposition zugreifen. Es wird wie folgt definiert:

  • Die Griffposition: Das Palmzentriert, wenn der Controller natürlich hält, nach links oder rechts, um die Position innerhalb des Griffs zu zentrieren.
  • Die Rechte Achse des Griffs: Wenn Sie Ihre Hand vollständig öffnen, um eine flache 5-Finger-Pose zu bilden, ist der Strahl, der normal für Ihre Handfläche ist (vorwärts von der linken Hand, rückwärts von der rechten Handfläche)
  • Die Vorwärtsachse der Griffausrichtung: Wenn Sie ihre Hand teilweise schließen (wie wenn Sie den Controller halten), zeigt der Strahl, der durch die Röhre durch Ihre Finger ohne Daumen "vorwärts" zeigt.
  • Die Up-Achse des Griffs: Die up-Achse, die von den Definitionen "Rechts" und "Vorwärts" impliziert wird.

Sie können über SpatialInteractionSourceState::P roperties::TryGetLocation(...)::SourcePointerPose oder SpatialInteractionSourceState::TryGetPointerPose(...)::TryGetInteractionSourcePose auf das Zeigerpose zugreifen.

Controllerspezifische Eingabeeigenschaften

Für Controller verfügt die SpatialInteractionSource über eine Controllereigenschaft mit zusätzlichen Funktionen.

  • HasThumbstick: Wenn true, weist der Controller einen Fingerabdruckstick auf. Überprüfen Sie die ControllerProperties-Eigenschaft des SpatialInteractionSourceState, um die X- und Y-Werte (ThumbstickX und ThumbstickY) sowie den gedrückten Zustand (IsThumbstickPressed) zu erhalten.
  • HasTouchpad: Wenn true, verfügt der Controller über ein Touchpad. Überprüfen Sie die ControllerProperties-Eigenschaft des SpatialInteractionSourceState, um die Touchpad-x- und y-Werte (TouchpadX und TouchpadY) zu erhalten, und um zu wissen, ob der Benutzer das Pad (IsTouchpadTouched) berührt und wenn er das Touchpad gedrückt hat (IsTouchpadPressed).
  • SimpleHapticsController: Die SimpleHapticsController-API für den Controller ermöglicht es Ihnen, die Haptikfunktionen des Controllers zu überprüfen, und es ermöglicht Ihnen auch, haptisches Feedback zu steuern.

Der Bereich für Touchpad und Fingerabdruckstick ist -1 bis 1 für beide Achsen (von unten nach oben und von links nach rechts). Der Bereich für den analogen Trigger, auf den mithilfe der SpatialInteractionSourceState::SelectPressedValue-Eigenschaft zugegriffen wird, weist einen Bereich von 0 bis 1 auf. Ein Wert von 1 korreliert mit IsSelectPressed, das gleich "true" ist; jeder andere Wert korreliert mit IsSelectPressed, der gleich "false" ist.

Gestikulierte Handverfolgung

Die Windows Mixed Reality-API bietet vollständige Unterstützung für die artikulierte Handverfolgung, z. B. für HoloLens 2. Die artikulierte Handnachverfolgung kann verwendet werden, um direkte Manipulations- und Zeige-und-Commit-Eingabemodelle in Ihren Anwendungen zu implementieren. Sie kann auch verwendet werden, um voll benutzerdefinierte Interaktionen zu erstellen.

Handskelett

Die Artikulierte Handverfolgung bietet ein 25 Gelenkskelett, das viele verschiedene Arten von Interaktionen ermöglicht. Das Skelett bietet fünf Gelenke für den Index/mittlere/ring/kleine Finger, vier Gelenke für den Daumen und ein Handgelenkgelenk. Das Handgelenk dient als Basis der Hierarchie. Die folgende Abbildung veranschaulicht das Layout des Skeletts.

Hand Skeleton

In den meisten Fällen wird jedes Gelenk basierend auf dem Knochen benannt, den er darstellt. Da bei jedem Gelenk zwei Knochen vorhanden sind, verwenden wir eine Konvention zur Benennung jedes Gelenks basierend auf dem Kinderknochen an dieser Stelle. Der Kinderknochen wird als Knochen weiter vom Handgelenk definiert. Beispielsweise enthält das "Index Proximal"-Gelenk die Anfangsposition des Indexproximalen Knochens und die Ausrichtung dieses Knochens. Es enthält nicht die Endposition des Knochens. Wenn Sie dies benötigen, würden Sie es vom nächsten Joint in der Hierarchie, dem "Index Intermediate"-Gelenk, erhalten.

Neben den 25 hierarchischen Gelenken bietet das System ein Handgelenk. Die Handfläche wird in der Regel nicht als Teil der Skelettstruktur betrachtet. Es wird nur als bequeme Möglichkeit bereitgestellt, die Gesamtposition und Ausrichtung der Hand zu erhalten.

Die folgenden Informationen werden für jede Gemeinsame bereitgestellt:

Name BESCHREIBUNG
Position 3D-Position des Gelenks, verfügbar in jedem angeforderten Koordinatensystem.
Ausrichtung 3D-Ausrichtung des Knochens, verfügbar in jedem angeforderten Koordinatensystem.
Radius Abstand zur Oberfläche der Haut an der Gelenkposition. Nützlich für die Optimierung von direkten Interaktionen oder Visualisierungen, die auf der Fingerbreite basieren.
Genauigkeit Stellt einen Hinweis darauf bereit, wie sicher das System über die Informationen dieses Joints fühlt.

Sie können über eine Funktion im SpatialInteractionSourceState auf die Handskelettdaten zugreifen. Die Funktion wird " TryGetHandPose" genannt, und es gibt ein Objekt namens "HandPose" zurück. Wenn die Quelle keine artikulierten Hände unterstützt, gibt diese Funktion null zurück. Sobald Sie über ein HandPose verfügen, können Sie aktuelle gemeinsame Daten erhalten, indem Sie TryGetJoint aufrufen, mit dem Namen des Gelenks, an dem Sie interessiert sind. Die Daten werden als JointPose-Struktur zurückgegeben. Der folgende Code ruft die Position der Indexfingerspitze ab. Die Variable currentState stellt eine Instanz von SpatialInteractionSourceState dar.

using namespace winrt::Windows::Perception::People;
using namespace winrt::Windows::Foundation::Numerics;

auto handPose = currentState.TryGetHandPose();
if (handPose)
{
	JointPose joint;
	if (handPose.TryGetJoint(desiredCoordinateSystem, HandJointKind::IndexTip, joint))
	{
		float3 indexTipPosition = joint.Position;

		// Do something with the index tip position
	}
}

Handgitter

Die artikulierte Handverfolgungs-API ermöglicht ein vollständig deformierbares Dreiecks-Handgitter. Dieses Gitter kann in Echtzeit zusammen mit dem Handskelett verformt werden und ist nützlich für Visualisierungen und fortgeschrittene Physiktechniken. Um auf das Handgitter zuzugreifen, müssen Sie zuerst ein HandMeshObserver-Objekt erstellen, indem Sie TryCreateHandMeshObserverAsync auf der SpatialInteractionSource aufrufen. Dies muss nur einmal pro Quelle ausgeführt werden, in der Regel das erste Mal, wenn sie angezeigt wird. Dies bedeutet, dass Sie diese Funktion aufrufen, um ein HandMeshObserver-Objekt zu erstellen, wenn eine Hand den FOV eingibt. Dies ist eine asynchrone Funktion, sodass Sie hier ein wenig Parallelität behandeln müssen. Sobald verfügbar, können Sie das HandMeshObserver-Objekt für den Dreiecksindexpuffer bitten, indem Sie GetTriangleIndices aufrufen. Indizes ändern den Frame nicht über Frame, sodass Sie diese einmal abrufen und diese für die Lebensdauer der Quelle zwischenspeichern können. Indizes werden im uhrzeigersinnigen Wicklungsreihenfolge bereitgestellt.

Mit dem folgenden Code wird ein getrennter std::thread zum Erstellen des Gitterbeobachters gedreht und der Indexpuffer extrahiert, sobald der Gitterbeobachter verfügbar ist. Es beginnt mit einer Variablen namens currentState, die eine Instanz von SpatialInteractionSourceState darstellt, die eine nachverfolgte Hand darstellt.

using namespace Windows::Perception::People;

std::thread createObserverThread([this, currentState]()
{
    HandMeshObserver newHandMeshObserver = currentState.Source().TryCreateHandMeshObserverAsync().get();
    if (newHandMeshObserver)
    {
		unsigned indexCount = newHandMeshObserver.TriangleIndexCount();
		vector<unsigned short> indices(indexCount);
		newHandMeshObserver.GetTriangleIndices(indices);

        // Save the indices and handMeshObserver for later use - and use a mutex to synchronize access if needed!
     }
});
createObserverThread.detach();

Das Starten eines getrennten Threads ist nur eine Option für die Behandlung asynchroner Aufrufe. Alternativ können Sie die neue co_await-Funktionalität verwenden, die von C++/WinRT unterstützt wird.

Sobald Sie ein HandMeshObserver-Objekt haben, sollten Sie es für die Dauer halten, für die die entsprechende SpatialInteractionSource aktiv ist. Anschließend können Sie ihn nach dem neuesten Vertexpuffer fragen, der die Hand darstellt, indem Sie GetVertexStateForPose aufrufen und eine HandPose-Instanz übergeben, die die Posen darstellt, für die Scheitelpunkte erforderlich sind. Jeder Scheitelpunkt im Puffer weist eine Position und eine normale Position auf. Hier sehen Sie ein Beispiel, wie Sie den aktuellen Satz von Scheitelpunkten für ein Handgitter abrufen. Wie zuvor stellt die currentState-Variable eine Instanz von SpatialInteractionSourceState dar.

using namespace winrt::Windows::Perception::People;

auto handPose = currentState.TryGetHandPose();
if (handPose)
{
    std::vector<HandMeshVertex> vertices(handMeshObserver.VertexCount());
    auto vertexState = handMeshObserver.GetVertexStateForPose(handPose);
    vertexState.GetVertices(vertices);

    auto meshTransform = vertexState.CoordinateSystem().TryGetTransformTo(desiredCoordinateSystem);
    if (meshTransform != nullptr)
    {
    	// Do something with the vertices and mesh transform, along with the indices that you saved earlier
    }
}

Im Gegensatz zu Skelettgelenken kann die Handgitter-API kein Koordinatensystem für die Scheitelpunkte angeben. Stattdessen gibt der HandMeshVertexState das Koordinatensystem an, in dem die Vertices bereitgestellt werden. Anschließend können Sie eine Gittertransformation abrufen, indem Sie TryGetTransformTo aufrufen und das gewünschte Koordinatensystem angeben. Sie müssen diese Gittertransformation verwenden, wenn Sie mit den Scheitelpunkten arbeiten. Dieser Ansatz reduziert CPU-Aufwand, insbesondere wenn Sie nur das Gitter für Renderingzwecke verwenden.

Blick- und Commit-zusammengesetzte Gesten

Für Anwendungen, die das Anzeige- und Commit-Eingabemodell verwenden, insbesondere auf HoloLens (erste Generation), stellt die Spatial Input-API eine optionale SpatialGestureRecognizer bereit, die verwendet werden kann, um zusammengesetzte Gesten zu aktivieren, die auf dem "Select"-Ereignis basieren. Durch das Routing von Interaktionen vom SpatialInteractionManager an den SpatialGestureRecognizer eines Holograms können Apps Tippen, Halten, Manipulation und Navigationsereignisse einheitlich über Hände, VoIP und räumliche Eingabegeräte erkennen, ohne die Drücken und Versionen manuell zu behandeln.

SpatialGestureRecognizer führt nur die minimale Disambiguation zwischen der Gruppe von Gesten aus, die Sie anfordern. Wenn Sie z. B. nur Tippen anfordern, hält der Benutzer den Finger nach unten, solange er mag, und ein Tippen tritt weiterhin auf. Wenn Sie sowohl tippen als auch halten anfordern, tritt nach etwa einer Sekunde, in der der Finger gedrückt wird, die Geste auf einen Halterand auf, und ein Tippen tritt nicht mehr auf.

Um SpatialGestureRecognizer zu verwenden, behandeln Sie das SpatialInteractionManager-Ereignis " InteractionDetected ", und greifen Sie dort die spatialPointerPose verfügbar. Verwenden Sie den Blickstrahl des Benutzers aus dieser Pose, um mit den Hologrammen und Oberflächengittern in der Umgebung des Benutzers zu schneiden, um zu bestimmen, mit welchem Benutzer interagieren soll. Weiterleiten Sie dann die SpatialInteraction in den Ereignisargumenten an das SpatialGestureRecognizer des Ziel-Hologramms, indem Sie die CaptureInteraction-Methode verwenden. Dies beginnt mit der Interpretation dieser Interaktion gemäß den SpatialGestureSettings , die auf dieser Erkennung zum Erstellungszeitpunkt festgelegt sind - oder von TrySetGestureSettings.

Auf HoloLens (erste Generation) sollten Interaktionen und Gesten deren Ziel von der Kopfanzeige des Benutzers abgeleitet werden, anstatt an der Stelle der Hand zu rendern oder zu interagieren. Sobald eine Interaktion gestartet wurde, können relative Bewegungen der Hand verwendet werden, um die Geste zu steuern, wie bei der Manipulations- oder Navigationsgeste.

Siehe auch