XR_ANDROID_spatial_annotation_tracking

Name String

XR_ANDROID_spatial_annotation_tracking

擴充功能類型

執行個體擴充功能

擴充功能註冊編號

795

修訂版本

1

批准狀態

未批准

擴充功能和版本依附元件

XR_EXT_spatial_entity
和
XR_EXT_spatial_image_tracking

上次修改日期

2026-01-12

IP 狀態

沒有已知的智慧財產權聲明。

著作人

Levana Chen, Google
Christopher Feil, Google
Martin Sundermeyer, Google
David Joseph Tan, Google
Jared Finder, Google
Nihav Jain, Google

總覽

這項擴充功能可為 XR_EXT_spatial_entity 擴充功能提供註解追蹤功能,追蹤場景中的各種註解。應用程式可透過這項功能,在執行階段參照定義的實體或虛擬物件上放置疊加層。

這項擴充功能提供基本註解類型「Quad」,這是一種恰好有 4 個邊的多邊形,即凸四邊形,代表執行階段參考中的一般化 2D 定界框。追蹤四邊形註解會以空間實體表示,並包含下列元件:

  • XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID

應用程式通常可以透過下列模式,使用空間註解追蹤擴充功能:

  • 應用程式會先建立 XrSpatialReferenceCacheANDROID 控制代碼,開始記錄指定來源的執行階段參考資料。
  • 接著,應用程式會擷取 XrSpatialReferenceImageEXT 的執行階段參照,並在參照快取的期間內,在參照中定義所需的註解。
  • 接著,應用程式會根據 XrSpatialCapabilityConfigurationAnnotationTrackingANDROID 提供的 XrSpatialReferenceImageEXT,建立 XrSpatialContextEXT 控制代碼。
  • 應用程式可以刪除 XrSpatialReferenceCacheANDROID 控制代碼,停止記錄執行階段參考資料,以減少記憶體用量,或等待 XR_TYPE_EVENT_DATA_SPATIAL_ANNOTATION_TRACKING_ANDROID 事件確認初始化結果。
  • 接著,應用程式會提取 XR_TYPE_EVENT_DATA_SPATIAL_ANNOTATION_TRACKING_ANDROID 事件,確認註解的初始化結果。
  • 如果初始化成功,應用程式可以提取 XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT 事件來追蹤註解。
  • 如果初始化失敗,應用程式可以使用事件中傳回的錯誤代碼判斷失敗原因,並刪除現有的 XrSpatialContextEXT 控制代碼,開始新的註解。
  • 無論初始化結果為何,應用程式在收到事件後,可以釋放圖片緩衝區,減少記憶體用量。
  • 應用程式會根據空間實體存取模式,探索及查詢註解。
  • 在有效的 XrSpatialReferenceCacheANDROID 期間,應用程式可以建立額外的 XrSpatialContextEXT 控制代碼,追蹤新參照中的註解。
  • 應用程式可以刪除 XrSpatialContextEXT 控制代碼,在執行階段動態減少可偵測和追蹤的註解。

執行階段支援

執行階段必須使用 xrEnumerateSpatialCapabilitiesEXT 列出下列功能,宣告支援註解追蹤功能:

  • XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID

如果執行階段支援註解追蹤功能:

xrEnumerateSpatialAnnotationReferenceSourcesANDROID 函式的定義如下:

XrResult xrEnumerateSpatialAnnotationReferenceSourcesANDROID(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    XrSpatialCapabilityEXT                      capability,
    uint32_t                                    sourceCapacityInput,
    uint32_t*                                   sourceCountOutput,
    XrSpatialAnnotationReferenceSourceANDROID*  sources);

參數說明

  • instance 是 XrInstance 的控制代碼。
  • systemId 是要列舉參考來源的 XrSystemId。
  • capability 是 XrSpatialCapabilityEXT,用於列舉參考來源。
  • sourceCapacityInput 是 sources 陣列的容量,或 0 表示要求擷取所需容量。
  • sourceCountOutput 是來源數量,或 sourceCapacityInput 不足時所需的容量。
  • sources 是 XrSpatialAnnotationReferenceSourceANDROID 的陣列。如果 sourceCapacityInput 為 0,則可以是 NULL。
  • 如要進一步瞭解如何擷取必要的 sources 大小,請參閱「緩衝區大小參數」一節。

應用程式可以使用 xrEnumerateSpatialAnnotationReferenceSourcesANDROID 列舉特定 XrSystemId 支援的參考來源清單。

執行階段「不得」列舉未啟用 instance 擴充功能的參考來源。

有效用途 (隱含)

傳回代碼

成功

  • XR_SUCCESS

失敗

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SIZE_INSUFFICIENT
  • XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT
  • XR_ERROR_SYSTEM_INVALID
  • XR_ERROR_VALIDATION_FAILURE

