XR_EXT_spatial_persistence

Name String

XR_EXT_spatial_persistence

拡張機能の種類

インスタンス拡張

登録済みの内線番号

764

リビジョン

1

承認ステータス

批准

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

XR_EXT_spatial_entity
および
XR_EXT_future

寄与者

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

概要

この拡張機能により、アプリケーションは、アプリケーション セッション、OpenXR セッション、セッション内の複数の OpenXR 空間コンテキストにわたって空間エンティティを検出して関連付けることができます。XR_EXT_spatial_entity 拡張機能により、XrSpatialContextEXT 内のエンティティが XrSpatialEntityIdEXT で表されることが確立されました。この拡張機能は、エンティティが永続化されている場合、アプリケーションと OpenXR セッション全体で XrUuid によって表されることを確立することで、そのコンセプトを拡張します。つまり、アプリケーションは、この拡張機能によって提供される XrUuid を使用して、セッション全体でエンティティを識別できます。この拡張機能は、XR_EXT_spatial_entity 拡張機能と重複する便利な機能も提供します。これにより、ユーザーの環境で永続化されたエンティティを検出し、そのコンポーネント データをクエリできます。

空間永続性コンテキスト

空間永続性コンテキストを作成する

XR_DEFINE_HANDLE(XrSpatialPersistenceContextEXT)

XrSpatialPersistenceContextEXT ハンドルは、永続的な空間エンティティ ストレージへの接続を表します。

xrCreateSpatialPersistenceContextAsyncEXT 関数は次のように定義されます。

XrResult xrCreateSpatialPersistenceContextAsyncEXT(
    XrSession                                   session,
    const XrSpatialPersistenceContextCreateInfoEXT* createInfo,
    XrFutureEXT*                                future);

パラメータの説明

  • session は、空間永続性コンテキストがアクティブになる XrSession です。
  • createInfo は、空間永続性コンテキスト パラメータの指定に使用される XrSpatialPersistenceContextCreateInfoEXT です。
  • future は XrFutureEXT へのポインタです。

アプリは、xrCreateSpatialPersistenceContextAsyncEXT 関数を使用して XrSpatialPersistenceContextEXT ハンドルを作成し、createInfo で永続性コンテキストのスコープを構成できます。

XrSpatialPersistenceContextCreateInfoEXT :: scope が xrEnumerateSpatialPersistenceScopesEXT によって列挙されていない場合、ランタイムは XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT を返さなければなりません。

ランタイムが権限システムを適用して、XrSpatialPersistenceContextEXT で表される永続ストレージへのアプリケーション アクセスを制御する場合、それらの権限がこのアプリケーションに付与されていない場合、ランタイムは XR_ERROR_PERMISSION_INSUFFICIENT を返さなければなりません。

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

戻りコード

成功

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

失敗

  • 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_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • XR_ERROR_VALIDATION_FAILURE

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

typedef struct XrSpatialPersistenceContextCreateInfoEXT {
    XrStructureType                 type;
    const void*                     next;
    XrSpatialPersistenceScopeEXT    scope;
} XrSpatialPersistenceContextCreateInfoEXT;

メンバーの説明

  • type は、この構造の XrStructureType です。
  • next は、NULL または構造体チェーン内の次の構造体へのポインタです。このような構造体は、コア OpenXR またはこの拡張機能では定義されていません。
  • scope は、永続性コンテキストのストレージ スコープを定義する XrSpatialPersistenceScopeEXT です。

XrSpatialPersistenceContextCreateInfoEXT 構造体は、XrSpatialPersistenceContextEXT ハンドルを作成するための情報を記述します。

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

