XR_EXT_spatial_marker_tracking

Ciąg znaków nazwy

XR_EXT_spatial_marker_tracking

Typ rozszerzenia

Rozszerzenie instancji

Zarejestrowany numer wewnętrzny

744

Wersja

1

Stan ratyfikacji

Ratyfikacja

Zależności rozszerzeń i wersji

XR_EXT_spatial_entity

Twórcy

Ron Bessems, Meta
Nihav Jain, Google
Natalie Fleury, Meta
Yuichi Taguchi, Meta
Yin Li, Microsoft
Jimmy Alamparambil, ByteDance
Zhipeng Liu, ByteDance
Jun Yan, ByteDance

Przegląd

To rozszerzenie jest oparte na XR_EXT_spatial_entity i umożliwia aplikacjom wykrywanie i śledzenie markerów w otoczeniu. Markery to kody 2D, które mogą obejmować kody QR, mikrokody QR, markery ArUco lub AprilTags.

Śledzony marker jest reprezentowany jako obiekt przestrzenny, który ma te komponenty:

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

Obsługa środowiska wykonawczego

Środowisko wykonawcze musi reklamować obsługę różnych funkcji śledzenia markerów za pomocą funkcji xrEnumerateSpatialCapabilitiesEXT, wymieniając dowolne z tych funkcji:

  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT
  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT
  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT
  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT

Konfiguracja

Aby włączyć wykrywanie typu znacznika, aplikacja musi przekazać odpowiednią strukturę konfiguracji do funkcji xrCreateSpatialContextAsyncEXT .

Konfiguracje typu znacznika

kody QR,

Struktura XrSpatialCapabilityConfigurationQrCodeEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialCapabilityConfigurationQrCodeEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
} XrSpatialCapabilityConfigurationQrCodeEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • capability musi mieć wartość XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT .
  • enabledComponentCount to uint32_t z liczbą elementów w enabledComponents .
  • enabledComponents to wskaźnik do tablicy komponentów, które mają być włączone w przypadku tej funkcji.

Jeśli kody QR są obsługiwane, środowisko wykonawcze musi włączyć śledzenie za pomocą kodu QR, gdy struktura XrSpatialCapabilityConfigurationQrCodeEXT jest przekazywana w XrSpatialContextCreateInfoEXT :: capabilityConfigs podczas wywoływania funkcji xrCreateSpatialContextAsyncEXT .

Środowisko wykonawcze musi zwrócić wartość XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT, jeśli wartość XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT nie jest wyliczana przez funkcję xrEnumerateSpatialCapabilitiesEXT .

Prawidłowe użycie (domyślne)

Mikrokody QR

Struktura XrSpatialCapabilityConfigurationMicroQrCodeEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialCapabilityConfigurationMicroQrCodeEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
} XrSpatialCapabilityConfigurationMicroQrCodeEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • capability musi mieć wartość XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT .
  • enabledComponentCount to uint32_t z liczbą elementów w enabledComponents .
  • enabledComponents to wskaźnik do tablicy komponentów, które mają być włączone w przypadku tej funkcji.

Jeśli kody Micro QR są obsługiwane, środowisko wykonawcze musi włączyć śledzenie kodów Micro QR, gdy struktura XrSpatialCapabilityConfigurationMicroQrCodeEXT jest przekazywana w XrSpatialContextCreateInfoEXT :: capabilityConfigs podczas wywoływania funkcji xrCreateSpatialContextAsyncEXT .

Środowisko wykonawcze musi zwrócić wartość XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT, jeśli wartość XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT nie jest wyliczana przez funkcję xrEnumerateSpatialCapabilitiesEXT .

Prawidłowe użycie (domyślne)

Znaczniki ArUco

Struktura XrSpatialCapabilityConfigurationArucoMarkerEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialCapabilityConfigurationArucoMarkerEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
    XrSpatialMarkerArucoDictEXT         arUcoDict;
} XrSpatialCapabilityConfigurationArucoMarkerEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • capability musi mieć wartość XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT .
  • enabledComponentCount to uint32_t z liczbą elementów w enabledComponents .
  • enabledComponents to wskaźnik do tablicy komponentów, które mają być włączone w przypadku tej funkcji.
  • arUcoDict to słownik znaczników do wykrycia.

