Rozszerzenie OpenXR XR_ANDROID_hand_mesh

Ciąg znaków nazwy

XR_ANDROID_hand_mesh

Typ rozszerzenia

Rozszerzenie instancji

Zarejestrowany numer wewnętrzny

704

Weryfikacja

1

Zależności rozszerzenia i wersji

OpenXR 1.0

Data ostatniej modyfikacji

2024-09-10

Stan adresu IP

Brak znanych roszczeń dotyczących adresu IP.

Twórcy

Nihav Jain, Google

Cairn Overturf, Google

Spencer Quin, Google

Levana Chen, Google

Omówienie

To rozszerzenie umożliwia śledzenie rąk reprezentowanych jako dynamiczna siatka dłoni.

To rozszerzenie ma udostępniać bufory wierzchołków i indeksów dla siatki personalizowanej reprezentacji rąk użytkownika. Można go używać do zasłonięcia i wizualizacji.

Tego rozszerzenia nie należy używać do innych celów śledzenia dłoni.

Dane śledzenia dłoni mogą zawierać wrażliwe dane osobowe i są ściśle powiązane z prywatnością i integralnością. Zdecydowanie zalecamy, aby aplikacje, które przechowują lub przesyłają dane śledzenia dłoni, zawsze prosiły użytkownika o aktywne i wyraźne wyrażenie zgody na takie działanie.

Sprawdzanie możliwości systemu

Aplikacja może sprawdzić, czy system jest w stanie śledzić siatki dłoni, łącząc strukturę XrSystemHandMeshTrackingPropertiesANDROID ze strukturą XrSystemProperties podczas wywołania funkcji xrGetSystemProperties.

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

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktury. Nie ma żadnych takich struktur zdefiniowanych w podstawowym OpenXR ani w tym rozszerzeniu.
  • supportsHandMeshTracking to XrBool32, który wskazuje, czy wybrana XrSystemId obsługuje śledzenie siatki dłoni.
  • supportsTextureUV to XrBool32, który wskazuje, czy wybrany XrSystemId obsługuje współrzędne UV tekstury dla wierzchołków siatki.
  • supportsVertexNormal to XrBool32, który wskazuje, czy wybrana XrSystemId obsługuje normalne wierzchołka dla wierzchołków siatki.

Aplikacja nie powinna używać funkcji siatki dłoni, gdy supportsHandMeshTracking jest XR_FALSE, ponieważ oznacza to, że system nie obsługuje śledzenia siatki dłoni. W tym przypadku funkcja xrCreateHandMeshTrackerANDROID zwróci wartość XR_ERROR_FEATURE_UNSUPPORTED.

Jeśli supportsHandMeshTracking zwraca XR_TRUE, system obsługuje śledzenie siatki dłoni. Aplikacja powinna używać funkcji XrHandMeshANDROID::indexCountXrHandMeshANDROID::vertexCount, aby uzyskiwać dostęp do buforów siatki dłoni i używać ich ponownie w pętli renderowania podczas wywoływania funkcji xrGetHandMeshANDROID w każdej klatce.

Jeśli funkcja supportsTextureUV zwraca wartość XR_FALSE, system nie obsługuje map UV tekstury dla wierzchołków siatki. W takim przypadku aplikacja otrzyma wartość NULL z funkcji XrHandMeshANDROID::textureUVs podczas wywołania funkcji xrGetHandMeshANDROID.

Jeśli supportsVertexNormal zwraca XR_FALSE, system nie obsługuje normali wierzchołków dla wierzchołków siatki, a aplikacja otrzyma XrHandMeshANDROID::normals NULL po wywołaniu xrGetHandMeshANDROID.

Prawidłowe użycie (domyślne)

Tworzenie uchwytu śledzenia dłoni

XR_DEFINE_HANDLE(XrHandMeshTrackerANDROID)

XrHandMeshTrackerANDROID reprezentuje śledzenie dłoni i zarządzanie powiązanymi zasobami.

Z tego uchwytu można korzystać, aby uzyskać dostęp do buforów siatki dłoni za pomocą innych funkcji w tym rozszerzeniu.

Aplikacja może utworzyć uchwyt XrHandMeshTrackerANDROID za pomocą funkcji xrCreateHandMeshTrackerANDROID.

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

Opisy parametrów

