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 และช่วยให้แอปพลิเคชันตรวจจับและติดตามเครื่องหมายในสภาพแวดล้อมได้ เครื่องหมายคือโค้ด 2 มิติซึ่งอาจรวมถึงคิวอาร์โค้ด, ไมโครคิวอาร์โค้ด, เครื่องหมาย ArUco หรือ AprilTag

เครื่องหมายที่ติดตามจะแสดงเป็นเอนทิตีเชิงพื้นที่ที่มี (หรือ "ซึ่งมี") คอมโพเนนต์ต่อไปนี้

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

การรองรับรันไทม์

รันไทม์ต้องโฆษณาการรองรับความสามารถในการติดตามเครื่องหมายต่างๆ โดยใช้ xrEnumerateSpatialCapabilitiesEXT ด้วยการแสดงรายการความสามารถต่อไปนี้

  • 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

การกำหนดค่า

หากต้องการเปิดใช้การตรวจจับประเภทตัวทำเครื่องหมาย แอปพลิเคชันต้องส่งโครงสร้างการกำหนดค่าที่เกี่ยวข้องไปยัง xrCreateSpatialContextAsyncEXT

การกำหนดค่าประเภทเครื่องหมาย

คิวอาร์โค้ด

โครงสร้าง 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 เป็นตัวชี้ไปยังอาร์เรย์ของคอมโพเนนต์ที่จะเปิดใช้สำหรับความสามารถนี้

หากรองรับคิวอาร์โค้ด รันไทม์ต้องเปิดใช้การติดตามคิวอาร์โค้ดเมื่อมีการส่งโครงสร้าง XrSpatialCapabilityConfigurationQrCodeEXT ใน XrSpatialContextCreateInfoEXT :: capabilityConfigs เมื่อเรียกใช้ xrCreateSpatialContextAsyncEXT

รันไทม์ต้องแสดงผล XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT หาก XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT ไม่ได้ระบุโดย xrEnumerateSpatialCapabilitiesEXT

การใช้งานที่ถูกต้อง (โดยนัย)

คิวอาร์โค้ดขนาดเล็ก

โครงสร้าง 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 รันไทม์ต้องเปิดใช้การติดตาม Micro QR Code เมื่อส่งโครงสร้าง XrSpatialCapabilityConfigurationMicroQrCodeEXT ใน XrSpatialContextCreateInfoEXT :: capabilityConfigs เมื่อเรียกใช้ xrCreateSpatialContextAsyncEXT

รันไทม์ต้องแสดงผล XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT หาก XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT ไม่ได้ระบุโดย xrEnumerateSpatialCapabilitiesEXT

การใช้งานที่ถูกต้อง (โดยนัย)

เครื่องหมาย 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 รันไทม์ต้องเปิดใช้การติดตามเครื่องหมาย ArUco เมื่อส่งโครงสร้าง XrSpatialCapabilityConfigurationArucoMarkerEXT ใน XrSpatialContextCreateInfoEXT :: capabilityConfigs เมื่อเรียกใช้ xrCreateSpatialContextAsyncEXT

รันไทม์ต้องส่งคืน XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT จาก xrCreateSpatialContextAsyncEXT หากโครงสร้าง XrSpatialCapabilityConfigurationArucoMarkerEXT อยู่ใน XrSpatialContextCreateInfoEXT :: capabilityConfigs แต่ XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT ไม่ได้ระบุโดย xrEnumerateSpatialCapabilitiesEXT

การใช้งานที่ถูกต้อง (โดยนัย)

การแจงนับ 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 — พจนานุกรมเครื่องหมาย Aruco ขนาด 4x4 พิกเซลที่มีรหัส 50 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 4x4 พิกเซลที่มีรหัส 100 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 4x4 พิกเซลที่มีรหัส 250 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 4x4 พิกเซลที่มีรหัส 1,000 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 5x5 พิกเซลที่มีรหัส 50 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 5x5 พิกเซลที่มีรหัส 100 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 5x5 พิกเซลที่มีรหัส 250 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 5x5 พิกเซลที่มีรหัส 1,000 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 6x6 พิกเซลที่มีรหัส 50 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 6x6 พิกเซลที่มีรหัส 100 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 6x6 พิกเซลที่มีรหัส 250 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 6x6 พิกเซลที่มีรหัส 1,000 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 7x7 พิกเซลที่มีรหัส 50 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 7x7 พิกเซลที่มีรหัส 100 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 7x7 พิกเซลที่มีรหัส 250 รายการ
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT — พจนานุกรมเครื่องหมาย Aruco ขนาด 7x7 พิกเซลที่มีรหัส 1,000 รายการ
AprilTags