Jeśli znaczniki ArUco są obsługiwane, środowisko wykonawcze musi włączyć śledzenie znaczników ArUco, gdy struktura XrSpatialCapabilityConfigurationArucoMarkerEXT jest przekazywana w XrSpatialContextCreateInfoEXT :: capabilityConfigs podczas wywoływania funkcji xrCreateSpatialContextAsyncEXT .

Środowisko wykonawcze musi zwracać XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT z funkcji xrCreateSpatialContextAsyncEXT, jeśli struktura XrSpatialCapabilityConfigurationArucoMarkerEXT znajduje się w XrSpatialContextCreateInfoEXT :: capabilityConfigs, ale XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT nie jest wyliczana przez xrEnumerateSpatialCapabilitiesEXT .

Prawidłowe użycie (domyślne)

Wyliczenie XrSpatialMarkerArucoDictEXT jest zdefiniowane w ten sposób:

typedef enum XrSpatialMarkerArucoDictEXT {
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT = 1,
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT = 2,
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT = 3,
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT = 4,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT = 5,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT = 6,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT = 7,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT = 8,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT = 9,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT = 10,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT = 11,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT = 12,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT = 13,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT = 14,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT = 15,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT = 16,
    XR_SPATIAL_MARKER_ARUCO_DICT_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialMarkerArucoDictEXT;

Obsługiwany predefiniowany słownik ArUco:

Opisy elementów wyliczenia

  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT – słownik znaczników Aruco o rozmiarze 4 x 4 piksele z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT – słownik markerów Aruco o rozmiarze 4 x 4 piksele zawierający 100 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT – słownik znaczników Aruco o rozmiarze 4 x 4 piksele z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT – słownik znaczników Aruco o rozmiarze 4 x 4 piksele z 1000 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT – słownik markerów Aruco 5 x 5 pikseli z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT – słownik znaczników Aruco o rozmiarze 5 x 5 pikseli zawierający 100 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT – słownik znaczników Aruco o rozmiarze 5 x 5 pikseli z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT – słownik znaczników Aruco o rozmiarze 5 x 5 pikseli z 1000 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT – słownik markerów Aruco o rozmiarze 6 x 6 pikseli z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT – słownik znaczników Aruco o rozmiarze 6 x 6 pikseli zawierający 100 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT – słownik znaczników Aruco o rozmiarze 6 x 6 pikseli z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT – słownik znaczników Aruco o rozmiarze 6 x 6 pikseli z 1000 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT – słownik markerów Aruco o rozmiarze 7 x 7 pikseli z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT – słownik znaczników Aruco o rozmiarze 7 x 7 pikseli zawierający 100 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT – słownik markerów Aruco o rozmiarze 7 x 7 pikseli z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT – słownik markerów Aruco o rozmiarze 7 x 7 pikseli z 1000 identyfikatorów.
AprilTags

Struktura XrSpatialCapabilityConfigurationAprilTagEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialCapabilityConfigurationAprilTagEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
    XrSpatialMarkerAprilTagDictEXT      aprilDict;
} XrSpatialCapabilityConfigurationAprilTagEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • capability musi mieć wartość XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT .
  • enabledComponentCount to uint32_t z liczbą elementów w enabledComponents .
  • enabledComponents to wskaźnik do tablicy komponentów, które mają być włączone w przypadku tej funkcji.
  • aprilDict to słownik znaczników do wykrycia.

Jeśli znaczniki AprilTag są obsługiwane, środowisko wykonawcze musi włączyć śledzenie znaczników AprilTag, gdy struktura XrSpatialCapabilityConfigurationAprilTagEXT jest przekazywana w XrSpatialContextCreateInfoEXT :: capabilityConfigs podczas wywoływania funkcji xrCreateSpatialContextAsyncEXT .

Środowisko wykonawcze musi zwracać XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT z funkcji xrCreateSpatialContextAsyncEXT, jeśli struktura XrSpatialCapabilityConfigurationAprilTagEXT znajduje się w XrSpatialContextCreateInfoEXT :: capabilityConfigs, ale XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT nie jest wyliczana przez xrEnumerateSpatialCapabilitiesEXT .

Prawidłowe użycie (domyślne)

