XR_EXT_spatial_marker_tracking

이름 문자열

XR_EXT_spatial_marker_tracking

확장 프로그램 유형

인스턴스 확장 프로그램

등록된 내선 번호

744

버전

1

승인 상태

비준됨

확장 프로그램 및 버전 종속 항목

XR_EXT_spatial_entity

도움을 주신 분들

론 베셈스, Meta
니하브 자인, Google
나탈리 플뢰리, Meta
유이치 타구치, Meta
인 리, Microsoft
지미 알람파람빌, ByteDance
지펑 리우, ByteDance
준 얀, ByteDance

개요

이 확장 프로그램은 XR_EXT_spatial_entity를 기반으로 하며 애플리케이션이 환경에서 마커를 감지하고 추적할 수 있도록 합니다. 마커는 QR 코드, 마이크로 QR 코드, ArUco 마커 또는 AprilTag를 포함할 수 있는 2D 코드입니다.

추적된 마커는 다음 구성요소가 있는 공간 항목으로 표현됩니다.

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

런타임 지원

런타임은 다음 기능 중 하나를 나열하여 xrEnumerateSpatialCapabilitiesEXT를 사용하는 다양한 마커 추적 기능에 대한 지원을 알려야 합니다(must).

  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT
  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT
  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT
  • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT

구성

마커 유형 감지를 사용 설정하려면 애플리케이션이 해당 구성 구조를 xrCreateSpatialContextAsyncEXT에 전달해야 합니다.

마커 유형 구성

QR 코드

XrSpatialCapabilityConfigurationQrCodeEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • capability는 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT여야 합니다.
  • enabledComponentCount는 enabledComponents의 요소 수가 있는 uint32_t입니다.
  • enabledComponents는 이 기능에 사용 설정할 구성요소 배열의 포인터입니다.

QR 코드가 지원되는 경우 런타임은 xrCreateSpatialContextAsyncEXT를 호출할 때 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 XrSpatialCapabilityConfigurationQrCodeEXT 구조가 전달되면 QR 코드 추적을 사용 설정해야 합니다(must).

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT가 xrEnumerateSpatialCapabilitiesEXT에 의해 열거되지 않으면 런타임은 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT를 반환해야 합니다(must).

올바른 사용 (암시적)

마이크로 QR 코드

XrSpatialCapabilityConfigurationMicroQrCodeEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • capability는 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT여야 합니다.
  • enabledComponentCount는 enabledComponents의 요소 수가 있는 uint32_t입니다.
  • enabledComponents는 이 기능에 사용 설정할 구성요소 배열의 포인터입니다.

마이크로 QR 코드가 지원되는 경우 런타임은 xrCreateSpatialContextAsyncEXT를 호출할 때 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 XrSpatialCapabilityConfigurationMicroQrCodeEXT 구조가 전달되면 마이크로 QR 코드 추적을 사용 설정해야 합니다.

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT가 xrEnumerateSpatialCapabilitiesEXT에 의해 열거되지 않으면 런타임은 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT를 반환해야 합니다(must).

올바른 사용 (암시적)

ArUco 마커

XrSpatialCapabilityConfigurationArucoMarkerEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • capability는 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT여야 합니다.
  • enabledComponentCount는 enabledComponents의 요소 수가 있는 uint32_t입니다.
  • enabledComponents는 이 기능에 사용 설정할 구성요소 배열의 포인터입니다.
  • arUcoDict는 감지할 마커 사전입니다.

ArUco 마커가 지원되는 경우 런타임은 xrCreateSpatialContextAsyncEXT를 호출할 때 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 XrSpatialCapabilityConfigurationArucoMarkerEXT 구조가 전달되면 ArUco 마커 추적을 사용 설정해야 합니다(must).

XrSpatialCapabilityConfigurationArucoMarkerEXT 구조가 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 있지만 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT가 xrEnumerateSpatialCapabilitiesEXT로 열거되지 않은 경우 런타임은 xrCreateSpatialContextAsyncEXT에서 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT를 반환해야 합니다(must).

