OpenXR-Erweiterung „XR_ANDROID_hand_mesh“

Namensstring

XR_ANDROID_hand_mesh

Erweiterungstyp

Instanzerweiterung

Registrierte Durchwahlnummer

704

Revision

1

Erweiterungs- und Versionsabhängigkeiten

OpenXR 1.0

Datum der letzten Änderung

2024-09-10

IP-Status

Es sind keine Ansprüche aufgrund von Urheberrechten bekannt.

Mitwirkende

Nihav Jain, Google

Cairn Overturf, Google

Spencer Quin, Google

Levana Chen, Google

Übersicht

Diese Erweiterung ermöglicht das Hand-Tracking als dynamisches Hand-Mesh.

Diese Erweiterung soll Vertex- und Index-Buffer für das Mesh einer personalisierten Darstellung der Hände des Nutzers bereitstellen. Es kann für Okklusion und Visualisierung verwendet werden.

Diese Erweiterung darf nicht für andere Zwecke des Handtrackings verwendet werden.

Daten aus der Handerkennung können sensible personenbezogene Daten sein und stehen in engem Zusammenhang mit dem Datenschutz und der Integrität von Personen. Bei Anwendungen, die Daten zur Handerkennung speichern oder übertragen, wird dringend empfohlen, den Nutzer immer um eine aktive und spezifische Einwilligung zu bitten.

Systemkapazität prüfen

Eine Anwendung kann prüfen, ob das System Meshes für das Hand-Tracking unterstützt, indem beim Aufruf von xrGetSystemProperties eine XrSystemHandMeshTrackingPropertiesANDROID-Struktur an die XrSystemProperties angehängt wird.

typedef struct XrSystemHandMeshTrackingPropertiesANDROID {
  XrStructureType    type;
  void*              next;
  XrBool32           supportsHandMeshTracking;
  XrBool32           supportsTextureUV;
  XrBool32           supportsVertexNormal;
} XrSystemHandMeshTrackingPropertiesANDROID;

Beschreibungen von Mitgliedern

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind in OpenXR oder dieser Erweiterung nicht definiert.
  • supportsHandMeshTracking ist ein XrBool32, das angibt, ob das ausgewählte XrSystemId das Mesh-Tracking von Händen unterstützt.
  • supportsTextureUV ist ein XrBool32, das angibt, ob das ausgewählte XrSystemId Textur-UVs für die Mesh-Ecken unterstützt.
  • supportsVertexNormal ist ein XrBool32, das angibt, ob die ausgewählte XrSystemId Vertexnormalen für die Mesh-Ecken unterstützt.

Die Anwendung sollte keine Hand-Mesh-Funktionen verwenden, wenn supportsHandMeshTracking XR_FALSE ist, da das System dann kein Hand-Mesh-Tracking unterstützt. In diesem Fall gibt xrCreateHandMeshTrackerANDROID XR_ERROR_FEATURE_UNSUPPORTED zurück.

Wenn supportsHandMeshTracking XR_TRUE zurückgibt, unterstützt das System das Mesh-Tracking von Händen. Eine Anwendung sollte XrHandMeshANDROID::indexCount und XrHandMeshANDROID::vertexCount verwenden, um auf Hand-Mesh-Buffer zuzugreifen und sie in ihrem Rendering-Loop wiederzuverwenden, wenn xrGetHandMeshANDROID in jedem Frame aufgerufen wird.

Wenn supportsTextureUV XR_FALSE zurückgibt, unterstützt das System keine Textur-UVs für die Mesh-Ecken. Eine Anwendung würde daher beim Aufruf von xrGetHandMeshANDROID XrHandMeshANDROID::textureUVs NULL zurückerhalten.

Wenn supportsVertexNormal XR_FALSE zurückgibt, unterstützt das System keine Knotennormalen für die Mesh-Knoten. Eine Anwendung erhält daher beim Aufruf von xrGetHandMeshANDROID XrHandMeshANDROID::normals NULL.

Gültige Verwendung (implizit)

Alias für einen Mesh-Tracker für die Hand erstellen

XR_DEFINE_HANDLE(XrHandMeshTrackerANDROID)

Der Handle XrHandMeshTrackerANDROID stellt einen Hand-Mesh-Tracker für das Hand-Mesh-Tracking und die Verwaltung der zugehörigen Ressourcen dar.

Über diesen Handle kann mit anderen Funktionen in dieser Erweiterung auf Hand-Mesh-Buffer zugegriffen werden.