typedef enum XrSpatialAnnotationReferenceSourceANDROID {
    XR_SPATIAL_ANNOTATION_REFERENCE_SOURCE_CAMERA_ANDROID = 0,
    XR_SPATIAL_ANNOTATION_REFERENCE_SOURCE_MEDIA_PROJECTION_ANDROID = 1,
    XR_SPATIAL_ANNOTATION_REFERENCE_SOURCE_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrSpatialAnnotationReferenceSourceANDROID;

XrSpatialAnnotationReferenceSourceANDROID 列舉會說明參考資料的來源,提供註解的中繼資料。

列舉的意義如下:

列舉說明

XR_SPATIAL_ANNOTATION_REFERENCE_SOURCE_CAMERA_ANDROID

參考圖像須為 Android 相機 API 輸出的未裁剪圖像,例如與 Camera2 CameraDevice 相關聯的 ImageReader 圖像,或與 CameraX 相關聯的 ImageAnalysis ImageProxy。這通常是朝前的其中一個 RGB 鏡頭。

XR_SPATIAL_ANNOTATION_REFERENCE_SOURCE_MEDIA_PROJECTION_ANDROID

參考圖像為 Android MediaProjection API 輸出的未裁剪圖片,例如與 MediaProjection 虛擬螢幕相關聯的 ImageReader 圖片。其中可能包含虛擬和真實內容。

XrSystemSpatialAnnotationPropertiesANDROID 結構定義如下:

typedef struct XrSystemSpatialAnnotationPropertiesANDROID {
    XrStructureType    type;
    void*              next;
    uint32_t           referenceCacheTimespan;
    uint32_t           maxReferencePixelWidth;
    uint32_t           maxReferencePixelHeight;
    uint32_t           maxReferenceCount;
    uint32_t           maxAnnotationCount;
} XrSystemSpatialAnnotationPropertiesANDROID;

成員說明

  • type 是這個結構的 XrStructureType。
  • next 是 NULL,或指向結構鏈中下一個結構的指標。
  • referenceCacheTimespan 表示有效 XrSpatialReferenceCacheANDROID 控制代碼的時間範圍 (以秒為單位)。
  • maxReferencePixelWidth:參考圖像邊緣的最大寬度 (以像素為單位)。
  • maxReferencePixelHeight:參考圖像邊緣的高度上限 (以像素為單位)。
  • maxReferenceCount 表示同時分配的參考圖像數量上限。
  • maxAnnotationCount 表示同時追蹤的註解數量上限。

如果執行階段支援註解追蹤功能,應用程式可以在呼叫 xrGetSystemProperties 時,將 XrSystemSpatialAnnotationPropertiesANDROID 結構鏈結至 XrSystemProperties,藉此檢查相關系統屬性。

如果 XrSpatialCapabilityConfigurationAnnotationTrackingANDROID :: reference 的 XrSpatialReferenceImageEXT :: width 超過 maxReferencePixelWidth,執行階段在呼叫 xrCreateSpatialContextAsyncEXT 時必須傳回 XR_ERROR_VALIDATION_FAILURE。

如果 XrSpatialCapabilityConfigurationAnnotationTrackingANDROID :: reference 的 XrSpatialReferenceImageEXT :: height 超過 maxReferencePixelHeight,執行階段在呼叫 xrCreateSpatialContextAsyncEXT 時必須傳回 XR_ERROR_VALIDATION_FAILURE。

如果 XrSpatialCapabilityConfigurationAnnotationTrackingANDROID :: time 超出 XrSpatialReferenceCacheANDROID :: cache 的時間範圍,執行階段在呼叫 xrCreateSpatialContextAsyncEXT 時必須傳回 XR_ERROR_TIME_INVALID。在 XrSpatialReferenceCacheANDROID 的時間範圍內,應用程式可以使用新的參考資料重新建立 XrSpatialContextEXT 控制代碼。

如果分配的參考圖像數量超過 maxReferenceCount,執行階段必須傳回 XR_ERROR_LIMIT_REACHED,並透過 XrEventDataSpatialAnnotationTrackingANDROID :: initializationResult 指出初始化失敗。應用程式可以刪除 XrSpatialContextEXT 控制代碼,並在待處理的初始化作業完成後重試。

如果有效註解數量超過 maxAnnotationCount,執行階段在呼叫 xrCreateSpatialContextAsyncEXT 時「必須」傳回 XR_ERROR_VALIDATION_FAILURE。

有效用途 (隱含)

執行階段參考資料快取

XR_DEFINE_HANDLE(XrSpatialReferenceCacheANDROID)

XrSpatialReferenceCacheANDROID 控制代碼代表從指定來源記錄的執行階段參考資料快取。

xrCreateSpatialReferenceCacheAsyncANDROID 函式的定義如下:

XrResult xrCreateSpatialReferenceCacheAsyncANDROID(
    XrSession                                   session,
    const XrSpatialReferenceCacheCreateInfoANDROID* createInfo,
    XrFutureEXT*                                future);

參數說明

應用程式可以呼叫 xrCreateSpatialReferenceCacheAsyncANDROID,建立 XrSpatialReferenceCacheANDROID 控制代碼。執行階段可能需要一些時間才能初始化追蹤服務。應用程式可以重複呼叫 xrCreateSpatialReferenceCacheCompleteANDROID,檢查這項非同步作業是否完成。

如果 xrEnumerateSpatialCapabilitiesEXT 未列出 XrSpatialReferenceCacheCreateInfoANDROID :: capability,執行階段必須傳回 XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT。

如果 xrEnumerateSpatialAnnotationReferenceSourcesANDROID 未針對指定功能列出 XrSpatialReferenceCacheCreateInfoANDROID :: source,執行階段必須傳回 XR_ERROR_FEATURE_UNSUPPORTED。

應用程式只能為指定功能的每個來源建立一個控制代碼。否則,執行階段必須傳回 XR_ERROR_LIMIT_REACHED。

應用程式可以在 XrSpatialReferenceCacheANDROID 控制代碼的時間範圍內擷取執行階段參照,設定新的 XrSpatialContextEXT 控制代碼。

有效用途 (隱含)

傳回代碼

成功

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

失敗

  • XR_ERROR_FEATURE_UNSUPPORTED
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CAPABILITY_UNSUPPORTED_EXT
  • XR_ERROR_VALIDATION_FAILURE

XrSpatialReferenceCacheCreateInfoANDROID 結構定義如下:

typedef struct XrSpatialReferenceCacheCreateInfoANDROID {
    XrStructureType                              type;
    const void*                                  next;
    XrSpatialCapabilityEXT                       capability;
    XrSpatialAnnotationReferenceSourceANDROID    source;
} XrSpatialReferenceCacheCreateInfoANDROID;

成員說明

XrSpatialReferenceCacheCreateInfoANDROID 結構描述建立 XrSpatialReferenceCacheANDROID 控制代碼的資訊。

有效用途 (隱含)

xrCreateSpatialReferenceCacheCompleteANDROID 函式的定義如下:

XrResult xrCreateSpatialReferenceCacheCompleteANDROID(
    XrSession                                   session,
    XrFutureEXT                                 future,
    XrCreateSpatialReferenceCacheCompletionANDROID* completion);

參數說明

應用程式「可以」呼叫 xrCreateSpatialReferenceCacheCompleteANDROID,等待 xrCreateSpatialReferenceCacheAsyncANDROID 啟動的非同步作業完成。

如果 future 未處於就緒狀態,執行階段必須傳回 XR_ERROR_FUTURE_PENDING_EXT。如果 future 已完成或取消,執行階段必須傳回 XR_ERROR_FUTURE_INVALID_EXT。

有效用途 (隱含)

傳回代碼

成功

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

失敗

  • XR_ERROR_FEATURE_UNSUPPORTED
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_FUTURE_INVALID_EXT
  • XR_ERROR_FUTURE_PENDING_EXT
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_VALIDATION_FAILURE

XrCreateSpatialReferenceCacheCompletionANDROID 結構定義如下:

typedef struct XrCreateSpatialReferenceCacheCompletionANDROID {
    XrStructureType                   type;
    void*                             next;
    XrResult                          futureResult;
    XrSpatialReferenceCacheANDROID    referenceCache;
} XrCreateSpatialReferenceCacheCompletionANDROID;

成員說明

  • type 是這個結構的 XrStructureType。
  • next 是 NULL,或指向結構鏈中下一個結構的指標。核心 OpenXR 或這個擴充功能中未定義這類結構。
  • futureResult 是參考快取建立作業的 XrResult。
  • 如果作業成功,referenceCache 是 XrSpatialReferenceCacheANDROID 控制代碼。

未來退貨代碼

futureResult 值:

成功

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

失敗

  • XR_ERROR_FEATURE_UNSUPPORTED
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_LIMIT_REACHED

如果 futureResult 是成功代碼,執行階段「必須」傳回有效的 referenceCache 控制代碼。如果 referenceCache 有效,則僅在 xrCreateSpatialReferenceCacheAsyncANDROID :: session 的生命週期內有效,或直到應用程式使用 xrDestroySpatialReferenceCacheANDROID 刪除控制代碼為止,以先發生者為準。

如果 referenceCache 有效,系統會將快取記錄在 XrSystemSpatialAnnotationPropertiesANDROID :: referenceCacheTimespan 中。

有效用途 (隱含)

xrDestroySpatialReferenceCacheANDROID 函式的定義如下:

XrResult xrDestroySpatialReferenceCacheANDROID(
    XrSpatialReferenceCacheANDROID              cacheHandle);

參數說明

應用程式可以呼叫 xrDestroySpatialReferenceCacheANDROID 函式,在完成空間情境建立後釋出 cacheHandle 控制代碼和基礎資源。

有效用途 (隱含)

執行緒安全

  • 存取 cacheHandle 和任何子項控制代碼時,必須從外部同步

傳回代碼

成功

  • XR_SUCCESS

失敗

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE

設定

XrSpatialCapabilityConfigurationAnnotationTrackingANDROID 結構定義如下:

typedef struct XrSpatialCapabilityConfigurationAnnotationTrackingANDROID {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
    XrSpatialReferenceCacheANDROID      cache;
    XrTime                              time;
    XrSpatialReferenceImageEXT          reference;
} XrSpatialCapabilityConfigurationAnnotationTrackingANDROID;

成員說明

  • type 是這個結構的 XrStructureType。
  • next 是 NULL,或指向結構鏈中下一個結構的指標。
  • capability 是 XrSpatialCapabilityEXT,且「必須」為 XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID。
  • enabledComponentCount 是 uint32_t,用於描述 enabledComponents 陣列中的元素數量。
  • enabledComponents 是指向 XrSpatialComponentTypeEXT 陣列的指標。
  • cache 是先前建立的 XrSpatialReferenceCacheANDROID,用於記錄 reference 設定的執行階段參考資料。
  • time 是擷取 reference 的 XrTime。
  • reference 是 XrSpatialReferenceImageEXT,其註解會鏈結至下一個指標。

應用程式可以啟用 XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID 空間功能,方法是在 XrSpatialContextCreateInfoEXT :: capabilityConfigs 中,將指標新增至 XrSpatialCapabilityConfigurationAnnotationTrackingANDROID 結構。

如果 capability 不是 XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID,執行階段「必須」傳回 XR_ERROR_VALIDATION_FAILURE。

如果 reference 不含任何註解,執行階段「必須」傳回 XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT。

如果註解元件列在 enabledComponents 中,但沒有與 reference 相關聯的對應註解,執行階段必須傳回 XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT。

如果 cache 不屬於傳遞至 xrCreateSpatialContextAsyncEXT 的同一個 XrSession,執行階段「必須」傳回 XR_ERROR_VALIDATION_FAILURE。

如果 time 超出 cache 的時間範圍,執行階段「必須」傳回 XR_ERROR_TIME_INVALID。

有效用途 (隱含)

註解追蹤事件

XrEventDataSpatialAnnotationTrackingANDROID 結構定義如下:

typedef struct XrEventDataSpatialAnnotationTrackingANDROID {
    XrStructureType        type;
    const void*            next;
    XrSpatialContextEXT    spatialContext;
    uint32_t               annotationIndex;
    XrResult               initializationResult;
} XrEventDataSpatialAnnotationTrackingANDROID;

成員說明

有效用途 (隱含)

執行階段必須為每個註解填入 XrEventDataSpatialAnnotationTrackingANDROID,表示初始化完成。無論初始化結果為何,應用程式在收到事件後,可以釋放圖片緩衝區,減少記憶體用量。

如果註解初始化成功,執行階段必須在 initializationResult 中填入 XR_SUCCESS。應用程式可以提取 XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT 事件來追蹤註解。

否則,執行階段必須在 initializationResult 中填入適當的錯誤代碼,指出失敗原因。應用程式可以刪除 XrSpatialContextEXT 控制代碼,開始新的註解,或繼續使用 spatialContext 追蹤其他註解。

四邊形註解

執行階段必須使用 xrEnumerateSpatialCapabilityComponentTypesEXT,列出下列元件類型,宣告支援四邊形註解:

  • XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID

Quad 參考資料

XrSpatialAnnotationQuadReferenceANDROID 結構定義如下:

typedef struct XrSpatialAnnotationQuadReferenceANDROID {
    XrStructureType                          type;
    const void*                              next;
    uint32_t                                 quadCount;
    const XrSpatialAnnotationQuadANDROID*    quads;
} XrSpatialAnnotationQuadReferenceANDROID;

成員說明

  • type 是這個結構的 XrStructureType。
  • next 是 NULL,或指向結構鏈中下一個結構的指標。
  • quadCount 是 uint32_t,用於描述 quads 陣列中的元素數量。
  • quads 是指向 XrSpatialAnnotationQuadANDROID 陣列的指標。

如果執行階段支援四邊形註解,應用程式可以設定註解,方法是將 XrSpatialAnnotationQuadReferenceANDROID 結構鏈結至 XrSpatialReferenceImageEXT :: next,並在建立 XrSpatialContextEXT 控制代碼時,於 XrSpatialCapabilityConfigurationAnnotationTrackingANDROID :: reference 中設定參照。

如果 quadCount 為 0,執行階段必須從 xrCreateSpatialContextAsyncEXT 傳回 XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT。

有效用途 (隱含)

XrSpatialAnnotationQuadANDROID 結構定義如下:

typedef struct XrSpatialAnnotationQuadANDROID {
    XrSpatialAnnotationQuadAlignmentANDROID    alignment;
    XrVector2f                                 upperLeft;
    XrVector2f                                 upperRight;
    XrVector2f                                 lowerRight;
    XrVector2f                                 lowerLeft;
} XrSpatialAnnotationQuadANDROID;

成員說明

  • alignment 是四邊形的 XrSpatialAnnotationQuadAlignmentANDROID。
  • upperLeft 是 XrVector2f,用於描述與原點相關的四邊形左上角座標。
  • upperRight 是 XrVector2f,用於描述與原點相關的四邊形右上角座標。
  • lowerRight 是 XrVector2f,用於描述與原點相關的四邊形右下角座標。
  • lowerLeft 是 XrVector2f,用於描述與原點相關的四邊形左下角座標。

2D 空間中的四邊形是順時針方向的凸四邊形。4 個角的值與四邊形相關聯的原點 (0, 0) 有關。

有效用途 (隱含)

typedef enum XrSpatialAnnotationQuadAlignmentANDROID {
    XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_SCREEN_ANDROID = 0,
    XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_OBJECT_ANDROID = 1,
    XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_SURFACE_ANDROID = 2,
    XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrSpatialAnnotationQuadAlignmentANDROID;

XrSpatialAnnotationQuadAlignmentANDROID 列舉會說明四邊形註解的對齊方式。

列舉的意義如下:

列舉說明

XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_SCREEN_ANDROID

註解四邊形與螢幕平面平行,但平面內旋轉仍鎖定世界重力。輸出內容會顯示為一般直立定界框。

XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_OBJECT_ANDROID

註解四邊形會直接錨定在物件上,與參考圖像中定義的對齊方式一致。輸出內容為凸四邊形,形狀會根據物件的透視角度調整。

XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_SURFACE_ANDROID

假設追蹤目標是平面物件或表面,則註解四邊形會與基礎物件的表面共面。輸出內容會與物體的實際幾何形狀完美貼合,並調整透視角度,平貼在特定表面上。

Quad 元件

XrSpatialAnnotationQuadDataANDROID 結構定義如下:

typedef struct XrSpatialAnnotationQuadDataANDROID {
    uint32_t                          annotationIndex;
    XrSpaceLocationData               origin;
    XrSpatialAnnotationQuadANDROID    quad;
} XrSpatialAnnotationQuadDataANDROID;

成員說明

有效用途 (隱含)

XrSpatialComponentAnnotationQuadListANDROID 結構定義如下:

typedef struct XrSpatialComponentAnnotationQuadListANDROID {
    XrStructureType                        type;
    void*                                  next;
    uint32_t                               quadCount;
    XrSpatialAnnotationQuadDataANDROID*    quads;
} XrSpatialComponentAnnotationQuadListANDROID;

成員說明

應用程式可以查詢 XrSpatialSnapshotEXT 中空間實體的四邊形註解元件,方法是在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中新增 XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID,並將 XrSpatialComponentAnnotationQuadListANDROID 新增至 XrSpatialComponentDataQueryResultEXT 的下一個指標鏈結。

如果 XrSpatialComponentAnnotationQuadListANDROID 位於 XrSpatialComponentDataQueryResultEXT :: next 的下一個鏈結中,但 XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID 未包含在 XrSpatialComponentDataQueryConditionEXT :: componentTypes 中,執行階段必須從 xrQuerySpatialComponentDataEXT 傳回 XR_ERROR_VALIDATION_FAILURE。

如果 quadCount 小於 XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput,執行階段必須從 xrQuerySpatialComponentDataEXT 傳回 XR_ERROR_SIZE_INSUFFICIENT。

有效用途 (隱含)

範例程式碼

檢查執行階段支援

以下程式碼範例說明如何檢查執行階段是否支援註解追蹤功能。

XrInstance instance;  // previously initialized
XrSystemId systemId;  // previously initialized
XrSession session;    // previously initialized
XrSpace localSpace;   // previously initialized, e.g. from
                      // XR_REFERENCE_SPACE_TYPE_LOCAL

PFN_xrEnumerateSpatialCapabilitiesEXT xrEnumerateSpatialCapabilitiesEXT;
PFN_xrEnumerateSpatialAnnotationReferenceSourcesANDROID xrEnumerateSpatialAnnotationReferenceSourcesANDROID;
PFN_xrEnumerateSpatialReferenceImageFormatsEXT xrEnumerateSpatialReferenceImageFormatsEXT;
PFN_xrEnumerateSpatialCapabilityComponentTypesEXT xrEnumerateSpatialCapabilityComponentTypesEXT;

// Check spatial annotation tracking capability
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_ANNOTATION_TRACKING_ANDROID) ==
    capabilities.end()) {
  // System does not support spatial annotation tracking.
  return;
}

