Mani e controller del movimento in DirectXHands and motion controllers in DirectX

Nota

Questo articolo si riferisce alle API native di WinRT legacy.This article relates to the legacy WinRT native APIs. Per i nuovi progetti di app native, è consigliabile usare l' API OpenXR.For new native app projects, we recommend using the OpenXR API.

Nella realtà mista di Windows, l'input del controller della mano e del movimento viene gestito tramite le API di input spaziali, disponibile nello spazio dei nomi Windows. UI. input. Spatial .In Windows Mixed Reality, both hand and motion controller input is handled through the spatial input APIs, found in the Windows.UI.Input.Spatial namespace. In questo modo è possibile gestire con facilità azioni comuni, come Select , che vengono stampate nello stesso modo tra le mani e i controller di movimento.This enables you to easily handle common actions like Select presses the same way across both hands and motion controllers.

IntroduzioneGetting started

Per accedere all'input spaziale in realtà mista di Windows, iniziare con l'interfaccia SpatialInteractionManager.To access spatial input in Windows Mixed Reality, start with the SpatialInteractionManager interface. È possibile accedere a questa interfaccia chiamando SpatialInteractionManager:: GetForCurrentView, in genere talvolta durante l'avvio dell'app.You can access this interface by calling SpatialInteractionManager::GetForCurrentView, typically sometime during app startup.

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

SpatialInteractionManager interactionManager = SpatialInteractionManager::GetForCurrentView();

Il processo di SpatialInteractionManager consente di fornire l'accesso a SpatialInteractionSources, che rappresentano un'origine di input.The SpatialInteractionManager's job is to provide access to SpatialInteractionSources, which represent a source of input. Sono disponibili tre tipi di SpatialInteractionSources nel sistema.There are three kinds of SpatialInteractionSources available in the system.

  • Hand rappresenta la mano rilevata da un utente.Hand represents a user's detected hand. Le origini della mano offrono funzionalità diverse in base al dispositivo, a partire da movimenti di base su HoloLens fino al rilevamento manuale completo su HoloLens 2.Hand sources offer different features based on the device, ranging from basic gestures on HoloLens to fully articulated hand tracking on HoloLens 2.
  • Il controller rappresenta un controller di movimento associato.Controller represents a paired motion controller. I controller di movimento possono offrire funzionalità diverse, ad esempio, selezionare trigger, pulsanti di menu, pulsanti di controllo, touchpad e ThumbSticks.Motion controllers can offer different capabilities, for example, Select triggers, Menu buttons, Grasp buttons, touchpads, and thumbsticks.
  • Voice rappresenta le parole chiave rilevate dal sistema vocale dell'utente.Voice represents the user's voice speaking system-detected keywords. Questa origine, ad esempio, inserisce una selezione stampa e rilascia ogni volta che l'utente dice "Select".For example, this source will inject a Select press and release whenever the user says "Select".

I dati per fotogramma per un'origine sono rappresentati dall'interfaccia SpatialInteractionSourceState .Per-frame data for a source is represented by the SpatialInteractionSourceState interface. Esistono due modi diversi per accedere a questi dati, a seconda che si desideri usare un modello basato sugli eventi o sul polling nell'applicazione.There are two different ways to access this data, depending on whether you want to use an event-driven or polling-based model in your application.

Input guidato dagli eventiEvent-driven input

SpatialInteractionManager fornisce una serie di eventi che l'app è in grado di ascoltare.The SpatialInteractionManager provides a number of events that your app can listen for. Alcuni esempi includono SourcePressed, [SourceReleased e SourceUpdated.A few examples include SourcePressed, [SourceReleased, and SourceUpdated.

Il codice seguente, ad esempio, associa un gestore eventi denominato MyApp:: OnSourcePressed all'evento SourcePressed.For example, the following code hooks up an event handler called MyApp::OnSourcePressed to the SourcePressed event. Ciò consente all'app di rilevare le pressioni su qualsiasi tipo di origine interazione.This allows your app to detect presses on any type of interaction source.

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

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

Questo evento premuto viene inviato all'app in modo asincrono, insieme al SpatialInteractionSourceState corrispondente nel momento in cui si è verificato il clic.This pressed event is sent to your app asynchronously, along with the corresponding SpatialInteractionSourceState at the time the press happened. L'app o il motore di gioco potrebbe voler avviare immediatamente l'elaborazione o accodare i dati dell'evento nella routine di elaborazione dell'input.Your app or game engine may want to start processing right away or queue up the event data in your input processing routine. Ecco una funzione del gestore eventi per l'evento SourcePressed, che controlla se è stato premuto il pulsante Seleziona.Here's an event handler function for the SourcePressed event, which checks whether the select button has been pressed.

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