Eine Anwendung kann mit der Funktion xrCreateHandMeshTrackerANDROID einen XrHandMeshTrackerANDROID-Handle erstellen.

XrResult xrCreateHandMeshTrackerANDROID(
    XrSession                                   session,
    const XrHandMeshTrackerCreateInfoANDROID*   createInfo,
    XrHandMeshTrackerANDROID*                   handMeshTracker);

Parameterbeschreibungen

Wenn das System das Mesh-Tracking von Händen nicht unterstützt, gibt xrCreateHandMeshTrackerANDROID XR_ERROR_FEATURE_UNSUPPORTED zurück.

Der Handle XrHandMeshTrackerANDROID ist für alle Ressourcen für das Hand-Mesh-Tracking verantwortlich. Nachdem die Hand-Mesh-Tracking-Funktionen nicht mehr benötigt werden, muss die Anwendung den Handle mit der Funktion xrDestroyHandMeshTrackerANDROID löschen.

Gültige Verwendung (implizit)

Rückgabecodes

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • XR_ERROR_FEATURE_UNSUPPORTED
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_LIMIT_REACHED

Die Struktur XrHandMeshTrackerCreateInfoANDROID beschreibt die Informationen zum Erstellen eines XrHandMeshTrackerANDROID-Handles.

typedef struct XrHandMeshTrackerCreateInfoANDROID {
    XrStructureType    type;
    const void*        next;
} XrHandMeshTrackerCreateInfoANDROID;

Beschreibungen von Mitgliedern

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind in OpenXR oder dieser Erweiterung nicht definiert.

Gültige Verwendung (implizit)

Die Funktion xrDestroyHandMeshTrackerANDROID gibt die handMeshTracker und die zugrunde liegenden Ressourcen frei, wenn das Tracking der Hand-Mesh-Modelle beendet ist.

XrResult xrDestroyHandMeshTrackerANDROID(
    XrHandMeshTrackerANDROID handMeshTracker);

Parameterbeschreibungen

Gültige Verwendung (implizit)

Threadsicherheit

  • Der Zugriff auf handMeshTracker und alle untergeordneten Handles muss extern synchronisiert werden.

Rückgabecodes

Erfolg

  • XR_SUCCESS

Fehler

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID

Hand-Meshes finden

Die Anwendung kann die Funktion xrGetHandMeshANDROID verwenden, um das Hand-Mesh zu einem bestimmten Zeitstempel abzurufen. Die Position und Normale der Hand-Mesh-Ecken werden im Raum dargestellt, der durch XrHandMeshGetInfoANDROID::baseSpace beim Aufruf von xrGetHandMeshANDROID angegeben wird.

XrResult xrGetHandMeshANDROID(
    XrHandMeshTrackerANDROID                    handMeshTracker,
    const XrHandMeshGetInfoANDROID*             getInfo,
    XrHandTrackingMeshesANDROID*                handMeshes);

Parameterbeschreibungen

Die Anwendung kann die Funktion xrGetHandMeshANDROID verwenden, um auf die von der Laufzeit generierten Hand-Mesh-Buffer zuzugreifen.

Die Anwendung sollte xrBeginFrame mindestens einmal während der Sitzung vor dem ersten Aufruf von xrGetHandMeshANDROID aufrufen.

Eine Anwendung sollte XrHandMeshANDROID::indexCount und XrHandMeshANDROID::vertexCount verwenden, um auf Hand-Mesh-Buffer zuzugreifen und sie in ihrem Rendering-Loop wiederzuverwenden, wenn xrGetHandMeshANDROID in jedem Frame aufgerufen wird.

Gültige Verwendung (implizit)

Rückgabecodes

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_SIZE_INSUFFICIENT
  • XR_ERROR_TIME_INVALID

In XrHandMeshGetInfoANDROID werden die Informationen beschrieben, die zum Abrufen von Hand-Mesh-Daten erforderlich sind.

typedef struct XrHandMeshGetInfoANDROID {
    XrStructureType    type;
    const void*        next;
    XrSpace            baseSpace;
    XrTime             time;
} XrHandMeshGetInfoANDROID;

Beschreibungen von Mitgliedern

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind in OpenXR oder dieser Erweiterung nicht definiert.
  • baseSpace ist ein XrSpace, der den Referenzraum definiert, in dem die Transformation für die Eckpunkte bei time zu finden ist.
  • time ist die XrTime, die den Zeitpunkt beschreibt, zu dem die Anwendung das Hand-Mesh abfragen möchte.