Wyliczenie XrSpatialMarkerAprilTagDictEXT jest zdefiniowane w ten sposób:

typedef enum XrSpatialMarkerAprilTagDictEXT {
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT = 1,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT = 2,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT = 3,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT = 4,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialMarkerAprilTagDictEXT;

Obsługiwany wstępnie zdefiniowany słownik AprilTag:

Opisy elementów wyliczenia

  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT – 4 x 4 bity, minimalna odległość Hamminga między dowolnymi 2 kodami = 5, 30 kodów.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT – 5 na 5 bitów, minimalna odległość Hamminga między dowolnymi 2 kodami = 9, 35 kodów.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT – 6 na 6 bitów, minimalna odległość Hamminga między dowolnymi 2 kodami = 10, 2320 kodów.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT – 6 na 6 bitów, minimalna odległość Hamminga między dowolnymi 2 kodami = 11, 587 kodów.

Opcjonalne konfiguracje znacznika

Aplikacje powinny wywoływać funkcję xrEnumerateSpatialCapabilityFeaturesEXT, aby uzyskać listę obsługiwanych funkcji opcjonalnych.

Pełną listę wszystkich funkcji przestrzennych obsługiwanych przez dowolne rozszerzenie znajdziesz w sekcji XrSpatialCapabilityFeatureEXT.

Rozmiar znacznika

Struktura XrSpatialMarkerSizeEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialMarkerSizeEXT {
    XrStructureType    type;
    const void*        next;
    float              markerSideLength;
} XrSpatialMarkerSizeEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • markerSideLength to rozmiar wszystkich znaczników w metrach.

Jeśli XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT jest wyliczany przez funkcję xrEnumerateSpatialCapabilityFeaturesEXT dla określonej funkcji, a aplikacja łączy strukturę XrSpatialMarkerSizeEXT z odpowiednią strukturą konfiguracji tej funkcji, środowisko wykonawcze musi założyć, że wszystkie wykryte znaczniki mają szerokość i wysokość markerSideLength . Przekazanie tych informacji do środowiska wykonawczego pozwala mu zwracać dokładniejsze dane o pozycji i rozmiarze. Ta struktura musi być połączona z łańcuchem next XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT lub XrSpatialCapabilityConfigurationAprilTagEXT .

Prawidłowe użycie (domyślne)

Optymalizacja statycznych znaczników

Struktura XrSpatialMarkerStaticOptimizationEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialMarkerStaticOptimizationEXT {
    XrStructureType    type;
    const void*        next;
    XrBool32           optimizeForStaticMarker;
} XrSpatialMarkerStaticOptimizationEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • optimizeForStaticMarker wskazuje, czy wszystkie markery w przestrzeni nie powinny się przemieszczać.

Jeśli XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT jest wyliczany przez funkcję xrEnumerateSpatialCapabilityFeaturesEXT dla określonej funkcji i jeśli aplikacja łączy strukturę XrSpatialMarkerStaticOptimizationEXT z odpowiednią strukturą konfiguracji tej funkcji, środowisko wykonawcze musi założyć, że wszystkie wykryte znaczniki są statyczne, jeśli wartość optimizeForStaticMarker jest ustawiona na XR_TRUE . Dzięki temu środowisko wykonawcze może generować dokładniejszą pozycję i rozmiar. Ta struktura musi być połączona z łańcuchem next XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT lub XrSpatialCapabilityConfigurationAprilTagEXT .

Prawidłowe użycie (domyślne)

Gwarantowane komponenty

Środowisko wykonawcze obsługujące XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT, XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT, XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT lub XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT musi udostępniać te komponenty przestrzenne jako gwarantowane komponenty wszystkich elementów wykrytych przez te funkcje i musi je wyliczać w funkcji xrEnumerateSpatialCapabilityComponentTypesEXT :

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

Komponent Markera

Dane komponentu

Struktura XrSpatialMarkerDataEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialMarkerDataEXT {
    XrSpatialCapabilityEXT    capability;
    uint32_t                  markerId;
    XrSpatialBufferEXT        data;
} XrSpatialMarkerDataEXT;

Opisy członków

  • capability to element XrSpatialCapabilityEXT, który wykrył marker.
  • markerId to zakodowany identyfikator z markera. W przypadku znaczników ArUco i AprilTag to pole musi być prawidłowe i zawierać zakodowany identyfikator. W przypadku kodów QR to pole musi mieć wartość zero.
  • data to identyfikator bufora i rodzaj dodatkowych informacji zawartych w znaczniku.

Atrybuty XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT obsługują dodatkowe dane. Jeśli capability jest jednym z tych symboli:

  • Jeśli środowisko wykonawcze prawidłowo zdekodowało dane znacznika, musi ustawić typ bufora data na XR_SPATIAL_BUFFER_TYPE_UINT8_EXT lub XR_SPATIAL_BUFFER_TYPE_STRING_EXT w zależności od danych w znaczniku. Środowisko wykonawcze musi też ustawić prawidłowy identyfikator bufora w data, którego aplikacja może używać z odpowiednią funkcją xrGetSpatialBuffer* do pobierania danych.
  • Jeśli środowisko wykonawcze nie zdekodowało jeszcze danych znacznika, musi ustawić identyfikator bufora data na XR_NULL_SPATIAL_BUFFER_ID_EXT, a typ bufora na XR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT .

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT nie obsługują dodatkowych danych, a środowisko wykonawcze musi ustawić identyfikator bufora data na XR_NULL_SPATIAL_BUFFER_ID_EXT .

Prawidłowe użycie (domyślne)

Struktura listy komponentów do wysyłania zapytań o dane

Struktura XrSpatialComponentMarkerListEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialComponentMarkerListEXT {
    XrStructureType            type;
    void*                      next;
    uint32_t                   markerCount;
    XrSpatialMarkerDataEXT*    markers;
} XrSpatialComponentMarkerListEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowej specyfikacji OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.
  • markerCount to liczba elementów w elemencie markers.
  • markers to tablica elementów XrSpatialMarkerDataEXT .

Aplikacja może wysyłać zapytania do komponentu znacznika przestrzennych elementów w XrSpatialSnapshotEXT, dodając XR_SPATIAL_COMPONENT_TYPE_MARKER_EXTXrSpatialComponentDataQueryConditionEXT :: componentTypes i dodając XrSpatialComponentMarkerListEXT do następnego łańcucha wskaźników XrSpatialComponentDataQueryResultEXT .

Środowisko wykonawcze musi zwracać XR_ERROR_VALIDATION_FAILURE z funkcji xrQuerySpatialComponentDataEXT, jeśli XrSpatialComponentMarkerListEXT znajduje się w następnym łańcuchu XrSpatialComponentDataQueryResultEXT :: next, ale XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT nie jest uwzględniony w XrSpatialComponentDataQueryConditionEXT :: componentTypes .

Środowisko wykonawcze musi zwracać XR_ERROR_SIZE_INSUFFICIENT z funkcji xrQuerySpatialComponentDataEXT, jeśli wartość markerCount jest mniejsza niż XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

Prawidłowe użycie (domyślne)

Konfiguracja

Jeśli w przypadku niektórych funkcji wyliczenie XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT znajduje się w XrSpatialCapabilityComponentTypesEXT :: componentTypes, aplikacja może włączyć tę funkcję, dodając wyliczenie do listy XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents w strukturze pochodnej XrSpatialCapabilityConfigurationBaseHeaderEXT funkcji, która obsługuje ten komponent.

Ten komponent nie wymaga specjalnej konfiguracji, aby można go było uwzględnić w łańcuchu XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.

Ograniczony komponent 2D

Ograniczony komponent 2D zawiera środek i rozmiar znacznika reprezentowanego przez element, na którym się znajduje. Więcej informacji o komponencie ograniczonym do 2D znajdziesz w sekcji Ograniczony do 2D.

Wartość XrSpatialBounded2DDataEXT :: center musi wskazywać środek znacznika. Patrząc na przednią stronę znacznika, oś X musi być skierowana w prawo, a oś Y musi być skierowana w górę. Środowisko wykonawcze musi być zgodne z konwencją prawoskrętnego układu współrzędnych, dlatego oś Z wychodzi z przedniej strony markera. Oznacza to, że marker o położeniu {0, 0, 0}, obrocie {0, 0, 0, 1} (bez obrotu) i rozmiarze {1, 1} odnosi się do markera o wymiarach 1 m × 1 m wyśrodkowanego w punkcie {0, 0, 0}, którego wektor normalny przedniej powierzchni jest skierowany w kierunku +Z w przestrzeni komponentu.

Poniżej znajduje się ilustracja orientacji znacznika.

xr ml marker understanding axis

Ilustracja 25. Marker kodu QR z osią

Kody testowe

Poniższe kody muszą mieć płaszczyznę XY w dokumencie, a oś Z musi być skierowana w stronę osoby przeglądającej. Punkt początkowy osi musi znajdować się na środku każdego znacznika. Oś X musi być skierowana w prawo, a oś Y musi być skierowana w górę dokumentu.

ext marker tracking qr

Rysunek 26. Kod QR z tekstem „OpenXR”

śledzenie znaczników zewnętrznych apriltag

Rysunek 27. AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT o identyfikatorze 42

ext marker tracking aruco

Rysunek 28. Znacznik ArUco XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT o identyfikatorze 43

Przykładowy kod

Konfigurowanie funkcji śledzenia za pomocą kodu QR

Poniższy przykładowy kod pokazuje, jak skonfigurować śledzenie za pomocą kodu QR podczas tworzenia kontekstu przestrzennego.

// Check if marker tracking capability is supported
uint32_t capabilityCount;
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, 0, &capabilityCount, nullptr));
std::vector<XrSpatialCapabilityEXT> capabilities(capabilityCount);
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, capabilityCount, &capabilityCount, capabilities.data()));

