XR_EXT_spatial_persistence

이름 문자열

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를 반환해야 합니다(must).

런타임이 XrSpatialPersistenceContextEXT로 표현되는 영구 스토리지에 대한 애플리케이션 액세스를 제어하기 위해 권한 시스템을 적용하는 경우, 이 애플리케이션에 해당 권한이 부여되지 않았다면 런타임은 XR_ERROR_PERMISSION_INSUFFICIENT를 반환해야 합니다(must).

올바른 사용 (암시적)

반품 코드

성공

  • 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 열거형은 다양한 유형의 지속성 컨텍스트 범위를 식별합니다.

enum의 의미는 다음과 같습니다.

enum 설명

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 값 배열의 포인터여야 합니다(MUST).

반품 코드

성공

  • 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를 반환해야 합니다(MUST). future가 이미 완료되었거나 취소된 경우 런타임은 XR_ERROR_FUTURE_INVALID_EXT를 반환해야 합니다(MUST).

올바른 사용 (암시적)

반품 코드

성공

  • 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를 설정해야 합니다(must).

올바른 사용 (암시적)

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 열거형의 성공 코드는 음수가 아닌 값이고 실패 코드는 음수 값입니다.

enum의 의미는 다음과 같습니다.

enum 설명

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 핸들을 해제할 수 있습니다.

xrDestroySpatialPersistenceContextEXT가 호출될 때 persistenceContext가 XrSpatialContextPersistenceConfigEXT를 통해 연결된 유효한 XrSpatialContextEXT 핸들이 있는 경우 런타임은 persistenceContext의 기본 리소스를 폐기하면 안 됩니다. 이는 지속성 컨텍스트의 리소스가 지속된 항목을 검색하기 위해 공간 컨텍스트에서 계속 사용되기 때문입니다. 이러한 상황에서 지속성 컨텍스트 핸들을 삭제하면 이러한 리소스에 대한 애플리케이션의 액세스 권한만 삭제됩니다.

소멸된 XrSpatialPersistenceContextEXT의 리소스는 지속성 컨텍스트가 연결된 모든 XrSpatialContextEXT 핸들이 소멸될 때 해제되어야 합니다.

올바른 사용 (암시적)

스레드 안전

  • persistenceContext 및 모든 하위 핸들에 대한 액세스는 외부에서 동기화되어야 합니다(must).

반품 코드

성공

  • 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의 다양한 상태를 식별합니다.

enum의 의미는 다음과 같습니다.

enum 설명

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를 반환해야 합니다(must).

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

다른 구성요소와 달리 런타임은 XrSpatialEntityTrackingStateEXT와 관계없이 XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT의 데이터를 설정해야 합니다.

올바른 사용 (암시적)

  • XR_EXT_spatial_persistence 확장 프로그램은 XrSpatialComponentPersistenceListEXT를 사용하기 전에 사용 설정해야 합니다.
  • type은(는) XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • persistData: persistDataCount XrSpatialPersistenceDataEXT 구조의 배열에 대한 포인터여야 합니다(must).
  • persistDataCount 매개변수는 0보다 커야 합니다.
구성

일부 기능의 XrSpatialCapabilityComponentTypesEXT :: componentTypes에 XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT가 열거된 경우 애플리케이션은 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 목록에 enum을 포함하여 이를 사용 설정할 수 있습니다(can). 이 구성요소는 XrSpatialCapabilityConfigurationBaseHeaderEXT의 다음 체인에 포함하기 위해 특별한 구성이 필요하지 않습니다. 애플리케이션이 사용 설정된 구성요소 목록에 XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT를 포함하는 경우 XrSpatialContextCreateInfoEXT의 다음 체인에 XrSpatialContextPersistenceConfigEXT도 포함해야 합니다(must). 그렇지 않으면 런타임은 xrCreateSpatialContextAsyncEXT에서 XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT를 반환해야 합니다(must).

지속성 컨텍스트로 공간 컨텍스트 구성

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는 유효한 XrSpatialPersistenceContextEXT 핸들 persistenceContextCount개의 배열에 대한 포인터여야 합니다.
  • 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를 사용하여 탐색 작업의 범위를 지속 UUID가 persistedUuids에 제공된 UUID 집합에 있는 항목으로만 지정할 수 있습니다.

애플리케이션이 XrSpatialDiscoverySnapshotCreateInfoEXT의 다음 체인에 XrSpatialDiscoveryPersistenceUuidFilterEXT를 추가하지만 xrCreateSpatialDiscoverySnapshotAsyncEXT :: spatialContext가 XrSpatialContextPersistenceConfigEXT를 사용하여 XrSpatialPersistenceContextEXT로 구성되지 않은 경우 런타임은 xrCreateSpatialDiscoverySnapshotAsyncEXT에서 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must).