올바른 사용 (암시적)

XrSpatialMarkerArucoDictEXT 열거형은 다음과 같이 정의됩니다.

typedef enum XrSpatialMarkerArucoDictEXT {
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT = 1,
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT = 2,
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT = 3,
    XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT = 4,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT = 5,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT = 6,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT = 7,
    XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT = 8,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT = 9,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT = 10,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT = 11,
    XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT = 12,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT = 13,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT = 14,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT = 15,
    XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT = 16,
    XR_SPATIAL_MARKER_ARUCO_DICT_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialMarkerArucoDictEXT;

지원되는 사전 정의된 ArUco 사전:

열거형 설명

  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_50_EXT: 50개의 ID가 있는 4x4픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_100_EXT: ID가 100개인 4x4픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT: 250개의 ID가 있는 4x4픽셀 ArUco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT: ID가 1,000개인 4x4픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT: ID가 50개인 5x5픽셀 ArUco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT: ID가 100개인 5x5픽셀 ArUco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT: 250개의 ID가 있는 5x5픽셀 ArUco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT: ID가 1,000개인 5x5픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT: 50개의 ID가 있는 6x6픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT: ID가 100개인 6x6픽셀 ArUco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT — ID가 250개인 6x6픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT: ID가 1,000개인 6x6픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT — ID가 50개인 7x7픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT: ID가 100개인 7x7픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_250_EXT: 250개의 ID가 있는 7x7픽셀 Aruco 마커 사전입니다.
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_1000_EXT: 1,000개의 ID가 있는 7x7픽셀 Aruco 마커 사전입니다.
AprilTags

XrSpatialCapabilityConfigurationAprilTagEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • capability는 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT여야 합니다.
  • enabledComponentCount는 enabledComponents의 요소 수가 있는 uint32_t입니다.
  • enabledComponents는 이 기능에 사용 설정할 구성요소 배열의 포인터입니다.
  • aprilDict는 감지할 마커 사전입니다.

AprilTag가 지원되는 경우 런타임은 xrCreateSpatialContextAsyncEXT를 호출할 때 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 XrSpatialCapabilityConfigurationAprilTagEXT 구조가 전달되면 AprilTag 추적을 사용 설정해야 합니다(must).

XrSpatialCapabilityConfigurationAprilTagEXT 구조가 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 있지만 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT가 xrEnumerateSpatialCapabilitiesEXT로 열거되지 않은 경우 런타임은 xrCreateSpatialContextAsyncEXT에서 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT를 반환해야 합니다(must).

올바른 사용 (암시적)

XrSpatialMarkerAprilTagDictEXT 열거형은 다음과 같이 정의됩니다.

typedef enum XrSpatialMarkerAprilTagDictEXT {
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT = 1,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT = 2,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT = 3,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT = 4,
    XR_SPATIAL_MARKER_APRIL_TAG_DICT_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialMarkerAprilTagDictEXT;

지원되는 사전 정의된 AprilTag 사전:

열거형 설명

  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_16H5_EXT — 4x4비트, 두 코드 간 최소 해밍 거리 = 5, 30개 코드
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT: 5x5비트, 두 코드 간 최소 해밍 거리 = 9, 35개 코드
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT — 6x6비트, 두 코드 간 최소 해밍 거리 = 10, 2320개 코드
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT — 6x6비트, 두 코드 간 최소 해밍 거리 = 11, 587개 코드

선택적 마커 구성

애플리케이션은 xrEnumerateSpatialCapabilityFeaturesEXT를 호출하여 지원되는 선택적 기능 목록을 가져와야 합니다(SHOULD).

확장 프로그램에서 지원하는 모든 공간 기능의 전체 목록은 XrSpatialCapabilityFeatureEXT를 참고하세요.

마커 크기

XrSpatialMarkerSizeEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • markerSideLength는 모든 마커의 크기(미터)입니다.

특정 기능에 대해 xrEnumerateSpatialCapabilityFeaturesEXT에 의해 XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT가 열거되고 애플리케이션이 XrSpatialMarkerSizeEXT를 해당 기능의 해당 구성 구조에 연결하는 경우 런타임은 감지된 모든 마커의 너비와 높이가 markerSideLength라고 가정해야 합니다(must). 이 정보를 런타임에 제공하면 런타임에서 더 정확한 포즈와 크기를 반환할 수 있습니다. 이 구조는 XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT 또는 XrSpatialCapabilityConfigurationAprilTagEXT의 next 체인에 연결되어야 합니다.

올바른 사용 (암시적)

  • XrSpatialMarkerSizeEXT를 사용하기 전에 XR_EXT_spatial_marker_tracking 확장 프로그램을 사용 설정해야 합니다(MUST).
  • type은(는) XR_TYPE_SPATIAL_MARKER_SIZE_EXT여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
정적 마커 최적화

XrSpatialMarkerStaticOptimizationEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • optimizeForStaticMarker는 공간의 모든 마커가 움직이지 않을 것으로 예상되는지 여부를 나타냅니다.

특정 기능에 대해 xrEnumerateSpatialCapabilityFeaturesEXT에서 XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT를 열거하고 애플리케이션이 XrSpatialMarkerStaticOptimizationEXT를 해당 기능의 해당 구성 구조에 연결하는 경우, optimizeForStaticMarker가 XR_TRUE로 설정되어 있으면 런타임은 감지된 모든 마커가 정적이라고 가정해야 합니다(must). 이렇게 하면 런타임에서 더 정확한 포즈와 크기를 생성할 수 있습니다. 이 구조는 XrSpatialCapabilityConfigurationQrCodeEXT, XrSpatialCapabilityConfigurationMicroQrCodeEXT, XrSpatialCapabilityConfigurationArucoMarkerEXT 또는 XrSpatialCapabilityConfigurationAprilTagEXT의 next 체인에 연결되어야 합니다.

올바른 사용 (암시적)

보장 구성요소

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를 지원하는 런타임은 다음 공간 구성요소를 이러한 기능으로 검색된 모든 항목의 보장된 구성요소로 제공해야 하며(must) xrEnumerateSpatialCapabilityComponentTypesEXT에 열거해야 합니다(must).

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

마커 구성요소

구성요소 데이터

XrSpatialMarkerDataEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • capability은 마커를 감지한 XrSpatialCapabilityEXT입니다.
  • markerId는 마커의 인코딩된 식별자입니다. ArUco 마커 및 AprilTag의 경우 이 필드는 유효해야 하며 인코딩된 ID로 채워져야 합니다. QR 코드의 경우 이 필드는 0이어야 합니다.
  • data는 마커에 포함된 추가 정보의 버퍼 ID 및 유형입니다.

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT 및 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT는 추가 데이터를 지원합니다. capability가 다음 중 하나인 경우:

  • 런타임이 마커의 데이터를 성공적으로 디코딩한 경우 마커의 데이터에 따라 data 버퍼 유형을 XR_SPATIAL_BUFFER_TYPE_UINT8_EXT 또는 XR_SPATIAL_BUFFER_TYPE_STRING_EXT로 설정해야 합니다(must). 또한 런타임은 data에 유효한 버퍼 ID를 설정해야 합니다. 애플리케이션은 이 ID를 적절한 xrGetSpatialBuffer* 함수와 함께 사용하여 데이터를 가져올 수 있습니다.
  • 런타임이 아직 마커의 데이터를 디코딩하지 않은 경우 data 버퍼 ID를 XR_NULL_SPATIAL_BUFFER_ID_EXT로, 버퍼 유형을 XR_SPATIAL_BUFFER_TYPE_UNKNOWN_EXT로 설정해야 합니다.

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT 및 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT는 추가 데이터를 지원하지 않으며 런타임은 data의 버퍼 ID를 XR_NULL_SPATIAL_BUFFER_ID_EXT로 설정해야 합니다.

올바른 사용 (암시적)

데이터를 쿼리하는 구성요소 목록 구조

XrSpatialComponentMarkerListEXT 구조는 다음과 같이 정의됩니다.

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다. 핵심 OpenXR 또는 이 확장 프로그램에는 이러한 구조가 정의되어 있지 않습니다.
  • markerCount은 markers 멤버의 요소 수입니다.
  • markers는 XrSpatialMarkerDataEXT의 배열입니다.

애플리케이션은 XrSpatialComponentDataQueryConditionEXT :: componentTypes에 XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT를 추가하고 XrSpatialComponentDataQueryResultEXT의 다음 포인터 체인에 XrSpatialComponentMarkerListEXT를 추가하여 XrSpatialSnapshotEXT에서 공간 엔티티의 마커 구성요소를 쿼리할 수 있습니다.

XrSpatialComponentMarkerListEXT가 XrSpatialComponentDataQueryResultEXT :: next의 다음 체인에 있지만 XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT가 XrSpatialComponentDataQueryConditionEXT :: componentTypes에 포함되지 않은 경우 런타임은 xrQuerySpatialComponentDataEXT에서 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must).

markerCount가 XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput보다 작은 경우 런타임은 xrQuerySpatialComponentDataEXT에서 XR_ERROR_SIZE_INSUFFICIENT를 반환해야 합니다(must).

올바른 사용 (암시적)

  • XR_EXT_spatial_marker_tracking 확장 프로그램은 XrSpatialComponentMarkerListEXT를 사용하기 전에 사용 설정해야 합니다.
  • type은(는) XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • markers는 markerCount XrSpatialMarkerDataEXT 구조의 배열에 대한 포인터여야 합니다(MUST).
  • markerCount 매개변수는 0보다 커야 합니다.
구성

일부 기능의 XrSpatialCapabilityComponentTypesEXT :: componentTypes에 XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT가 열거된 경우 애플리케이션은 이 구성요소를 지원하는 기능의 XrSpatialCapabilityConfigurationBaseHeaderEXT 파생 구조의 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 목록에 열거자를 포함하여 이를 사용 설정할 수 있습니다.

이 구성요소는 XrSpatialCapabilityConfigurationBaseHeaderEXT :: next 체인에 포함하기 위해 특별한 구성이 필요하지 않습니다.

제한된 2D 구성요소

경계가 지정된 2D 구성요소는 마커가 있는 항목으로 표현되는 마커의 중심과 범위를 제공합니다. 경계가 있는 2D 구성요소에 관한 자세한 내용은 경계가 있는 2D를 참고하세요.

XrSpatialBounded2DDataEXT :: center는 마커의 중심을 가리켜야 합니다(must). 마커의 전면을 볼 때 X축은 오른쪽을 가리키고 Y축은 마커의 상단을 가리켜야 합니다. 런타임은 오른손 좌표계 규칙을 따라야(MUST) 하므로 Z축은 마커의 앞면에서 나옵니다. 즉, 위치가 {0, 0, 0}이고 회전이 {0, 0, 0, 1} (회전 없음)이며 범위가 {1, 1}인 마커는 {0, 0, 0}을 중심으로 하는 1m x 1m 마커를 나타내며, 전면 법선 벡터는 구성요소 공간에서 +Z 방향을 가리킵니다.

마커의 방향은 아래와 같이 표시됩니다.

xr ml marker understanding axis

그림 25. 축이 있는 QR 코드 마커

테스트 코드

다음 코드는 문서 내에 X-Y 평면이 있고 Z축이 뷰어를 가리켜야 합니다. 축 원점은 각 마커의 중앙에 표시되어야 합니다. X축은 오른쪽을 가리켜야 하고 Y축은 문서 상단을 가리켜야 합니다.

ext marker tracking qr

그림 26. 'OpenXR' 텍스트가 있는 QR 코드

ext marker tracking apriltag

그림 27. ID가 42인 AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT

ext marker tracking aruco

그림 28. ID가 43인 ArUco 마커 XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT

예제 코드

QR 코드 추적 기능 구성

다음 예시 코드는 공간 컨텍스트를 만들 때 QR 코드 추적 기능을 구성하는 방법을 보여줍니다.

// Check if marker tracking capability is supported
uint32_t capabilityCount;
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, 0, &capabilityCount, nullptr));
std::vector<XrSpatialCapabilityEXT> capabilities(capabilityCount);
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, capabilityCount, &capabilityCount, capabilities.data()));

