XR_ANDROID_spatial_discovery_raycast

Nazwa ciągu znaków

XR_ANDROID_spatial_discovery_raycast

Typ rozszerzenia

Rozszerzenie instancji

Zarejestrowany numer rozszerzenia

787

Wersja

1

Stan ratyfikacji

Niezatwierdzone

Zależności rozszerzenia i wersji

XR_EXT_spatial_entity

Data ostatniej modyfikacji

2025-08-12

Stan własności intelektualnej

Brak znanych roszczeń dotyczących własności intelektualnej.

Twórcy

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

Przegląd

To rozszerzenie bazuje na XR_EXT_spatial_entity i zapewnia funkcję raycast dla istniejących funkcji przestrzennych, takich jak XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT , aby wykrywać jednostki przestrzenne.

To rozszerzenie wprowadza też nową funkcję przestrzenną do raycastingu w buforze głębi.

Uprawnienia

Wymagane uprawnienia zależą od funkcji używanych przez aplikację na Androida. Jeśli używana jest funkcja XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID, aplikacja musi mieć uprawnienie android.permission.SCENE_UNDERSTANDING_FINE. Jeśli używana jest funkcja XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, aplikacja musi mieć uprawnienie android.permission.SCENE_UNDERSTANDING_COARSE. Uprawnienie android.permission.SCENE_UNDERSTANDING_FINE implikuje też uprawnienie android.permission.SCENE_UNDERSTANDING_COARSE. Jeśli aplikacja używa obu funkcji, nie musi oddzielnie prosić o oba uprawnienia.

Zarówno android.permission.SCENE_UNDERSTANDING_COARSE, jak i android.permission.SCENE_UNDERSTANDING_FINE są uważane za uprawnienia niebezpieczne.

(poziom ochrony: niebezpieczny)

Obsługa środowiska wykonawczego

Jeśli środowisko wykonawcze obsługuje wykrywanie jednostek przestrzennych za pomocą raycastingu, musi wskazać to, wyliczając XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID w xrEnumerateSpatialCapabilityComponentTypesEXT dla funkcji, które obsługują wykrywanie za pomocą raycastingu.

Jeśli środowisko wykonawcze obsługuje raycasting w buforze głębi, musi wyliczyć XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID w xrEnumerateSpatialCapabilitiesEXT .

Wykrywanie jednostek przestrzennych za pomocą raycastingu

Struktura XrSpatialRaycastInfoANDROID jest zdefiniowana w ten sposób:

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

Opisy elementów

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • space to XrSpace, w którym będzie się znajdować pozycja XrSpatialRaycastResultDataANDROID.
  • time to XrTime, w którym zdefiniowano pozycję XrSpatialRaycastResultDataANDROID.
  • origin to XrVector3f, który opisuje początek promienia.
  • direction to XrVector3f, który opisuje kierunek promienia.
  • maxDistance to odległość w metrach, którą aplikacja może opcjonalnie określić, aby ograniczyć wykrywanie jednostek znajdujących się w określonej odległości od origin wzdłuż direction .

Aplikacja może uwzględnić XrSpatialRaycastInfoANDROID w łańcuchu XrSpatialDiscoverySnapshotCreateInfoEXT :: next , aby wykrywać jednostki przestrzenne, które przecinają promień zdefiniowany w tej strukturze.

Jeśli aplikacja używa XrSpatialRaycastInfoANDROID z XrSpatialContextEXT, który został skonfigurowany bez włączenia XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID dla żadnej funkcji, środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT z xrCreateSpatialDiscoverySnapshotAsyncEXT lub xrCreateSpatialRaycastSnapshotANDROID .

Środowisko wykonawcze musi uwzględnić w XrSpatialSnapshotEXT dane komponentu i identyfikatory tylko tych jednostek przestrzennych, które pochodzą z funkcji obsługujących komponent XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID.

Jeśli aplikacja ustawi maxDistance na wartość dodatnią, środowisko wykonawcze nie może uwzględniać w zrzucie żadnych jednostek przestrzennych, które znajdują się w odległości większej niż maxDistance od panme:origin wzdłuż direction . Jeśli maxDistance jest ustawiona na 0 lub wartość ujemną, środowisko wykonawcze musi uznać promień za nieograniczony.

Prawidłowe użycie (niejawne)

Komponent wyniku raycastingu

Struktura XrSpatialRaycastResultDataANDROID jest zdefiniowana w ten sposób:

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

