XR_ANDROID_spatial_discovery_raycast

이름 문자열

XR_ANDROID_spatial_discovery_raycast

확장 프로그램 유형

인스턴스 확장 프로그램

등록된 내선 번호

787

버전

1

승인 상태

비준되지 않음

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

XR_EXT_spatial_entity

최종 수정일

2025-08-12

IP 상태

알려진 IP 소유권 주장이 없습니다.

도움을 주신 분들

Brian Chen, Google
Levana Chen, Google
Kyle Chen, Google
Nihav Jain, Google
Spencer Quin, Google
Natalie Fleury, Meta
Yuichi Taguchi, Meta
Jimmy Alamparambil, ByteDance
Zhipeng Liu, ByteDance

개요

이 확장 프로그램은 XR_EXT_spatial_entity를 기반으로 하며 XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT와 같은 기존 공간 기능에 레이캐스트 기능을 제공하여 공간 항목을 검색합니다.

이 확장 프로그램은 깊이 버퍼에 대한 레이캐스팅을 위한 새로운 공간 기능도 도입합니다.

권한

Android 애플리케이션에서 사용하는 기능에 따라 필요한 권한입니다. XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID를 사용하는 경우 애플리케이션에 android.permission.SCENE_UNDERSTANDING_FINE 권한이 있어야 합니다. XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT를 사용하는 경우 애플리케이션에 android.permission.SCENE_UNDERSTANDING_COARSE 권한이 있어야 합니다. android.permission.SCENE_UNDERSTANDING_FINE은 android.permission.SCENE_UNDERSTANDING_COARSE 권한도 암시합니다. 애플리케이션이 두 기능을 모두 사용하는 경우 애플리케이션은 두 권한을 별도로 요청할 필요가 없습니다.

android.permission.SCENE_UNDERSTANDING_COARSE 및 android.permission.SCENE_UNDERSTANDING_FINE은 모두 위험한 권한으로 간주됩니다.

(보호 수준: 위험)

런타임 지원

런타임이 레이캐스팅을 통한 공간 엔티티 검색을 지원하는 경우 레이캐스트를 통한 검색을 지원하는 기능의 xrEnumerateSpatialCapabilityComponentTypesEXT에 XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID를 열거하여 이를 나타내야 합니다(must).

런타임이 깊이 버퍼에 대한 레이캐스팅을 지원하는 경우 xrEnumerateSpatialCapabilitiesEXT에서 XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID를 열거해야 합니다.

레이캐스팅으로 공간 항목 탐색

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

typedef struct XrSpatialRaycastInfoANDROID {
    XrStructureType    type;
    const void*        next;
    XrSpace            space;
    XrTime             time;
    XrVector3f         origin;
    XrVector3f         direction;
    float              maxDistance;
} XrSpatialRaycastInfoANDROID;

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • space는 XrSpatialRaycastResultDataANDROID의 포즈가 위치할 XrSpace입니다.
  • time은 XrSpatialRaycastResultDataANDROID의 포즈가 정의된 XrTime입니다.
  • origin은 광선의 원점을 설명하는 XrVector3f입니다.
  • direction은 광선의 방향을 설명하는 XrVector3f입니다.
  • maxDistance는 애플리케이션이 direction를 따라 origin에서 지정된 거리 내에 있는 항목의 검색을 제한하기 위해 선택적으로 지정할 수 있는 거리(미터)입니다.

애플리케이션은 XrSpatialDiscoverySnapshotCreateInfoEXT :: next 체인에 XrSpatialRaycastInfoANDROID를 포함하여 이 구조체에 정의된 광선과 교차하는 공간 엔티티를 검색할 수 있습니다.

애플리케이션이 어떤 기능에 대해서도 XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID를 사용 설정하지 않고 구성된 XrSpatialContextEXT와 함께 XrSpatialRaycastInfoANDROID를 사용하는 경우 런타임은 xrCreateSpatialDiscoverySnapshotAsyncEXT 또는 xrCreateSpatialRaycastSnapshotANDROID에서 XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT를 반환해야 합니다(must).

런타임은 XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID 구성요소를 지원하는 기능에서 가져온 XrSpatialSnapshotEXT의 공간 항목의 구성요소 데이터와 ID만 포함해야 합니다.

