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 de ratificação

Ratified

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 na 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 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 que oferece suporte aos vários recursos de rastreamento de marcadores usando xrEnumerateSpatialCapabilitiesEXT e listando 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 dos 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 que serão ativados para esse recurso.

Se houver suporte para QR codes, o ambiente de execução precisa ativar o rastreamento de QR codes quando uma estrutura XrSpatialCapabilityConfigurationQrCodeEXT for transmitida em XrSpatialContextCreateInfoEXT :: capabilityConfigs ao chamar xrCreateSpatialContextAsyncEXT .

O ambiente 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 dos 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 que serão ativados para esse recurso.

Se houver suporte para Micro QR codes, o ambiente de execução precisa ativar o rastreamento de Micro QR codes quando uma estrutura XrSpatialCapabilityConfigurationMicroQrCodeEXT for transmitida em XrSpatialContextCreateInfoEXT :: capabilityConfigs ao chamar xrCreateSpatialContextAsyncEXT .

O ambiente 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 dos 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 que serão ativados para esse recurso.
  • arUcoDict é o dicionário de marcadores a ser detectado.

Se os marcadores ArUco forem compatíveis, o ambiente 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 enumerada 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 enumerantes

  • 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 dos 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 que serão ativados para esse recurso.
  • aprilDict é o dicionário de marcadores a ser detectado.

Se as AprilTags forem compatíveis, o ambiente de execução precisará ativar o rastreamento de AprilTags quando uma estrutura XrSpatialCapabilityConfigurationAprilTagEXT 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 XrSpatialCapabilityConfigurationAprilTagEXT estiver em XrSpatialContextCreateInfoEXT :: capabilityConfigs, mas XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT não for enumerada 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 de AprilTag predefinido compatível:

Descrições de enumerantes

  • 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 de Hamming mínima 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 precisam chamar xrEnumerateSpatialCapabilityFeaturesEXT para receber a lista de recursos opcionais compatíveis.

Consulte XrSpatialCapabilityFeatureEXT para conferir 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 dos 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 ambiente de execução precisará presumir que todos os marcadores detectados têm largura e altura de markerSideLength . Ao fornecer essas informações ao ambiente de execução, ele pode retornar uma pose e um tamanho mais precisos. Essa estrutura precisa estar 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 dos 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 ambiente de execução precisará presumir que todos os marcadores detectados são estáticos se optimizeForStaticMarker estiver definido como XR_TRUE . Isso permite que o ambiente de execução gere uma pose e um tamanho mais precisos. Essa estrutura precisa estar 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 do componente

A estrutura XrSpatialMarkerDataEXT é definida como:

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

Descrições dos 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 tiver decodificado os dados do marcador, ele precisa 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 ambiente 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 ambiente de execução precisa definir o ID do buffer de data como XR_NULL_SPATIAL_BUFFER_ID_EXT .

Uso válido (implícito)

Estrutura de lista de componentes para consultar dados

A estrutura XrSpatialComponentMarkerListEXT é definida como:

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

Descrições dos membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma estrutura desse tipo é 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 ambiente 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 ambiente 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 algum recurso, um aplicativo pode ativá-lo incluindo o enumerador na lista XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents da estrutura derivada de XrSpatialCapabilityConfigurationBaseHeaderEXT do recurso 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 limitado fornece o centro e as extensões do marcador representado pela entidade em que ele está. Consulte Bounded 2D para mais detalhes sobre o componente 2D limitado.

O XrSpatialBounded2DDataEXT :: center precisa apontar para o centro do marcador. Ao olhar para a face frontal do marcador, o eixo X precisa apontar para a direita, e o eixo Y precisa apontar para a parte de cima do marcador. O ambiente de execução precisa seguir a convenção do sistema de coordenadas para destros. Assim, o eixo Z sai da face frontal 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.

eixo de compreensão de marcadores de ML de XR

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"

rastreamento de marcador externo 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 o recurso 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 consultar dados de componentes

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 do componente.

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
  • Estendendo 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
  • Estendendo XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • Estendendo 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