if (std::find(capabilities.begin(), capabilities.end(), XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT) == capabilities.end()) {
  return;
}

uint32_t featureCount = 0;
CHK_XR(xrEnumerateSpatialCapabilityFeaturesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT, 0, &featureCount, nullptr));
std::vector<XrSpatialCapabilityFeatureEXT> capabilityFeatures(featureCount);
CHK_XR(xrEnumerateSpatialCapabilityFeaturesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT, featureCount, &featureCount, capabilityFeatures.data()));

bool supportsFixedMarkerSize = std::find(capabilityFeatures.begin(), capabilityFeatures.end(), XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT) != capabilityFeatures.end();

// Create a spatial context
XrSpatialContextEXT spatialContext{};

// Enable the 2 guaranteed components of the qr code tracking capability
std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT,
};
XrSpatialCapabilityConfigurationQrCodeEXT markerConfiguration{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT};
markerConfiguration.capability = XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT;
markerConfiguration.enabledComponentCount = static_cast<uint32_t>(enabledComponents.size());
markerConfiguration.enabledComponents = enabledComponents.data();

// only chained if features.markerSideLength is true.
XrSpatialMarkerSizeEXT markerSize{XR_TYPE_SPATIAL_MARKER_SIZE_EXT};
markerSize.markerSideLength = 0.10f;
if (supportsFixedMarkerSize) {
  markerConfiguration.next = &markerSize;
}