Il codice sopra riportato controlla solo la pressione ' Select ', che corrisponde all'azione principale del dispositivo.The above code only checks for the 'Select' press, which corresponds to the primary action on the device. Gli esempi includono l'operazione di AirTap in HoloLens o il pull del trigger in un controller di movimento.Examples include doing an AirTap on HoloLens or pulling the trigger on a motion controller. Le pressioni ' Select ' rappresentano l'intenzione dell'utente di attivare l'ologramma di destinazione.'Select' presses represent the user's intention to activate the hologram they're targeting. L'evento SourcePressed viene attivato per una serie di pulsanti e movimenti diversi ed è possibile controllare altre proprietà nel SpatialInteractionSource per verificare i casi.The SourcePressed event will fire for a number of different buttons and gestures, and you can inspect other properties on the SpatialInteractionSource to test for those cases.

Input basato sul pollingPolling-based input

È anche possibile usare SpatialInteractionManager per eseguire il polling dello stato corrente dell'input di ogni frame.You can also use SpatialInteractionManager to poll for the current state of input every frame. A tale scopo, chiamare GetDetectedSourcesAtTimestamp ogni frame.To do this, call GetDetectedSourcesAtTimestamp every frame. Questa funzione restituisce una matrice contenente un SpatialInteractionSourceState per ogni SpatialInteractionSourceattivo.This function returns an array containing one SpatialInteractionSourceState for every active SpatialInteractionSource. Ciò significa uno per ogni controller di movimento attivo, uno per ogni mano registrata e uno per il riconoscimento vocale se è stato recentemente pronunciato un comando ' Select '.This means one for each active motion controller, one for each tracked hand, and one for speech if a 'select' command was recently uttered. È quindi possibile esaminare le proprietà in ogni SpatialInteractionSourceState per guidare l'input nell'applicazione.You can then inspect the properties on each SpatialInteractionSourceState to drive input into your application.

Di seguito è riportato un esempio di come verificare l'azione ' Select ' usando il metodo di polling.Here's an example of how to check for the 'select' action using the polling method. La variabile di stima rappresenta un oggetto HolographicFramePrediction , che può essere ottenuto da HolographicFrame.The prediction variable represents a HolographicFramePrediction object, which can be obtained from the HolographicFrame.

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

Ogni SpatialInteractionSource dispone di un ID, che è possibile usare per identificare nuove origini e correlare le origini esistenti dal frame al frame.Each SpatialInteractionSource has an ID, which you can use to identify new sources and correlate existing sources from frame to frame. Le mani ottengono un nuovo ID ogni volta che lasciano e immettono il FOV, ma gli ID del controller rimangono statici per la durata della sessione.Hands get a new ID every time they leave and enter the FOV, but controller IDs remain static for the duration of the session. È possibile usare gli eventi in SpatialInteractionManager, ad esempio SourceDetected e SourceLost, per reagire quando le mani entrano o lasciano la visualizzazione del dispositivo o quando i controller di movimento sono accesi o spenti oppure sono abbinati o non abbinati.You can use the events on SpatialInteractionManager such as SourceDetected and SourceLost, to react when hands enter or leave the device's view, or when motion controllers are turned on/off or are paired/unpaired.

Pose stimate rispetto alla cronologiaPredicted vs. historical poses

GetDetectedSourcesAtTimestamp ha un parametro timestamp.GetDetectedSourcesAtTimestamp has a timestamp parameter. Ciò consente di richiedere lo stato e di porre dati stimati o cronologici, consentendo di correlare le interazioni spaziali con altre origini di input.This enables you to request state and pose data that is either predicted or historical, letting you correlate spatial interactions with other sources of input. Ad esempio, quando si esegue il rendering della posizione della mano nel frame corrente, è possibile passare il timestamp stimato fornito da HolographicFrame.For example, when rendering the hand's position in the current frame, you can pass in the predicted timestamp provided by the HolographicFrame. In questo modo, il sistema è in grado di eseguire la stima della posizione della mano per allinearsi strettamente all'output del frame di cui è stato eseguito il rendering, riducendoThis enables the system to forward-predict the hand position to closely align with the rendered frame output, minimizing perceived latency.