Opisy elementów

  • hitPose to XrPosef określający punkt, w którym promień przecina jednostkę przestrzenną.
  • distanceSquared to kwadrat odległości od początku promienia do punktu przecięcia.

Komponent XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID będzie obecny tylko w XrSpatialSnapshotEXT utworzonym na podstawie xrCreateSpatialDiscoverySnapshotAsyncEXT, gdzie XrSpatialRaycastInfoANDROID jest uwzględniony w łańcuchu XrSpatialDiscoverySnapshotCreateInfoEXT :: next , lub w XrSpatialSnapshotEXT utworzonym na podstawie xrCreateSpatialRaycastSnapshotANDROID .

Środowisko wykonawcze nie może uwzględniać tego komponentu w żadnym XrSpatialSnapshotEXT utworzonym za pomocą xrCreateSpatialUpdateSnapshotEXT .

Jeśli aplikacja uwzględni XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID w XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes , środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE z xrCreateSpatialUpdateSnapshotEXT .

Jeśli XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID jest włączony tylko w przypadku niektórych funkcji, środowisko wykonawcze musi uwzględniać w zrzucie tylko jednostki przestrzenne udostępniane przez te funkcje. Jeśli np. obiekt i płaszczyzna są ustawione w tym samym kierunku, a XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID jest włączony tylko w przypadku XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT , zostanie wykryta tylko płaszczyzna.

hitPose komponentu XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID będzie się znajdować w XrCreateSpatialDiscoverySnapshotCompletionInfoEXT :: baseSpace w XrCreateSpatialDiscoverySnapshotCompletionInfoEXT :: time . Dodatnia oś Z jest normalną powierzchnią trafienia, a ujemna oś Y wskazuje w przybliżeniu na początek promienia.

Prawidłowe użycie (niejawne)

Struktura listy komponentów do wysyłania zapytań o dane

Struktura XrSpatialComponentRaycastResultListANDROID jest zdefiniowana w ten sposób:

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

Opisy elementów

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • raycastResultCount to uint32_t opisujący liczbę elementów w tablicy raycastResults.
  • raycastResults to tablica XrSpatialRaycastResultDataANDROID .

Aby wysłać zapytanie o komponent wyniku raycastingu jednostek przestrzennych w XrSpatialSnapshotEXT , uwzględnij XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID w XrSpatialComponentDataQueryConditionEXT :: componentTypes i dodaj XrSpatialComponentRaycastResultListANDROID do łańcucha XrSpatialComponentDataQueryResultEXT :: next.

Jeśli XrSpatialComponentRaycastResultListANDROID znajduje się w łańcuchu XrSpatialComponentDataQueryResultEXT :: next , ale XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID nie jest uwzględniony w XrSpatialComponentDataQueryConditionEXT :: componentTypes , środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE z xrQuerySpatialComponentDataEXT .

Jeśli raycastResultCount jest mniejszy niż XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput , środowisko wykonawcze musi zwrócić XR_ERROR_SIZE_INSUFFICIENT z xrQuerySpatialComponentDataEXT .

Zwrócone raycastResults są nieuporządkowane. Aplikacja może użyć XrSpatialRaycastResultDataANDROID :: distanceSquared , aby posortować wyniki według odległości.

Prawidłowe użycie (niejawne)

Konfiguracja

Jeśli XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID jest wyliczony w XrSpatialCapabilityComponentTypesEXT :: componentTypes dla jakiejś funkcji, aplikacja może go włączyć, uwzględniając wartość enum na liście XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents. Aby uwzględnić ten komponent w następnym łańcuchu XrSpatialCapabilityConfigurationBaseHeaderEXT, nie trzeba go specjalnie konfigurować .

Jeśli aplikacja uwzględni XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID w XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes , środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE z xrCreateSpatialUpdateSnapshotEXT . Ten komponent jest specyficzny dla zrzutów wykrywania.

Funkcja przestrzenna raycastingu głębi

Konfiguracja

Struktura XrSpatialCapabilityConfigurationDepthRaycastANDROID jest zdefiniowana w ten sposób:

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

Opisy elementów

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • capability to XrSpatialCapabilityEXT i musi mieć wartość XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID .
  • enabledComponentCount to uint32_t opisujący liczbę elementów w tablicy enabledComponents. Musi być większa niż 0.
  • enabledComponents to wskaźnik do tablicy XrSpatialComponentTypeEXT .