애플리케이션이 maxDistance를 양수 값으로 설정하는 경우 런타임은 direction를 따라 panme:origin에서 maxDistance보다 멀리 떨어진 스냅샷에 적중된 공간 항목을 포함해서는 안 됩니다. maxDistance가 0 또는 음수 값으로 설정된 경우 런타임은 광선을 제한되지 않은 것으로 간주해야 합니다(MUST).

올바른 사용 (암시적)

  • XrSpatialRaycastInfoANDROID를 사용하기 전에 XR_ANDROID_spatial_discovery_raycast 확장 프로그램을 사용 설정해야 합니다.
  • type은(는) XR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • space는 유효한 XrSpace 핸들이어야 합니다(must).

Raycast Result Component

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

typedef struct XrSpatialRaycastResultDataANDROID {
    XrPosef    hitPose;
    float      distanceSquared;
} XrSpatialRaycastResultDataANDROID;

회원 설명

  • hitPose는 광선이 공간 엔티티와 교차하는 지점을 정의하는 XrPosef입니다.
  • distanceSquared는 광선 원점에서 교차점까지의 거리의 제곱입니다.

XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID 구성요소는 xrCreateSpatialDiscoverySnapshotAsyncEXT에서 생성된 XrSpatialSnapshotEXT에만 존재합니다. 여기서 XrSpatialRaycastInfoANDROID는 XrSpatialDiscoverySnapshotCreateInfoEXT :: next 체인에 포함되거나 xrCreateSpatialRaycastSnapshotANDROID에서 생성된 XrSpatialSnapshotEXT에 포함됩니다.

런타임은 xrCreateSpatialUpdateSnapshotEXT를 사용하여 생성된 XrSpatialSnapshotEXT에 이 구성요소를 포함해서는 안 됩니다.

애플리케이션이 XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes에 XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID를 포함하는 경우 런타임은 xrCreateSpatialUpdateSnapshotEXT에서 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must).

XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID가 특정 기능에만 사용 설정된 경우 런타임은 스냅샷에 해당 기능에서 제공하는 공간 항목만 포함해야 합니다(must). 예를 들어 객체와 평면이 같은 방향으로 정렬되어 있고 XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID가 XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT에만 사용 설정된 경우 평면만 검색됩니다.

XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID의 hitPose는 XrCreateSpatialDiscoverySnapshotCompletionInfoEXT :: baseSpace(XrCreateSpatialDiscoverySnapshotCompletionInfoEXT :: time)에 있습니다. 양의 Z축은 히트 표면의 법선이고 음의 Y축은 대략 광선 원점을 가리킵니다.

올바른 사용 (암시적)

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

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

typedef struct XrSpatialComponentRaycastResultListANDROID {
    XrStructureType                       type;
    void*                                 next;
    uint32_t                              raycastResultCount;
    XrSpatialRaycastResultDataANDROID*    raycastResults;
} XrSpatialComponentRaycastResultListANDROID;

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • raycastResultCount은 raycastResults 배열의 요소 수를 설명하는 uint32_t입니다.
  • raycastResults는 XrSpatialRaycastResultDataANDROID의 배열입니다.

XrSpatialSnapshotEXT에서 공간 항목의 레이캐스트 결과 구성요소를 쿼리하려면 XrSpatialComponentDataQueryConditionEXT :: componentTypes에 XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID를 포함하고 XrSpatialComponentDataQueryResultEXT :: next 체인에 XrSpatialComponentRaycastResultListANDROID를 추가합니다.

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

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

반환되는 raycastResults은 정렬되지 않습니다. 애플리케이션은 XrSpatialRaycastResultDataANDROID :: distanceSquared를 사용하여 거리에 따라 결과를 정렬할 수 있습니다.

올바른 사용 (암시적)

  • XrSpatialComponentRaycastResultListANDROID를 사용하기 전에 XR_ANDROID_spatial_discovery_raycast 확장 프로그램을 사용 설정해야 합니다.
  • type은(는) XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • raycastResults는 raycastResultCount XrSpatialRaycastResultDataANDROID 구조의 배열에 대한 포인터여야 합니다(must).
  • raycastResultCount 매개변수는 0보다 커야 합니다.

구성