typedef enum XrSpatialPersistenceScopeEXT {
    XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT = 1,
    XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT = 1000781000,
    XR_SPATIAL_PERSISTENCE_SCOPE_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1 = 1000808000,
    XR_SPATIAL_PERSISTENCE_SCOPE_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceScopeEXT;

XrSpatialPersistenceScopeEXT 列挙型は、さまざまなタイプの永続性コンテキスト スコープを識別します。

列挙型の意味は次のとおりです。

列挙型の説明

XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT

システムによって永続化および管理される空間エンティティへの読み取り専用アクセス権をアプリに付与します(つまり、アプリはこのスコープに関連付けられたストアを変更できません)。アプリは、このスコープの永続性コンポーネントの UUID を使用して、空間コンテキストとデバイスの再起動をまたいでエンティティを関連付けることができます。

XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT

永続化オペレーションとデータアクセスは、同じデバイス上の同じユーザーと同じアプリの空間アンカーに限定されます(XR_EXT_spatial_persistence_operations 拡張機能によって追加)。

XR_SPATIAL_PERSISTENCE_SCOPE_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1

永続化オペレーションとデータアクセスは、同じクラウド プロジェクトが所有、管理する空間アンカーに限定されます。(XR_ANDROIDX1_spatial_anchor_cloud_sharing 拡張機能によって追加)

xrEnumerateSpatialPersistenceScopesEXT 関数は次のように定義されます。

XrResult xrEnumerateSpatialPersistenceScopesEXT(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    uint32_t                                    persistenceScopeCapacityInput,
    uint32_t*                                   persistenceScopeCountOutput,
    XrSpatialPersistenceScopeEXT*               persistenceScopes);

パラメータの説明

  • instance は XrInstance のハンドルです。
  • systemId は、空間永続性スコープを列挙する XrSystemId です。
  • persistenceScopeCapacityInput は persistenceScopes 配列の容量です。0 の場合は、必要な容量を取得するリクエストであることを示します。
  • persistenceScopeCountOutput は、永続性スコープの数、または persistenceScopeCapacityInput が不十分な場合の必要な容量です。
  • persistenceScopes は XrSpatialPersistenceScopeEXT の配列です。persistenceScopeCapacityInput が 0 の場合、NULL になることがあります。
  • 必要な persistenceScopes サイズの取得方法の詳細については、バッファサイズ パラメータの章をご覧ください。

アプリは、xrEnumerateSpatialPersistenceScopesEXT を使用して、特定の XrSystemId でサポートされている空間永続性スコープのリストを列挙できます。

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

  • xrEnumerateSpatialPersistenceScopesEXT を呼び出す前に、XR_EXT_spatial_persistence 拡張機能を有効にする必要があります。
  • instance は、有効な XrInstance ハンドルでなければなりません。
  • persistenceScopeCountOutput は uint32_t 値へのポインタでなければなりません
  • persistenceScopeCapacityInput が 0 でない場合、persistenceScopes は persistenceScopeCapacityInput XrSpatialPersistenceScopeEXT 値の配列へのポインタでなければなりません。

戻りコード

成功

  • XR_SUCCESS

失敗

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

xrCreateSpatialPersistenceContextCompleteEXT 関数は次のように定義されます。

XrResult xrCreateSpatialPersistenceContextCompleteEXT(
    XrSession                                   session,
    XrFutureEXT                                 future,
    XrCreateSpatialPersistenceContextCompletionEXT* completion);

パラメータの説明

xrCreateSpatialPersistenceContextCompleteEXT は、xrCreateSpatialPersistenceContextAsyncEXT によって開始された非同期オペレーションを完了します。future が準備完了状態でない場合、ランタイムは XR_ERROR_FUTURE_PENDING_EXT を返さなければなりません。future がすでに完了またはキャンセルされている場合、ランタイムは XR_ERROR_FUTURE_INVALID_EXT を返さなければなりません。

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

戻りコード

成功

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

失敗

  • 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

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

typedef struct XrCreateSpatialPersistenceContextCompletionEXT {
    XrStructureType                         type;
    void*                                   next;
    XrResult                                futureResult;
    XrSpatialPersistenceContextResultEXT    createResult;
    XrSpatialPersistenceContextEXT          persistenceContext;
} XrCreateSpatialPersistenceContextCompletionEXT;

メンバーの説明

今後の返品コード

futureResult の値:

成功

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

失敗

  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_PERMISSION_INSUFFICIENT

futureResult と createResult がどちらも成功コードの場合、persistenceContext は有効である必要があります。persistenceContext が有効な場合、xrCreateSpatialPersistenceContextAsyncEXT :: session のライフサイクル内、またはアプリが persistenceContext で xrDestroySpatialPersistenceContextEXT を使用するまで(いずれか早い方)、有効なままでなければなりません。

ランタイムは、futureResult が成功コードの場合にのみ createResult を設定しなければなりません。

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

typedef enum XrSpatialPersistenceContextResultEXT {
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT = 0,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT = -1000781001,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT = -1000781002,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_LOCALIZATION_FAILURE_ANDROIDX1 = -1000808000,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1 = -1000808001,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1 = -1000808002,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1 = -1000808003,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceContextResultEXT;

XrSpatialPersistenceContextResultEXT 列挙型は、永続性オペレーションのさまざまなタイプの結果コードを識別します。永続化オペレーション中のエラーは、必ずしもアプリケーションで制御できるとは限りません。この列挙型は、そのようなケースを伝えるために使用されます。XrResult と同様に、XrSpatialPersistenceContextResultEXT 列挙型の成功コードは非負の値、失敗コードは負の値です。

列挙型の意味は次のとおりです。

列挙型の説明

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT

永続コンテキスト オペレーションが成功しました。

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT

エンティティをランタイムで追跡できなかったため、永続化オペレーションが失敗しました。(XR_EXT_spatial_persistence_operations 拡張機能によって追加)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT

指定された永続 UUID がストレージで見つかりませんでした。(XR_EXT_spatial_persistence_operations 拡張機能によって追加)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_LOCALIZATION_FAILURE_ANDROIDX1

ローカライズに失敗したため、永続化オペレーションが失敗しました。(XR_ANDROIDX1_spatial_anchor_cloud_sharing 拡張機能によって追加)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1

ローカライズ マップ機能が不十分なため、永続化オペレーションが失敗しました。(XR_ANDROIDX1_spatial_anchor_cloud_sharing 拡張機能によって追加)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1

ネットワーク接続に失敗したため、永続化オペレーションが失敗しました。(XR_ANDROIDX1_spatial_anchor_cloud_sharing 拡張機能によって追加)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1

ネットワーク タイムアウトのため、永続化オペレーションが失敗しました。(XR_ANDROIDX1_spatial_anchor_cloud_sharing 拡張機能によって追加)

空間永続性コンテキストを破棄する

xrDestroySpatialPersistenceContextEXT 関数は次のように定義されます。

XrResult xrDestroySpatialPersistenceContextEXT(
    XrSpatialPersistenceContextEXT              persistenceContext);

パラメータの説明

アプリケーションは、空間永続性タスクが完了したときに、xrDestroySpatialPersistenceContextEXT を使用して persistenceContext ハンドルを解放できます。

XrSpatialContextPersistenceConfigEXT を介して persistenceContext がリンクされている有効な XrSpatialContextEXT ハンドルがある場合、xrDestroySpatialPersistenceContextEXT が呼び出されたときに、ランタイムは persistenceContext の基盤となるリソースを破棄してはなりません。これは、永続化されたエンティティを検出するために、永続化コンテキストのリソースが空間コンテキストによって引き続き使用されるためです。このような状況で永続コンテキスト ハンドルを破棄すると、これらのリソースへのアプリケーションのアクセスのみが削除されます。

破棄された XrSpatialPersistenceContextEXT のリソースは、永続性コンテキストがリンクされていたすべての XrSpatialContextEXT ハンドルが破棄されたときに解放しなければなりません。

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

スレッドセーフ

  • persistenceContext とその子ハンドルへのアクセスは、外部で同期する必要があります。

戻りコード

成功

  • XR_SUCCESS

失敗

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE

永続化されたエンティティを検出する

永続性コンポーネント

永続化された空間エンティティには永続化コンポーネントがあります。XrSpatialContextEXT の作成時に XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT が有効になっていて、XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes または XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes に含まれている場合、ランタイムは検出スナップショットと更新スナップショットにこのコンポーネントを含める必要があります。

コンポーネント データ

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

typedef struct XrSpatialPersistenceDataEXT {
    XrUuid                          persistUuid;
    XrSpatialPersistenceStateEXT    persistState;
} XrSpatialPersistenceDataEXT;

メンバーの説明

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

typedef enum XrSpatialPersistenceStateEXT {
    XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT = 1,
    XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT = 2,
    XR_SPATIAL_PERSISTENCE_STATE_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceStateEXT;

XrSpatialPersistenceStateEXT 列挙型は、永続化された UUID のさまざまな状態を識別します。

列挙型の意味は次のとおりです。

列挙型の説明

XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT

永続化された UUID がストレージから正常に読み込まれました。

XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT

永続化された UUID がストレージに見つかりませんでした。削除されたか、最初から存在していなかった可能性があります。

データをクエリするコンポーネント リストの構造

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

typedef struct XrSpatialComponentPersistenceListEXT {
    XrStructureType                 type;
    void*                           next;
    uint32_t                        persistDataCount;
    XrSpatialPersistenceDataEXT*    persistData;
} XrSpatialComponentPersistenceListEXT;

メンバーの説明

  • type は、この構造の XrStructureType です。
  • next は、NULL または構造体チェーン内の次の構造体へのポインタです。このような構造体は、コア OpenXR またはこの拡張機能では定義されていません。
  • persistDataCount は、persistData 配列内の要素の数を表す uint32_t です。
  • persistData は XrSpatialPersistenceDataEXT の配列です。

XrSpatialComponentPersistenceListEXT が XrSpatialComponentDataQueryResultEXT :: next の次のチェーンにあり、XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT が XrSpatialComponentDataQueryConditionEXT :: componentTypes に含まれていない場合、ランタイムは xrQuerySpatialComponentDataEXT から XR_ERROR_VALIDATION_FAILURE を返さなければなりません。

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

他のコンポーネントとは異なり、ランタイムは XrSpatialEntityTrackingStateEXT に関係なく、XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT のデータを設定する必要があります。

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

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

XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT が XrSpatialCapabilityComponentTypesEXT :: componentTypes で列挙されている場合、アプリは XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents リストに列挙型を含めることで、その機能を有効にできます。このコンポーネントでは、XrSpatialCapabilityConfigurationBaseHeaderEXT の次のチェーンに含める特別な構成は必要ありません。アプリが有効なコンポーネント リストに XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT を含める場合、XrSpatialContextCreateInfoEXT の次のチェーンに XrSpatialContextPersistenceConfigEXT も含める必要があります。そうしない場合、ランタイムは xrCreateSpatialContextAsyncEXT から XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT を返す必要があります。

永続性コンテキストを使用して空間コンテキストを構成する

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

typedef struct XrSpatialContextPersistenceConfigEXT {
    XrStructureType                          type;
    const void*                              next;
    uint32_t                                 persistenceContextCount;
    const XrSpatialPersistenceContextEXT*    persistenceContexts;
} XrSpatialContextPersistenceConfigEXT;

メンバーの説明

  • type は、この構造の XrStructureType です。
  • next は、NULL または構造体チェーン内の次の構造体へのポインタです。このような構造体は、コア OpenXR またはこの拡張機能では定義されていません。
  • persistenceContextCount は、persistenceContexts 配列内の要素の数を表す uint32_t です。
  • persistenceContexts は XrSpatialPersistenceContextEXT の配列です。

アプリは、XrSpatialContextPersistenceConfigEXT を XrSpatialContextCreateInfoEXT の次のチェーンに追加できます。これにより、作成された XrSpatialContextEXT が persistenceContexts で構成され、アプリは persistenceContexts の XrSpatialPersistenceContextEXT ハンドルで表されるストレージに永続化された空間エンティティを検出できるようになります。

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

  • XrSpatialContextPersistenceConfigEXT を使用する前に、XR_EXT_spatial_persistence 拡張機能を有効にする必要があります。
  • type は XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT にする必要があります。
  • next は、NULL または構造体チェーン内の次の構造体への有効なポインタでなければなりません。
  • persistenceContexts は、persistenceContextCount 個の有効な XrSpatialPersistenceContextEXT ハンドルの配列へのポインタでなければなりません
  • persistenceContextCount パラメータは 0 より大きい値にする必要があります。

検出スナップショットを作成する

特定の UUID を持つエンティティを検出する

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

typedef struct XrSpatialDiscoveryPersistenceUuidFilterEXT {
    XrStructureType    type;
    const void*        next;
    uint32_t           persistedUuidCount;
    const XrUuid*      persistedUuids;
} XrSpatialDiscoveryPersistenceUuidFilterEXT;

メンバーの説明

  • type は、この構造の XrStructureType です。
  • next は、NULL または構造体チェーン内の次の構造体へのポインタです。このような構造体は、コア OpenXR またはこの拡張機能では定義されていません。
  • persistedUuidCount は、persistedUuids 配列内の要素の数を表す uint32_t です。
  • persistedUuids は XrUuid の配列です。

アプリは、XrSpatialDiscoverySnapshotCreateInfoEXT の次のチェーンで XrSpatialDiscoveryPersistenceUuidFilterEXT を使用して、persistedUuids で指定された UUID のセットに永続化された UUID が含まれるエンティティのみに検出オペレーションの範囲を限定できます。

アプリケーションが XrSpatialDiscoverySnapshotCreateInfoEXT の次のチェーンに XrSpatialDiscoveryPersistenceUuidFilterEXT を追加したが、xrCreateSpatialDiscoverySnapshotAsyncEXT :: spatialContext が XrSpatialContextPersistenceConfigEXT を使用して XrSpatialPersistenceContextEXT で構成されていない場合、ランタイムは xrCreateSpatialDiscoverySnapshotAsyncEXT から XR_ERROR_VALIDATION_FAILURE を返さなければなりません。

ランタイムは、XrSpatialDiscoveryPersistenceUuidFilterEXT フィルタを、XrSpatialDiscoverySnapshotCreateInfoEXT またはその次のチェーンで提供される他のフィルタとの「AND」条件として扱う必要があります。ランタイムは、persistedUuids 配列自体を「OR」条件として扱う必要があります。つまり、その配列で指定された UUID のいずれかを持つエンティティをフィルタします。

ランタイムは、現時点で XrSpatialPersistenceStateEXT 状態を特定できた persistedUuids 内の UUID ごとに、作成されたスナップショットに 1 つのエントリを含める必要があります。

  • ランタイムがストレージで UUID を正常に見つけた場合、

    • ランタイムは、このエンティティの XrSpatialPersistenceDataEXT の XrSpatialPersistenceStateEXT を XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT に設定しなければなりません。
    • ランタイムは、作成されたスナップショットに、このエンティティの有効な XrSpatialEntityIdEXT を含める必要があります。
    • ランタイムは、エンティティをアクティブにトラッキングしており、そのコンポーネントの有効なデータがある場合、そのエンティティの XrSpatialEntityTrackingStateEXT を XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT に設定しなければなりません。それ以外の場合、ランタイムは XrSpatialEntityTrackingStateEXT を XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT に設定しなければなりません。
  • UUID がストレージに存在しないとランタイムが判断した場合(その UUID がストレージに存在したことがないか、一度は存在したものの、その後永続化が解除されたかに関係なく)、次のようになります。

    • ランタイムは、このエンティティの XrSpatialPersistenceDataEXT の XrSpatialPersistenceStateEXT を XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT に設定して、この UUID がストレージに存在しなくなったことをアプリに示す必要があります。
    • ランタイムは、作成されたスナップショットでこのエンティティの XrSpatialEntityIdEXT を XR_NULL_SPATIAL_ENTITY_ID_EXT に設定しなければなりません。
    • ランタイムは、そのエンティティの XrSpatialEntityTrackingStateEXT を XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT に設定して、このエンティティが追跡されないことをアプリに示す必要があります。
  • ランタイムが UUID がストレージに存在するかどうかを判断できなかった場合、UUID をスナップショットに含めてはなりません。

アプリは、XrSpatialComponentDataQueryConditionEXT の次のチェーンで XrSpatialDiscoveryPersistenceUuidFilterEXT を使用して、既存のスナップショット内の特定の UUID のエンティティをクエリすることもできます。XrSpatialComponentDataQueryConditionEXT とともに使用する場合、XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids に XrSpatialSnapshotEXT にない XrUuid が含まれている場合、ランタイムはクエリ結果にその XrUuid のエントリを含めてはなりません。また、クエリ結果のエンティティの順序(シーケンス)は、XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids で指定された UUID の順序と一致しない可能性があります。アプリケーションは、XrSpatialComponentDataQueryConditionEXT :: componentTypes に XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT を、XrSpatialComponentDataQueryResultEXT の次のチェーンに XrSpatialComponentPersistenceListEXT を含め、各クエリ結果インデックスの XrSpatialPersistenceDataEXT :: persistUuid を確認して、現在の結果インデックスがどの UUID に対応しているかを把握するべきです。

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

  • XR_EXT_spatial_persistence 拡張機能は、XrSpatialDiscoveryPersistenceUuidFilterEXT を使用する前に有効にする必要があります。
  • type は XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT にする必要があります。
  • next は、NULL または構造体チェーン内の次の構造体への有効なポインタでなければなりません。
  • persistedUuids は、persistedUuidCount XrUuid 構造体の配列へのポインタでなければなりません
  • persistedUuidCount パラメータは 0 より大きい値にする必要があります。
永続化されたすべてのエンティティを検出する

アプリケーションが xrCreateSpatialDiscoverySnapshotAsyncEXT を使用し、XrSpatialDiscoveryPersistenceUuidFilterEXT を使用せず、XrSpatialPersistenceContextEXT で構成された XrSpatialContextEXT を使用する場合、ランタイムは、XrSpatialPersistenceContextEXT で表されるストレージに永続化され、XrSpatialDiscoverySnapshotCreateInfoEXT で提供されるフィルタを満たすエンティティを、作成されたスナップショットに含めなければなりません。これらのエンティティについては、

  • ランタイムは、このエンティティの XrSpatialPersistenceDataEXT の XrSpatialPersistenceStateEXT を XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT に設定しなければなりません。
  • ランタイムは、作成されたスナップショットに、このエンティティの有効な XrSpatialEntityIdEXT を含める必要があります。
  • ランタイムは、エンティティをアクティブにトラッキングしており、そのコンポーネントの有効なデータがある場合、そのエンティティの XrSpatialEntityTrackingStateEXT を XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT に設定しなければなりません。それ以外の場合、ランタイムは XrSpatialEntityTrackingStateEXT を XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT に設定しなければなりません。

新しいオブジェクト タイプ

新しいコマンド

新しい構造

新しい列挙型

新しい列挙型定数

  • XR_EXT_SPATIAL_PERSISTENCE_EXTENSION_NAME
  • XR_EXT_spatial_persistence_SPEC_VERSION
  • XrObjectType の拡張:

    • XR_OBJECT_TYPE_SPATIAL_PERSISTENCE_CONTEXT_EXT
  • XrResult の拡張:

    • XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • XrSpatialComponentTypeEXT の拡張:

    • XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT
  • XrStructureType の拡張:

    • XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT
    • XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT
    • XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT
    • XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT
    • XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT

コード例

永続性コンテキストを作成する

// Check if the required persistence scope supported
uint32_t scopeCount;
CHK_XR(xrEnumerateSpatialPersistenceScopesEXT(instance, systemId, 0, &scopeCount, nullptr));
std::vector<XrSpatialPersistenceScopeEXT> persistenceScopes(scopeCount);
CHK_XR(xrEnumerateSpatialPersistenceScopesEXT(instance, systemId, scopeCount, &scopeCount, persistenceScopes.data()));

if (std::find(persistenceScopes.begin(), persistenceScopes.end(), XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT) == persistenceScopes.end()) {
  return;
}

XrSpatialPersistenceContextEXT persistenceContext{};

XrSpatialPersistenceContextCreateInfoEXT persistenceContextCreateInfo{XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT};
persistenceContextCreateInfo.scope = XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT;
XrFutureEXT createContextFuture;
CHK_XR(xrCreateSpatialPersistenceContextAsyncEXT(session, &persistenceContextCreateInfo, &createContextFuture));

waitUntilReady(createContextFuture);

XrCreateSpatialPersistenceContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT};
CHK_XR(xrCreateSpatialPersistenceContextCompleteEXT(session, createContextFuture, &completion));
if (completion.futureResult != XR_SUCCESS || completion.createResult != XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT) {
  return;
}

persistenceContext = completion.persistenceContext;

// ...
// Connect persistence context to a spatial context and discover persisted entities.
// ...

CHK_XR(xrDestroySpatialPersistenceContextEXT(persistenceContext));

永続性コンテキストを空間コンテキストに接続する

// Note: Anchor capability is just used as an example here. Persistence can be
// supported by other capabilities too. xrEnumerateSpatialCapabilityComponentTypesEXT() can
// be used to check if a certain capability supports persistence.
if (!isSpatialCapabilitySupported(instance, systemId, XR_SPATIAL_CAPABILITY_ANCHOR_EXT)) {
  return;
}

const bool supportsPersistenceComponent = isSpatialComponentSupported(instance, systemId, XR_SPATIAL_CAPABILITY_ANCHOR_EXT, XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT);

// Create a spatial spatial context
XrSpatialContextEXT spatialContext{};
{

  std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
    XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT,
  };

  if (supportsPersistenceComponent) {
    enabledComponents.push_back(XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT);
  }

  XrSpatialCapabilityConfigurationAnchorEXT anchorConfig{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT};
  anchorConfig.capability = XR_SPATIAL_CAPABILITY_ANCHOR_EXT;
  anchorConfig.enabledComponentCount = enabledComponents.size();
  anchorConfig.enabledComponents = enabledComponents.data();

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

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

  XrSpatialContextPersistenceConfigEXT persistenceConfig{XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT};
  persistenceConfig.persistenceContextCount = 1;
  persistenceConfig.persistenceContexts = &persistenceContext;

  if (supportsPersistenceComponent) {
    spatialContextCreateInfo.next = &persistenceConfig;
  }

  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;
}

// ...
// Discover persisted anchors.
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

永続化されたすべてのエンティティを検出する

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_PERSISTENCE_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 semantic label 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<XrSpatialPersistenceDataEXT> persistenceData(queryResult.entityIdCountOutput);
    XrSpatialComponentPersistenceListEXT persistenceDataList{XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT};
    persistenceDataList.persistDataCount = persistenceData.size();
    persistenceDataList.persistData = persistenceData.data();
    queryResult.next = &persistenceDataList;

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

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      // persistenceData[i].persistUuid is the UUID of the persisted entity whose entity ID is entityIds[i].
      // The persistenceData array is essentially the uuids persisted in the scope that the current
      // XrSpatialPersistenceContextEXT is configured with.
    }

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