// Inspect system properties for annotation tracking variables
XrSystemSpatialAnnotationPropertiesANDROID annotationSystemProperties{
    XR_TYPE_SYSTEM_SPATIAL_ANNOTATION_PROPERTIES_ANDROID};
XrSystemProperties systemProperties{.type = XR_TYPE_SYSTEM_PROPERTIES,
                                    .next = &annotationSystemProperties,
                                    .systemId = systemId};
CHK_XR(xrGetSystemProperties(instance, systemId, &systemProperties));
if (annotationSystemProperties.maxAnnotationCount == 0) {
  // System does not support any active annotations.
  return;
}

// Enumerate supported reference sources
uint32_t sourceCountOutput = 0;
XrSpatialAnnotationReferenceSourceANDROID desiredSource =
    XR_SPATIAL_ANNOTATION_REFERENCE_SOURCE_CAMERA_ANDROID;
CHK_XR(xrEnumerateSpatialAnnotationReferenceSourcesANDROID(
    instance, systemId, XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID,
    0, &sourceCountOutput, nullptr));
std::vector<XrSpatialAnnotationReferenceSourceANDROID> sources(sourceCountOutput);
CHK_XR(xrEnumerateSpatialAnnotationReferenceSourcesANDROID(
    instance, systemId, XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID,
    sourceCountOutput, &sourceCountOutput, sources.data()));
