XR_EXT_spatial_marker_tracking

String de nome

XR_EXT_spatial_marker_tracking

Tipo de extensão

Extensão de instância

Número de ramal registrado

744

Revisão

1

Status da ratificação

Ratificado

Dependências de extensão e versão

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

Visão geral

Essa extensão se baseia no XR_EXT_spatial_entity e permite que os aplicativos detectem e rastreiem marcadores no ambiente. Os marcadores são códigos 2D que podem incluir QR codes, micro QR codes, marcadores ArUco ou AprilTags.

Um marcador rastreado é representado como uma entidade espacial com (ou "que tem") os seguintes componentes:

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

Suporte ao ambiente de execução

Um ambiente de execução precisa anunciar a compatibilidade com os vários recursos de rastreamento de marcadores usando xrEnumerateSpatialCapabilitiesEXT ao listar qualquer um dos seguintes recursos:

  • 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

Configuração

Para ativar a detecção de um tipo de marcador, o aplicativo precisa transmitir a estrutura de configuração correspondente para xrCreateSpatialContextAsyncEXT .

Configurações de tipo de marcador

QR codes

A estrutura XrSpatialCapabilityConfigurationQrCodeEXT é definida como:

typedef struct XrSpatialCapabilityConfigurationQrCodeEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
} XrSpatialCapabilityConfigurationQrCodeEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • capability precisa ser XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT .
  • enabledComponentCount é um uint32_t com o número de elementos em enabledComponents .
  • enabledComponents é um ponteiro para uma matriz de componentes a serem ativados para essa capacidade.

Se os QR codes forem compatíveis, o tempo de execução deverá ativar o rastreamento de QR code quando uma estrutura XrSpatialCapabilityConfigurationQrCodeEXT for transmitida em XrSpatialContextCreateInfoEXT :: capabilityConfigs ao chamar xrCreateSpatialContextAsyncEXT .

O tempo de execução precisa retornar XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT se XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT não for enumerado por xrEnumerateSpatialCapabilitiesEXT .

Uso válido (implícito)

Micro QR codes

A estrutura XrSpatialCapabilityConfigurationMicroQrCodeEXT é definida como:

typedef struct XrSpatialCapabilityConfigurationMicroQrCodeEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
} XrSpatialCapabilityConfigurationMicroQrCodeEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • capability precisa ser XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT .
  • enabledComponentCount é um uint32_t com o número de elementos em enabledComponents .
  • enabledComponents é um ponteiro para uma matriz de componentes a serem ativados para essa capacidade.

Se os Micro QR codes forem compatíveis, o tempo de execução deverá ativar o rastreamento de Micro QR code quando uma estrutura XrSpatialCapabilityConfigurationMicroQrCodeEXT for transmitida em XrSpatialContextCreateInfoEXT :: capabilityConfigs ao chamar xrCreateSpatialContextAsyncEXT .

O tempo de execução precisa retornar XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT se XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT não for enumerado por xrEnumerateSpatialCapabilitiesEXT .

Uso válido (implícito)

Marcadores ArUco

A estrutura XrSpatialCapabilityConfigurationArucoMarkerEXT é definida como:

typedef struct XrSpatialCapabilityConfigurationArucoMarkerEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
    XrSpatialMarkerArucoDictEXT         arUcoDict;
} XrSpatialCapabilityConfigurationArucoMarkerEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • capability precisa ser XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT .
  • enabledComponentCount é um uint32_t com o número de elementos em enabledComponents .
  • enabledComponents é um ponteiro para uma matriz de componentes a serem ativados para essa capacidade.
  • arUcoDict é o dicionário de marcadores a ser detectado.

Se os marcadores ArUco forem compatíveis, o tempo de execução precisa ativar o rastreamento de marcadores ArUco quando uma estrutura XrSpatialCapabilityConfigurationArucoMarkerEXT for transmitida em XrSpatialContextCreateInfoEXT :: capabilityConfigs ao chamar xrCreateSpatialContextAsyncEXT .