런타임은 XrSpatialDiscoveryPersistenceUuidFilterEXT 필터를 XrSpatialDiscoverySnapshotCreateInfoEXT 또는 다음 체인에 제공된 다른 필터와 함께 'AND' 조건으로 처리해야 합니다(MUST). 런타임은 persistedUuids 배열 자체를 'OR' 조건으로 처리해야 합니다. 즉, 해당 배열에 제공된 UUID가 있는 항목을 필터링해야 합니다.

런타임은 생성된 스냅샷에 persistedUuids의 각 UUID에 대해 하나의 항목을 포함해야 합니다. 이 UUID에 대해 런타임은 현재 XrSpatialPersistenceStateEXT 상태를 확인할 수 있었습니다.

  • 런타임이 저장소에서 UUID를 찾으면 다음을 수행합니다.

    • 런타임은 이 항목의 XrSpatialPersistenceDataEXT에서 XrSpatialPersistenceStateEXT를 XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT로 설정해야 합니다(must).
    • 런타임은 생성된 스냅샷에 이 항목의 유효한 XrSpatialEntityIdEXT를 포함해야 합니다(must).
    • 런타임은 항목을 적극적으로 추적하고 구성요소에 유효한 데이터가 있는 경우 해당 항목의 XrSpatialEntityTrackingStateEXT를 XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT로 설정해야 합니다(MUST). 그렇지 않으면 런타임은 XrSpatialEntityTrackingStateEXT를 XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT로 설정해야 합니다(must).
  • 런타임에서 UUID가 저장소에 없다고 판단한 경우 (UUID가 저장소에 없었거나 한 번 있었지만 이후 유지되지 않은 경우) 다음을 수행합니다.

    • 런타임은 이 UUID가 더 이상 저장소에 없음을 애플리케이션에 나타내기 위해 이 항목의 XrSpatialPersistenceDataEXT에서 XrSpatialPersistenceStateEXT를 XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT로 설정해야 합니다(MUST).
    • 런타임은 생성된 스냅샷에서 이 항목의 XrSpatialEntityIdEXT를 XR_NULL_SPATIAL_ENTITY_ID_EXT로 설정해야 합니다(must).
    • 런타임은 이 항목의 XrSpatialEntityTrackingStateEXT를 XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT로 설정하여 이 항목이 추적되지 않음을 애플리케이션에 표시해야 합니다(must).
  • 런타임이 UUID가 저장소에 있는지 확인할 수 없는 경우 스냅샷에 UUID를 포함하지 않아야 합니다(MUST NOT).

애플리케이션은 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를 사용하기 전에 사용 설정되어야 합니다(must).
  • type은(는) XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • persistedUuids: persistedUuidCount XrUuid 구조 배열의 포인터여야 합니다(must).
  • persistedUuidCount 매개변수는 0보다 커야 합니다.
모든 영구 항목 검색

애플리케이션이 XrSpatialDiscoveryPersistenceUuidFilterEXT 없이 XrSpatialPersistenceContextEXT로 구성된 XrSpatialContextEXT와 함께 xrCreateSpatialDiscoverySnapshotAsyncEXT를 사용하는 경우 런타임은 XrSpatialPersistenceContextEXT로 표현되는 저장소에 유지되고 XrSpatialDiscoverySnapshotCreateInfoEXT에 제공된 필터를 충족하는 생성된 스냅샷에 이러한 항목을 포함해야 합니다(must). 이러한 법인의 경우

  • 런타임은 이 항목의 XrSpatialPersistenceDataEXT에서 XrSpatialPersistenceStateEXT를 XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT로 설정해야 합니다(must).
  • 런타임은 생성된 스냅샷에 이 항목의 유효한 XrSpatialEntityIdEXT를 포함해야 합니다(must).
  • 런타임은 항목을 적극적으로 추적하고 구성요소에 유효한 데이터가 있는 경우 해당 항목의 XrSpatialEntityTrackingStateEXT를 XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT로 설정해야 합니다(MUST). 그렇지 않으면 런타임은 XrSpatialEntityTrackingStateEXT를 XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT로 설정해야 합니다(must).

새 객체 유형

새 명령어

새로운 구조

새 enum

새 enum 상수

  • 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일 (니하브 자인, Google)

    • 초기 확장 프로그램 설명