std::array<XrSpatialCapabilityConfigurationBaseHeaderEXT*, 1> capabilityConfigs = {
  reinterpret_cast<XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&markerConfiguration),
};

XrSpatialContextCreateInfoEXT spatialContextCreateInfo{XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT};
spatialContextCreateInfo.capabilityConfigCount = capabilityConfigs.size();
spatialContextCreateInfo.capabilityConfigs = capabilityConfigs.data();
XrFutureEXT createContextFuture;
CHK_XR(xrCreateSpatialContextAsyncEXT(session, &spatialContextCreateInfo, &createContextFuture));

waitUntilReady(createContextFuture);

XrCreateSpatialContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};
CHK_XR(xrCreateSpatialContextCompleteEXT(session, createContextFuture, &completion));
if (completion.futureResult != XR_SUCCESS) {
  return;
}

spatialContext = completion.spatialContext;

// ...
// Discovery entities with the spatial context
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

Odkrywanie obiektów przestrzennych i wysyłanie zapytań dotyczących danych komponentów

Poniższy przykładowy kod pokazuje, jak wykrywać elementy przestrzenne w kontekście skonfigurowanym za pomocą XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT i wysyłać zapytania o dane komponentów.

XrFutureEXT future = XR_NULL_FUTURE_EXT;

