XR_EXT_spatial_marker_tracking

Name String

XR_EXT_spatial_marker_tracking

Typ rozszerzenia

Rozszerzenie instancji

Zarejestrowany numer wewnętrzny

744

Wersja

1

Stan ratyfikacji

Ratified

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 bazuje na XR_EXT_spatial_entity i umożliwia aplikacjom wykrywanie i śledzenie znaczników w ich środowisku. Znaczniki to kody 2D, które mogą obejmować kody QR, kody Micro QR, znaczniki ArUco lub AprilTag.

Śledzony znacznik jest reprezentowany jako encja przestrzenna z tymi komponentami:

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

Obsługa środowiska wykonawczego

Środowisko wykonawcze musi informować o obsłudze różnych funkcji śledzenia znaczników za pomocą 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 xrCreateSpatialContextAsyncEXT .

Konfiguracje typów znaczników

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 być 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ą zostać włączone dla tej funkcji.

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

Środowisko wykonawcze musi zwracać XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT, jeśli XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT nie jest wyliczany przez xrEnumerateSpatialCapabilitiesEXT .

Prawidłowe użycie (pośrednie)

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 być 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ą zostać włączone dla 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 xrCreateSpatialContextAsyncEXT .

Środowisko wykonawcze musi zwracać XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT, jeśli XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT nie jest wyliczany przez xrEnumerateSpatialCapabilitiesEXT .

Prawidłowe użycie (pośrednie)

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 być 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ą zostać włączone dla 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 xrCreateSpatialContextAsyncEXT .

Środowisko wykonawcze musi zwracać XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT z 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 (pośrednie)

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 wstępnie zdefiniowany słownik ArUco:

Opisy elementów wyliczenia

  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT – słownik znaczników ArUco 4 x 4 piksele z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT – słownik znaczników Aruco o wymiarach 4 x 4 piksele ze 100 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT – słownik znaczników ArUco 4 x 4 piksele z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT – słownik znaczników ArUco o wymiarach 4 x 4 piksele z 1000 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT – słownik znaczników Aruco o wymiarach 5 x 5 pikseli z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT – słownik znaczników ArUco o wymiarach 5 x 5 pikseli ze 100 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT – słownik znaczników Aruco o wymiarach 5 x 5 pikseli z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT – słownik znaczników Aruco o wymiarach 5 x 5 pikseli z 1000 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT – słownik znaczników Aruco 6 x 6 pikseli z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT – słownik znaczników ArUco o wymiarach 6 x 6 pikseli ze 100 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT – słownik znaczników ArUco o wymiarach 6 x 6 pikseli z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT – słownik znaczników Aruco o wymiarach 6 x 6 pikseli z 1000 identyfikatorów.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT – słownik znaczników Aruco o wymiarach 7 x 7 pikseli z 50 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT – słownik znaczników Aruco o wymiarach 7 x 7 pikseli ze 100 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT – słownik znaczników Aruco o wymiarach 7 x 7 pikseli z 250 identyfikatorami.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT – słownik znaczników Aruco o wymiarach 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 być 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ą zostać włączone dla tej funkcji.
  • aprilDict to słownik znaczników do wykrycia.

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

Środowisko wykonawcze musi zwracać XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT z 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 (pośrednie)

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 x 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 x 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 x 6 bitów, minimalna odległość Hamminga między dowolnymi 2 kodami = 11, 587 kodów.

Opcjonalne konfiguracje znaczników

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

Pełną listę wszystkich funkcji związanych z przestrzenią obsługiwanych przez dowolne rozszerzenie znajdziesz w artykule 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 xrEnumerateSpatialCapabilityFeaturesEXT dla określonej funkcji i jeśli aplikacja łączy XrSpatialMarkerSizeEXT z odpowiednią strukturą konfiguracji tej funkcji, środowisko wykonawcze musi założyć, że wszystkie wykryte znaczniki mają szerokość i wysokość markerSideLength . Dzięki tym informacjom środowisko wykonawcze może zwrócić dokładniejszą pozycję i rozmiar. Ta struktura musi być połączona z łańcuchem next XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT lub XrSpatialCapabilityConfigurationAprilTagEXT .

Prawidłowe użycie (pośrednie)

Optymalizacja znaczników statycznych

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 znaczniki w przestrzeni nie powinny się poruszać.

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

Prawidłowe użycie (pośrednie)

Komponenty gwarantowane

Ś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 xrEnumerateSpatialCapabilityComponentTypesEXT :

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

Komponent Marker

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 XrSpatialCapabilityEXT, który wykrył znacznik.
  • markerId to zakodowany identyfikator z znacznika. 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ść 0.
  • data to identyfikator bufora i typ dodatkowych informacji zawartych w znaczniku.

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT i XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT obsługują dodatkowe dane. Jeśli capability jest jednym z tych:

  • Jeśli środowisko wykonawcze pomyślnie 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żyć z odpowiednią funkcją xrGetSpatialBuffer*, aby pobrać dane.
  • 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_EXT i XR_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 (pośrednie)

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 podstawowym interfejsie OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.
  • markerCount to liczba elementów w elemencie markers.
  • markers to tablica obiektów XrSpatialMarkerDataEXT .

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

Środowisko wykonawcze musi zwracać XR_ERROR_VALIDATION_FAILURE z 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 xrQuerySpatialComponentDataEXT, jeśli markerCount jest mniejsze niż XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

Prawidłowe użycie (pośrednie)

Konfiguracja

Jeśli XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT jest wymieniony w XrSpatialCapabilityComponentTypesEXT :: componentTypes dla danej funkcji, aplikacja może go włączyć, dodając element wyliczeniowy do listy XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents struktury pochodnej XrSpatialCapabilityConfigurationBaseHeaderEXT funkcji, która obsługuje ten komponent.

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

Ograniczony komponent 2D

Komponent ograniczony 2D podaje środek i zakres znacznika reprezentowanego przez element, na którym się znajduje. Więcej informacji o komponencie ograniczonym 2D znajdziesz w sekcji Ograniczony 2D.

XrSpatialBounded2DDataEXT :: center musi wskazywać środek znacznika. Gdy patrzysz na przednią stronę znacznika, oś X musi wskazywać w prawo, a oś Y musi wskazywać górę znacznika. Środowisko wykonawcze musi być zgodne z konwencją prawoskrętnego układu współrzędnych, więc oś Z wychodzi z przedniej strony znacznika. Oznacza to, że znacznik o pozycji {0, 0, 0}, obrocie {0, 0, 0, 1} (brak obrotu) i rozmiarze {1, 1} odnosi się do znacznika o wymiarach 1 m x 1 m wyśrodkowanego w punkcie {0, 0, 0} z wektorem normalnym przedniej powierzchni skierowanym w kierunku +Z w przestrzeni komponentu.

Poniżej pokazujemy, jak wygląda orientacja znacznika.

xr ml marker understanding axis

Rysunek 25. Znacznik kodu QR z osią

Kody testowe

Płaszczyzna X-Y poniższych kodów musi znajdować się wewnątrz dokumentu, a oś Z musi być skierowana w stronę czytelnika. Początek osi musi znajdować się w ś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”

ext marker tracking 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ć funkcję śledzenia 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 elementów przestrzennych i wykonywanie zapytań o dane 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 wykonywać zapytania dotyczące danych komponentu.

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 domy

Nowe wartości w polu enum

Nowe stałe typu wyliczeniowego

  • 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
  • Rozszerzenie 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 lipca 2024 r. (Ron Bessems, Meta)

    • Początkowy opis rozszerzenia