일부 기능의 XrSpatialCapabilityComponentTypesEXT :: componentTypes에 XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID가 열거된 경우 애플리케이션은 XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents 목록에 enum 값을 포함하여 이를 사용 설정할 수 있습니다. 이 구성요소는 XrSpatialCapabilityConfigurationBaseHeaderEXT의 다음 체인에 포함하기 위해 특별한 구성이 필요하지 않습니다.

애플리케이션이 XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes에 XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID를 포함하는 경우 런타임은 xrCreateSpatialUpdateSnapshotEXT에서 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must). 이 구성요소는 탐색 스냅샷에만 적용됩니다.

Depth Raycast 공간 기능

구성

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

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

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다.
  • capability은 XrSpatialCapabilityEXT이며 XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID여야 합니다.
  • enabledComponentCount은 enabledComponents 배열의 요소 수를 설명하는 uint32_t입니다. 0보다 커야 합니다.
  • enabledComponents는 XrSpatialComponentTypeEXT 배열의 포인터입니다.

애플리케이션은 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 XrSpatialCapabilityConfigurationDepthRaycastANDROID 구조에 대한 포인터를 포함하여 XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID 공간 기능을 사용 설정할 수 있습니다.

capability가 XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID가 아닌 경우 런타임은 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must).

이 기능을 통해 발견된 항목의 ID는 항상 XR_NULL_SPATIAL_ENTITY_ID_EXT입니다. 즉, 애플리케이션은 이러한 항목의 XrSpatialEntityEXT 핸들을 만들 수 없으므로 XrSpatialUpdateSnapshotCreateInfoEXT :: entities에 포함하여 업데이트 스냅샷을 만들 수 없습니다.

올바른 사용 (암시적)

보장 구성요소

XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID를 지원하는 런타임은 이 기능으로 검색된 항목의 보장된 구성요소로 다음 공간 구성요소를 지원해야 하며(must) xrEnumerateSpatialCapabilityComponentTypesEXT에 열거해야 합니다(must).

  • XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID

동기식 레이캐스트

xrCreateSpatialRaycastSnapshotANDROID 함수는 다음과 같이 정의됩니다.

XrResult xrCreateSpatialRaycastSnapshotANDROID(
    XrSpatialContextEXT                         spatialContext,
    const XrSpatialRaycastSnapshotCreateInfoANDROID* createInfo,
    XrSpatialSnapshotEXT*                       snapshot);

파라미터 설명

대부분의 사용 사례에서는 xrCreateSpatialDiscoverySnapshotAsyncEXT로 충분하지만, 즉각적인 레이캐스트 결과가 필요한 애플리케이션의 경우 느린 것으로 간주됩니다. xrCreateSpatialRaycastSnapshotANDROID는 동기식 레이캐스팅을 시작하여 스냅샷을 생성하므로 애플리케이션이 즉시 레이캐스트 결과를 쿼리할 수 있습니다.

spatialContext을 만들 때 XrSpatialContextCreateInfoEXT :: capabilityConfigs에 전달된 공간 기능에 대해 XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes의 XrSpatialComponentTypeEXT 중 하나라도 사용 설정되지 않은 경우 런타임은 XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT를 반환해야 합니다(must).

애플리케이션이 XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes에서 공간 구성요소 유형 목록을 제공하지 않는 경우 런타임은 spatialContext에 구성된 레이캐스트 지원 기능의 XrSpatialCapabilityConfigurationBaseHeaderEXT ::enabledComponents에 열거된 구성요소 집합이 있는 스냅샷의 모든 공간 항목을 포함해야 합니다(must). 런타임은 spatialContext에 구성된 레이캐스트 지원 기능의 사용 설정된 모든 구성요소에 관한 데이터를 포함해야 합니다(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_COMPONENT_NOT_ENABLED_EXT
  • XR_ERROR_TIME_INVALID
  • XR_ERROR_VALIDATION_FAILURE

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

typedef struct XrSpatialRaycastSnapshotCreateInfoANDROID {
    XrStructureType                       type;
    const void*                           next;
    uint32_t                              componentTypeCount;
    const XrSpatialComponentTypeEXT*      componentTypes;
    const XrSpatialRaycastInfoANDROID*    raycastInfo;
} XrSpatialRaycastSnapshotCreateInfoANDROID;

회원 설명

  • type는 이 구조의 XrStructureType입니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 포인터입니다. 핵심 OpenXR 또는 이 확장 프로그램에는 이러한 구조가 정의되어 있지 않습니다.
  • componentTypeCount은 componentTypes 배열의 요소 수를 설명하는 uint32_t입니다.
  • componentTypes는 XrSpatialComponentTypeEXT의 배열입니다.
  • raycastInfo는 광선 정보를 설명하는 XrSpatialRaycastInfoANDROID 구조입니다.

올바른 사용 (암시적)

예시 코드

깊이 레이캐스트 및 평면 추적 기능 구성

다음 예시 코드는 레이캐스트 기능을 지원하는 기능으로 공간 컨텍스트를 만드는 방법을 보여줍니다. 이 예시에서는 XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID 및 XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT가 사용됩니다.

// Check runtime supported capabilities
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_DEPTH_RAYCAST_ANDROID) == capabilities.end()) {
  return;
}

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