Jeśli system nie obsługuje śledzenia siatki dłoni, funkcja xrCreateHandMeshTrackerANDROID zwróci wartość XR_ERROR_FEATURE_UNSUPPORTED.

Obiekt XrHandMeshTrackerANDROID obsługuje wszystkie zasoby do śledzenia siatki dłoni. Po zakończeniu śledzenia dłoni aplikacja musi zniszczyć uchwyt za pomocą funkcji xrDestroyHandMeshTrackerANDROID.

Prawidłowe użycie (domyślne)

Kody zwrotu

Gotowe

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • 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

Struktura XrHandMeshTrackerCreateInfoANDROID zawiera informacje potrzebne do utworzenia uchwytu XrHandMeshTrackerANDROID.

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

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktury. Nie ma żadnych takich struktur zdefiniowanych w podstawowym OpenXR ani w tym rozszerzeniu.

Prawidłowe użycie (domyślne)

Funkcja xrDestroyHandMeshTrackerANDROID zwalnia handMeshTracker i podstawowe zasoby po zakończeniu śledzenia dłoni.

XrResult xrDestroyHandMeshTrackerANDROID(
    XrHandMeshTrackerANDROID handMeshTracker);

Opisy parametrów

Prawidłowe użycie (domyślne)

Bezpieczeństwo wątków

  • Dostęp do handMeshTracker i wszystkich jego uchwytów podrzędnych musi być zsynchronizowany zewnętrznie.

Kody zwrotu

Gotowe

  • XR_SUCCESS

Błąd

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID

Znajdowanie siatek dłoni

Aplikacja może użyć funkcji xrGetHandMeshANDROID, aby pobrać siatkę dłoni w określonym sygnaturze czasowej. Pozycja wierzchołków siatki dłoni i ich normalne są reprezentowane w przestrzeni określonej przez XrHandMeshGetInfoANDROID::baseSpace podczas wywoływania funkcji xrGetHandMeshANDROID.

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

Opisy parametrów

Aplikacja może używać funkcji xrGetHandMeshANDROID, aby uzyskać dostęp do buforów siatki dłoni wygenerowanych przez środowisko uruchomieniowe.

Aplikacja powinna wywołać xrBeginFrame co najmniej raz podczas sesji przed pierwszym wywołaniem xrGetHandMeshANDROID.

Aplikacja powinna używać funkcji XrHandMeshANDROID::indexCountXrHandMeshANDROID::vertexCount, aby uzyskać dostęp do buforów siatki dłoni i ich ponownego użycia w pętli renderowania podczas wywoływania funkcji xrGetHandMeshANDROID w każdej klatce.

Prawidłowe użycie (domyślne)

Kody zwrotu

Gotowe

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • 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

XrHandMeshGetInfoANDROID zawiera informacje wymagane do uzyskania danych dotyczących dłoni.

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

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowym OpenXR ani w tym rozszerzeniu nie zdefiniowano żadnych takich struktur.
  • baseSpace to XrSpace określający przestrzeń odniesienia, w której należy zlokalizować transformację wierzchołków w time.
  • time to XrTime, który określa czas, w którym aplikacja chce wysłać zapytanie do siatki dłoni.

Prawidłowe użycie (domyślne)

Struktura XrHandTrackingMeshesANDROID zawiera dane siatki dla obu rąk.

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

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktury. Nie ma żadnych takich struktur zdefiniowanych w podstawowym OpenXR ani w tym rozszerzeniu.
  • leftHandMesh to XrHandMeshANDROID dla lewej ręki.
  • rightHandMesh to XrHandMeshANDROID dla prawej ręki.

Prawidłowe użycie (domyślne)