Tuttavia, tale posizione stimata non produce un raggio di puntamento ideale per la destinazione con un'origine interazione.However, such a predicted pose doesn't produce an ideal pointing ray for targeting with an interaction source. Ad esempio, quando si preme un pulsante del controller di movimento, potrebbero essere necessarie fino a 20 ms per l'evento per la propagazione tramite Bluetooth al sistema operativo.For example, when a motion controller button is pressed, it can take up to 20 ms for that event to bubble up through Bluetooth to the operating system. Analogamente, dopo che un utente ha eseguito un gesto di mano, una certa quantità di tempo può trascorrere prima che il sistema rilevi il gesto e l'app esegua il polling.Similarly, after a user does a hand gesture, some amount of time may pass before the system detects the gesture and your app then polls for it. Nel momento in cui l'app esegue il polling di una modifica dello stato, le pose Head e Hand usate per la destinazione dell'interazione si sono effettivamente verificate in passato.By the time your app polls for a state change, the head and hand poses used to target that interaction actually happened in the past. Se si imposta come destinazione passando il timestamp corrente di HolographicFrame a GetDetectedSourcesAtTimestamp, la posizione verrà invece stimata sul raggio di destinazione nel momento in cui verrà visualizzato il frame, che potrebbe essere più di 20 ms in futuro.If you target by passing your current HolographicFrame's timestamp to GetDetectedSourcesAtTimestamp, the pose will instead be forward predicted to the targeting ray at the time the frame will be displayed, which could be more than 20 ms in the future. Questa generazione futura è ideale per il rendering dell'origine interazione, ma costituisce un problema di tempo per la destinazione dell'interazione, in quanto la destinazione dell'utente si è verificata in precedenza.This future pose is good for rendering the interaction source, but compounds our time problem for targeting the interaction, as the user's targeting occurred in the past.