特定の UUID を持つエンティティを検出する

XrFutureEXT future = XR_NULL_FUTURE_EXT;

// Load up the uuids that the app has stored on its own i.e. the uuids it is interested in.
std::vector<XrUuid> uuidsStoredByApp = loadPersistedUuids();

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

auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
  XrSpatialDiscoveryPersistenceUuidFilterEXT persistenceFilter{XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT};
  persistenceFilter.persistedUuidCount = uuidsStoredByApp.size();
  persistenceFilter.persistedUuids = uuidsStoredByApp.data();

  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  snapshotCreateInfo.next = &persistenceFilter;

  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 semantic label 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<XrSpatialPersistenceDataEXT> persistenceData(queryResult.entityIdCountOutput);
    XrSpatialComponentPersistenceListEXT persistenceDataList{XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT};
    persistenceDataList.persistDataCount = persistenceData.size();
    persistenceDataList.persistData = persistenceData.data();
    queryResult.next = &persistenceDataList;

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

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      if (persistenceData[i].persistState == XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT) {
        // persistenceData[i].persistUuid, requested by the app, is present in the persistence scope
        // and its corresponding entity ID and state are entityIds[i] & entityStates[i] respectively.
      } else if (persistenceData[i].persistState == XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT) {
        // persistenceData[i].persistUuid, requested by the app, is NOT present in the persistence scope
        // and its corresponding entity ID (entityIds[i]) would be XR_NULL_SPATIAL_ENTITY_ID_EXT
        // and tracking state (entityStates[i]) would be XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT.
      }
    }

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

問題

変更履歴

  • リビジョン 1、2024 年 8 月 29 日(Nihav Jain、Google)

    • 拡張機能の初期説明