if (std::find(sources.begin(), sources.end(), desiredSource) == sources.end()) {
  // The desired source is not supported.
  return;
}

// Enumerate supported reference image formats, provided by XR_EXT_spatial_image_tracking.
uint32_t formatCountOutput = 0;
XrSpatialReferenceImageFormatEXT desiredFormat =
    XR_SPATIAL_REFERENCE_IMAGE_FORMAT_YUV_420_888_EXT; // Or XR_SPATIAL_REFERENCE_IMAGE_FORMAT_RGBA_8888_EXT for screenshot.
CHK_XR(xrEnumerateSpatialReferenceImageFormatsEXT(
    instance, systemId, XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID, 0,
    &formatCountOutput, nullptr));
std::vector<XrSpatialReferenceImageFormatEXT> formats(formatCountOutput);
CHK_XR(xrEnumerateSpatialReferenceImageFormatsEXT(
    instance, systemId, XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID,
    formats.size(), &formatCountOutput, formats.data()));
if (std::find(formats.begin(), formats.end(), desiredFormat) == formats.end()) {
  // The desired format is not supported
  return;
}

// Enumerate supported components for annotation tracking capability.
XrSpatialCapabilityComponentTypesEXT capabilityComponentTypes{
    XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT};
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(
    instance, systemId, XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID,
    &capabilityComponentTypes));