Aplikacje mogą włączyć funkcję przestrzenną XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID , uwzględniając wskaźnik do struktury XrSpatialCapabilityConfigurationDepthRaycastANDROID w XrSpatialContextCreateInfoEXT :: capabilityConfigs .

Jeśli capability nie ma wartości XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID , środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE .

Identyfikator jednostek wykrytych za pomocą tej funkcji jest zawsze XR_NULL_SPATIAL_ENTITY_ID_EXT . Oznacza to też, że aplikacja nie może utworzyć uchwytu XrSpatialEntityEXT dla tych jednostek, a tym samym nie można ich uwzględnić w XrSpatialUpdateSnapshotCreateInfoEXT :: entities , aby utworzyć zrzut aktualizacji.

Prawidłowe użycie (niejawne)

Gwarantowane komponenty

Środowisko wykonawcze, które obsługuje XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID , musi obsługiwać te komponenty przestrzenne jako gwarantowane komponenty jednostek wykrytych za pomocą tej funkcji i musi je wyliczać w xrEnumerateSpatialCapabilityComponentTypesEXT:

  • XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID

Synchroniczny raycasting

Funkcja xrCreateSpatialRaycastSnapshotANDROID jest zdefiniowana w ten sposób:

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

Opisy parametrów

Funkcja xrCreateSpatialDiscoverySnapshotAsyncEXT jest wystarczająca w większości przypadków użycia, ale jest uważana za wolną w przypadku aplikacji, które wymagają natychmiastowych wyników raycastingu. Funkcja xrCreateSpatialRaycastSnapshotANDROID rozpoczyna synchroniczny raycasting, aby utworzyć zrzut, co umożliwia aplikacjom natychmiastowe wysyłanie zapytań o wyniki raycastingu.

Jeśli którykolwiek z XrSpatialComponentTypeEXT w XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes nie jest włączony w przypadku funkcji przestrzennych przekazanych do XrSpatialContextCreateInfoEXT :: capabilityConfigs podczas tworzenia spatialContext , środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT .

Jeśli aplikacja nie poda listy typów komponentów przestrzennych w XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes , środowisko wykonawcze musi uwzględnić w zrzucie wszystkie jednostki przestrzenne, które mają zestaw komponentów wyliczonych w XrSpatialCapabilityConfigurationBaseHeaderEXT ::enabledComponents dla funkcji obsługujących raycasting skonfigurowanych dla spatialContext . Środowisko wykonawcze musi uwzględnić dane wszystkich włączonych komponentów funkcji obsługujących raycasting skonfigurowanych dla spatialContext .

Prawidłowe użycie (niejawne)

Kody powrotu

Sukces

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • 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

Struktura XrSpatialRaycastSnapshotCreateInfoANDROID jest zdefiniowana w ten sposób:

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

Opisy elementów

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowym OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.
  • componentTypeCount to uint32_t opisujący liczbę elementów w tablicy componentTypes.
  • componentTypes to tablica XrSpatialComponentTypeEXT .
  • raycastInfo to struktura XrSpatialRaycastInfoANDROID opisująca informacje o promieniu.

Prawidłowe użycie (niejawne)

Przykładowy kod

Konfigurowanie funkcji raycastingu głębi i śledzenia płaszczyzny

Poniższy przykładowy kod pokazuje, jak utworzyć kontekst przestrzenny z funkcjami obsługującymi raycasting. W tym przykładzie użyto funkcji XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID i 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))

Wykrywanie jednostek przestrzennych i wysyłanie zapytań o dane komponentów

Poniższy przykładowy kod pokazuje, jak wykrywać jednostki przestrzenne w kontekście skonfigurowanym za pomocą funkcji XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID i XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT oraz jak wysyłać zapytania o dane komponentów.

// 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);

Tworzenie zrzutu raycastingu

Poniższy przykładowy kod pokazuje, jak utworzyć synchroniczny zrzut raycastingu.

// 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);

Nowe polecenia

Nowe struktury

Nowe stałe enum

  • XR_ANDROID_SPATIAL_DISCOVERY_RAYCAST_EXTENSION_NAME
  • XR_ANDROID_spatial_discovery_raycast_SPEC_VERSION
  • Rozszerzanie XrSpatialCapabilityEXT :

    • XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID
  • Rozszerzanie XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID
  • Rozszerzanie 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

Problemy

Historia zmian

  • Wersja 1, 15 lipca 2025 r. (Brian Chen)

    • Wstępny opis rozszerzenia.