// Create capability config for depth raycasting
std::vector<XrSpatialComponentTypeEXT> depthRaycastComponents {
  XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID
};

// Create capability config for depth raycasting
XrSpatialCapabilityConfigurationDepthRaycastANDROID depthRaycastConfig {
  .type = XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID,
  .next = nullptr,
  .capability = XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID,
  .enabledComponentCount = (uint32_t)depthRaycastComponents.size(),
  .enabledComponents = depthRaycastComponents.data(),
};

// Enumerate runtime supported components for plane tracking capability
XrSpatialCapabilityComponentTypesEXT capabilityComponentTypes {
  XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT
};

bool isRaycastSupportedViaPlaneTracking;
std::vector<XrSpatialComponentTypeEXT> planeTrackingComponents {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_PLANE_ALIGNMENT_EXT,
};

CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId,
       XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, &capabilityComponentTypes));

planeTrackingComponents.resize(capabilityComponentTypes.componentTypeCountOutput);
capabilityComponentTypes.componentTypeCapacityInput = (uint32_t)planeTrackingComponents.size();
capabilityComponentTypes.componentTypes = planeTrackingComponents.data();

CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId,
       XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, &capabilityComponentTypes));

// Check if raycast is supported by plane tracking
isRaycastSupportedViaPlaneTracking = std::find(planeTrackingComponents.begin(),
planeTrackingComponents.end(), XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID)
!= planeTrackingComponents.end();

// Create capability config for plane tracking
XrSpatialCapabilityConfigurationPlaneTrackingEXT planeTrackingConfig {
  .type = XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_PLANE_TRACKING_EXT,
  .next = nullptr,
  .capability = XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT,
  .enabledComponentCount = (uint32_t)planeTrackingComponents.size(),
  .enabledComponents = planeTrackingComponents.data(),
};

// Create spatial context
// Types of raycast is determined by configs included in XrSpatialContextCreateInfoEXT
// For this example, both plane raycast & depth raycast are performed
std::vector<const XrSpatialCapabilityConfigurationBaseHeaderEXT*> capabilityConfigs;
capabilityConfigs.push_back(reinterpret_cast<const XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&depthRaycastConfig));
if(isRaycastSupportedViaPlaneTracking) capabilityConfigs.push_back(reinterpret_cast<const XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&planeTrackingConfig));

XrSpatialContextCreateInfoEXT contextCreateInfo {
  .type = XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT,
  .next = nullptr,
  .capabilityConfigCount = (uint32_t)capabilityConfigs.size(),
  .capabilityConfigs = capabilityConfigs.data(),
};

CHK_XR(xrCreateSpatialContextAsyncEXT(session, &contextCreateInfo, &future))

// Completes creating spatial context
XrCreateSpatialContextCompletionEXT contextCompletion{
XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};

CHK_XR(xrCreateSpatialContextCompleteEXT(session, future, &contextCompletion))

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

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

// Fill in the raycast info.
XrSpatialRaycastInfoANDROID raycastInfo {
  .type        = XR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID,
  .next        = nullptr,
  .space       = viewSpace,
  .time        = updateTime,
  .origin      = {0.0f, 0.0f, 0.0f},
  .direction   = {0.0f, 0.0f,-1.0f},
  .maxDistance = 0.0f  // ray is unbounded
};