std::vector<XrSpatialComponentTypeEXT>
    annotationTypes(capabilityComponentTypes.componentTypeCountOutput);
capabilityComponentTypes.componentTypeCapacityInput = annotationTypes.size();
capabilityComponentTypes.componentTypes = annotationTypes.data();
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(
    instance, systemId, XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID,
    &capabilityComponentTypes));

// Check supported annotation components.
XrSpatialComponentTypeEXT desiredComponent =
    XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID;
const auto supportedComponent = [&annotationTypes](
                                    XrSpatialComponentTypeEXT component) {
  return std::find(annotationTypes.begin(), annotationTypes.end(), component) !=
         annotationTypes.end();
};
if (!supportedComponent(desiredComponent)) {
  // The desired annotation is not supported.
  return;
}

設定四邊形註解

以下程式碼範例示範如何設定四邊形註解。

XrInstance instance;  // previously initialized
XrSystemId systemId;  // previously initialized
XrSession session;    // previously initialized
XrSpace localSpace;   // previously initialized, e.g. from
                      // XR_REFERENCE_SPACE_TYPE_LOCAL

PFN_xrCreateSpatialReferenceCacheAsyncANDROID xrCreateSpatialReferenceCacheAsyncANDROID;
PFN_xrCreateSpatialReferenceCacheCompleteANDROID xrCreateSpatialReferenceCacheCompleteANDROID;
PFN_xrDestroySpatialReferenceCacheANDROID xrDestroySpatialReferenceCacheANDROID;
PFN_xrCreateSpatialContextAsyncEXT xrCreateSpatialContextAsyncEXT;
PFN_xrCreateSpatialContextCompleteEXT xrCreateSpatialContextCompleteEXT;
void (*waitUntilReady)(XrFutureEXT);

