XR_EXT_spatial_marker_tracking
名稱字串
XR_EXT_spatial_marker_tracking
擴充功能類型
執行個體擴充功能
擴充功能註冊編號
744
修訂版本
1
批准狀態
批准
擴充功能和版本依附元件
XR_EXT_spatial_entity
著作人
Ron Bessems (Meta)
Nihav Jain (Google)
Natalie Fleury (Meta)
田口雄一 (Meta)
Yin Li (Microsoft)
Jimmy Alamparambil (ByteDance)
Zhipeng Liu (ByteDance)
Jun Yan (ByteDance)
總覽
這項擴充功能以 XR_EXT_spatial_entity 為基礎,可讓應用程式偵測及追蹤環境中的標記。標記是 2D 碼,可能包含 QR code、微型 QR code、ArUco 標記或 AprilTag。
追蹤的標記會以空間實體表示,並具有下列元件:
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXTXR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT
執行階段支援
執行階段必須使用 xrEnumerateSpatialCapabilitiesEXT 列出下列任一功能,宣傳其支援各種標記追蹤功能:
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
設定
如要啟用標記類型偵測功能,應用程式必須將對應的設定結構體傳遞至 xrCreateSpatialContextAsyncEXT。
標記類型設定
QR code
XrSpatialCapabilityConfigurationQrCodeEXT 結構定義如下:
typedef struct XrSpatialCapabilityConfigurationQrCodeEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationQrCodeEXT;
成員說明
type是這個結構的 XrStructureType。next是NULL,或是結構鏈中下一個結構的指標。capability必須為XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT。enabledComponentCount是uint32_t,其中包含enabledComponents中的元素數量。enabledComponents是指向要為這項功能啟用的元件陣列指標。
如果支援 QR code,當呼叫 xrCreateSpatialContextAsyncEXT 時,如果將 XrSpatialCapabilityConfigurationQrCodeEXT 結構體傳遞至 XrSpatialContextCreateInfoEXT :: capabilityConfigs,執行階段必須啟用 QR code 追蹤功能。
如果 xrEnumerateSpatialCapabilitiesEXT 未列舉 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT,執行階段必須傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。
有效使用 (隱含)
- 使用 XrSpatialCapabilityConfigurationQrCodeEXT 前,
XR_EXT_spatial_marker_tracking擴充功能必須啟用 -
type必須為XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT -
nextmust 為NULL,或指向結構體鏈結中下一個結構體的有效指標。另請參閱:XrSpatialMarkerSizeEXT、XrSpatialMarkerStaticOptimizationEXT -
capability必須是有效的 XrSpatialCapabilityEXT 值 -
enabledComponents必須是指向enabledComponentCount個有效 XrSpatialComponentTypeEXT 值的陣列的指標 -
enabledComponentCount參數必須大於0
微型 QR code
XrSpatialCapabilityConfigurationMicroQrCodeEXT 結構定義如下:
typedef struct XrSpatialCapabilityConfigurationMicroQrCodeEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationMicroQrCodeEXT;
成員說明
type是這個結構的 XrStructureType。next是NULL,或是結構鏈中下一個結構的指標。capability必須為XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT。enabledComponentCount是uint32_t,其中包含enabledComponents中的元素數量。enabledComponents是指向要為這項功能啟用的元件陣列指標。
如果支援 Micro QR code,當 XrSpatialCapabilityConfigurationMicroQrCodeEXT 結構體在呼叫 xrCreateSpatialContextAsyncEXT 時傳遞至 XrSpatialContextCreateInfoEXT :: capabilityConfigs,執行階段必須啟用 Micro QR code 追蹤功能。
如果 xrEnumerateSpatialCapabilitiesEXT 未列舉 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT,執行階段必須傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。
有效使用 (隱含)
- 使用 XrSpatialCapabilityConfigurationMicroQrCodeEXT 前,
XR_EXT_spatial_marker_tracking擴充功能必須啟用 -
type必須為XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT -
nextmust 為NULL,或指向結構體鏈結中下一個結構體的有效指標。另請參閱:XrSpatialMarkerSizeEXT、XrSpatialMarkerStaticOptimizationEXT -
capability必須是有效的 XrSpatialCapabilityEXT 值 -
enabledComponents必須是指向enabledComponentCount個有效 XrSpatialComponentTypeEXT 值的陣列的指標 -
enabledComponentCount參數必須大於0
ArUco 標記
XrSpatialCapabilityConfigurationArucoMarkerEXT 結構定義如下:
typedef struct XrSpatialCapabilityConfigurationArucoMarkerEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
XrSpatialMarkerArucoDictEXT arUcoDict;
} XrSpatialCapabilityConfigurationArucoMarkerEXT;
成員說明
type是這個結構的 XrStructureType。next是NULL,或是結構鏈中下一個結構的指標。capability必須為XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT。enabledComponentCount是uint32_t,其中包含enabledComponents中的元素數量。enabledComponents是指向要為這項功能啟用的元件陣列指標。arUcoDict是要偵測的標記字典。
如果支援 ArUco 標記,當呼叫 xrCreateSpatialContextAsyncEXT 時,如果 XrSpatialCapabilityConfigurationArucoMarkerEXT 結構體傳遞至 XrSpatialContextCreateInfoEXT :: capabilityConfigs,執行階段必須啟用 ArUco 標記追蹤功能。
如果 XrSpatialCapabilityConfigurationArucoMarkerEXT 結構位於 XrSpatialContextCreateInfoEXT :: capabilityConfigs 中,但 xrEnumerateSpatialCapabilitiesEXT 未列舉 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT,則執行階段必須從 xrCreateSpatialContextAsyncEXT 傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。
有效使用 (隱含)
- 使用 XrSpatialCapabilityConfigurationArucoMarkerEXT 前,
XR_EXT_spatial_marker_tracking擴充功能必須啟用 -
type必須為XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT -
nextmust 為NULL,或指向結構體鏈結中下一個結構體的有效指標。另請參閱:XrSpatialMarkerSizeEXT、XrSpatialMarkerStaticOptimizationEXT -
capability必須是有效的 XrSpatialCapabilityEXT 值 -
enabledComponents必須是指向enabledComponentCount個有效 XrSpatialComponentTypeEXT 值的陣列的指標 -
arUcoDict必須是有效的 XrSpatialMarkerArucoDictEXT 值 -
enabledComponentCount參數必須大於0
XrSpatialMarkerArucoDictEXT 列舉定義如下:
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;
支援的預先定義 ArUco 字典:
列舉值說明
XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT- 4x4 像素 Aruco 標記字典,具有 50 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT- 4x4 像素的 Aruco 標記字典,具有 100 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT- 4x4 像素的 Aruco 標記字典,具有 250 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT- 4x4 像素 Aruco 標記字典,具有 1000 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT— 5x5 像素的 Aruco 標記字典,具有 50 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT- 5x5 像素 Aruco 標記字典,具有 100 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT— 5 x 5 像素的 Aruco 標記字典,具有 250 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT- 5 x 5 像素 Aruco 標記字典,具有 1000 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT- 6x6 像素的 Aruco 標記字典,內含 50 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT- 6 x 6 像素的 Aruco 標記字典,內含 100 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT- 6x6 像素的 Aruco 標記字典,內含 250 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT- 6x6 像素的 Aruco 標記字典,具有 1000 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT- 7 x 7 像素的 Aruco 標記字典,內含 50 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT- 7x7 像素的 Aruco 標記字典,具有 100 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT- 7x7 像素的 Aruco 標記字典,內含 250 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT- 7x7 像素的 Aruco 標記字典,具有 1000 個 ID。
AprilTag
XrSpatialCapabilityConfigurationAprilTagEXT 結構定義如下:
typedef struct XrSpatialCapabilityConfigurationAprilTagEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
XrSpatialMarkerAprilTagDictEXT aprilDict;
} XrSpatialCapabilityConfigurationAprilTagEXT;
成員說明
type是這個結構的 XrStructureType。next是NULL,或是結構鏈中下一個結構的指標。capability必須為XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT。enabledComponentCount是uint32_t,其中包含enabledComponents中的元素數量。enabledComponents是指向要為這項功能啟用的元件陣列指標。aprilDict是要偵測的標記字典。
如果支援 AprilTag,當呼叫 xrCreateSpatialContextAsyncEXT 時,如果 XrSpatialCapabilityConfigurationAprilTagEXT 結構體傳遞至 XrSpatialContextCreateInfoEXT :: capabilityConfigs,執行階段「必須」啟用 AprilTag 追蹤。
如果 XrSpatialCapabilityConfigurationAprilTagEXT 結構位於 XrSpatialContextCreateInfoEXT :: capabilityConfigs 中,但 xrEnumerateSpatialCapabilitiesEXT 未列舉 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT,則執行階段必須從 xrCreateSpatialContextAsyncEXT 傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。
有效使用 (隱含)
-
XR_EXT_spatial_marker_tracking擴充功能必須先啟用,才能使用 XrSpatialCapabilityConfigurationAprilTagEXT -
type必須為XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT -
nextmust 為NULL,或指向結構體鏈結中下一個結構體的有效指標。另請參閱:XrSpatialMarkerSizeEXT、XrSpatialMarkerStaticOptimizationEXT -
capability必須是有效的 XrSpatialCapabilityEXT 值 -
enabledComponents必須是指向enabledComponentCount個有效 XrSpatialComponentTypeEXT 值的陣列的指標 -
aprilDict必須是有效的 XrSpatialMarkerAprilTagDictEXT 值 -
enabledComponentCount參數必須大於0
XrSpatialMarkerAprilTagDictEXT 列舉定義如下:
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;
支援的預先定義 AprilTag 字典:
列舉值說明
XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT- 4 x 4 位元,任意兩個代碼間的最小漢明距離 = 5,30 個代碼。XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT- 5 x 5 位元,任意兩個代碼間的最小漢明距離 = 9,35 個代碼。XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT- 6 x 6 位元,任意兩個代碼間的最小漢明距離 = 10,2320 個代碼。XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT- 6 x 6 位元,任意兩個代碼間的最小漢明距離 = 11,587 個代碼。
選用標記設定
應用程式「應」呼叫 xrEnumerateSpatialCapabilityFeaturesEXT,取得支援的選用功能清單。
如需擴充功能支援的所有空間功能完整清單,請參閱 XrSpatialCapabilityFeatureEXT。
標記大小
XrSpatialMarkerSizeEXT 結構體的定義如下:
typedef struct XrSpatialMarkerSizeEXT {
XrStructureType type;
const void* next;
float markerSideLength;
} XrSpatialMarkerSizeEXT;
成員說明
type是這個結構的 XrStructureType。next是NULL,或是結構鏈中下一個結構的指標。markerSideLength是所有標記的大小 (以公尺為單位)。
如果 XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT 是由特定功能的 xrEnumerateSpatialCapabilityFeaturesEXT 列舉,且應用程式將 XrSpatialMarkerSizeEXT 鏈結至該功能的對應設定結構,則執行階段必須假設偵測到的所有標記寬度和高度皆為 markerSideLength。將這項資訊提供給執行階段,可讓執行階段傳回更準確的姿勢和大小。這個結構必須連結至 XrSpatialCapabilityConfigurationQrCodeEXT、XrSpatialCapabilityConfigurationMicroQrCodeEXT、XrSpatialCapabilityConfigurationArucoMarkerEXT 或 XrSpatialCapabilityConfigurationAprilTagEXT 的 next 鏈結。
有效使用 (隱含)
- 使用 XrSpatialMarkerSizeEXT 前,
XR_EXT_spatial_marker_tracking擴充功能必須啟用 -
type必須為XR_TYPE_SPATIAL_MARKER_SIZE_EXT -
next必須是NULL,或是結構體鏈結中下一個結構體的有效指標
靜態標記最佳化
XrSpatialMarkerStaticOptimizationEXT 結構定義如下:
typedef struct XrSpatialMarkerStaticOptimizationEXT {
XrStructureType type;
const void* next;
XrBool32 optimizeForStaticMarker;
} XrSpatialMarkerStaticOptimizationEXT;
成員說明
type是這個結構的 XrStructureType。next是NULL,或是結構鏈中下一個結構的指標。optimizeForStaticMarker表示空間中的所有標記都不會移動。
如果 XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT 是由 xrEnumerateSpatialCapabilityFeaturesEXT 為特定功能列舉,且應用程式將 XrSpatialMarkerStaticOptimizationEXT 鏈結至該功能的對應設定結構,則如果 optimizeForStaticMarker 設為 XR_TRUE,執行階段必須假設偵測到的所有標記都是靜態。這樣一來,執行階段就能生成更準確的姿勢和大小。這個結構必須連結至 XrSpatialCapabilityConfigurationQrCodeEXT、XrSpatialCapabilityConfigurationMicroQrCodeEXT、XrSpatialCapabilityConfigurationArucoMarkerEXT 或 XrSpatialCapabilityConfigurationAprilTagEXT 的 next 鏈結。
有效使用 (隱含)
- 使用 XrSpatialMarkerStaticOptimizationEXT 前,
XR_EXT_spatial_marker_tracking擴充功能必須啟用 -
type必須為XR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT -
next必須是NULL,或是結構體鏈結中下一個結構體的有效指標
保證元件
支援 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 的執行階段必須提供下列空間元件,做為這些功能所探索到所有實體的保證元件,且必須在 xrEnumerateSpatialCapabilityComponentTypesEXT 中列舉這些元件:
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXTXR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT
標記元件
元件資料
XrSpatialMarkerDataEXT 結構體的定義如下:
typedef struct XrSpatialMarkerDataEXT {
XrSpatialCapabilityEXT capability;
uint32_t markerId;
XrSpatialBufferEXT data;
} XrSpatialMarkerDataEXT;
成員說明
capability是偵測到標記的 XrSpatialCapabilityEXT。markerId是標記中的編碼 ID。如果是 ArUco 標記和 AprilTag,這個欄位必須有效,且填入編碼 ID。如果是 QR code,這個欄位必須為零。data是緩衝區 ID,以及標記中包含的其他資訊類型。
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT 和 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT 支援額外資料,如果 capability 是下列其中一項:
- 如果執行階段已成功解碼標記的資料,則必須根據標記中的資料,將
data緩衝區類型設為XR_SPATIAL_BUFFER_TYPE_UINT8_EXT或XR_SPATIAL_BUFFER_TYPE_STRING_EXT。執行階段必須在data中設定有效的緩衝區 ID,應用程式可以使用適當的xrGetSpatialBuffer*函式取得資料。 - 如果執行階段尚未解碼標記的資料,則必須將
data緩衝區 ID 設為 XR_NULL_SPATIAL_BUFFER_ID_EXT,並將緩衝區類型設為XR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT。
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT 和 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT 不支援額外資料,且執行階段必須將 data 的緩衝區 ID 設為 XR_NULL_SPATIAL_BUFFER_ID_EXT。
有效使用 (隱含)
- 必須先啟用
XR_EXT_spatial_marker_tracking擴充功能,才能使用 XrSpatialMarkerDataEXT -
capability必須是有效的 XrSpatialCapabilityEXT 值 -
data必須是有效的 XrSpatialBufferEXT 結構
查詢資料的元件清單結構
XrSpatialComponentMarkerListEXT 結構定義如下:
typedef struct XrSpatialComponentMarkerListEXT {
XrStructureType type;
void* next;
uint32_t markerCount;
XrSpatialMarkerDataEXT* markers;
} XrSpatialComponentMarkerListEXT;
成員說明
type是這個結構的 XrStructureType。next是NULL,或是指向結構鏈中下一個結構的指標。核心 OpenXR 或這個擴充功能中未定義這類結構。markerCount是markers成員中的元素數量。markers是 XrSpatialMarkerDataEXT 的陣列。
應用程式可以在 XrSpatialSnapshotEXT 中查詢空間實體的標記元件,方法是在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中新增 XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT,並將 XrSpatialComponentMarkerListEXT 新增至 XrSpatialComponentDataQueryResultEXT 的下一個指標鏈。
如果 XrSpatialComponentMarkerListEXT 位於 XrSpatialComponentDataQueryResultEXT 的下一個鏈結中 (next),但 XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT 未納入 XrSpatialComponentDataQueryConditionEXT (componentTypes),則執行階段「必須」從 xrQuerySpatialComponentDataEXT 傳回 XR_ERROR_VALIDATION_FAILURE。
如果 markerCount 小於 XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput,執行階段必須從 xrQuerySpatialComponentDataEXT 傳回 XR_ERROR_SIZE_INSUFFICIENT。
有效使用 (隱含)
- 使用 XrSpatialComponentMarkerListEXT 前,
XR_EXT_spatial_marker_tracking擴充功能必須啟用 -
type必須為XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT -
next必須是NULL,或是結構體鏈結中下一個結構體的有效指標 -
markers必須是指向markerCountXrSpatialMarkerDataEXT 結構陣列的指標 -
markerCount參數必須大於0
設定
如果 XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT 列舉於 XrSpatialCapabilityComponentTypesEXT :: componentTypes 的某項功能中,應用程式可以在支援此元件的功能的 XrSpatialCapabilityConfigurationBaseHeaderEXT 衍生結構體中,將列舉值納入 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 清單,藉此啟用該功能。
如要將這個元件納入 XrSpatialCapabilityConfigurationBaseHeaderEXT :: next 鏈結,不需要進行任何特殊設定。
有界 2D 元件
有界 2D 元件提供標記的中心和範圍,該標記由其所在的實體代表。如要進一步瞭解有界 2D 元件,請參閱這篇文章。
XrSpatialBounded2DDataEXT :: center must 指向標記的中心。查看標記正面時,X 軸必須指向右側,Y 軸必須指向標記頂端。執行階段必須遵循右手座標系統慣例,因此 Z 軸會從標記的前表面伸出。也就是說,位置為 {0, 0, 0}、旋轉為 {0, 0, 0, 1} (無旋轉),且範圍為 {1, 1} 的標記,是指以 {0, 0, 0} 為中心、正面法線向量指向元件空間中 +Z 方向的 1 公尺 x 1 公尺標記。
標記方向的表示方式如下所示。
圖 25. 附有軸的 QR code 標記
測試代碼
下列程式碼必須在文件中具有 X-Y 平面,且 Z 軸指向檢視者。軸原點必須顯示在每個標記的中心。X 軸必須指向右側,Y 軸必須指向文件頂端。
圖 26. 顯示「OpenXR」文字的 QR code
圖 27. ID 為 42 的 AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT
圖 28. ID 為 43 的 ArUco 標記 XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT
範例程式碼
設定 QR code 追蹤功能
下列程式碼範例說明如何建立空間環境時,設定 QR code 追蹤功能。
// 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));
探索空間實體和查詢元件資料
下列程式碼範例說明如何探索以 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT 設定的環境空間實體,並查詢其元件資料。
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
// ...
}
新結構
- XrSpatialCapabilityConfigurationAprilTagEXT
- XrSpatialCapabilityConfigurationArucoMarkerEXT
- XrSpatialCapabilityConfigurationMicroQrCodeEXT
- XrSpatialCapabilityConfigurationQrCodeEXT
- XrSpatialMarkerDataEXT
擴充 XrSpatialCapabilityConfigurationArucoMarkerEXT、XrSpatialCapabilityConfigurationAprilTagEXT、XrSpatialCapabilityConfigurationQrCodeEXT、XrSpatialCapabilityConfigurationMicroQrCodeEXT:
新列舉
新增列舉常數
XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAMEXR_EXT_spatial_marker_tracking_SPEC_VERSION-
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
擴充 XrSpatialCapabilityFeatureEXT:
XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXTXR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT
正在擴充 XrSpatialComponentTypeEXT:
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
擴充 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
版本記錄
修訂版本 1,2024-07-29 (Ron Bessems,Meta)
- 擴充功能初始說明