// Next pointing to the raycast info.
XrSpatialDiscoverySnapshotCreateInfoEXT discoverySnapshotCreateInfo {
  .type = XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT,
  .next = &raycastInfo
};

// Create snapshot
CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT (
spatialContext, &discoverySnapshotCreateInfo, &future));

waitUntilReady(future);

// Complete async operation.
XrCreateSpatialDiscoverySnapshotCompletionInfoEXT
  createSnapshotCompletionInfo {
    .type      = XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT,
    .baseSpace = viewSpace,
    .time      = updateTime,
    .future    = future,
  };

XrCreateSpatialDiscoverySnapshotCompletionEXT completion {
  XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};

CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(
           spatialContext, &createSnapshotCompletionInfo,
           &completion));

if(completion.futureResult != XR_SUCCESS) return;

// Query hit result components
std::array<XrSpatialComponentTypeEXT, 1> enabledComponents = {
  XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID
};

XrSpatialComponentDataQueryConditionEXT queryCond {
  .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT,
  .componentTypeCount = 1,
  .componentTypes     = enabledComponents.data(),
};

XrSpatialComponentDataQueryResultEXT queryResult {
  .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT,
};

XrResult result = xrQuerySpatialComponentDataEXT(
           completion.snapshot, &queryCond, &queryResult);

// Check query result.
if(result != XR_SUCCESS) return;

// Query again for the hit result list.
std::vector<XrSpatialRaycastResultDataANDROID> raycastResults;
raycastResults.resize(queryResult.entityIdCountOutput);
XrSpatialComponentRaycastResultListANDROID raycastResultList {
  .type               = XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID,
  .raycastResultCount = (uint32_t)raycastResults.size(),
  .raycastResults     = raycastResults.data(),
};

queryResult.next = &raycastResultList;
result = xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult);

// Check query result again.
if(result != XR_SUCCESS) return;

std::vector<XrSpatialEntityEXT> hitEntities;
std::vector<XrPosef> depthHitPoses;
for(uint32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
    // access raycastResults[i] for id & pose
    XrSpatialEntityIdEXT   id   = queryResult.entityIds[i];
    XrPosef                pose = raycastResults[i].hitPose;

    if (id != XR_NULL_SPATIAL_ENTITY_ID_EXT) {
        // hit entities (e.g. planes)
    // get entity handle via entity id
    XrSpatialEntityFromIdCreateInfoEXT entityCreateInfo {
      .type = XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT,
      .entityId = id,
    };

    XrSpatialEntityEXT entity = XR_NULL_HANDLE;
    xrCreateSpatialEntityFromIdEXT(spatialContext, &entityCreateInfo, &entity);

    hitEntities.push_back(entity);
  } else {
    // hit depth
    depthHitPoses.push_back(pose);
  }
}

// Cleanup
xrDestroySpatialSnapshotEXT(completion.snapshot);

Raycast 스냅샷 만들기

다음 예시 코드는 동기식 레이캐스트 스냅샷을 만드는 방법을 보여줍니다.

// fill in create info
XrSpatialRaycastSnapshotCreateInfoANDROID createInfo {
  .type = XR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID,
  .componentTypeCount = 0,   // include all hit spatial entities
  .componentTypes = nullptr,
  .raycastInfo = &raycastInfo
};

// create raycast snapshot
XrSpatialSnapshotEXT raycastSnapshot = XR_NULL_HANDLE;
CHK_XR(xrCreateSpatialRaycastSnapshotANDROID(
  spatialContext, &createInfo, &raycastSnapshot));

// ...
// query component data as previous example
// ...

// Cleanup
xrDestroySpatialSnapshotEXT(raycastSnapshot);

새 명령어

새로운 구조

새 enum 상수

  • XR_ANDROID_SPATIAL_DISCOVERY_RAYCAST_EXTENSION_NAME
  • XR_ANDROID_spatial_discovery_raycast_SPEC_VERSION
  • XrSpatialCapabilityEXT 확장:

    • XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID
  • XrSpatialComponentTypeEXT 확장:

    • XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID
  • XrStructureType 확장:

    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID
    • XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID
    • XR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID
    • XR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID

문제

버전 기록

  • 버전 1, 2025년 7월 15일 (브라이언 첸)

    • 초기 확장 프로그램 설명입니다.