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_EXTXR_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_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXTXR_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
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.capabilitymusi mieć wartośćXR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT.enabledComponentCounttouint32_tz liczbą elementów wenabledComponents.enabledComponentsto 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)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialCapabilityConfigurationQrCodeEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur . Zobacz też: XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitymusi być prawidłową wartością XrSpatialCapabilityEXT. -
enabledComponentsmusi być wskaźnikiem do tablicyenabledComponentCountprawidłowych wartości XrSpatialComponentTypeEXT. - Parametr
enabledComponentCountmusi być większy niż0.
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
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.capabilitymusi mieć wartośćXR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT.enabledComponentCounttouint32_tz liczbą elementów wenabledComponents.enabledComponentsto 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)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialCapabilityConfigurationMicroQrCodeEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur . Zobacz też: XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitymusi być prawidłową wartością XrSpatialCapabilityEXT. -
enabledComponentsmusi być wskaźnikiem do tablicyenabledComponentCountprawidłowych wartości XrSpatialComponentTypeEXT. - Parametr
enabledComponentCountmusi być większy niż0.
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
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.capabilitymusi mieć wartośćXR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT.enabledComponentCounttouint32_tz liczbą elementów wenabledComponents.enabledComponentsto wskaźnik do tablicy komponentów, które mają być włączone w przypadku tej funkcji.arUcoDictto 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)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialCapabilityConfigurationArucoMarkerEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur . Zobacz też: XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitymusi być prawidłową wartością XrSpatialCapabilityEXT. -
enabledComponentsmusi być wskaźnikiem do tablicyenabledComponentCountprawidłowych wartości XrSpatialComponentTypeEXT. -
arUcoDictmusi być prawidłową wartością XrSpatialMarkerArucoDictEXT - Parametr
enabledComponentCountmusi być większy niż0.
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
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.capabilitymusi mieć wartośćXR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT.enabledComponentCounttouint32_tz liczbą elementów wenabledComponents.enabledComponentsto wskaźnik do tablicy komponentów, które mają być włączone w przypadku tej funkcji.aprilDictto 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)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialCapabilityConfigurationAprilTagEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur . Zobacz też: XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitymusi być prawidłową wartością XrSpatialCapabilityEXT. -
enabledComponentsmusi być wskaźnikiem do tablicyenabledComponentCountprawidłowych wartości XrSpatialComponentTypeEXT. -
aprilDictmusi być prawidłową wartością XrSpatialMarkerAprilTagDictEXT - Parametr
enabledComponentCountmusi być większy niż0.
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
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.markerSideLengthto 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)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialMarkerSizeEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_MARKER_SIZE_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur.
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
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.optimizeForStaticMarkerwskazuje, 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)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialMarkerStaticOptimizationEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur.
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_EXTXR_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
capabilityto element XrSpatialCapabilityEXT, który wykrył marker.markerIdto 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.datato identyfikator bufora i rodzaj dodatkowych informacji zawartych w znaczniku.
Atrybuty 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 symboli:
- Jeśli środowisko wykonawcze prawidłowo zdekodowało dane znacznika, musi ustawić typ bufora
datanaXR_SPATIAL_BUFFER_TYPE_UINT8_EXTlubXR_SPATIAL_BUFFER_TYPE_STRING_EXTw zależności od danych w znaczniku. Środowisko wykonawcze musi też ustawić prawidłowy identyfikator bufora wdata, 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
datana XR_NULL_SPATIAL_BUFFER_ID_EXT, a typ bufora naXR_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 (domyślne)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialMarkerDataEXT. -
capabilitymusi być prawidłową wartością XrSpatialCapabilityEXT. -
datamusi być prawidłową strukturą XrSpatialBufferEXT
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
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowej specyfikacji OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.markerCountto liczba elementów w elemenciemarkers.markersto 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_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 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)
- Rozszerzenie
XR_EXT_spatial_marker_trackingmusi być włączone przed użyciem XrSpatialComponentMarkerListEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur. -
markersmusi być wskaźnikiem tablicy strukturmarkerCountXrSpatialMarkerDataEXT. - Parametr
markerCountmusi być większy niż0.
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.
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.
Rysunek 26. Kod QR z tekstem „OpenXR”
Rysunek 27. AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT o identyfikatorze 42
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
- XrSpatialCapabilityConfigurationAprilTagEXT
- XrSpatialCapabilityConfigurationArucoMarkerEXT
- XrSpatialCapabilityConfigurationMicroQrCodeEXT
- XrSpatialCapabilityConfigurationQrCodeEXT
- XrSpatialMarkerDataEXT
Rozszerzenie XrSpatialCapabilityConfigurationArucoMarkerEXT , XrSpatialCapabilityConfigurationAprilTagEXT , XrSpatialCapabilityConfigurationQrCodeEXT , XrSpatialCapabilityConfigurationMicroQrCodeEXT :
Rozszerzanie XrSpatialComponentDataQueryResultEXT :
Nowe wartości w polu enum
Nowe stałe wyliczeniowe
XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAMEXR_EXT_spatial_marker_tracking_SPEC_VERSIONRozszerzenie XrSpatialCapabilityEXT :
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT
Rozszerzenie XrSpatialCapabilityFeatureEXT :
XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXTXR_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_EXTXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXTXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXTXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXTXR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXTXR_TYPE_SPATIAL_MARKER_SIZE_EXTXR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT
Historia zmian
Wersja 1, 29.07.2024 r. (Ron Bessems, Meta)
- Wstępny opis rozszerzenia