XR_EXT_spatial_marker_tracking
Name String
XR_EXT_spatial_marker_tracking
擴充功能類型
執行個體擴充功能
擴充功能註冊編號
744
修訂版本
1
批准狀態
已批准
擴充功能和版本依附元件
XR_EXT_spatial_entity
著作人
Ron Bessems,Meta
Nihav Jain,Google
Natalie Fleury,Meta
Yuichi Taguchi,Meta
Yin Li,Microsoft
Jimmy Alamparambil,ByteDance
Zhipeng Liu,ByteDance
Jun Yan,ByteDance
總覽
這項擴充功能以 XR_EXT_spatial_entity 為基礎,可讓應用程式偵測及追蹤環境中的標記。標記是 2D 代碼,可能包含 QR code、Micro 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 時,執行階段必須在 XrSpatialContextCreateInfoEXT :: capabilityConfigs 中傳遞 XrSpatialCapabilityConfigurationQrCodeEXT 結構,啟用 QR code 追蹤功能。
如果 xrEnumerateSpatialCapabilitiesEXT 未列舉 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT,執行階段「必須」傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。
有效用途 (隱含)
- 必須先啟用
XR_EXT_spatial_marker_tracking擴充功能,才能使用 XrSpatialCapabilityConfigurationQrCodeEXT -
type「必須」為XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT -
next「必須」為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是指向元件陣列的指標,用於啟用這項功能。
如果支援微型 QR code,當呼叫 xrCreateSpatialContextAsyncEXT 時,XrSpatialContextCreateInfoEXT :: capabilityConfigs 傳入 XrSpatialCapabilityConfigurationMicroQrCodeEXT 結構,執行階段必須啟用微型 QR code 追蹤功能。
如果 xrEnumerateSpatialCapabilitiesEXT 未列舉 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT,執行階段「必須」傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。
有效用途 (隱含)
- 必須先啟用
XR_EXT_spatial_marker_tracking擴充功能,才能使用 XrSpatialCapabilityConfigurationMicroQrCodeEXT -
type「必須」為XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT -
next「必須」為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 標記追蹤。
如果 XrSpatialContextCreateInfoEXT :: capabilityConfigs 中有 XrSpatialCapabilityConfigurationArucoMarkerEXT 結構,但 xrEnumerateSpatialCapabilitiesEXT 未列舉 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT,則執行階段必須從 xrCreateSpatialContextAsyncEXT 傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。
有效用途 (隱含)
- 必須先啟用
XR_EXT_spatial_marker_tracking擴充功能,才能使用 XrSpatialCapabilityConfigurationArucoMarkerEXT -
type「必須」為XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT -
next「必須」為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:5x5 像素 Aruco 標記字典,包含 250 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT:5x5 像素 Aruco 標記字典,含 1000 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT:6x6 像素 Aruco 標記字典,包含 50 個 ID。XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT:6x6 像素 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:7x7 像素 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 追蹤。
如果 XrSpatialContextCreateInfoEXT :: capabilityConfigs 中有 XrSpatialCapabilityConfigurationAprilTagEXT 結構,但 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 -
next「必須」為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:4x4 位元,任兩個代碼之間的最小漢明距離 = 5,30 個代碼。XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT:5x5 位元,任兩個代碼之間的最短漢明距離 = 9,35 個代碼。XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT:6x6 位元,任兩個代碼之間的最小漢明距離 = 10,2320 個代碼。XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT:6x6 位元,任兩個代碼之間的最小漢明距離 = 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 鏈結。
有效用途 (隱含)
- 必須先啟用
XR_EXT_spatial_marker_tracking擴充功能,才能使用 XrSpatialMarkerSizeEXT -
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 鏈結。
有效用途 (隱含)
- 必須先啟用
XR_EXT_spatial_marker_tracking擴充功能,才能使用 XrSpatialMarkerStaticOptimizationEXT -
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*函式使用該 ID 來取得資料。 - 如果執行階段尚未解碼標記資料,則必須將
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。
有效用途 (隱含)
- 必須先啟用
XR_EXT_spatial_marker_tracking擴充功能,才能使用 XrSpatialComponentMarkerListEXT -
type「必須」為XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT -
next「必須」為NULL,或指向結構鏈中下一個結構的有效指標 -
markers「必須」是指向markerCountXrSpatialMarkerDataEXT 結構陣列的指標 -
markerCount參數必須大於0
設定
如果 XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT 在 XrSpatialCapabilityComponentTypesEXT :: componentTypes 中列舉了某項功能,應用程式可以啟用該功能,方法是將列舉值加入 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 清單中,該清單位於支援此元件的功能的 XrSpatialCapabilityConfigurationBaseHeaderEXT 衍生結構中。
這個元件不需要任何特殊設定,即可納入 XrSpatialCapabilityConfigurationBaseHeaderEXT :: next 鏈結。
有界 2D 元件
有界限的 2D 元件會提供標記的中心和範圍,由標記所在的實體表示。如要進一步瞭解有界 2D 元件,請參閱「有界 2D」。
XrSpatialBounded2DDataEXT :: center「必須」指向標記中心。查看標記正面時,X 軸「必須」指向右側,Y 軸「必須」指向標記頂端。執行階段必須遵循右手座標系統慣例,因此 Z 軸會從標記的前面延伸出來。也就是說,如果標記的位置為 {0, 0, 0}、旋轉角度為 {0, 0, 0, 1} (不旋轉),且範圍為 {1, 1},則代表 1 公尺 x 1 公尺的標記,中心點為 {0, 0, 0},正面法向量指向元件空間中的 +Z 方向。
下圖顯示標記的方向。
圖 25. 有軸線的 QR code 標記
測試代碼
下列代碼的 X-Y 平面必須位於文件內,且 Z 軸指向檢視者。軸原點必須顯示在每個標記的中心。X 軸必須指向右側,Y 軸必須指向文件頂端。
圖 26. QR code,內含文字「OpenXR」
圖 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
-
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)
- 初始擴充功能說明