Gültige Verwendung (implizit)

Die Struktur XrHandTrackingMeshesANDROID enthält Mesh-Daten für beide Hände.

typedef struct XrHandTrackingMeshesANDROID {
    XrStructureType      type;
    void*                next;
    XrHandMeshANDROID    leftHandMesh;
    XrHandMeshANDROID    rightHandMesh;
} XrHandTrackingMeshesANDROID;

Beschreibungen von Mitgliedern

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind in OpenXR oder dieser Erweiterung nicht definiert.
  • leftHandMesh ist das XrHandMeshANDROID für die linke Hand.
  • rightHandMesh ist das XrHandMeshANDROID für die rechte Hand.

Gültige Verwendung (implizit)

Eine XrHandMeshANDROID-Struktur enthält Daten und Puffer zum Empfangen von Hand-Mesh-Tracking-Daten von der Funktion xrGetHandMeshANDROID für eine Hand.

typedef struct XrHandMeshANDROID {
    XrBool32             isActive;
    XrTime               dynamicLastUpdateTime;
    uint32_t             indexCount;
    uint32_t             vertexCount;
    const uint32_t*      indices;
    const XrVector2f*    textureUVs;
    const XrVector3f*    positions;
    const XrVector3f*    normals;
    XrPosef              baseSpaceFromVertexSpace;
} XrHandMeshANDROID;

Beschreibungen von Mitgliedern

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind in OpenXR oder dieser Erweiterung nicht definiert.
  • isActive ist ein XrBool32, das angibt, ob der aktuelle Mesh-Tracker für die Hand aktiv ist und die Mesh-Daten gültig sind.
  • dynamicLastUpdateTime ist die XrTime, die den Zeitpunkt angibt, zu dem die dynamischen Puffer zuletzt aktualisiert wurden.
  • indexCount ist ein uint32_t, das als indices der Handnetzhaut dient.
  • vertexCount ist ein uint32_t, das als positions der Hand-Mesh-Struktur dient. Sie kann auch für textureUVs oder normals verwendet werden, wenn diese vom System unterstützt werden.
  • indices ist ein Array von uint32_t, das die Mesh-Indexe für Dreiecke in gegen dem Uhrzeigersinn verlaufender Reihenfolge darstellt. Die Anzahl der Werte, auf die verwiesen wird, ist indexCount.
  • textureUVs ist NULL oder ein Array von XrVector2f, das die Texturkoordinaten des Vertex darstellt. Die Anzahl der Werte, auf die verwiesen wird, ist vertexCount.
  • positions ist ein Array von XrVector3f, das die Scheitelpunktpositionen in baseSpaceFromVertexSpace darstellt. Die Anzahl der Werte, auf die verwiesen wird, ist vertexCount.
  • normals ist eine NULL oder ein Array von XrVector3f, das die Knotennormalen in baseSpaceFromVertexSpace darstellt. Die Anzahl der Werte, auf die verwiesen wird, ist vertexCount.
  • baseSpaceFromVertexSpace ist der XrSpace-Knoten in XrHandMeshGetInfoANDROID::baseSpace beim Aufruf von xrGetHandMeshANDROID. Anwendungen können dies verwenden, um den Koordinatenraum der Mesh-Ecken und -Normalen während des Renderings zu transformieren.

Das Hand-Mesh wird in Dreieckslisten dargestellt und die Eckpunkte jedes Dreiecks sind in umgekehrter Richtung gegen den Uhrzeigersinn angeordnet, wenn man von außen auf die Hand schaut.

Wenn der zurückgegebene isActive-Wert XR_FALSE ist, wird die Hand nicht aktiv erfasst. Das kann z. B. daran liegen, dass sich die Hand außerhalb des Erfassungsbereichs des Sensors befindet, der Eingabefokus nicht auf der Anwendung liegt oder die Anwendung nicht die Berechtigungen zum Zugriff auf Daten der Handerkennung hat.

Wenn der zurückgegebene isActive-Wert XR_TRUE ist, werden das in indices und positions dargestellte Hand-Tracking-Mesh, einschließlich textureUVs und normals, sofern vom System unterstützt, auf die neuesten Daten der XrHandMeshGetInfoANDROID::time aktualisiert, die an die Funktion xrGetHandMeshANDROID übergeben wurden.

