XR_EXT_spatial_marker_tracking
Chaîne de nom
XR_EXT_spatial_marker_tracking
Type d'extension
Extension d'instance
Numéro d'extension enregistré
744
Révision
1
État de ratification
Ratifié
Dépendances des extensions et des versions
XR_EXT_spatial_entity
Participants
Ron Bessems, Meta
Nihav Jain, Google
Natalie Fleury, Meta
Yuichi Taguchi, Meta
Yin Li, Microsoft
Jimmy Alamparambil, ByteDance
Zhipeng Liu, ByteDance
Jun Yan, ByteDance
Présentation
Cette extension s'appuie sur XR_EXT_spatial_entity et permet aux applications de détecter et de suivre les marqueurs dans leur environnement. Les repères sont des codes 2D qui peuvent inclure des codes QR, des micro codes QR, des repères ArUco ou des AprilTags.
Un repère suivi est représenté sous la forme d'une entité spatiale avec (ou "qui comporte") les composants suivants :
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXTXR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT
Prise en charge des environnements d'exécution
Un environnement d'exécution doit indiquer sa compatibilité avec les différentes fonctionnalités de suivi des repères à l'aide de xrEnumerateSpatialCapabilitiesEXT en listant l'une des fonctionnalités suivantes :
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
Configuration
Pour activer la détection d'un type de repère, l'application doit transmettre la structure de configuration correspondante à xrCreateSpatialContextAsyncEXT .
Configurations du type de repère
Codes QR
La structure XrSpatialCapabilityConfigurationQrCodeEXT est définie comme suit :
typedef struct XrSpatialCapabilityConfigurationQrCodeEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationQrCodeEXT;
Descriptions des membres
typeest le XrStructureType de cette structure.nextestNULLou un pointeur vers la structure suivante dans une chaîne de structures.capabilitydoit êtreXR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT.enabledComponentCountest unuint32_tavec le nombre d'éléments dansenabledComponents.enabledComponentsest un pointeur vers un tableau de composants à activer pour cette fonctionnalité.
Si les codes QR sont acceptés, le runtime doit activer le suivi des codes QR lorsqu'une structure XrSpatialCapabilityConfigurationQrCodeEXT est transmise dans XrSpatialContextCreateInfoEXT :: capabilityConfigs lors de l'appel de xrCreateSpatialContextAsyncEXT .
L'exécution doit renvoyer XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT si XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT n'est pas énuméré par xrEnumerateSpatialCapabilitiesEXT .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialCapabilityConfigurationQrCodeEXT. -
typedoit êtreXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT. -
nextdoit êtreNULLou un pointeur valide vers la structure suivante dans une chaîne de structures . Voir aussi : XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitydoit être une valeur XrSpatialCapabilityEXT valide. -
enabledComponentsmust être un pointeur vers un tableau deenabledComponentCountvaleurs XrSpatialComponentTypeEXT valides. - Le paramètre
enabledComponentCountdoit être supérieur à0
Micro QR codes
La structure XrSpatialCapabilityConfigurationMicroQrCodeEXT est définie comme suit :
typedef struct XrSpatialCapabilityConfigurationMicroQrCodeEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationMicroQrCodeEXT;
Descriptions des membres
typeest le XrStructureType de cette structure.nextestNULLou un pointeur vers la structure suivante dans une chaîne de structures.capabilitydoit êtreXR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT.enabledComponentCountest unuint32_tavec le nombre d'éléments dansenabledComponents.enabledComponentsest un pointeur vers un tableau de composants à activer pour cette fonctionnalité.
Si les micro codes QR sont acceptés, le runtime doit activer le suivi des micro codes QR lorsqu'une structure XrSpatialCapabilityConfigurationMicroQrCodeEXT est transmise dans XrSpatialContextCreateInfoEXT::capabilityConfigs lors de l'appel de xrCreateSpatialContextAsyncEXT .
L'exécution doit renvoyer XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT si XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT n'est pas énuméré par xrEnumerateSpatialCapabilitiesEXT .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialCapabilityConfigurationMicroQrCodeEXT. -
typedoit êtreXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT. -
nextdoit êtreNULLou un pointeur valide vers la structure suivante dans une chaîne de structures . Voir aussi : XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitydoit être une valeur XrSpatialCapabilityEXT valide. -
enabledComponentsmust être un pointeur vers un tableau deenabledComponentCountvaleurs XrSpatialComponentTypeEXT valides. - Le paramètre
enabledComponentCountdoit être supérieur à0
Marqueurs ArUco
La structure XrSpatialCapabilityConfigurationArucoMarkerEXT est définie comme suit :
typedef struct XrSpatialCapabilityConfigurationArucoMarkerEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
XrSpatialMarkerArucoDictEXT arUcoDict;
} XrSpatialCapabilityConfigurationArucoMarkerEXT;
Descriptions des membres
typeest le XrStructureType de cette structure.nextestNULLou un pointeur vers la structure suivante dans une chaîne de structures.capabilitydoit êtreXR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT.enabledComponentCountest unuint32_tavec le nombre d'éléments dansenabledComponents.enabledComponentsest un pointeur vers un tableau de composants à activer pour cette fonctionnalité.arUcoDictest le dictionnaire de marqueurs à détecter.
Si les marqueurs ArUco sont compatibles, le runtime doit activer le suivi des marqueurs ArUco lorsqu'une structure XrSpatialCapabilityConfigurationArucoMarkerEXT est transmise dans XrSpatialContextCreateInfoEXT :: capabilityConfigs lors de l'appel de xrCreateSpatialContextAsyncEXT .
L'exécution doit renvoyer XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT à partir de xrCreateSpatialContextAsyncEXT si une structure XrSpatialCapabilityConfigurationArucoMarkerEXT se trouve dans XrSpatialContextCreateInfoEXT::capabilityConfigs, mais que XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT n'est pas énuméré par xrEnumerateSpatialCapabilitiesEXT .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialCapabilityConfigurationArucoMarkerEXT. -
typedoit êtreXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT. -
nextdoit êtreNULLou un pointeur valide vers la structure suivante dans une chaîne de structures . Voir aussi : XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitydoit être une valeur XrSpatialCapabilityEXT valide. -
enabledComponentsmust être un pointeur vers un tableau deenabledComponentCountvaleurs XrSpatialComponentTypeEXT valides. -
arUcoDictmust doit être une valeur XrSpatialMarkerArucoDictEXT valide - Le paramètre
enabledComponentCountdoit être supérieur à0
L'énumération XrSpatialMarkerArucoDictEXT est définie comme suit :
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;
Dictionnaire ArUco prédéfini compatible :
Descriptions des énumérants
XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT: dictionnaire de marqueurs Aruco de 4 x 4 pixels avec 50 ID.XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT: dictionnaire de marqueurs Aruco de 4 x 4 pixels avec 100 ID.XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT: dictionnaire de marqueurs Aruco de 4 x 4 pixels avec 250 ID.XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT: dictionnaire de marqueurs Aruco de 4 x 4 pixels avec 1 000 ID.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT: dictionnaire de marqueurs Aruco de 5 x 5 pixels avec 50 ID.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT: dictionnaire de marqueurs Aruco de 5 x 5 pixels avec 100 ID.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT: dictionnaire de marqueurs Aruco de 5 x 5 pixels avec 250 ID.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT: dictionnaire de marqueurs Aruco de 5 x 5 pixels avec 1 000 ID.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT: dictionnaire de marqueurs Aruco de 6 x 6 pixels avec 50 ID.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT: dictionnaire de marqueurs Aruco de 6 x 6 pixels avec 100 ID.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT: dictionnaire de marqueurs Aruco de 6 x 6 pixels avec 250 ID.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT: dictionnaire de marqueurs Aruco 6 x 6 pixels avec 1 000 ID.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT: dictionnaire de marqueurs Aruco de 7 x 7 pixels avec 50 ID.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT: dictionnaire de marqueurs Aruco de 7 x 7 pixels avec 100 ID.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT: dictionnaire de marqueurs Aruco de 7 x 7 pixels avec 250 ID.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT: dictionnaire de marqueurs Aruco de 7 x 7 pixels avec 1 000 ID.
AprilTags
La structure XrSpatialCapabilityConfigurationAprilTagEXT est définie comme suit :
typedef struct XrSpatialCapabilityConfigurationAprilTagEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
XrSpatialMarkerAprilTagDictEXT aprilDict;
} XrSpatialCapabilityConfigurationAprilTagEXT;
Descriptions des membres
typeest le XrStructureType de cette structure.nextestNULLou un pointeur vers la structure suivante dans une chaîne de structures.capabilitydoit êtreXR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT.enabledComponentCountest unuint32_tavec le nombre d'éléments dansenabledComponents.enabledComponentsest un pointeur vers un tableau de composants à activer pour cette fonctionnalité.aprilDictest le dictionnaire de marqueurs à détecter.
Si les AprilTags sont compatibles, le runtime doit activer le suivi des AprilTags lorsqu'une structure XrSpatialCapabilityConfigurationAprilTagEXT est transmise dans XrSpatialContextCreateInfoEXT::capabilityConfigs lors de l'appel de xrCreateSpatialContextAsyncEXT .
Le runtime doit renvoyer XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT à partir de xrCreateSpatialContextAsyncEXT si une structure XrSpatialCapabilityConfigurationAprilTagEXT se trouve dans XrSpatialContextCreateInfoEXT::capabilityConfigs, mais que XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT n'est pas énuméré par xrEnumerateSpatialCapabilitiesEXT .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialCapabilityConfigurationAprilTagEXT. -
typedoit êtreXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT. -
nextdoit êtreNULLou un pointeur valide vers la structure suivante dans une chaîne de structures . Voir aussi : XrSpatialMarkerSizeEXT , XrSpatialMarkerStaticOptimizationEXT -
capabilitydoit être une valeur XrSpatialCapabilityEXT valide. -
enabledComponentsmust être un pointeur vers un tableau deenabledComponentCountvaleurs XrSpatialComponentTypeEXT valides. -
aprilDictdoit être une valeur XrSpatialMarkerAprilTagDictEXT valide - Le paramètre
enabledComponentCountdoit être supérieur à0
L'énumération XrSpatialMarkerAprilTagDictEXT est définie comme suit :
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;
Dictionnaire AprilTag prédéfini compatible :
Descriptions des énumérants
XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT: 4 bits sur 4, distance de Hamming minimale entre deux codes = 5, 30 codes.XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT: 5 bits sur 5, distance de Hamming minimale entre deux codes = 9, 35 codes.XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT: 6 bits sur 6, distance de Hamming minimale entre deux codes = 10, 2 320 codes.XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT: 6 bits sur 6, distance de Hamming minimale entre deux codes = 11, 587 codes.
Configurations de repères facultatives
Les applications doivent appeler xrEnumerateSpatialCapabilityFeaturesEXT pour obtenir la liste des fonctionnalités facultatives compatibles.
Consultez XrSpatialCapabilityFeatureEXT pour obtenir la liste complète de toutes les fonctionnalités spatiales compatibles avec une extension.
Taille du repère
La structure XrSpatialMarkerSizeEXT est définie comme suit :
typedef struct XrSpatialMarkerSizeEXT {
XrStructureType type;
const void* next;
float markerSideLength;
} XrSpatialMarkerSizeEXT;
Descriptions des membres
typeest le XrStructureType de cette structure.nextestNULLou un pointeur vers la structure suivante dans une chaîne de structures.markerSideLengthcorrespond à la taille (en mètres) de tous les repères.
Si XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT est énuméré par xrEnumerateSpatialCapabilityFeaturesEXT pour une certaine fonctionnalité, et si l'application enchaîne XrSpatialMarkerSizeEXT à la structure de configuration correspondante de cette fonctionnalité, le runtime doit supposer que tous les marqueurs détectés ont une largeur et une hauteur de markerSideLength . En fournissant ces informations au moteur d'exécution, celui-ci peut renvoyer une pose et une taille plus précises. Cette structure doit être liée à la chaîne next de XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT ou XrSpatialCapabilityConfigurationAprilTagEXT .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialMarkerSizeEXT. -
typedoit êtreXR_TYPE_SPATIAL_MARKER_SIZE_EXT. -
nextdoit êtreNULLou un pointeur valide vers la structure suivante dans une chaîne de structures.
Optimisation des repères statiques
La structure XrSpatialMarkerStaticOptimizationEXT est définie comme suit :
typedef struct XrSpatialMarkerStaticOptimizationEXT {
XrStructureType type;
const void* next;
XrBool32 optimizeForStaticMarker;
} XrSpatialMarkerStaticOptimizationEXT;
Descriptions des membres
typeest le XrStructureType de cette structure.nextestNULLou un pointeur vers la structure suivante dans une chaîne de structures.optimizeForStaticMarkerindique si tous les repères de l'espace ne doivent pas bouger.
Si XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT est énuméré par xrEnumerateSpatialCapabilityFeaturesEXT pour une certaine fonctionnalité, et si l'application enchaîne XrSpatialMarkerStaticOptimizationEXT à la structure de configuration correspondante de cette fonctionnalité, le runtime doit supposer que tous les repères détectés sont statiques si optimizeForStaticMarker est défini sur XR_TRUE . Cela permet au moteur d'exécution de générer une pose et une taille plus précises. Cette structure doit être liée à la chaîne next de XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT ou XrSpatialCapabilityConfigurationAprilTagEXT .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialMarkerStaticOptimizationEXT. -
typedoit êtreXR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT. -
nextdoit êtreNULLou un pointeur valide vers la structure suivante dans une chaîne de structures.
Composants garantis
Un moteur d'exécution compatible avec 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 ou XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT doit fournir les composants spatiaux suivants en tant que composants garantis de toutes les entités découvertes par ces fonctionnalités, et doit les énumérer dans xrEnumerateSpatialCapabilityComponentTypesEXT :
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXTXR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT
Composant de repère
Données des composants
La structure XrSpatialMarkerDataEXT est définie comme suit :
typedef struct XrSpatialMarkerDataEXT {
XrSpatialCapabilityEXT capability;
uint32_t markerId;
XrSpatialBufferEXT data;
} XrSpatialMarkerDataEXT;
Descriptions des membres
capabilitycorrespond à XrSpatialCapabilityEXT qui a détecté le repère.markerIdest l'identifiant encodé du repère. Pour les marqueurs ArUco et les AprilTag, ce champ doit être valide et contenir l'ID encodé. Pour les codes QR, ce champ doit être défini sur zéro.datacorrespond à l'ID du tampon et au type d'informations supplémentaires contenues dans le repère.
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT et XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT acceptent les données supplémentaires. Si capability correspond à l'une des options suivantes :
- Si le runtime a décodé les données du repère, il doit définir le type de tampon
datasurXR_SPATIAL_BUFFER_TYPE_UINT8_EXTouXR_SPATIAL_BUFFER_TYPE_STRING_EXT, selon les données du repère. Le runtime doit également définir un ID de tampon valide dansdataque l'application peut utiliser avec la fonctionxrGetSpatialBuffer*appropriée pour obtenir les données. - Si le runtime n'a pas encore décodé les données du repère, il doit définir l'ID du tampon
datasur XR_NULL_SPATIAL_BUFFER_ID_EXT et le type de tampon surXR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT.
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT et XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT ne sont pas compatibles avec les données supplémentaires, et le runtime doit définir l'ID de tampon de data sur XR_NULL_SPATIAL_BUFFER_ID_EXT .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialMarkerDataEXT. -
capabilitydoit être une valeur XrSpatialCapabilityEXT valide. -
datadoit être une structure XrSpatialBufferEXT valide
Structure de la liste des composants pour interroger les données
La structure XrSpatialComponentMarkerListEXT est définie comme suit :
typedef struct XrSpatialComponentMarkerListEXT {
XrStructureType type;
void* next;
uint32_t markerCount;
XrSpatialMarkerDataEXT* markers;
} XrSpatialComponentMarkerListEXT;
Descriptions des membres
typeest le XrStructureType de cette structure.nextestNULLou un pointeur vers la structure suivante dans une chaîne de structures. Aucune structure de ce type n'est définie dans l'extension ni dans le cœur d'OpenXR.markerCountcorrespond au nombre d'éléments du membremarkers.markersest un tableau de XrSpatialMarkerDataEXT .
L'application peut interroger le composant de repère des entités spatiales dans un XrSpatialSnapshotEXT en ajoutant XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT dans XrSpatialComponentDataQueryConditionEXT :: componentTypes et en ajoutant XrSpatialComponentMarkerListEXT à la chaîne de pointeur suivante de XrSpatialComponentDataQueryResultEXT .
Le runtime doit renvoyer XR_ERROR_VALIDATION_FAILURE à partir de xrQuerySpatialComponentDataEXT si XrSpatialComponentMarkerListEXT se trouve dans la chaîne suivante de XrSpatialComponentDataQueryResultEXT :: next, mais que XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT n'est pas inclus dans XrSpatialComponentDataQueryConditionEXT :: componentTypes .
Le runtime doit renvoyer XR_ERROR_SIZE_INSUFFICIENT à partir de xrQuerySpatialComponentDataEXT si markerCount est inférieur à XrSpatialComponentDataQueryResultEXT::entityIdCountOutput .
Utilisation valide (implicite)
- L'extension
XR_EXT_spatial_marker_trackingdoit être activée avant d'utiliser XrSpatialComponentMarkerListEXT. -
typedoit êtreXR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT. -
nextdoit êtreNULLou un pointeur valide vers la structure suivante dans une chaîne de structures. -
markersmust être un pointeur vers un tableau de structuresmarkerCountXrSpatialMarkerDataEXT. - Le paramètre
markerCountdoit être supérieur à0
Configuration
Si XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT est énuméré dans XrSpatialCapabilityComponentTypesEXT :: componentTypes pour une fonctionnalité, une application peut l'activer en incluant l'énumérant dans la liste XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents de la structure dérivée XrSpatialCapabilityConfigurationBaseHeaderEXT de la fonctionnalité qui prend en charge ce composant.
Ce composant ne nécessite aucune configuration spéciale pour être inclus dans la chaîne XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.
Composant 2D limité
Le composant 2D limité fournit le centre et les limites du repère représenté par l'entité sur laquelle il se trouve. Pour en savoir plus sur le composant 2D limité, consultez 2D limité.
XrSpatialBounded2DDataEXT :: center must doit pointer vers le centre du repère. Lorsque vous regardez la face avant du marqueur, l'axe X doit pointer vers la droite et l'axe Y doit pointer vers le haut du marqueur. L'exécution doit suivre la convention du système de coordonnées de la main droite, de sorte que l'axe Z sort de la face avant du repère. Cela signifie qu'un repère avec une position de {0, 0, 0}, une rotation de {0, 0, 0, 1} (aucune rotation) et une étendue de {1, 1} fait référence à un repère de 1 mètre x 1 mètre centré sur {0, 0, 0} avec son vecteur normal de face avant pointant vers la direction +Z dans l'espace du composant.
Une représentation de l'orientation du repère est présentée ci-dessous.
Figure 25. Marqueur de code QR avec axe
Codes de test
Les codes suivants doivent avoir leur plan X-Y à l'intérieur du document et l'axe Z pointant vers le lecteur. L'origine de l'axe doit apparaître au centre de chaque repère. L'axe X doit pointer vers la droite et l'axe Y doit pointer vers le haut du document.
Figure 26. Code QR avec le texte "OpenXR"
Figure 27. AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT avec l'ID 42
Figure 28. Marqueur ArUco XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT avec l'ID 43
Exemple de code
Configurer la fonctionnalité de suivi par QR code
L'exemple de code suivant montre comment configurer la fonctionnalité de suivi des codes QR lors de la création d'un contexte spatial.
// 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));
Découvrir les entités spatiales et interroger les données des composants
L'exemple de code suivant montre comment découvrir des entités spatiales pour un contexte configuré avec XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT et interroger ses données de composants.
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
// ...
}
Nouvelles structures
- XrSpatialCapabilityConfigurationAprilTagEXT
- XrSpatialCapabilityConfigurationArucoMarkerEXT
- XrSpatialCapabilityConfigurationMicroQrCodeEXT
- XrSpatialCapabilityConfigurationQrCodeEXT
- XrSpatialMarkerDataEXT
Extension de XrSpatialCapabilityConfigurationArucoMarkerEXT , XrSpatialCapabilityConfigurationAprilTagEXT , XrSpatialCapabilityConfigurationQrCodeEXT , XrSpatialCapabilityConfigurationMicroQrCodeEXT :
Extension de XrSpatialComponentDataQueryResultEXT :
Nouveaux enums
Nouvelles constantes d'énumération
XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAMEXR_EXT_spatial_marker_tracking_SPEC_VERSIONExtension de XrSpatialCapabilityEXT :
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXTXR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT
Extension de XrSpatialCapabilityFeatureEXT :
XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXTXR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT
Extension de XrSpatialComponentTypeEXT :
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
Extension de 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
Historique des versions
Révision 1, 29/07/2024 (Ron Bessems, Meta)
- Description initiale de l'extension