O ambiente de execução precisa retornar XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT de xrCreateSpatialContextAsyncEXT se uma estrutura XrSpatialCapabilityConfigurationArucoMarkerEXT estiver em XrSpatialContextCreateInfoEXT :: capabilityConfigs, mas XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT não for enumerado por xrEnumerateSpatialCapabilitiesEXT .

Uso válido (implícito)

A enumeração XrSpatialMarkerArucoDictEXT é definida como:

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;

Dicionário ArUco predefinido compatível:

Descrições de enumeradores

  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT: dicionário de marcadores Aruco de 4 por 4 pixels com 50 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT: dicionário de marcadores Aruco de 4 por 4 pixels com 100 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT: dicionário de marcadores Aruco de 4 por 4 pixels com 250 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT: dicionário de marcadores Aruco de 4 por 4 pixels com 1.000 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT: dicionário de marcadores Aruco de 5 por 5 pixels com 50 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT: dicionário de marcadores Aruco de 5 por 5 pixels com 100 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT: dicionário de marcadores Aruco de 5 por 5 pixels com 250 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT: dicionário de marcadores Aruco de 5 por 5 pixels com 1.000 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT: dicionário de marcadores Aruco de 6 por 6 pixels com 50 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT: dicionário de marcadores Aruco de 6 por 6 pixels com 100 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT: dicionário de marcadores Aruco de 6 por 6 pixels com 250 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT: dicionário de marcadores Aruco de 6 por 6 pixels com 1.000 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT: dicionário de marcadores Aruco de 7 por 7 pixels com 50 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT: dicionário de marcadores Aruco de 7 por 7 pixels com 100 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT: dicionário de marcadores Aruco de 7 por 7 pixels com 250 IDs.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT: dicionário de marcadores Aruco de 7 por 7 pixels com 1.000 IDs.
AprilTags

A estrutura XrSpatialCapabilityConfigurationAprilTagEXT é definida como:

typedef struct XrSpatialCapabilityConfigurationAprilTagEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
    XrSpatialMarkerAprilTagDictEXT      aprilDict;
} XrSpatialCapabilityConfigurationAprilTagEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • capability precisa ser XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT .
  • enabledComponentCount é um uint32_t com o número de elementos em enabledComponents .
  • enabledComponents é um ponteiro para uma matriz de componentes a serem ativados para essa capacidade.
  • aprilDict é o dicionário de marcadores a ser detectado.

Se os AprilTags forem compatíveis, o tempo de execução deverá ativar o rastreamento de AprilTag quando uma estrutura XrSpatialCapabilityConfigurationAprilTagEXT for transmitida em XrSpatialContextCreateInfoEXT :: capabilityConfigs ao chamar xrCreateSpatialContextAsyncEXT .

O ambiente de execução deve retornar XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT de xrCreateSpatialContextAsyncEXT se uma estrutura XrSpatialCapabilityConfigurationAprilTagEXT estiver em XrSpatialContextCreateInfoEXT :: capabilityConfigs, mas XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT não for enumerado por xrEnumerateSpatialCapabilitiesEXT .

Uso válido (implícito)

A enumeração XrSpatialMarkerAprilTagDictEXT é definida como:

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;

Dicionário predefinido do AprilTag compatível:

Descrições de enumeradores

  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT: 4 por 4 bits, distância de Hamming mínima entre dois códigos = 5, 30 códigos.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT: 5 por 5 bits, distância de Hamming mínima entre dois códigos = 9, 35 códigos.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT: 6 por 6 bits, distância mínima de Hamming entre dois códigos = 10, 2.320 códigos.
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT: 6 por 6 bits, distância mínima de Hamming entre dois códigos = 11, 587 códigos.

Configurações opcionais de marcadores

Os aplicativos devem chamar xrEnumerateSpatialCapabilityFeaturesEXT para receber a lista de recursos opcionais compatíveis.

Consulte XrSpatialCapabilityFeatureEXT para uma lista completa de todos os recursos de capacidade espacial compatíveis com qualquer extensão.