โครงสร้าง 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 รันไทม์ต้องเปิดใช้การติดตาม AprilTag เมื่อส่งโครงสร้าง XrSpatialCapabilityConfigurationAprilTagEXT ใน XrSpatialContextCreateInfoEXT :: capabilityConfigs เมื่อเรียกใช้ xrCreateSpatialContextAsyncEXT

รันไทม์ต้องส่งคืน XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT จาก xrCreateSpatialContextAsyncEXT หากโครงสร้าง XrSpatialCapabilityConfigurationAprilTagEXT อยู่ใน XrSpatialContextCreateInfoEXT :: capabilityConfigs แต่ XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT ไม่ได้ระบุโดย xrEnumerateSpatialCapabilitiesEXT

การใช้งานที่ถูกต้อง (โดยนัย)

การแจงนับ 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 บิตต่อ 4 บิต ระยะทางแฮมมิงขั้นต่ำระหว่างรหัส 2 รหัสใดๆ = 5, 30 รหัส
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT — 5 บิต, ระยะทางแฮมมิงขั้นต่ำระหว่างรหัส 2 รหัสใดๆ = 9, 35 รหัส
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT — 6 บิต x 6 บิต ระยะทางแฮมมิงขั้นต่ำระหว่างรหัส 2 รหัสใดๆ = 10, 2320 รหัส
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT — 6 บิต x 6 บิต ระยะทางแฮมมิงขั้นต่ำระหว่างรหัส 2 รหัสใดๆ = 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 การให้ข้อมูลนี้แก่รันไทม์จะช่วยให้รันไทม์แสดงท่าทางและขนาดที่แม่นยำยิ่งขึ้น โครงสร้างนี้ต้องลิงก์เข้ากับเชน next ของ XrSpatialCapabilityConfigurationQrCodeEXT , XrSpatialCapabilityConfigurationMicroQrCodeEXT , XrSpatialCapabilityConfigurationArucoMarkerEXT หรือ XrSpatialCapabilityConfigurationAprilTagEXT

การใช้งานที่ถูกต้อง (โดยนัย)

การเพิ่มประสิทธิภาพเครื่องหมายแบบคงที่

โครงสร้าง 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 ซึ่งช่วยให้รันไทม์สร้างท่าทางและขนาดที่แม่นยำยิ่งขึ้นได้ โครงสร้างนี้ต้องลิงก์เข้ากับเชน next ของ XrSpatialCapabilityConfigurationQrCodeEXT , XrSpatialCapabilityConfigurationMicroQrCodeEXT , XrSpatialCapabilityConfigurationArucoMarkerEXT หรือ XrSpatialCapabilityConfigurationAprilTagEXT

การใช้งานที่ถูกต้อง (โดยนัย)

คอมโพเนนต์ที่รับประกัน

รันไทม์ที่รองรับ 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_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

คอมโพเนนต์เครื่องหมาย

ข้อมูลคอมโพเนนต์

โครงสร้าง XrSpatialMarkerDataEXT มีการกำหนดไว้ดังนี้

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

คำอธิบายสมาชิก

  • capability คือ XrSpatialCapabilityEXT ที่ตรวจพบตัวทำเครื่องหมาย
  • markerId คือตัวระบุที่เข้ารหัสจากเครื่องหมาย สำหรับเครื่องหมาย ArUco และ AprilTag ฟิลด์นี้ต้องถูกต้องและกรอกรหัสที่เข้ารหัสแล้ว สำหรับคิวอาร์โค้ด ฟิลด์นี้ต้องเป็น 0
  • data คือรหัสบัฟเฟอร์และประเภทของข้อมูลเพิ่มเติมที่อยู่ในเครื่องหมาย

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 ซึ่งแอปพลิเคชันใช้กับฟังก์ชัน xrGetSpatialBuffer* ที่เหมาะสมเพื่อรับข้อมูลได้
  • หากรันไทม์ยังไม่ได้ถอดรหัสข้อมูลของเครื่องหมาย ต้องตั้งค่า data รหัสบัฟเฟอร์เป็น 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 เป็น 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 ได้โดยการเพิ่ม XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT ใน XrSpatialComponentDataQueryConditionEXT :: componentTypes และเพิ่ม XrSpatialComponentMarkerListEXT ลงในเชนพอยน์เตอร์ถัดไปของ XrSpatialComponentDataQueryResultEXT

รันไทม์ต้องส่งคืน XR_ERROR_VALIDATION_FAILURE จาก xrQuerySpatialComponentDataEXT หาก XrSpatialComponentMarkerListEXT อยู่ในเชนถัดไปของ XrSpatialComponentDataQueryResultEXT :: next แต่ XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT ไม่ได้รวมอยู่ใน XrSpatialComponentDataQueryConditionEXT :: componentTypes