if (std::find(capabilities.begin(), capabilities.end(), XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT) == capabilities.end()) {
  return;
}

uint32_t featureCount = 0;
CHK_XR(xrEnumerateSpatialCapabilityFeaturesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT, 0, &featureCount, nullptr));
std::vector<XrSpatialCapabilityFeatureEXT> capabilityFeatures(featureCount);
CHK_XR(xrEnumerateSpatialCapabilityFeaturesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT, featureCount, &featureCount, capabilityFeatures.data()));

bool supportsFixedMarkerSize = std::find(capabilityFeatures.begin(), capabilityFeatures.end(), XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT) != capabilityFeatures.end();

// Create a spatial context
XrSpatialContextEXT spatialContext{};

// Enable the 2 guaranteed components of the qr code tracking capability
std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT,
};
XrSpatialCapabilityConfigurationQrCodeEXT markerConfiguration{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT};
markerConfiguration.capability = XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT;
markerConfiguration.enabledComponentCount = static_cast<uint32_t>(enabledComponents.size());
markerConfiguration.enabledComponents = enabledComponents.data();

// only chained if features.markerSideLength is true.
XrSpatialMarkerSizeEXT markerSize{XR_TYPE_SPATIAL_MARKER_SIZE_EXT};
markerSize.markerSideLength = 0.10f;
if (supportsFixedMarkerSize) {
  markerConfiguration.next = &markerSize;
}