// We want to look for entities that have the following components.
std::vector<XrSpatialComponentTypeEXT> snapshotComponents = {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT,
};

auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &snapshotCreateInfo, &future));

  waitUntilReady(future);

  XrCreateSpatialDiscoverySnapshotCompletionInfoEXT completionInfo{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT};
  completionInfo.baseSpace = localSpace;
  completionInfo.time = time;
  completionInfo.future = future;

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(spatialContext, &completionInfo, &completion));
  if (completion.futureResult == XR_SUCCESS) {

    // Query for the bounded2D and marker component data
    XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
    queryCond.componentTypeCount = snapshotComponents.size();
    queryCond.componentTypes = snapshotComponents.data();

    XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
    std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
    queryResult.entityIdCapacityInput = entityIds.size();
    queryResult.entityIds = entityIds.data();
    queryResult.entityStateCapacityInput = entityStates.size();
    queryResult.entityStates = entityStates.data();

    std::vector<XrSpatialBounded2DDataEXT> bounded2D(queryResult.entityIdCountOutput);
    XrSpatialComponentBounded2DListEXT bounded2DList{XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT};
    bounded2DList.boundCount = bounded2D.size();
    bounded2DList.bounds = bounded2D.data();
    queryResult.next = &bounded2DList;

    std::vector<XrSpatialMarkerDataEXT> markers;
    XrSpatialComponentMarkerListEXT markerList{XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT};
    markers.resize(queryResult.entityIdCountOutput);
    markerList.markerCount = markers.size();
    markerList.markers = markers.data();
    bounded2DList.next = &markerList;

    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      if (entityStates[i] != XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
        continue;
      }

      // 2D bounds for entity entityIds[i] is bounded2D[i].extents centered on bounded2D[i].center.

      if (markers[i].capability == XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT) {
        // Check if marker data has been decoded.
        if (markers[i].data.bufferId != XR_NULL_SPATIAL_BUFFER_ID_EXT) {
          if (markers[i].data.bufferType == XR_SPATIAL_BUFFER_TYPE_STRING_EXT) {
            // Qr Code data can be queried using
            // XrSpatialBufferGetInfoEXT getInfo{XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT};
            // info.bufferId = markers[i].data.bufferId;
            // xrGetSpatialBufferStringEXT(completion.snapshot, &getInfo, ...)
          } else if (markers[i].data.bufferType == XR_SPATIAL_BUFFER_TYPE_UINT8_EXT) {
            // Qr Code data can be queried using
            // XrSpatialBufferGetInfoEXT getInfo{XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT};
            // info.bufferId = markers[i].data.bufferId;
            // xrGetSpatialBufferUint8(completion.snapshot, &getInfo, ...)
          }
        }
      }
    }

    CHK_XR(xrDestroySpatialSnapshotEXT(completion.snapshot));
  }
};

while (1) {
  // ...
  // For every frame in frame loop
  // ...

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

  // Poll for the XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT event
  XrEventDataBuffer event = {XR_TYPE_EVENT_DATA_BUFFER};
  XrResult result = xrPollEvent(instance, &event);
  if (result == XR_SUCCESS) {
      switch (event.type) {
          case XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT: {
              const XrEventDataSpatialDiscoveryRecommendedEXT& eventdata =
                  *reinterpret_cast<XrEventDataSpatialDiscoveryRecommendedEXT*>(&event);
              // Discover spatial entities for the context that we received the "discovery
              // recommended" event for.
              discoverSpatialEntities(eventdata.spatialContext, time);
              break;
          }
      }
  }

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

Nowe struktury

Nowe wartości w polu enum

Nowe stałe wyliczeniowe

  • XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAME
  • XR_EXT_spatial_marker_tracking_SPEC_VERSION
  • Rozszerzenie XrSpatialCapabilityEXT :

    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT
    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT
    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT
    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT
  • Rozszerzenie XrSpatialCapabilityFeatureEXT :

    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT
    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT
  • Rozszerzanie XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • Rozszerzanie XrStructureType :

    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT
    • XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT
    • XR_TYPE_SPATIAL_MARKER_SIZE_EXT
    • XR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT

Historia zmian

  • Wersja 1, 29.07.2024 r. (Ron Bessems, Meta)

    • Wstępny opis rozszerzenia