รันไทม์ต้องส่งคืน XR_ERROR_SIZE_INSUFFICIENT จาก xrQuerySpatialComponentDataEXT หาก markerCount น้อยกว่า XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput

การใช้งานที่ถูกต้อง (โดยนัย)

การกำหนดค่า

หากมีการแจงนับ XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT ใน XrSpatialCapabilityComponentTypesEXT :: componentTypes สำหรับความสามารถบางอย่าง แอปพลิเคชันสามารถเปิดใช้ได้โดยรวมการแจงนับไว้ในรายการ XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents ของโครงสร้างที่ได้จาก XrSpatialCapabilityConfigurationBaseHeaderEXT ของความสามารถที่รองรับคอมโพเนนต์นี้

คอมโพเนนต์นี้ไม่จำเป็นต้องมีการกำหนดค่าพิเศษใดๆ เพื่อรวมไว้ในเชน XrSpatialCapabilityConfigurationBaseHeaderEXT :: next

คอมโพเนนต์ 2 มิติที่ล้อมรอบ

คอมโพเนนต์ 2 มิติที่ล้อมรอบจะระบุจุดกึ่งกลางและขอบเขตของเครื่องหมายที่แสดงโดยเอนทิตีที่เครื่องหมายนั้นอยู่ ดูรายละเอียดเพิ่มเติมเกี่ยวกับคอมโพเนนต์ 2 มิติแบบมีขอบเขตได้ที่2 มิติแบบมีขอบเขต

XrSpatialBounded2DDataEXT :: center ต้องชี้ไปที่กึ่งกลางของตัวทำเครื่องหมาย เมื่อมองที่ด้านหน้าของเครื่องหมาย แกน X ต้องชี้ไปทางขวา และแกน Y ต้องชี้ไปที่ด้านบนของเครื่องหมาย รันไทม์ต้องเป็นไปตามกฎเกณฑ์ของระบบพิกัดมือขวา ดังนั้นแกน Z จะออกมาจากด้านหน้าของเครื่องหมาย ซึ่งหมายความว่าตัวทำเครื่องหมายที่มีตำแหน่ง {0, 0, 0}, การหมุน {0, 0, 0, 1} (ไม่มีการหมุน) และขอบเขต {1, 1} จะอ้างอิงถึงตัวทำเครื่องหมายขนาด 1 ม. x 1 ม. ซึ่งอยู่ตรงกลางที่ {0, 0, 0} โดยมีเวกเตอร์ปกติของด้านหน้าชี้ไปในทิศทาง +Z ในพื้นที่ของคอมโพเนนต์

ภาพแสดงการวางแนวของเครื่องหมายจะแสดงอยู่ด้านล่าง

แกนความเข้าใจเครื่องหมาย ML ของ XR

รูปที่ 25 เครื่องหมายคิวอาร์โค้ดพร้อมแกน

รหัสทดสอบ

รหัสต่อไปนี้ต้องมีระนาบ X-Y อยู่ภายในเอกสารและแกน Z ชี้ไปที่ผู้ชม จุดกำเนิดของแกนต้องปรากฏที่กึ่งกลางของเครื่องหมายแต่ละอัน แกน X ต้องชี้ไปทางขวา แกน Y ต้องชี้ไปด้านบนของเอกสาร

ext marker tracking qr

รูปที่ 26 คิวอาร์โค้ดที่มีข้อความ "OpenXR"

การติดตามเครื่องหมาย ext apriltag

รูปที่ 27 AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT ที่มีรหัส 42

ext marker tracking aruco

รูปที่ 28 เครื่องหมาย ArUco XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT ที่มีรหัส 43

โค้ดตัวอย่าง

กำหนดค่าความสามารถในการติดตามคิวอาร์โค้ด

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีตั้งค่าความสามารถในการติดตามคิวอาร์โค้ดเมื่อสร้างบริบทเชิงพื้นที่

// 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
  // ...
}

โครงสร้างใหม่

Enum ใหม่

ค่าคงที่ Enum ใหม่

  • XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAME
  • XR_EXT_spatial_marker_tracking_SPEC_VERSION
  • การขยาย 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
  • การขยาย XrSpatialCapabilityFeatureEXT :

    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT
    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT
  • การขยาย XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • การขยาย 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

ประวัติเวอร์ชัน

  • ฉบับแก้ไขที่ 1, 29-07-2024 (Ron Bessems, Meta)

    • คำอธิบายส่วนขยายเริ่มต้น