XrSpatialReferenceImageFormatEXT desiredFormat;
XrSpatialAnnotationReferenceSourceANDROID desiredSource;
XrSpatialComponentTypeEXT desiredComponent;

// Create and start reference cache to prepare for capturing reference images.
XrSpatialReferenceCacheANDROID referenceCache;
XrSpatialReferenceCacheCreateInfoANDROID cacheCreateInfo{
  .type = XR_TYPE_SPATIAL_REFERENCE_CACHE_CREATE_INFO_ANDROID,
  .next = nullptr,
  .capability = XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID,
  .source = desiredSource,
};
XrFutureEXT cacheFuture = XR_NULL_FUTURE_EXT;
CHK_XR(xrCreateSpatialReferenceCacheAsyncANDROID(session, &cacheCreateInfo, &cacheFuture));

waitUntilReady(cacheFuture);

XrCreateSpatialReferenceCacheCompletionANDROID cacheCompletion{
    XR_TYPE_CREATE_SPATIAL_REFERENCE_CACHE_COMPLETION_ANDROID};
CHK_XR(xrCreateSpatialReferenceCacheCompleteANDROID(session, cacheFuture,
                                                     &cacheCompletion));
if (cacheCompletion.futureResult != XR_SUCCESS) {
  // Error, reference cache creation failed
  return;
}