Tamanho do marcador

A estrutura XrSpatialMarkerSizeEXT é definida como:

typedef struct XrSpatialMarkerSizeEXT {
    XrStructureType    type;
    const void*        next;
    float              markerSideLength;
} XrSpatialMarkerSizeEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • markerSideLength é o tamanho em metros de todos os marcadores.

Se XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT for enumerado por xrEnumerateSpatialCapabilityFeaturesEXT para um determinado recurso e se o aplicativo encadear XrSpatialMarkerSizeEXT à estrutura de configuração correspondente desse recurso, o tempo de execução deverá presumir que todos os marcadores detectados têm largura e altura de markerSideLength . Ao fornecer essas informações para o tempo de execução, ele pode retornar uma postura e um tamanho mais precisos. Essa estrutura precisa ser vinculada à cadeia next de XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT ou XrSpatialCapabilityConfigurationAprilTagEXT .

Uso válido (implícito)

Otimização de marcadores estáticos

A estrutura XrSpatialMarkerStaticOptimizationEXT é definida como:

typedef struct XrSpatialMarkerStaticOptimizationEXT {
    XrStructureType    type;
    const void*        next;
    XrBool32           optimizeForStaticMarker;
} XrSpatialMarkerStaticOptimizationEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • optimizeForStaticMarker indica se todos os marcadores no espaço não devem se mover.

Se XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT for enumerado por xrEnumerateSpatialCapabilityFeaturesEXT para um determinado recurso e se o aplicativo encadear XrSpatialMarkerStaticOptimizationEXT à estrutura de configuração correspondente desse recurso, o tempo de execução deverá presumir que todos os marcadores detectados são estáticos se optimizeForStaticMarker estiver definido como XR_TRUE . Isso permite que o tempo de execução gere uma postura e um tamanho mais precisos. Essa estrutura precisa ser vinculada à cadeia next de XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT ou XrSpatialCapabilityConfigurationAprilTagEXT .

Uso válido (implícito)

Componentes garantidos

Um ambiente de execução que oferece suporte a 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 precisa fornecer os seguintes componentes espaciais como componentes garantidos de todas as entidades descobertas por esses recursos e precisa enumerá-los em xrEnumerateSpatialCapabilityComponentTypesEXT :

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

Componente de marcador

Dados de componentes

A estrutura XrSpatialMarkerDataEXT é definida da seguinte forma:

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

Descrições de membros

  • capability é o XrSpatialCapabilityEXT que detectou o marcador.
  • markerId é o identificador codificado do marcador. Para marcadores ArUco e AprilTag, esse campo precisa ser válido e preenchido com o ID codificado. Para QR codes, esse campo precisa ser zero.
  • data é o ID do buffer e o tipo de informação adicional contida no marcador.

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT e XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT são compatíveis com dados extras. Se capability for um destes:

  • Se o ambiente de execução decodificar os dados do marcador, ele deverá definir o tipo de buffer data como XR_SPATIAL_BUFFER_TYPE_UINT8_EXT ou XR_SPATIAL_BUFFER_TYPE_STRING_EXT , dependendo dos dados no marcador. O ambiente de execução também precisa definir um ID de buffer válido em data, que o aplicativo pode usar com a função xrGetSpatialBuffer* adequada para receber os dados.
  • Se o tempo de execução ainda não tiver decodificado os dados do marcador, ele precisa definir o ID do buffer data como XR_NULL_SPATIAL_BUFFER_ID_EXT e o tipo de buffer como XR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT .

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT e XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT não são compatíveis com dados extras, e o tempo de execução precisa definir o ID do buffer de data como XR_NULL_SPATIAL_BUFFER_ID_EXT .

Uso válido (implícito)

Estrutura da lista de componentes para consultar dados

A estrutura XrSpatialComponentMarkerListEXT é definida da seguinte maneira:

typedef struct XrSpatialComponentMarkerListEXT {
    XrStructureType            type;
    void*                      next;
    uint32_t                   markerCount;
    XrSpatialMarkerDataEXT*    markers;
} XrSpatialComponentMarkerListEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma dessas estruturas está definida no OpenXR principal ou nesta extensão.
  • markerCount é o número de elementos no membro markers.
  • markers é uma matriz de XrSpatialMarkerDataEXT .

O aplicativo pode consultar o componente de marcador das entidades espaciais em um XrSpatialSnapshotEXT adicionando XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT em XrSpatialComponentDataQueryConditionEXT :: componentTypes e adicionando XrSpatialComponentMarkerListEXT à próxima cadeia de ponteiros de XrSpatialComponentDataQueryResultEXT .

O tempo de execução precisa retornar XR_ERROR_VALIDATION_FAILURE de xrQuerySpatialComponentDataEXT se XrSpatialComponentMarkerListEXT estiver na próxima cadeia de XrSpatialComponentDataQueryResultEXT :: next, mas XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT não estiver incluído em XrSpatialComponentDataQueryConditionEXT :: componentTypes .

O tempo de execução precisa retornar XR_ERROR_SIZE_INSUFFICIENT de xrQuerySpatialComponentDataEXT se markerCount for menor que XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

Uso válido (implícito)

Configuração

Se XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT for enumerado em XrSpatialCapabilityComponentTypesEXT :: componentTypes para alguma capacidade, um aplicativo poderá ativar incluindo o enumerador na lista XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents da estrutura derivada XrSpatialCapabilityConfigurationBaseHeaderEXT da capacidade que oferece suporte a esse componente.

Esse componente não requer nenhuma configuração especial para ser incluído na cadeia XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.

Componente 2D limitado

O componente 2D delimitado fornece o centro e as extensões do marcador representado pela entidade em que ele está. Consulte 2D delimitado para mais detalhes sobre o componente 2D delimitado.

O XrSpatialBounded2DDataEXT :: center precisa apontar para o centro do marcador. Ao olhar para a frente do marcador, o eixo X precisa apontar para a direita, e o eixo Y precisa apontar para a parte de cima do marcador. O tempo de execução precisa seguir a convenção do sistema de coordenadas orientado para a direita. Assim, o eixo Z sai da frente do marcador. Isso significa que um marcador com uma posição de {0, 0, 0}, rotação de {0, 0, 0, 1} (sem rotação) e uma extensão de {1, 1} se refere a um marcador de 1 metro x 1 metro centralizado em {0, 0, 0} com o vetor normal da face frontal apontando para a direção +Z no espaço do componente.

Confira abaixo uma representação da orientação do marcador.

xr ml marker understanding axis

Figura 25. Marcador de QR code com eixo

Códigos de teste

Os códigos a seguir precisam ter o plano X-Y dentro do documento e o eixo Z apontando para o espectador. A origem do eixo precisa aparecer no centro de cada marcador. O eixo X precisa apontar para a direita, e o eixo Y precisa apontar para a parte de cima do documento.

ext marker tracking qr

Figura 26. QR code com o texto "OpenXR"

ext marker tracking apriltag

Figura 27. AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT com ID 42

ext marker tracking aruco

Figura 28. Marcador ArUco XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT com ID 43

Código de exemplo

Configurar a capacidade de rastreamento de QR code

O exemplo de código a seguir demonstra como configurar o recurso de rastreamento de QR code ao criar um 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));

Descobrir entidades espaciais e dados de componentes de consulta

O exemplo de código a seguir demonstra como descobrir entidades espaciais para um contexto configurado com XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT e consultar os dados de componentes dele.

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

Novas estruturas

Novos tipos enumerados

Novas constantes de tipo enumerado

  • XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAME
  • XR_EXT_spatial_marker_tracking_SPEC_VERSION
  • Extensão de 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
  • Estendendo XrSpatialCapabilityFeatureEXT :

    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT
    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT
  • Extensão de XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • Extensão de 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

Histórico de versões

  • Revisão 1, 29/07/2024 (Ron Bessems, Meta)

    • Descrição inicial da extensão