std::array<XrSpatialCapabilityConfigurationBaseHeaderEXT*, 1> capabilityConfigs = {
  reinterpret_cast<XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&markerConfiguration),
};

XrSpatialContextCreateInfoEXT spatialContextCreateInfo{XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT};
spatialContextCreateInfo.capabilityConfigCount = capabilityConfigs.size();
spatialContextCreateInfo.capabilityConfigs = capabilityConfigs.data();
XrFutureEXT createContextFuture;
CHK_XR(xrCreateSpatialContextAsyncEXT(session, &spatialContextCreateInfo, &createContextFuture));

waitUntilReady(createContextFuture);

XrCreateSpatialContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};
CHK_XR(xrCreateSpatialContextCompleteEXT(session, createContextFuture, &completion));
if (completion.futureResult != XR_SUCCESS) {
  return;
}

spatialContext = completion.spatialContext;

// ...
// Discovery entities with the spatial context
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

공간 항목 및 쿼리 구성요소 데이터 탐색

다음 예시 코드는 XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT로 구성된 컨텍스트의 공간 항목을 검색하고 구성요소 데이터를 쿼리하는 방법을 보여줍니다.

XrFutureEXT future = XR_NULL_FUTURE_EXT;

// We want to look for entities that have the following components.
std::vector<XrSpatialComponentTypeEXT> snapshotComponents = {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT,
};

auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &snapshotCreateInfo, &future));

  waitUntilReady(future);

  XrCreateSpatialDiscoverySnapshotCompletionInfoEXT completionInfo{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT};
  completionInfo.baseSpace = localSpace;
  completionInfo.time = time;
  completionInfo.future = future;

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(spatialContext, &completionInfo, &completion));
  if (completion.futureResult == XR_SUCCESS) {

    // Query for the bounded2D and marker component data
    XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
    queryCond.componentTypeCount = snapshotComponents.size();
    queryCond.componentTypes = snapshotComponents.data();

    XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
    std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
    queryResult.entityIdCapacityInput = entityIds.size();
    queryResult.entityIds = entityIds.data();
    queryResult.entityStateCapacityInput = entityStates.size();
    queryResult.entityStates = entityStates.data();

    std::vector<XrSpatialBounded2DDataEXT> bounded2D(queryResult.entityIdCountOutput);
    XrSpatialComponentBounded2DListEXT bounded2DList{XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT};
    bounded2DList.boundCount = bounded2D.size();
    bounded2DList.bounds = bounded2D.data();
    queryResult.next = &bounded2DList;

    std::vector<XrSpatialMarkerDataEXT> markers;
    XrSpatialComponentMarkerListEXT markerList{XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT};
    markers.resize(queryResult.entityIdCountOutput);
    markerList.markerCount = markers.size();
    markerList.markers = markers.data();
    bounded2DList.next = &markerList;

    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      if (entityStates[i] != XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
        continue;
      }

      // 2D bounds for entity entityIds[i] is bounded2D[i].extents centered on bounded2D[i].center.

      if (markers[i].capability == XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT) {
        // Check if marker data has been decoded.
        if (markers[i].data.bufferId != XR_NULL_SPATIAL_BUFFER_ID_EXT) {
          if (markers[i].data.bufferType == XR_SPATIAL_BUFFER_TYPE_STRING_EXT) {
            // Qr Code data can be queried using
            // XrSpatialBufferGetInfoEXT getInfo{XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT};
            // info.bufferId = markers[i].data.bufferId;
            // xrGetSpatialBufferStringEXT(completion.snapshot, &getInfo, ...)
          } else if (markers[i].data.bufferType == XR_SPATIAL_BUFFER_TYPE_UINT8_EXT) {
            // Qr Code data can be queried using
            // XrSpatialBufferGetInfoEXT getInfo{XR_TYPE_SPATIAL_BUFFER_GET_INFO_EXT};
            // info.bufferId = markers[i].data.bufferId;
            // xrGetSpatialBufferUint8(completion.snapshot, &getInfo, ...)
          }
        }
      }
    }

    CHK_XR(xrDestroySpatialSnapshotEXT(completion.snapshot));
  }
};