Fortunatamente, gli eventi SourcePressed, [SourceReleased e SourceUpdated forniscono lo stato cronologico associato a ogni evento di input.Fortunately, the SourcePressed, [SourceReleased, and SourceUpdated events provide the historical State associated with each input event. Questo include direttamente le rappresentazioni della sede e della mano cronologiche disponibili tramite TryGetPointerPose, oltre a un timestamp cronologico che è possibile passare ad altre API per la correlazione con questo evento.This directly includes the historical head and hand poses available through TryGetPointerPose, along with a historical Timestamp that you can pass to other APIs to correlate with this event.

Ciò comporta le seguenti procedure consigliate per il rendering e la destinazione con le procedure e i controller di ogni frame:That leads to the following best practices when rendering and targeting with hands and controllers each frame:

  • Per il rendering della mano/controller ogni frame, l'app deve eseguire il polling per la posizione stimata in base a ogni origine interazione al momento del fotone del frame corrente.For hand/controller rendering each frame, your app should poll for the forward-predicted pose of each interaction source at the current frame’s photon time. È possibile eseguire il polling per tutte le origini interazione chiamando GetDetectedSourcesAtTimestamp ogni frame, passando il timestamp stimato fornito da HolographicFrame:: CurrentPrediction.You can poll for all interaction sources by calling GetDetectedSourcesAtTimestamp each frame, passing in the predicted timestamp provided by HolographicFrame::CurrentPrediction.
  • Per la selezione di mano/controller su una pressione o un rilascio, l'app deve gestire gli eventi premuti o rilasciati, Raycasting in base all'intestazione o alla mano storica per quell'evento.For hand/controller targeting upon a press or release, your app should handle pressed/released events, raycasting based on the historical head or hand pose for that event. Si ottiene questo raggio di destinazione gestendo l'evento SourcePressed o SourceReleased , ottenendo la proprietà state dagli argomenti dell'evento e quindi chiamando il relativo metodo TryGetPointerPose .You get this targeting ray by handling the SourcePressed or SourceReleased event, getting the State property from the event arguments, and then calling its TryGetPointerPose method.

Proprietà input tra dispositiviCross-device input properties

L'API SpatialInteractionSource supporta i controller e i sistemi di rilevamento manuale con una vasta gamma di funzionalità.The SpatialInteractionSource API supports controllers and hand tracking systems with a wide range of capabilities. Alcune di queste funzionalità sono comuni tra i tipi di dispositivi.A number of these capabilities are common between device types. Ad esempio, il rilevamento manuale e i controller di movimento forniscono un'azione ' Select ' e una posizione 3D.For example, hand tracking and motion controllers both provide a 'select' action and a 3D position. Laddove possibile, l'API esegue il mapping di queste funzionalità comuni alle stesse proprietà in SpatialInteractionSource.Wherever possible, the API maps these common capabilities to the same properties on the SpatialInteractionSource. Ciò consente alle applicazioni di supportare più facilmente un'ampia gamma di tipi di input.This enables applications to more easily support a wide range of input types. Nella tabella seguente vengono descritte le proprietà supportate e il modo in cui vengono confrontate tra i tipi di input.The following table describes the properties that are supported, and how they compare across input types.

ProprietàProperty DescrizioneDescription Movimenti di HoloLens (1a generazione)HoloLens(1st gen) Gestures Controller di movimentoMotion Controllers Mano articolataArticulated Hands
SpatialInteractionSource::manualitàSpatialInteractionSource::Handedness A destra o a sinistra/controller.Right or left hand / controller. Non supportatoNot Supported SupportatoSupported SupportatoSupported
SpatialInteractionSourceState::IsSelectPressedSpatialInteractionSourceState::IsSelectPressed Stato corrente del pulsante primario.Current state of the primary button. Rubinetto aereoAir Tap TriggerTrigger Tocco aria rilassato (tocco verticale)Relaxed Air Tap (upright pinch)
SpatialInteractionSourceState:: è stato afferratoSpatialInteractionSourceState::IsGrasped Stato corrente del pulsante di cattura.Current state of the grab button. Non supportatoNot Supported Pulsante di catturaGrab button Pinza o chiusaPinch or Closed Hand
SpatialInteractionSourceState::IsMenuPressedSpatialInteractionSourceState::IsMenuPressed Stato corrente del pulsante di menu.Current state of the menu button. Non supportatoNot Supported Pulsante di menuMenu Button Non supportatoNot Supported
SpatialInteractionSourceLocation::positionSpatialInteractionSourceLocation::Position Posizione XYZ della mano o della posizione del grip sul controller.XYZ location of the hand or grip position on the controller. Percorso PalmPalm location Posizione del gripGrip pose position Percorso PalmPalm location
SpatialInteractionSourceLocation::OrientationSpatialInteractionSourceLocation::Orientation Quaternione che rappresenta l'orientamento della mano o della posizione del grip sul controller.Quaternion representing the orientation of the hand or grip pose on the controller. Non supportatoNot Supported Orientamento della posizione del gripGrip pose orientation Orientamento PalmPalm orientation
SpatialPointerInteractionSourcePose::positionSpatialPointerInteractionSourcePose::Position Origine del raggio di puntamento.Origin of the pointing ray. Non supportatoNot Supported SupportatoSupported SupportatoSupported
SpatialPointerInteractionSourcePose::ForwardDirectionSpatialPointerInteractionSourcePose::ForwardDirection Direzione del raggio di puntamento.Direction of the pointing ray. Non supportatoNot Supported SupportatoSupported SupportatoSupported

Alcune delle proprietà indicate sopra non sono disponibili in tutti i dispositivi e l'API fornisce un mezzo per testarlo.Some of the above properties aren't available on all devices, and the API provides a means to test for this. Ad esempio, è possibile esaminare la proprietà SpatialInteractionSource:: IsGraspSupported per determinare se l'origine fornisce un'azione di comprensione.For example, you can inspect the SpatialInteractionSource::IsGraspSupported property to determine whether the source provides a grasp action.

Posa del grip e puntamentoGrip pose vs. pointing pose

La realtà mista di Windows supporta i controller di movimento in diversi fattori di forma.Windows Mixed Reality supports motion controllers in different form factors. Supporta anche sistemi di rilevamento a mano articolati.It also supports articulated hand tracking systems. Tutti questi sistemi hanno relazioni diverse tra la posizione della mano e la direzione naturale "Avanti" che le app devono usare per puntare o eseguire il rendering degli oggetti nella mano dell'utente.All of these systems have different relationships between the hand position and the natural "forward" direction that apps should use for pointing or rendering objects in the user's hand. Per supportare questa operazione, sono disponibili due tipi di istanze 3D per i controller di rilevamento e movimento della mano.To support all of this, there are two types of 3D poses provided for both hand tracking and motion controllers. Il primo è costituito da grip, che rappresenta la posizione della mano dell'utente.The first is grip pose, which represents the user's hand position. Il secondo sta puntando a pose, che rappresenta un raggio di puntamento che origina dalla mano o dal controller dell'utente.The second is pointing pose, which represents a pointing ray originating from the user's hand or controller. Se quindi si desidera eseguire il rendering della mano dell'utente o di un oggetto contenuto nella mano dell'utente, ad esempio una spada o una pistola, utilizzare il grip.So, if you want to render the user's hand or an object held in the user's hand, such as a sword or gun, use the grip pose. Se si desidera Raycast dal controller o dalla mano, ad esempio quando l'utente è * * che punta all'interfaccia utente, utilizzare la posizione di puntamento.If you want to raycast from the controller or hand, for example when the user is **pointing at UI, use the pointing pose.

È possibile accedere al grip con SpatialInteractionSourceState::P oprietà:: TryGetLocation (...). Viene definito come segue:You can access the grip pose through SpatialInteractionSourceState::Properties::TryGetLocation(...). It's defined as follows:

  • Posizione del grip: il centro della palma quando si tiene il controller in modo naturale, regolato a sinistra o a destra per centrare la posizione all'interno del grip.The grip position: The palm centroid when holding the controller naturally, adjusted left or right to center the position within the grip.
  • L' asse destro dell'orientamento del grip: quando si apre completamente la mano per formare una formula a 5 dita piatta, il raggio normale per la Palma (in avanti dal palmo sinistro e viceversa)The grip orientation's Right axis: When you completely open your hand to form a flat 5-finger pose, the ray that is normal to your palm (forward from left palm, backward from right palm)
  • Asse di avanzamento dell'orientamento del grip: quando si chiude parzialmente la mano (come se si utilizzasse il controller), il raggio che punta "in poi" attraverso il tubo formato dalle dita non Thumb.The grip orientation's Forward axis: When you close your hand partially (as if holding the controller), the ray that points "forward" through the tube formed by your non-thumb fingers.
  • Asse verticale dell'orientamento del grip: l'asse verso l'alto implicato dalle definizioni di destra e di avanzamento.The grip orientation's Up axis: The Up axis implied by the Right and Forward definitions.

È possibile accedere al puntatore con SpatialInteractionSourceState::P oprietà:: TryGetLocation (...):: SourcePointerPose o SpatialInteractionSourceState:: TryGetPointerPose (...):: TryGetInteractionSourcePose.You can access the pointer pose through SpatialInteractionSourceState::Properties::TryGetLocation(...)::SourcePointerPose or SpatialInteractionSourceState::TryGetPointerPose(...)::TryGetInteractionSourcePose.

Proprietà di input specifiche del controllerController-specific input properties

Per i controller, SpatialInteractionSource dispone di una proprietà Controller con funzionalità aggiuntive.For controllers, the SpatialInteractionSource has a Controller property with additional capabilities.

  • HasThumbstick: Se true, il controller dispone di un levetta.HasThumbstick: If true, the controller has a thumbstick. Esaminare la proprietà ControllerProperties di SpatialInteractionSourceState per acquisire i valori levetta x e y (ThumbstickX e ThumbstickY), così come lo stato premuto (IsThumbstickPressed).Inspect the ControllerProperties property of the SpatialInteractionSourceState to acquire the thumbstick x and y values (ThumbstickX and ThumbstickY), as well as its pressed state (IsThumbstickPressed).
  • HasTouchpad: Se true, il controller dispone di un touchpad.HasTouchpad: If true, the controller has a touchpad. Esaminare la proprietà ControllerProperties di SpatialInteractionSourceState per acquisire i valori x e y del touchpad (TouchpadX e Touchpady) e per verificare se l'utente sta toccando il riquadro (IsTouchpadTouched) e se sta premendo il touchpad verso il basso (IsTouchpadPressed).Inspect the ControllerProperties property of the SpatialInteractionSourceState to acquire the touchpad x and y values (TouchpadX and TouchpadY), and to know if the user is touching the pad (IsTouchpadTouched) and if they're pressing the touchpad down (IsTouchpadPressed).
  • SimpleHapticsController: L'API SimpleHapticsController per il controller consente di esaminare le funzionalità haptics del controller e di controllare il feedback tattile.SimpleHapticsController: The SimpleHapticsController API for the controller allows you to inspect the haptics capabilities of the controller, and it also allows you to control haptic feedback.

L'intervallo per touchpad e levetta è-1 a 1 per entrambi gli assi (dal basso verso l'alto e da sinistra a destra).The range for touchpad and thumbstick is -1 to 1 for both axes (from bottom to top, and from left to right). L'intervallo per il trigger analogico, a cui si accede tramite la proprietà SpatialInteractionSourceState:: SelectPressedValue, ha un intervallo compreso tra 0 e 1.The range for the analog trigger, which is accessed using the SpatialInteractionSourceState::SelectPressedValue property, has a range of 0 to 1. Il valore 1 è correlato a IsSelectPressed in modo che sia uguale a true; qualsiasi altro valore correlato a IsSelectPressed è uguale a false.A value of 1 correlates with IsSelectPressed being equal to true; any other value correlates with IsSelectPressed being equal to false.

Rilevamento a mano articolataArticulated hand tracking

L'API di realtà mista di Windows fornisce il supporto completo per il rilevamento manuale articolato, ad esempio in HoloLens 2.The Windows Mixed Reality API provides full support for articulated hand tracking, for example on HoloLens 2. Il rilevamento a mano articolata può essere usato per implementare la manipolazione diretta e i modelli di input Point-and-commit nelle applicazioni.Articulated hand tracking can be used to implement direct manipulation and point-and-commit input models in your applications. Può essere usato anche per creare interazioni completamente personalizzate.It can also be used to author fully custom interactions.

Scheletro manoHand skeleton

Il rilevamento a mano articolata offre una struttura a 25 forme che consente molti tipi diversi di interazioni.Articulated hand tracking provides a 25 joint skeleton that enables many different types of interactions. La struttura fornisce cinque giunzioni per le barrette index/Middle/Ring/Little, le quattro giunzioni per il pollice e un insieme di polsi.The skeleton provides five joints for the index/middle/ring/little fingers, four joints for the thumb, and one wrist joint. Il giunto del polso funge da base della gerarchia.The wrist joint serves as the base of the hierarchy. Nell'immagine seguente viene illustrato il layout dello scheletro.The following picture illustrates the layout of the skeleton.

Scheletro mano

Nella maggior parte dei casi, ogni joint viene denominato in base all'osso che rappresenta.In most cases, each joint is named based on the bone that it represents. Poiché sono presenti due ossa in ogni giunzione, viene usata una convenzione di denominazione di ogni joint in base all'osso figlio in tale posizione.Since there are two bones at every joint, we use a convention of naming each joint based on the child bone at that location. L'osso figlio viene definito come l'osso più a fondo.The child bone is defined as the bone further from the wrist. Ad esempio, il giunto "index Prossimal" contiene la posizione iniziale dell'osso prossimale dell'indice e l'orientamento di tale osso.For example, the "Index Proximal" joint contains the beginning position of the index proximal bone, and the orientation of that bone. Non contiene la posizione finale dell'osso.It doesn't contain the ending position of the bone. Se necessario, è possibile ottenerlo dalla giunzione successiva nella gerarchia, ovvero il collegamento "index Intermediate".If you need that, you'd get it from the next joint in the hierarchy, the "Index Intermediate" joint.

Oltre ai 25 giunti gerarchici, il sistema fornisce un insieme di Palm.In addition to the 25 hierarchical joints, the system provides a palm joint. Il Palm non è in genere considerato parte della struttura scheletrica.The palm isn't typically considered part of the skeletal structure. Viene fornito solo come un modo pratico per ottenere la posizione e l'orientamento complessivi della mano.It's provided only as a convenient way to get the hand's overall position and orientation.

Per ogni giunzione vengono fornite le informazioni seguenti:The following information is provided for each joint:

NomeName DescrizioneDescription
PosizionePosition posizione 3D del giunto, disponibile in qualsiasi sistema di coordinate richiesto.3D position of the joint, available in any requested coordinate system.
OrientamentoOrientation orientamento 3D dell'osso, disponibile in qualsiasi sistema di coordinate richiesto.3D orientation of the bone, available in any requested coordinate system.
RadiusRadius Distanza dalla superficie dell'interfaccia in corrispondenza della posizione di giunzione.Distance to surface of the skin at the joint position. Utile per l'ottimizzazione di interazioni dirette o visualizzazioni basate sulla larghezza del dito.Useful for tuning direct interactions or visualizations that rely on finger width.
AccuratezzaAccuracy Fornisce un suggerimento sul modo in cui il sistema ritiene attendibile le informazioni di questo comune.Provides a hint on how confident the system feels about this joint's information.

È possibile accedere ai dati dello scheletro della mano tramite una funzione in SpatialInteractionSourceState.You can access the hand skeleton data through a function on the SpatialInteractionSourceState. La funzione viene chiamata TryGetHandPosee restituisce un oggetto denominato HandPose.The function is called TryGetHandPose, and it returns an object called HandPose. Se l'origine non supporta le lancette articolate, questa funzione restituirà null.If the source doesn't support articulated hands, then this function will return null. Quando si dispone di un HandPose, è possibile ottenere i dati comuni correnti chiamando TryGetJoint, con il nome del giunto a cui si è interessati.Once you have a HandPose, you can get current joint data by calling TryGetJoint, with the name of the joint you're interested in. I dati vengono restituiti come struttura JointPose .The data is returned as a JointPose structure. Il codice seguente ottiene la posizione del suggerimento per il dito dell'indice.The following code gets the position of the index finger tip. La variabile CurrentState rappresenta un'istanza di SpatialInteractionSourceState.The variable currentState represents an instance of SpatialInteractionSourceState.

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

Mesh manoHand mesh

L'API di rilevamento a mano articolata consente un reticolo a mano triangolo completamente deformabile.The articulated hand tracking API allows for a fully deformable triangle hand mesh. Questa mesh può deformarsi in tempo reale insieme allo scheletro della mano ed è utile per le tecniche di visualizzazione e di fisica avanzata.This mesh can deform in real time along with the hand skeleton, and is useful for visualization and advanced physics techniques. Per accedere alla rete a mano, è necessario innanzitutto creare un oggetto HandMeshObserver chiamando TryCreateHandMeshObserverAsync in SpatialInteractionSource.To access the hand mesh, you need to first create a HandMeshObserver object by calling TryCreateHandMeshObserverAsync on the SpatialInteractionSource. Questa operazione deve essere eseguita solo una volta per origine, in genere la prima volta che viene visualizzata.This only needs to be done once per source, typically the first time you see it. Questo significa che si chiamerà questa funzione per creare un oggetto HandMeshObserver ogni volta che una mano entra nell'oggetto FOV.That means you'll call this function to create a HandMeshObserver object whenever a hand enters the FOV. Si tratta di una funzione asincrona, quindi è necessario gestire un po' di concorrenza.This is an async function, so you'll have to deal with a bit of concurrency here. Una volta disponibile, è possibile chiedere all'oggetto HandMeshObserver per il buffer dell'indice del triangolo chiamando GetTriangleIndices.Once available, you can ask the HandMeshObserver object for the triangle index buffer by calling GetTriangleIndices. Gli indici non cambiano frame rispetto al frame, quindi è possibile ottenerli una volta e memorizzarli nella cache per la durata dell'origine.Indices don't change frame over frame, so you can get those once and cache them for the lifetime of the source. Gli indici vengono specificati in ordine di avvolgimento in senso orario.Indices are provided in clockwise winding order.

Il codice seguente consente di avviare un std:: thread scollegato per creare l'osservatore mesh ed estrarre il buffer dell'indice dopo che l'osservatore mesh è disponibile.The following code spins up a detached std::thread to create the mesh observer and extracts the index buffer once the mesh observer is available. Inizia da una variabile denominata CurrentState, che è un'istanza di SpatialInteractionSourceState che rappresenta una mano rilevata.It starts from a variable called currentState, which is an instance of SpatialInteractionSourceState representing a tracked hand.

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();

L'avvio di un thread scollegato è solo un'opzione per la gestione delle chiamate asincrone.Starting a detached thread is just one option for handling async calls. In alternativa, è possibile usare la nuova funzionalità di co_await supportata da C++/WinRT.Alternatively, you could use the new co_await functionality supported by C++/WinRT.

Quando si dispone di un oggetto HandMeshObserver, è necessario mantenerlo per la durata di attivazione del SpatialInteractionSource corrispondente.Once you have a HandMeshObserver object, you should hold onto it for the duration that its corresponding SpatialInteractionSource is active. Ogni frame, quindi, può essere richiesto per l'ultimo buffer di vertex che rappresenta la mano chiamando GetVertexStateForPose e passando un'istanza di HandPose che rappresenta la posa per la quale si desiderano i vertici.Then each frame, you can ask it for the latest vertex buffer that represents the hand by calling GetVertexStateForPose and passing in a HandPose instance that represents the pose that you want vertices for. Ogni vertice nel buffer ha una posizione e una normale.Each vertex in the buffer has a position and a normal. Di seguito è riportato un esempio di come ottenere il set corrente di vertici per una mesh a mano.Here's an example of how to get the current set of vertices for a hand mesh. Come prima, la variabile CurrentState rappresenta un'istanza di SpatialInteractionSourceState.As before, the currentState variable represents an instance of SpatialInteractionSourceState.

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

Diversamente dalle giunzioni di scheletro, l'API della mesh mano non consente di specificare un sistema di coordinate per i vertici.In contrast to skeleton joints, the hand mesh API doesn't allow you to specify a coordinate system for the vertices. Il HandMeshVertexState specifica invece il sistema di coordinate in cui vengono forniti i vertici.Instead, the HandMeshVertexState specifies the coordinate system that the vertices are provided in. È quindi possibile ottenere una trasformazione mesh chiamando TryGetTransformTo e specificando il sistema di coordinate desiderato.You can then get a mesh transform by calling TryGetTransformTo and specifying the coordinate system you want. È necessario usare questa trasformazione mesh ogni volta che si lavora con i vertici.You'll need to use this mesh transform whenever you work with the vertices. Questo approccio riduce il sovraccarico della CPU, soprattutto se si usa solo la rete a scopo di rendering.This approach reduces CPU overhead, especially if you're only using the mesh for rendering purposes.

Movimenti compositi di sguardi e commitGaze and Commit composite gestures

Per le applicazioni che usano il modello di input con sguardo e commit, in particolare in HoloLens (First Gen), l'API di input spaziale fornisce un SpatialGestureRecognizer facoltativo che può essere usato per abilitare i movimenti compositi compilati sopra l'evento ' Select '.For applications using the gaze-and-commit input model, particularly on HoloLens (first gen), the Spatial Input API provides an optional SpatialGestureRecognizer that can be used to enable composite gestures built on top of the 'select' event. Tramite il routing delle interazioni da SpatialInteractionManager a SpatialGestureRecognizer di un ologramma, le app possono rilevare gli eventi di tocco, attesa, manipolazione e navigazione in modo uniforme tra le mani, le voci e i dispositivi di input spaziali, senza dover gestire manualmente le pressioni e le versioni.By routing interactions from the SpatialInteractionManager to a hologram's SpatialGestureRecognizer, apps can detect Tap, Hold, Manipulation, and Navigation events uniformly across hands, voice, and spatial input devices, without having to handle presses and releases manually.

SpatialGestureRecognizer esegue solo la disambiguazione minima tra il set di movimenti richiesto.SpatialGestureRecognizer does only the minimal disambiguation between the set of gestures that you request. Ad esempio, se si richiede solo il tocco, l'utente può mantenere il dito verso il basso fino a quando si desidera e si verificherà ancora un tocco.For example, if you request just Tap, the user may hold their finger down as long as they like and a Tap will still occur. Se si richiedono sia toccare che tenere premuto, dopo circa un secondo di tenere premuto il dito, il movimento si promuoverà a una tenuta e non si verificherà alcun tocco.If you request both Tap and Hold, after about a second of holding down their finger the gesture will promote to a Hold and a Tap will no longer occur.

Per usare SpatialGestureRecognizer, gestire l'evento InteractionDetected di SpatialInteractionManager e fare in modo che i SpatialPointerPose esposti siano presenti.To use SpatialGestureRecognizer, handle the SpatialInteractionManager's InteractionDetected event and grab the SpatialPointerPose exposed there. Usare il raggio di sguardi dell'utente da questa posa per intersecare gli ologrammi e le mesh di superficie nell'ambiente dell'utente per determinare gli elementi che l'utente intende interagire.Use the user's head gaze ray from this pose to intersect with the holograms and surface meshes in the user's surroundings to determine what the user is intending to interact with. Quindi, indirizzare il SpatialInteraction negli argomenti dell'evento al SpatialGestureRecognizer dell'ologramma di destinazione usando il metodo CaptureInteraction .Then, route the SpatialInteraction in the event arguments to the target hologram's SpatialGestureRecognizer, using its CaptureInteraction method. Questa operazione inizia a interpretare l'interazione in base al set di SpatialGestureSettings in quel riconoscimento al momento della creazione, o TrySetGestureSettings.This starts interpreting that interaction according to the SpatialGestureSettings set on that recognizer at creation time - or by TrySetGestureSettings.

In HoloLens (First Gen), le interazioni e i movimenti dovrebbero derivare il loro targeting dallo sguardo a capo dell'utente, invece di eseguire il rendering o l'interazione nella posizione della mano.On HoloLens (first gen), interactions and gestures should derive their targeting from the user's head gaze, rather than rendering or interacting at the hand's location. Una volta avviata un'interazione, è possibile usare i movimenti relativi della mano per controllare il movimento, come per il gesto di manipolazione o spostamento.Once an interaction has started, relative motions of the hand may be used to control the gesture, as with the Manipulation or Navigation gesture.

Vedere ancheSee also