referenceCache = cacheCompletion.referenceCache;

// Create the reference image with quad annotations

//  YUV 4:2:0 Planar:
// ----------------------
// |     Y      |Cb |Cr |
// ----------------------
XrSpatialReferenceImagePlaneEXT cameraImagePlanes[3];
// for each plane (0=Y, 1=U(cb), 2=V(Cr)) return by Image#getPlanes().
for (int i = 0; i < 3; ++i) {
  cameraImagePlanes[i].buffer; // read from Plane#getBuffer().
  cameraImagePlanes[i].bufferSize; // set each buffer size. Y = width * height (bytes); U = Y / 4 (bytes); V = Y / 4 (bytes).
  cameraImagePlanes[i].rowStride; // read from Plane#getRowStride().
  cameraImagePlanes[i].pixelStride; // read from Plane#getPixelStride().
}
XrSpatialReferenceImageEXT referenceImage{
      XR_TYPE_SPATIAL_REFERENCE_IMAGE_EXT};
referenceImage.width = 640;
referenceImage.height = 480;
referenceImage.format = desiredFormat;
referenceImage.planeCount = 3;
referenceImage.planes = cameraImagePlanes;

XrSpatialAnnotationQuadANDROID
    quad; // quad coordinates within the reference image.
quad.alignment = XR_SPATIAL_ANNOTATION_QUAD_ALIGNMENT_OBJECT_ANDROID;
// Set unnormalized pixel coordinates of 4 corners.
quad.upperLeft = {0.0, 0.0};
quad.upperRight = {0.0, 100.0};
quad.lowerRight = {100.0, 100.0};
quad.lowerLeft = {0.0, 100.0};

XrSpatialAnnotationQuadReferenceANDROID quadReference{
    XR_TYPE_SPATIAL_ANNOTATION_QUAD_REFERENCE_ANDROID};
quadReference.quads = &quad;
quadReference.quadCount = 1;
referenceImage.next = &quadReference;

// Create the spatial context with annotation configuration.
XrSpatialContextEXT spatialContext{};
{
  const std::array<XrSpatialComponentTypeEXT, 1> enabledComponents = {
      desiredComponent,
  };

  // Configure annotation tracking
  XrSpatialCapabilityConfigurationAnnotationTrackingANDROID annotationConfig{
      XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANNOTATION_TRACKING_ANDROID};
  annotationConfig.capability =
      XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID;
  annotationConfig.enabledComponentCount = enabledComponents.size();
  annotationConfig.enabledComponents = enabledComponents.data();
  annotationConfig.cache = referenceCache;
  annotationConfig.time; // The time when this reference image is captured.
  annotationConfig.reference = referenceImage;

  std::vector<XrSpatialCapabilityConfigurationBaseHeaderEXT *>
      capabilityConfigs;
  capabilityConfigs.push_back(
      reinterpret_cast<XrSpatialCapabilityConfigurationBaseHeaderEXT *>(
          &annotationConfig));

  XrSpatialContextCreateInfoEXT spatialContextCreateInfo{
      XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT};
  spatialContextCreateInfo.capabilityConfigCount = capabilityConfigs.size();
  spatialContextCreateInfo.capabilityConfigs = capabilityConfigs.data();

  XrFutureEXT createContextFuture = XR_NULL_FUTURE_EXT;
  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) {
    // Error, spatial context creation failed
    return;
  }

  spatialContext = completion.spatialContext;
  CHK_XR(xrDestroySpatialReferenceCacheANDROID(referenceCache));
}

探索有效註解

以下程式碼範例示範如何探索及查詢註解。

XrInstance instance;  // previously initialized
XrSession session;    // previously initialized
XrSpace localSpace;   // previously initialized, e.g. from
                      // XR_REFERENCE_SPACE_TYPE_LOCAL
