XR_EXT_spatial_marker_tracking

מחרוזת שם

XR_EXT_spatial_marker_tracking

סוג התוסף

הרחבת המכונה

מספר שלוחה רשום

744

Revision

1

סטטוס האישור

אושר

תלות בתוסף ובגרסה

XR_EXT_spatial_entity

שותפים ביצירת התוכן

רון בסמס, Meta
ניחב ג'יין, Google
נטלי פלורי, Meta
יויצ'י טאגוצ'י, Meta
יין לי, Microsoft
ג'ימי אלמפרמביל, ByteDance
ג'יפנג ליו, ByteDance
ג'ון יאן, ByteDance

סקירה כללית

התוסף הזה מבוסס על XR_EXT_spatial_entity ומאפשר לאפליקציות לזהות ולעקוב אחרי סמנים בסביבה שלהן. סמנים הם קודים דו-ממדיים שיכולים לכלול קודי QR, קודי מיקרו QR, סמני ArUco או AprilTags.

סמן למעקב מיוצג כישות מרחבית עם הרכיבים הבאים:

  • 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 .

הגדרות של סוגי מרקרים

קודי QR

המבנה 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, סביבת הריצה חייבת להפעיל מעקב אחרי קודי QR כשמבנה XrSpatialCapabilityConfigurationQrCodeEXT מועבר ב-XrSpatialContextCreateInfoEXT :: capabilityConfigs כשקוראים ל-xrCreateSpatialContextAsyncEXT .

סביבת זמן הריצה חייבת להחזיר את הערך XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT אם XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT לא מפורט על ידי xrEnumerateSpatialCapabilitiesEXT .

שימוש תקף (משתמע)

קודי QR קטנים

המבנה 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, סביבת זמן הריצה חייבת להפעיל מעקב אחרי קודי Micro QR כשמבנה 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 בגודל ‎5 x 5 פיקסלים עם 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 ביטים, מרחק המינג מינימלי בין כל שני קודים = 5, 30 קודים.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT – 5 על 5 ביטים, מרחק המינג מינימלי בין כל שני קודים = 9, 35 קודים.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT — 6 על 6 ביטים, מרחק המינג מינימלי בין כל שני קודים = 10, 2320 קודים.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT — 6 על 6 ביטים, מרחק המינג מינימלי בין כל שני קודים = 11, 587 קודים.

הגדרות אופציונליות של סמנים

אפליקציות צריכות להתקשר אל xrEnumerateSpatialCapabilityFeaturesEXT כדי לקבל את רשימת התכונות האופציונליות הנתמכות.

כאן אפשר לראות רשימה מלאה של כל התכונות של יכולות מרחביות שנתמכות על ידי תוסף כלשהו.

גודל הסמן

המבנה 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, השדה הזה חייב להיות תקין ומלא במזהה המקודד. במקרה של קודי QR, הערך בשדה הזה חייב להיות אפס.
  • 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 .

שימוש תקף (משתמע)

מבנה רשימת הרכיבים לשליחת שאילתות לנתונים

המבנה 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.

רכיב דו-ממדי מוגבל

רכיב ה-2D המוגבל מספק את המרכז וההיקף של הסמן שמיוצג על ידי הישות שהוא נמצא עליה. פרטים נוספים על רכיב ה-2D המוגבל מופיעים במאמר 2D מוגבל.

הפרמטר XrSpatialBounded2DDataEXT :: center חייב להצביע על מרכז הסמן. כשמסתכלים על החלק הקדמי של הסמן, ציר ה-X חייב להצביע ימינה וציר ה-Y חייב להצביע לחלק העליון של הסמן. זמן הריצה חייב לפעול לפי המוסכמה של מערכת קואורדינטות ימנית, ולכן ציר ה-Z יוצא מהפנים הקדמיות של הסמן. כלומר, סמן עם מיקום של {0, 0, 0}, סיבוב של {0, 0, 0, 1} (ללא סיבוב) וגודל של {1, 1} מתייחס לסמן בגודל מטר על מטר שממורכז במיקום {0, 0, 0} ושהווקטור הנורמלי של הפאה הקדמית שלו מצביע לכיוון +Z במרחב של הרכיב.

בהמשך מוצגת דוגמה לאופן שבו הסמן מוצג.

xr ml marker understanding axis

איור 25. סמן קוד QR עם ציר

קודי בדיקה

הקודים הבאים חייבים להיות במישור X-Y בתוך המסמך, וציר Z צריך להיות מכוון אל הצופה. נקודת האפס של הציר חייבת להופיע במרכז של כל סמן. ציר ה-X חייב להצביע ימינה, וציר ה-Y חייב להצביע לחלק העליון של המסמך.

ext marker tracking qr

איור 26. קוד QR עם הטקסט 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

קוד לדוגמה

הגדרת יכולת מעקב אחרי קוד QR

בדוגמת הקוד הבאה אפשר לראות איך מגדירים את היכולת לעקוב אחרי קוד QR כשיוצרים הקשר מרחבי.

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

מבנים חדשים

New Enums

New Enum Constants

  • 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 (רון בסמס, Meta)

    • תיאור ראשוני של התוסף