XR_EXT_spatial_marker_tracking
Cadena de nombre
XR_EXT_spatial_marker_tracking
Tipo de extensión
Extensión de la instancia
Número de extensión registrado
744
Revisión
1
Estado de ratificación
Ratificado
Dependencias de extensiones y versiones
XR_EXT_spatial_entity
Colaboradores
Ron Bessems, Meta
Nihav Jain, Google
Natalie Fleury, Meta
Yuichi Taguchi, Meta
Yin Li, Microsoft
Jimmy Alamparambil, ByteDance
Zhipeng Liu, ByteDance
Jun Yan, ByteDance
Descripción general
Esta extensión se basa en XR_EXT_spatial_entity y permite que las aplicaciones detecten y hagan un seguimiento de los marcadores en su entorno. Los marcadores son códigos 2D que pueden incluir códigos QR, códigos QR micro, marcadores ArUco o AprilTags.
Un marcador rastreado se representa como una entidad espacial con los siguientes componentes:
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXTXR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT
Asistencia del entorno de ejecución
Un tiempo de ejecución debe anunciar su compatibilidad con las diversas capacidades de seguimiento de marcadores a través de xrEnumerateSpatialCapabilitiesEXT enumerando cualquiera de las siguientes capacidades:
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
Configuración
Para habilitar la detección de un tipo de marcador, la aplicación debe pasar la estructura de configuración correspondiente a xrCreateSpatialContextAsyncEXT .
Configuración de tipos de marcadores
códigos QR
La estructura XrSpatialCapabilityConfigurationQrCodeEXT se define de la siguiente manera:
typedef struct XrSpatialCapabilityConfigurationQrCodeEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationQrCodeEXT;
Descripciones de los miembros
typees el XrStructureType de esta estructura.nextesNULLo un puntero a la siguiente estructura en una cadena de estructuras.capabilitydebe serXR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT.enabledComponentCountes unuint32_tcon la cantidad de elementos enenabledComponents.enabledComponentses un puntero a un array de componentes que se habilitarán para esta capacidad.
Si se admiten códigos QR, el tiempo de ejecución debe habilitar el seguimiento de códigos QR cuando se pasa una estructura XrSpatialCapabilityConfigurationQrCodeEXT en XrSpatialContextCreateInfoEXT :: capabilityConfigs cuando se llama a xrCreateSpatialContextAsyncEXT .
El tiempo de ejecución debe devolver XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT si xrEnumerateSpatialCapabilitiesEXT no enumera XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialCapabilityConfigurationQrCodeEXT -
typedebe serXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT -
nextdebe serNULLo un puntero válido a la siguiente estructura en una cadena de estructuras . Consulta también: XrSpatialMarkerSizeEXT y XrSpatialMarkerStaticOptimizationEXT -
capabilitydebe ser un valor XrSpatialCapabilityEXT válido. -
enabledComponentsdebe ser un puntero a un array de valores XrSpatialComponentTypeEXT válidos deenabledComponentCount. - El parámetro
enabledComponentCountdebe ser mayor que0.
Códigos QR pequeños
La estructura XrSpatialCapabilityConfigurationMicroQrCodeEXT se define de la siguiente manera:
typedef struct XrSpatialCapabilityConfigurationMicroQrCodeEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationMicroQrCodeEXT;
Descripciones de los miembros
typees el XrStructureType de esta estructura.nextesNULLo un puntero a la siguiente estructura en una cadena de estructuras.capabilitydebe serXR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT.enabledComponentCountes unuint32_tcon la cantidad de elementos enenabledComponents.enabledComponentses un puntero a un array de componentes que se habilitarán para esta capacidad.
Si se admiten los códigos QR pequeños, el tiempo de ejecución debe habilitar el seguimiento de códigos QR pequeños cuando se pasa una estructura XrSpatialCapabilityConfigurationMicroQrCodeEXT en XrSpatialContextCreateInfoEXT :: capabilityConfigs cuando se llama a xrCreateSpatialContextAsyncEXT .
El tiempo de ejecución debe devolver XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT si xrEnumerateSpatialCapabilitiesEXT no enumera XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialCapabilityConfigurationMicroQrCodeEXT -
typedebe serXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT -
nextdebe serNULLo un puntero válido a la siguiente estructura en una cadena de estructuras . Consulta también: XrSpatialMarkerSizeEXT y XrSpatialMarkerStaticOptimizationEXT -
capabilitydebe ser un valor XrSpatialCapabilityEXT válido. -
enabledComponentsdebe ser un puntero a un array de valores XrSpatialComponentTypeEXT válidos deenabledComponentCount. - El parámetro
enabledComponentCountdebe ser mayor que0.
Marcadores ArUco
La estructura XrSpatialCapabilityConfigurationArucoMarkerEXT se define de la siguiente manera:
typedef struct XrSpatialCapabilityConfigurationArucoMarkerEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
XrSpatialMarkerArucoDictEXT arUcoDict;
} XrSpatialCapabilityConfigurationArucoMarkerEXT;
Descripciones de los miembros
typees el XrStructureType de esta estructura.nextesNULLo un puntero a la siguiente estructura en una cadena de estructuras.capabilitydebe serXR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT.enabledComponentCountes unuint32_tcon la cantidad de elementos enenabledComponents.enabledComponentses un puntero a un array de componentes que se habilitarán para esta capacidad.arUcoDictes el diccionario de marcadores que se detectará.
Si se admiten los marcadores ArUco, el tiempo de ejecución debe habilitar el seguimiento de marcadores ArUco cuando se pasa una estructura XrSpatialCapabilityConfigurationArucoMarkerEXT en XrSpatialContextCreateInfoEXT :: capabilityConfigs cuando se llama a xrCreateSpatialContextAsyncEXT .
El tiempo de ejecución debe devolver XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT de xrCreateSpatialContextAsyncEXT si hay una estructura XrSpatialCapabilityConfigurationArucoMarkerEXT en XrSpatialContextCreateInfoEXT :: capabilityConfigs, pero XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT no está enumerado por xrEnumerateSpatialCapabilitiesEXT .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialCapabilityConfigurationArucoMarkerEXT -
typedebe serXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT -
nextdebe serNULLo un puntero válido a la siguiente estructura en una cadena de estructuras . Consulta también: XrSpatialMarkerSizeEXT y XrSpatialMarkerStaticOptimizationEXT -
capabilitydebe ser un valor XrSpatialCapabilityEXT válido. -
enabledComponentsdebe ser un puntero a un array de valores XrSpatialComponentTypeEXT válidos deenabledComponentCount. -
arUcoDictdebe ser un valor XrSpatialMarkerArucoDictEXT válido. - El parámetro
enabledComponentCountdebe ser mayor que0.
La enumeración XrSpatialMarkerArucoDictEXT se define de la siguiente manera:
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;
Diccionario ArUco predefinido compatible:
Descripciones de los enumerantes
XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT: Diccionario de marcadores Aruco de 4 x 4 píxeles con 50 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT: Diccionario de marcadores Aruco de 4 x 4 píxeles con 100 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT: Diccionario de marcadores Aruco de 4 x 4 píxeles con 250 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT: Diccionario de marcadores Aruco de 4 x 4 píxeles con 1,000 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT: Diccionario de marcadores Aruco de 5 x 5 píxeles con 50 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT: Diccionario de marcadores Aruco de 5 x 5 píxeles con 100 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT: Diccionario de marcadores Aruco de 5 x 5 píxeles con 250 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT: Diccionario de marcadores Aruco de 5 x 5 píxeles con 1,000 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT: Diccionario de marcadores Aruco de 6 x 6 píxeles con 50 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT: Diccionario de marcadores Aruco de 6 x 6 píxeles con 100 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT: Diccionario de marcadores Aruco de 6 x 6 píxeles con 250 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT: Diccionario de marcadores Aruco de 6 x 6 píxeles con 1,000 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT: Diccionario de marcadores Aruco de 7 x 7 píxeles con 50 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT: Diccionario de marcadores Aruco de 7 x 7 píxeles con 100 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT: Diccionario de marcadores Aruco de 7 x 7 píxeles con 250 IDs.XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT: Diccionario de marcadores Aruco de 7 x 7 píxeles con 1,000 IDs.
AprilTags
La estructura XrSpatialCapabilityConfigurationAprilTagEXT se define de la siguiente manera:
typedef struct XrSpatialCapabilityConfigurationAprilTagEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
XrSpatialMarkerAprilTagDictEXT aprilDict;
} XrSpatialCapabilityConfigurationAprilTagEXT;
Descripciones de los miembros
typees el XrStructureType de esta estructura.nextesNULLo un puntero a la siguiente estructura en una cadena de estructuras.capabilitydebe serXR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT.enabledComponentCountes unuint32_tcon la cantidad de elementos enenabledComponents.enabledComponentses un puntero a un array de componentes que se habilitarán para esta capacidad.aprilDictes el diccionario de marcadores que se detectará.
Si se admiten AprilTags, el tiempo de ejecución debe habilitar el seguimiento de AprilTags cuando se pasa una estructura XrSpatialCapabilityConfigurationAprilTagEXT en XrSpatialContextCreateInfoEXT :: capabilityConfigs cuando se llama a xrCreateSpatialContextAsyncEXT .
El tiempo de ejecución debe devolver XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT de xrCreateSpatialContextAsyncEXT si hay una estructura XrSpatialCapabilityConfigurationAprilTagEXT en XrSpatialContextCreateInfoEXT :: capabilityConfigs, pero xrEnumerateSpatialCapabilitiesEXT no enumera XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialCapabilityConfigurationAprilTagEXT -
typedebe serXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT -
nextdebe serNULLo un puntero válido a la siguiente estructura en una cadena de estructuras . Consulta también: XrSpatialMarkerSizeEXT y XrSpatialMarkerStaticOptimizationEXT -
capabilitydebe ser un valor XrSpatialCapabilityEXT válido. -
enabledComponentsdebe ser un puntero a un array de valores XrSpatialComponentTypeEXT válidos deenabledComponentCount. -
aprilDictdebe ser un valor de XrSpatialMarkerAprilTagDictEXT válido. - El parámetro
enabledComponentCountdebe ser mayor que0.
La enumeración XrSpatialMarkerAprilTagDictEXT se define de la siguiente manera:
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;
Diccionario de AprilTag predefinido compatible:
Descripciones de los enumerantes
XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT: 4 por 4 bits, distancia de Hamming mínima entre dos códigos = 5, 30 códigos.XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT: 5 bits por 5 bits, distancia de Hamming mínima entre dos códigos = 9, 35 códigos.XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT: 6 por 6 bits, distancia de Hamming mínima entre dos códigos cualquiera = 10, 2320 códigos.XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT: 6 por 6 bits, distancia de Hamming mínima entre dos códigos cualesquiera = 11, 587 códigos.
Configuración opcional de marcadores
Las aplicaciones deben llamar a xrEnumerateSpatialCapabilityFeaturesEXT para obtener la lista de funciones opcionales compatibles.
Consulta XrSpatialCapabilityFeatureEXT para obtener una lista completa de todas las funciones de capacidad espacial compatibles con cualquier extensión.
Tamaño del marcador
La estructura XrSpatialMarkerSizeEXT se define de la siguiente manera:
typedef struct XrSpatialMarkerSizeEXT {
XrStructureType type;
const void* next;
float markerSideLength;
} XrSpatialMarkerSizeEXT;
Descripciones de los miembros
typees el XrStructureType de esta estructura.nextesNULLo un puntero a la siguiente estructura en una cadena de estructuras.markerSideLengthes el tamaño en metros de todos los marcadores.
Si XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT se enumera con xrEnumerateSpatialCapabilityFeaturesEXT para una determinada capacidad, y si la aplicación encadena XrSpatialMarkerSizeEXT a la estructura de configuración correspondiente de esa capacidad, el tiempo de ejecución debe suponer que todos los marcadores detectados tienen un ancho y una altura de markerSideLength . Proporcionar esta información al tiempo de ejecución permite que este devuelva una posición y un tamaño más precisos. Esta estructura debe vincularse a la cadena next de XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT o XrSpatialCapabilityConfigurationAprilTagEXT .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialMarkerSizeEXT -
typedebe serXR_TYPE_SPATIAL_MARKER_SIZE_EXT -
nextdebe serNULLo un puntero válido a la siguiente estructura en una cadena de estructuras
Optimización de marcadores estáticos
La estructura XrSpatialMarkerStaticOptimizationEXT se define de la siguiente manera:
typedef struct XrSpatialMarkerStaticOptimizationEXT {
XrStructureType type;
const void* next;
XrBool32 optimizeForStaticMarker;
} XrSpatialMarkerStaticOptimizationEXT;
Descripciones de los miembros
typees el XrStructureType de esta estructura.nextesNULLo un puntero a la siguiente estructura en una cadena de estructuras.optimizeForStaticMarkerindica si se espera que todos los marcadores del espacio no se muevan.
Si XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT se enumera con xrEnumerateSpatialCapabilityFeaturesEXT para una determinada capacidad y si la aplicación encadena XrSpatialMarkerStaticOptimizationEXT a la estructura de configuración correspondiente de esa capacidad, el tiempo de ejecución debe suponer que todos los marcadores detectados son estáticos si optimizeForStaticMarker se establece en XR_TRUE . Esto permite que el tiempo de ejecución genere una pose y un tamaño más precisos. Esta estructura debe vincularse a la cadena next de XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT o XrSpatialCapabilityConfigurationAprilTagEXT .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialMarkerStaticOptimizationEXT. -
typedebe serXR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT -
nextdebe serNULLo un puntero válido a la siguiente estructura en una cadena de estructuras
Componentes garantizados
Un tiempo de ejecución que admite 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 o XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT debe proporcionar los siguientes componentes espaciales como componentes garantizados de todas las entidades descubiertas por esas capacidades, y debe enumerarlos en xrEnumerateSpatialCapabilityComponentTypesEXT :
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXTXR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT
Componente de marcador
Datos del componente
La estructura XrSpatialMarkerDataEXT se define de la siguiente manera:
typedef struct XrSpatialMarkerDataEXT {
XrSpatialCapabilityEXT capability;
uint32_t markerId;
XrSpatialBufferEXT data;
} XrSpatialMarkerDataEXT;
Descripciones de los miembros
capabilityes el XrSpatialCapabilityEXT que detectó el marcador.markerIdes el identificador codificado del marcador. En el caso de los marcadores ArUco y AprilTag, este campo debe ser válido y estar completado con el ID codificado. Para los códigos QR, este campo debe ser cero.dataes el ID del búfer y el tipo de información adicional que contiene el marcador.
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT y XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT admiten datos adicionales. Si capability es uno de los siguientes,
- Si el tiempo de ejecución decodificó correctamente los datos del marcador, debe establecer el tipo de búfer
dataenXR_SPATIAL_BUFFER_TYPE_UINT8_EXToXR_SPATIAL_BUFFER_TYPE_STRING_EXT, según los datos del marcador. El tiempo de ejecución también debe establecer un ID de búfer válido endataque la aplicación pueda usar con la funciónxrGetSpatialBuffer*adecuada para obtener los datos. - Si el tiempo de ejecución aún no decodificó los datos del marcador, debe establecer el ID de búfer
dataen XR_NULL_SPATIAL_BUFFER_ID_EXT y el tipo de búfer enXR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT.
XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT y XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT no admiten datos adicionales, y el tiempo de ejecución debe establecer el ID de búfer de data en XR_NULL_SPATIAL_BUFFER_ID_EXT .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialMarkerDataEXT -
capabilitydebe ser un valor XrSpatialCapabilityEXT válido. -
datadebe ser una estructura XrSpatialBufferEXT válida.
Estructura de la lista de componentes para consultar datos
La estructura XrSpatialComponentMarkerListEXT se define de la siguiente manera:
typedef struct XrSpatialComponentMarkerListEXT {
XrStructureType type;
void* next;
uint32_t markerCount;
XrSpatialMarkerDataEXT* markers;
} XrSpatialComponentMarkerListEXT;
Descripciones de los miembros
typees el XrStructureType de esta estructura.nextesNULLo un puntero a la siguiente estructura en una cadena de estructuras. No se definen tales estructuras en OpenXR principal ni en esta extensión.markerCountes la cantidad de elementos del miembromarkers.markerses un array de XrSpatialMarkerDataEXT .
La aplicación puede consultar el componente de marcador de las entidades espaciales en un XrSpatialSnapshotEXT agregando XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT en XrSpatialComponentDataQueryConditionEXT :: componentTypes y agregando XrSpatialComponentMarkerListEXT a la siguiente cadena de punteros de XrSpatialComponentDataQueryResultEXT .
El tiempo de ejecución debe devolver XR_ERROR_VALIDATION_FAILURE de xrQuerySpatialComponentDataEXT si XrSpatialComponentMarkerListEXT está en la siguiente cadena de XrSpatialComponentDataQueryResultEXT :: next, pero XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT no se incluye en XrSpatialComponentDataQueryConditionEXT :: componentTypes .
El tiempo de ejecución debe devolver XR_ERROR_SIZE_INSUFFICIENT de xrQuerySpatialComponentDataEXT si markerCount es menor que XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .
Uso válido (implícito)
- La extensión
XR_EXT_spatial_marker_trackingdebe habilitarse antes de usar XrSpatialComponentMarkerListEXT -
typedebe serXR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT -
nextdebe serNULLo un puntero válido a la siguiente estructura en una cadena de estructuras -
markersdebe ser un puntero a un array de estructurasmarkerCountXrSpatialMarkerDataEXT. - El parámetro
markerCountdebe ser mayor que0.
Configuración
Si XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT se enumera en XrSpatialCapabilityComponentTypesEXT :: componentTypes para alguna capacidad, una aplicación puede habilitarla si incluye el enumerador en la lista XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents de la estructura derivada XrSpatialCapabilityConfigurationBaseHeaderEXT de la capacidad que admite este componente.
Este componente no requiere ninguna configuración especial para incluirse en la cadena XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.
Componente 2D delimitado
El componente 2D delimitado proporciona el centro y las extensiones del marcador representado por la entidad en la que se encuentra. Consulta Bounded 2D para obtener más detalles sobre el componente Bounded 2D.
El XrSpatialBounded2DDataEXT :: center debe apuntar al centro del marcador. Cuando mires la cara frontal del marcador, el eje X debe apuntar hacia la derecha y el eje Y debe apuntar hacia la parte superior del marcador. El tiempo de ejecución debe seguir la convención del sistema de coordenadas a la derecha, por lo que el eje Z sale de la cara frontal del marcador. Esto significa que un marcador con una posición de {0, 0, 0}, una rotación de {0, 0, 0, 1} (sin rotación) y una extensión de {1, 1} hace referencia a un marcador de 1 m x 1 m centrado en {0, 0, 0} con su vector normal de la cara frontal apuntando hacia la dirección +Z en el espacio del componente.
A continuación, se muestra una representación de la orientación del marcador.
Figura 25. Marcador de código QR con eje
Códigos de prueba
Los siguientes códigos deben tener su plano XY dentro del documento y el eje Z apuntando hacia el visor. El origen del eje debe aparecer en el centro de cada marcador. El eje X debe apuntar hacia la derecha y el eje Y debe apuntar hacia la parte superior del documento.
Figura 26. Código QR con el texto "OpenXR"
Figura 27. AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT con ID 42
Figura 28. Marcador ArUco XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT con ID 43
Código de ejemplo
Cómo configurar la capacidad de seguimiento de códigos QR
En el siguiente ejemplo de código, se muestra cómo configurar la capacidad de seguimiento de códigos QR cuando se crea un contexto espacial.
// 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));
Descubre entidades espaciales y datos de componentes de consultas
En el siguiente ejemplo de código, se muestra cómo descubrir entidades espaciales para un contexto configurado con XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT y consultar sus datos de componentes.
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
// ...
}
Nuevas estructuras
- XrSpatialCapabilityConfigurationAprilTagEXT
- XrSpatialCapabilityConfigurationArucoMarkerEXT
- XrSpatialCapabilityConfigurationMicroQrCodeEXT
- XrSpatialCapabilityConfigurationQrCodeEXT
- XrSpatialMarkerDataEXT
Se extienden XrSpatialCapabilityConfigurationArucoMarkerEXT, XrSpatialCapabilityConfigurationAprilTagEXT, XrSpatialCapabilityConfigurationQrCodeEXT y XrSpatialCapabilityConfigurationMicroQrCodeEXT :
Extensión de XrSpatialComponentDataQueryResultEXT :
Enums nuevos
Nuevas constantes de enumeración
XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAMEXR_EXT_spatial_marker_tracking_SPEC_VERSIONExtensión 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
Extensión de XrSpatialCapabilityFeatureEXT :
XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXTXR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT
Extensión de XrSpatialComponentTypeEXT :
XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
Extensión 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
Historial de versiones
Revisión 1, 29/7/2024 (Ron Bessems, Meta)
- Descripción inicial de la extensión