XR_EXT_spatial_marker_tracking

Name String

XR_EXT_spatial_marker_tracking

拡張機能の種類

インスタンス拡張

登録済みの内線番号

744

リビジョン

1

承認ステータス

批准

拡張機能とバージョンの依存関係

XR_EXT_spatial_entity

寄与者

Ron Bessems、Meta
Nihav Jain、Google
Natalie Fleury、Meta
Yuichi Taguchi、Meta
Yin Li、Microsoft
Jimmy Alamparambil、ByteDance
Zhipeng Liu、ByteDance
Jun Yan、ByteDance

概要

この拡張機能は XR_EXT_spatial_entity をベースにしており、アプリが環境内のマーカーを検出して追跡できるようにします。マーカーは 2D コードで、QR コード、マイクロ QR コード、ArUco マーカー、AprilTag などがあります。

追跡対象マーカーは、次のコンポーネントを持つ空間エンティティとして表されます。

  • XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT
  • XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT

ランタイム サポート

ランタイムは、xrEnumerateSpatialCapabilitiesEXT を使用して、次のいずれかの機能をリストすることで、さまざまなマーカー トラッキング機能のサポートをアドバタイズしなければなりません。

  • 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 コード トラッキングを有効にしなければなりません。

XR_SPATIAL_CAPABILITY_MARKER_TRACKING_QR_CODE_EXT が xrEnumerateSpatialCapabilitiesEXT によって列挙されていない場合、ランタイムは XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT を返さなければなりません。

有効な使用方法(暗黙的)

マイクロ 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 を返さなければなりません。

有効な使用方法(暗黙的)

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 マーカー トラッキングを有効にしなければなりません。

XrSpatialCapabilityConfigurationArucoMarkerEXT 構造体が XrSpatialContextCreateInfoEXT :: capabilityConfigs にあるが、XR_SPATIAL_CAPABILITY_MARKER_TRACKING_ARUCO_MARKER_EXT が xrEnumerateSpatialCapabilitiesEXT によって列挙されていない場合、ランタイムは xrCreateSpatialContextAsyncEXT から XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT を返さなければなりません。

有効な使用方法(暗黙的)

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 - 100 個の ID を持つ 4x4 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_250_EXT - 250 個の ID を持つ 4x4 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_4X4_1000_EXT - 1,000 個の ID を持つ 4x4 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_50_EXT - 50 個の ID を持つ 5x5 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_100_EXT - 100 個の ID を持つ 5x5 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_250_EXT - 250 個の ID を持つ 5x5 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_5X5_1000_EXT - 1,000 個の ID を持つ 5x5 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_50_EXT - 50 個の ID を持つ 6x6 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_100_EXT - 100 個の ID を持つ 6x6 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_250_EXT - 250 個の ID を持つ 6x6 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_6X6_1000_EXT - 1,000 個の ID を持つ 6x6 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_50_EXT - 50 個の ID を持つ 7x7 ピクセルの Aruco マーカー辞書。
  • XR_SPATIAL_MARKER_ARUCO_DICT_7X7_100_EXT - 100 個の ID を持つ 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 マーカー辞書。
AprilTag

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 トラッキングを有効にしなければなりません。

XrSpatialCapabilityConfigurationAprilTagEXT 構造体が XrSpatialContextCreateInfoEXT :: capabilityConfigs にあるが、XR_SPATIAL_CAPABILITY_MARKER_TRACKING_APRIL_TAG_EXT が xrEnumerateSpatialCapabilitiesEXT によって列挙されていない場合、ランタイムは xrCreateSpatialContextAsyncEXT から XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT を返さなければなりません。

有効な使用方法(暗黙的)

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 ビット、任意の 2 つのコード間の最小ハミング距離 = 5、30 コード。
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_25H9_EXT - 5x5 ビット、任意の 2 つのコード間の最小ハミング距離 = 9、35 コード。
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H10_EXT - 6x6 ビット、任意の 2 つのコード間の最小ハミング距離 = 10、2,320 コード。
  • XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT - 6x6 ビット、任意の 2 つのコード間の最小ハミング距離 = 11、587 コード。

オプションのマーカー構成

アプリは、xrEnumerateSpatialCapabilityFeaturesEXT を呼び出して、サポートされているオプション機能のリストを取得すべきです。

拡張機能でサポートされているすべての空間機能の一覧については、XrSpatialCapabilityFeatureEXT をご覧ください。

マーカーのサイズ

XrSpatialMarkerSizeEXT 構造体は次のように定義されます。

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

メンバーの説明

  • type は、この構造の XrStructureType です。
  • next は、NULL または構造体チェーン内の次の構造体へのポインタです。
  • markerSideLength は、すべてのマーカーのサイズ(メートル単位)です。

XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_FIXED_SIZE_MARKERS_EXT が特定の機能の xrEnumerateSpatialCapabilityFeaturesEXT によって列挙され、アプリが XrSpatialMarkerSizeEXT をその機能の対応する構成構造にチェーンする場合、ランタイムは、検出されたすべてのマーカーの幅と高さが markerSideLength であると想定しなければなりません。この情報をランタイムに提供することで、ランタイムはより正確なポーズとサイズを返すことができます。この構造体は、XrSpatialCapabilityConfigurationQrCodeEXT、XrSpatialCapabilityConfigurationMicroQrCodeEXT、XrSpatialCapabilityConfigurationArucoMarkerEXT、XrSpatialCapabilityConfigurationAprilTagEXT の next チェーンにリンクする必要があります。

有効な使用方法(暗黙的)

  • XrSpatialMarkerSizeEXT を使用する前に、XR_EXT_spatial_marker_tracking 拡張機能を有効にしなければなりません。
  • 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 は、スペース内のすべてのマーカーが移動しないことが想定されているかどうかを示します。

XR_SPATIAL_CAPABILITY_FEATURE_MARKER_TRACKING_STATIC_MARKERS_EXT が特定の機能の xrEnumerateSpatialCapabilityFeaturesEXT によって列挙され、アプリケーションが XrSpatialMarkerStaticOptimizationEXT をその機能の対応する構成構造にチェーンする場合、optimizeForStaticMarker が XR_TRUE に設定されている場合、ランタイムは検出されたすべてのマーカーが静的であると想定しなければなりません。これにより、ランタイムはより正確なポーズとサイズを生成できます。この構造体は、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 をサポートするランタイムは、これらの機能によって検出されたすべてのエンティティの保証コンポーネントとして、次の空間コンポーネントを提供しなければなりません。また、xrEnumerateSpatialCapabilityComponentTypesEXT でそれらを列挙しなければなりません。

  • 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 に設定しなければなりません。また、ランタイムは、data に有効なバッファ ID を設定する必要があります。アプリは、適切な xrGetSpatialBuffer* 関数でこのバッファ ID を使用して、データを取得できます。
  • ランタイムがマーカーのデータをまだデコードしていない場合、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 を返さなければなりません。

markerCount が XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput より小さい場合、ランタイムは xrQuerySpatialComponentDataEXT から XR_ERROR_SIZE_INSUFFICIENT を返さなければなりません。

有効な使用方法(暗黙的)

  • XrSpatialComponentMarkerListEXT を使用する前に、XR_EXT_spatial_marker_tracking 拡張機能を有効にする必要があります。
  • type は XR_TYPE_SPATIAL_COMPONENT_MARKER_LIST_EXT にする必要があります。
  • next は、NULL または構造体チェーン内の次の構造体への有効なポインタでなければなりません。
  • markers は、markerCount XrSpatialMarkerDataEXT 構造体の配列へのポインタでなければなりません。
  • markerCount パラメータは 0 より大きい値にする必要があります。
構成

XR_SPATIAL_COMPONENT_TYPE_MARKER_EXT が XrSpatialCapabilityComponentTypesEXT :: componentTypes で列挙されている場合、アプリは、このコンポーネントをサポートする機能の XrSpatialCapabilityConfigurationBaseHeaderEXT 派生構造の XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents リストに列挙子を含めることで、この機能を有効にできます。

このコンポーネントを XrSpatialCapabilityConfigurationBaseHeaderEXT :: next チェーンに含めるために、特別な構成は必要ありません。

境界付き 2D コンポーネント

境界付き 2D コンポーネントは、それが配置されているエンティティによって表されるマーカーの中心と範囲を提供します。境界付き 2D コンポーネントの詳細については、境界付き 2D をご覧ください。

XrSpatialBounded2DDataEXT :: center は、マーカーの中心を指さなければなりません。マーカーの前面を見たときに、X 軸は右を指し、Y 軸はマーカーの上部を指す必要があります。ランタイムは右手座標系の規則に従う必要があります。したがって、Z 軸はマーカーの前面から出ます。つまり、位置が {0, 0, 0}、回転が {0, 0, 0, 1}(回転なし)、範囲が {1, 1} のマーカーは、{0, 0, 0} を中心とする 1 m x 1 m のマーカーを指し、その前面の法線ベクトルはコンポーネントの空間で +Z 方向を指します。

マーカーの向きを以下に示します。

xr ml marker understanding axis

図 25. 軸付きの QR コード マーカー

テストコード

次のコードは、X-Y 平面がドキュメント内にあり、Z 軸が閲覧者を向いている必要があります。軸の原点は、各マーカーの中心に表示される必要があります。X 軸は右を指し、Y 軸はドキュメントの上部を指す必要があります。

外部マーカー トラッキング QR

図 26. 「OpenXR」というテキストを含む QR コード

外部マーカー トラッキング apriltag

図 27. ID 42 の AprilTag XR_SPATIAL_MARKER_APRIL_TAG_DICT_36H11_EXT

外部マーカー トラッキング 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
  // ...
}

新しい構造

新しい列挙型

新しい列挙型定数

  • 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-07-29(Ron Bessems、Meta)

    • 拡張機能の初期説明