Struktura XrHandMeshANDROID zawiera dane i bufory do odbierania danych śledzenia siatki dłoni z funkcji xrGetHandMeshANDROID dla jednej dłoni.

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;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktury. Nie ma żadnych takich struktur zdefiniowanych w podstawowym OpenXR ani w tym rozszerzeniu.
  • isActive to XrBool32 wskazujący, czy bieżący lokalizator siatki dłoni jest aktywny i czy dane siatki są prawidłowe.
  • dynamicLastUpdateTime to XrTime określający czas ostatniej aktualizacji dynamicznych buforów.
  • indexCount to uint32_t, który służy jako liczba indices siatki rękawicy.
  • vertexCount to uint32_t, który jest liczbą positions siatki ręki. Możesz też użyć tych funkcji w przypadku textureUVs lub normals, jeśli są obsługiwane przez system.
  • indices to tablica uint32_t reprezentująca indeksy siatki dla trójkątów w kolejności przeciwnej do ruchu wskazówek zegara. Liczba wartości, do których się odwołuje, to indexCount.
  • textureUVs to NULL lub tablica XrVector2f reprezentująca wierzchołek współrzędnych tekstury. Liczba wartości, na które wskazuje ten element, to vertexCount.
  • positions to tablica XrVector3f reprezentująca pozycje wierzchołków w baseSpaceFromVertexSpace. Liczba wartości, na które wskazuje ten element, to vertexCount.
  • normals to NULL lub tablica XrVector3f reprezentująca wierzchołeknormals w baseSpaceFromVertexSpace. Liczba wartości, do których odwołuje się ten element, to vertexCount.
  • baseSpaceFromVertexSpace to wierzchołek XrSpace znajdujący się w funkcji XrHandMeshGetInfoANDROID::baseSpace podczas wywoływania funkcji xrGetHandMeshANDROID. Aplikacje mogą używać tego do przekształcania przestrzeni współrzędnych wierzchołków i normali siatki podczas renderowania.

Siatka dłoni jest reprezentowana przez listy trójkątów, a wierzchołki każdego trójkąta są w kolejności przeciwnej do ruchu wskazówek zegara, gdy patrzymy na dłoń z zewnątrz.

Jeśli zwrócona wartość isActive to XR_FALSE, oznacza to, że ręka nie jest aktywnie śledzona. Może to być spowodowane na przykład tym, że ręka znajduje się poza zasięgiem czujnika, aplikacja nie jest aktywna lub nie ma uprawnień do dostępu do danych śledzenia ręki.

Gdy zwrócona wartość isActive to XR_TRUE, siatki śledzenia dłoni reprezentowane przez indicespositions, w tym textureUVsnormals, jeśli są obsługiwane przez system, są aktualizowane do najnowszych danych XrHandMeshGetInfoANDROID::time podanych funkcji xrGetHandMeshANDROID.

Pamięć wskazywana przez bufory siatki dłoni zwracane w XrHandMeshANDROID jest własnością środowiska wykonawczego i jest udostępniana aplikacji. Pamięć jest bezpieczna do dostępu z dowolnego wątku do następnego wywołania funkcji xrBeginFrame, gdy uchwyt XrHandMeshTrackerANDROID jest prawidłowy.

  • Wartości wskazywane przez indicestextureUVs nie są dynamiczne.
  • Wskaźnik i wartości wskazujące na positionsnormalsdynamicznemogą się zmieniać między wywołaniami funkcji xrBeginFrame. Aplikacja może użyć funkcji dynamicLastUpdateTime, aby sprawdzić, czy wartości zmieniły się od ostatniego kadru, i uniknąć niepotrzebnego przetwarzania danych, gdy nie ma żadnych zmian.

Prawidłowe użycie (domyślne)

  • Przed użyciem rozszerzenia XR_ANDROID_hand_mesh musi być włączone XrHandMeshANDROID
  • indices musi być wskaźnikiem do prawidłowej wartości uint32_t.
  • textureUVs musi być wskaźnikiem do prawidłowej struktury XrVector2f
  • positions musi być wskaźnikiem do prawidłowej struktury XrVector3f
  • normals musi być wskaźnikiem do prawidłowej struktury XrVector3f

Przykładowy kod do śledzenia siatki dłoni

Poniższy przykładowy kod pokazuje, jak uzyskać dostęp do buforów siatki dłoni na potrzeby renderowania.

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

Nowe typy obiektów

Nowe stałe typu wyliczeniowego

Wyliczenie XrObjectType zostało rozszerzone o:

  • XR_OBJECT_TYPE_HAND_MESH_TRACKER_ANDROID

Wyliczenie XrStructureType zostało rozszerzone o:

  • 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

Nowe wartości w polu enum

Nowe struktury

Nowe funkcje

Problemy

Historia wersji

  • Wersja 1, 10 września 2024 r. (Levana Chen)
    • Początkowy opis rozszerzenia