while (1) {
  // ...
  // For every frame in frame loop
  // ...

  XrFrameState frameState;  // previously returned from xrWaitFrame
  const XrTime time = frameState.predictedDisplayTime;

  // Poll for the XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT event
  XrEventDataBuffer event = {XR_TYPE_EVENT_DATA_BUFFER};
  XrResult result = xrPollEvent(instance, &event);
  if (result == XR_SUCCESS) {
      switch (event.type) {
          case XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT: {
              const XrEventDataSpatialDiscoveryRecommendedEXT& eventdata =
                  *reinterpret_cast<XrEventDataSpatialDiscoveryRecommendedEXT*>(&event);
              // Discover spatial entities for the context that we received the "discovery
              // recommended" event for.
              discoverSpatialEntities(eventdata.spatialContext, time);
              break;
          }
      }
  }

  // ...
  // Finish frame loop
  // ...
}

새로운 구조

새 enum

새 enum 상수

  • XR_EXT_SPATIAL_MARKER_TRACKING_EXTENSION_NAME
  • XR_EXT_spatial_marker_tracking_SPEC_VERSION
  • XrSpatialCapabilityEXT 확장:

    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT
    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT
    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_MICRO_QR_CODE_EXT
    • XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT
  • XrSpatialCapabilityFeatureEXT 확장:

    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT
    • XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT
  • XrSpatialComponentTypeEXT 확장:

    • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XrStructureType 확장:

    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_APRIL_TAG_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ARUCO_MARKER_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_MICRO_QR_CODE_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_QR_CODE_EXT
    • XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT
    • XR_TYPE_SPATIAL_MARKER_SIZE_EXT
    • XR_TYPE_SPATIAL_MARKER_STATIC_OPTIMIZATION_EXT

버전 기록

  • 버전 1, 2024년 7월 29일 (론 베셈스, Meta)

    • 초기 확장 프로그램 설명