Der Speicher, auf den von Hand-Mesh-Buffers in XrHandMeshANDROID verwiesen wird, gehört der Laufzeit und wird mit der Anwendung geteilt. Der Zugriff auf den Arbeitsspeicher ist von jedem Thread aus sicher bis zum nächsten Aufruf von xrBeginFrame, solange der Handle XrHandMeshTrackerANDROID gültig ist.

  • Die Werte, auf die indices und textureUVs verweisen, sind nicht dynamisch.
  • Der Zeiger und die Werte, auf die positions und normals verweisen, sind dynamisch und können sich zwischen den Aufrufen von xrBeginFrame ändern. Die Anwendung kann dynamicLastUpdateTime verwenden, um zu prüfen, ob sich die Werte seit dem letzten Frame geändert haben, und unnötige Datenverarbeitung vermeiden, wenn keine Änderungen vorliegen.

Gültige Verwendung (implizit)

  • Die XR_ANDROID_hand_mesh-Erweiterung muss aktiviert sein, bevor XrHandMeshANDROID verwendet werden kann.
  • indices muss ein Verweis auf einen gültigen uint32_t-Wert sein.
  • textureUVs muss ein Verweis auf eine gültige XrVector2f-Struktur sein.
  • positions muss ein Verweis auf eine gültige XrVector3f-Struktur sein.
  • normals muss ein Verweis auf eine gültige XrVector3f-Struktur sein.

Beispielcode für das Mesh-Tracking von Händen

Im folgenden Beispielcode wird gezeigt, wie Sie für das Rendering auf Hand-Mesh-Buffer zugreifen.

XrInstance instance;  // Created at app startup
XrSystemId systemId;  // Received from xrGetSystem() at app startup
XrSession session;    // Created at app startup.
XrSpace appPlaySpace; // Created at app startup.

// The function pointers are previously initialized using xrGetInstanceProcAddr.
PFN_xrCreateHandMeshTrackerANDROID xrCreateHandMeshTrackerANDROID; // previously initialized
PFN_xrDestroyHandMeshTrackerANDROID xrDestroyHandMeshTrackerANDROID; // previously initialized
PFN_xrGetHandMeshANDROID xrGetHandMeshANDROID; // previously initialized

// Inspect system capability
XrSystemHandMeshTrackingPropertiesANDROID handMeshTrackingProps = {
  .type = XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID,
};
XrSystemProperties sysProps = {
  .type = XR_TYPE_SYSTEM_PROPERTIES,
  .next = &handMeshTrackingProps
};
CHK_XR(xrGetSystemProperties(instance, systemId, &sysProps));
if (!handMeshTrackingProps.supportsHandMeshTracking) {
  // hand mesh tracking is not supported.
  return;
}

XrHandMeshTrackerCreateInfoANDROID trackerCreateInfo = {
  .type = XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
};
XrHandMeshTrackerANDROID handMeshTracker = XR_NULL_HANDLE;
CHK_XR(xrCreateHandMeshTrackerANDROID(
    session, &trackerCreateInfo, &handMeshTracker));
// app update loop
while (true) {
    // ...
    // For every frame in frame loop
    // ...

    XrFrameState frameState;  // previously returned from xrWaitFrame
    const XrTime time = frameState.predictedDisplayTime;

    // ...
    XrHandMeshGetInfoANDROID getInfo = {
        .type = XR_TYPE_HAND_MESH_GET_INFO_ANDROID,
        .baseSpace = appPlaySpace,
        .time = time,
    };
    XrHandTrackingMeshesANDROID handMeshes = {
        .type = XR_TYPE_HAND_TRACKING_MESHES_ANDROID
    };
    CHK_XR(xrGetHandMeshANDROID(handMeshTracker, &getInfo, &handMeshes));

    if (handMeshes.leftHandMesh.isActive) {
        // access vertex/index buffers for rendering.
    }

    // ...
    // Finish frame loop
    // ...
}

CHECK_XR(xrDestroyHandMeshTracker(handMeshTracker));

Neue Objekttypen

Neue Enum-Konstanten

Die Aufzählung XrObjectType wurde um Folgendes erweitert:

  • XR_OBJECT_TYPE_HAND_MESH_TRACKER_ANDROID

Die Aufzählung XrStructureType wurde um folgende Elemente erweitert:

  • XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID
  • XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
  • XR_TYPE_HAND_MESH_GET_INFO_ANDROID
  • XR_TYPE_HAND_TRACKING_MESHES_ANDROID

Neue Enums

Neue Strukturen

Neue Funktionen

Probleme

Versionsverlauf

  • Revision 1, 10.09.2024 (Levana Chen)
    • Erste Beschreibung der Erweiterung