XrSpatialContextEXT spatialContext; // previously created

PFN_xrCreateSpatialDiscoverySnapshotAsyncEXT xrCreateSpatialDiscoverySnapshotAsyncEXT;
PFN_xrCreateSpatialDiscoverySnapshotCompleteEXT xrCreateSpatialDiscoverySnapshotCompleteEXT;
PFN_xrQuerySpatialComponentDataEXT xrQuerySpatialComponentDataEXT;
PFN_xrDestroySpatialSnapshotEXT xrDestroySpatialSnapshotEXT;
PFN_xrPollEvent xrPollEvent;
PFN_xrDestroySpatialContextEXT xrDestroySpatialContextEXT;
void (*waitUntilReady)(XrFutureEXT);

XrSpatialComponentTypeEXT desiredComponent; // e.g. XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID

auto discoverAnnotations = [&](XrSpatialContextEXT spatialContext, XrTime time,
                               XrSpace baseSpace) {
  std::array<XrSpatialComponentTypeEXT, 1> snapshotComponents{desiredComponent};
  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{
      XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  XrFutureEXT discoveryFuture = XR_NULL_FUTURE_EXT;
  CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(
      spatialContext, &snapshotCreateInfo, &discoveryFuture));

  waitUntilReady(discoveryFuture);

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

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{
      XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(
      spatialContext, &completionInfo, &completion));
  if (completion.futureResult == XR_SUCCESS) {
    // Query for desired annotation data, e.g. quad.
    XrSpatialComponentTypeEXT componentsToQuery[] = {
        XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID};
    XrSpatialComponentDataQueryConditionEXT queryCond{
        XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
    queryCond.componentTypeCount = 1;
    queryCond.componentTypes = componentsToQuery;
    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.entityStateCountOutput);
    queryResult.entityIdCapacityInput = entityIds.size();
    queryResult.entityIds = entityIds.data();
    queryResult.entityStateCapacityInput = entityStates.size();
    queryResult.entityStates = entityStates.data();

    std::vector<XrSpatialAnnotationQuadDataANDROID> quads(
        queryResult.entityIdCountOutput);
    XrSpatialComponentAnnotationQuadListANDROID quadList{
        XR_TYPE_SPATIAL_COMPONENT_ANNOTATION_QUAD_LIST_ANDROID};
    quadList.quadCount = quads.size();
    quadList.quads = quads.data();
    queryResult.next = &quadList;

    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) {
        const XrSpatialAnnotationQuadDataANDROID &currentQuad = quads[i];
        // Rendering quad in the view.
      }
    }

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

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

  XrSpace space;           // Application's play space.
  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_ANNOTATION_TRACKING_ANDROID: {
      const XrEventDataSpatialAnnotationTrackingANDROID &eventdata =
          *reinterpret_cast<XrEventDataSpatialAnnotationTrackingANDROID *>(
              &event);
      if (eventdata.initializationResult != XR_SUCCESS) {
        // handle initialization failure.
        // e.g. CHK_XR(xrDestroySpatialContextEXT(spatialContext));
      }
      break;
    }
    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, space);
      break;
    }
    }
  }

  // Finish frame loop
}

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

新物件類型

新指令

新結構

新列舉

新列舉常數

  • XR_ANDROID_SPATIAL_ANNOTATION_TRACKING_EXTENSION_NAME
  • XR_ANDROID_spatial_annotation_tracking_SPEC_VERSION
  • 擴充 XrObjectType:

    • XR_OBJECT_TYPE_SPATIAL_REFERENCE_CACHE_ANDROID
  • 擴充 XrSpatialCapabilityEXT:

    • XR_SPATIAL_CAPABILITY_ANNOTATION_TRACKING_ANDROID
  • 擴充 XrSpatialComponentTypeEXT:

    • XR_SPATIAL_COMPONENT_TYPE_ANNOTATION_QUAD_ANDROID
  • 擴充 XrStructureType:

    • XR_TYPE_CREATE_SPATIAL_REFERENCE_CACHE_COMPLETION_ANDROID
    • XR_TYPE_EVENT_DATA_SPATIAL_ANNOTATION_TRACKING_ANDROID
    • XR_TYPE_SPATIAL_ANNOTATION_QUAD_REFERENCE_ANDROID
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANNOTATION_TRACKING_ANDROID
    • XR_TYPE_SPATIAL_COMPONENT_ANNOTATION_QUAD_LIST_ANDROID
    • XR_TYPE_SPATIAL_REFERENCE_CACHE_CREATE_INFO_ANDROID
    • XR_TYPE_SYSTEM_SPATIAL_ANNOTATION_PROPERTIES_ANDROID

問題

版本記錄

  • 修訂版本 1,2025 年 9 月 17 日 (Levana Chen)

    • 初始擴充功能說明。