XR_ANDROID_spatial_discovery_raycast
Name String
XR_ANDROID_spatial_discovery_raycast
Extension Type
Instance extension
Registered Extension Number
787
Revision
1
Ratification Status
Not ratified
Extension and Version Dependencies
XR_EXT_spatial_entity
Last Modified Date
2025-08-12
IP Status
No known IP claims.
Contributors
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
Overview
This extension builds on XR_EXT_spatial_entity and provides raycast functionality for existing spatial capabilities, such as XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT , to discover spatial entities.
This extension also introduces a new spatial capability for raycasting against depth buffer.
Permissions
Required permissions depending on the capabilities the Android application uses. If XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID is used, the application must have android.permission.SCENE_UNDERSTANDING_FINE permission. If XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT is used, the application must have android.permission.SCENE_UNDERSTANDING_COARSE permission. The android.permission.SCENE_UNDERSTANDING_FINE also implies the android.permission.SCENE_UNDERSTANDING_COARSE permission, if the application uses both capabilities, the application does not need to request both permissions separately.
Both android.permission.SCENE_UNDERSTANDING_COARSE and android.permission.SCENE_UNDERSTANDING_FINE are considered dangerous permissions.
(protection level: dangerous)
Runtime Support
If the runtime supports discovery of spatial entities via raycasting, it must indicate this by enumerating XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID in xrEnumerateSpatialCapabilityComponentTypesEXT for the capabilities that support discovery by raycast.
If the runtime supports raycasting against the depth buffer, it must enumerate XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID in xrEnumerateSpatialCapabilitiesEXT .
Discover spatial entities by raycasting
The XrSpatialRaycastInfoANDROID structure is defined as:
typedef struct XrSpatialRaycastInfoANDROID {
XrStructureType type;
const void* next;
XrSpace space;
XrTime time;
XrVector3f origin;
XrVector3f direction;
float maxDistance;
} XrSpatialRaycastInfoANDROID;
Member Descriptions
typeis the XrStructureType of this structure.nextisNULLor a pointer to the next structure in a structure chain.spaceis the XrSpace in which the pose of XrSpatialRaycastResultDataANDROID will be located.timeis anXrTimeat which the pose of XrSpatialRaycastResultDataANDROID defined.originis an XrVector3f which describes the origin of the ray.directionis an XrVector3f which describes the direction of the ray.maxDistanceis the distance in meters that application can optionally specify to limit the discovery of entities that are within the specified distance from theorigin, alongdirection.
An application can include XrSpatialRaycastInfoANDROID in the XrSpatialDiscoverySnapshotCreateInfoEXT :: next chain to discover spatial entities that intersect with the ray defined in this struct.
If an application uses XrSpatialRaycastInfoANDROID with an XrSpatialContextEXT that was configured without enabling XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID for any capability, the runtime must return XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT from xrCreateSpatialDiscoverySnapshotAsyncEXT or xrCreateSpatialRaycastSnapshotANDROID .
The runtime must include the component data and ids of only those spatial entities in XrSpatialSnapshotEXT that come from capabilities that support the XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID component.
If an application sets maxDistance to a positive value, the runtime must not include any hit spatial entities in the snapshot that are more than maxDistance away from the panme:origin along direction . If maxDistance is set to 0 or a negative value, the runtime must consider the ray unbounded.
Valid Usage (Implicit)
- The
XR_ANDROID_spatial_discovery_raycastextension must be enabled prior to using XrSpatialRaycastInfoANDROID -
typemust beXR_TYPE_SPATIAL_RAYCAST_INFO_ANDROID -
nextmust beNULLor a valid pointer to the next structure in a structure chain -
spacemust be a valid XrSpace handle
Raycast Result Component
The XrSpatialRaycastResultDataANDROID structure is defined as:
typedef struct XrSpatialRaycastResultDataANDROID {
XrPosef hitPose;
float distanceSquared;
} XrSpatialRaycastResultDataANDROID;
Member Descriptions
hitPoseis an XrPosef defining the point where the ray intersects with the spatial entity.distanceSquaredis the squared of the distance from origin of the ray to the intersection point.
The XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID component will only be present in an XrSpatialSnapshotEXT created from xrCreateSpatialDiscoverySnapshotAsyncEXT where XrSpatialRaycastInfoANDROID is included in the XrSpatialDiscoverySnapshotCreateInfoEXT :: next chain or in an XrSpatialSnapshotEXT created from xrCreateSpatialRaycastSnapshotANDROID .
The runtime must not include this component in any XrSpatialSnapshotEXT that is created using xrCreateSpatialUpdateSnapshotEXT .
The runtime must return XR_ERROR_VALIDATION_FAILURE from xrCreateSpatialUpdateSnapshotEXT if the application includes XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID in XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes .
If XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID is enabled only for certain capabilities, the runtime must include only spatial entities provided by those capabilities in the snapshot. For example, if an object and a plane lines up in the same direction and XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID is enabled only for XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT , only the plane will be discovered.
The hitPose of the XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID will be located in XrCreateSpatialDiscoverySnapshotCompletionInfoEXT :: baseSpace at XrCreateSpatialDiscoverySnapshotCompletionInfoEXT :: time . The positive Z axis is the normal of the hit surface, and the negative Y axis roughly points toward the ray origin.
Valid Usage (Implicit)
- The
XR_ANDROID_spatial_discovery_raycastextension must be enabled prior to using XrSpatialRaycastResultDataANDROID
Component list struct to query data
The XrSpatialComponentRaycastResultListANDROID structure is defined as:
typedef struct XrSpatialComponentRaycastResultListANDROID {
XrStructureType type;
void* next;
uint32_t raycastResultCount;
XrSpatialRaycastResultDataANDROID* raycastResults;
} XrSpatialComponentRaycastResultListANDROID;
Member Descriptions
typeis the XrStructureType of this structure.nextisNULLor a pointer to the next structure in a structure chain.raycastResultCountis auint32_tdescribing the count of elements in theraycastResultsarray.raycastResultsis an array of XrSpatialRaycastResultDataANDROID .
To query the raycast result component of the spatial entities in an XrSpatialSnapshotEXT , include XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID in XrSpatialComponentDataQueryConditionEXT :: componentTypes and add XrSpatialComponentRaycastResultListANDROID to the XrSpatialComponentDataQueryResultEXT :: next chain.
The runtime must return XR_ERROR_VALIDATION_FAILURE from xrQuerySpatialComponentDataEXT if XrSpatialComponentRaycastResultListANDROID is in the XrSpatialComponentDataQueryResultEXT :: next chain but XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID is not included in XrSpatialComponentDataQueryConditionEXT :: componentTypes .
The runtime must return XR_ERROR_SIZE_INSUFFICIENT from xrQuerySpatialComponentDataEXT if raycastResultCount is less than XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .
The returned raycastResults are unordered. An application can use XrSpatialRaycastResultDataANDROID :: distanceSquared to sort the results by distance.
Valid Usage (Implicit)
- The
XR_ANDROID_spatial_discovery_raycastextension must be enabled prior to using XrSpatialComponentRaycastResultListANDROID -
typemust beXR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID -
nextmust beNULLor a valid pointer to the next structure in a structure chain -
raycastResultsmust be a pointer to an array ofraycastResultCountXrSpatialRaycastResultDataANDROID structures - The
raycastResultCountparameter must be greater than0
Configuration
If XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID is enumerated in XrSpatialCapabilityComponentTypesEXT :: componentTypes for some capability, the application can enable it by including the enum value in the XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents list. This component does not require any special configuration to be included in the next chain of XrSpatialCapabilityConfigurationBaseHeaderEXT .
The runtime must return XR_ERROR_VALIDATION_FAILURE from xrCreateSpatialUpdateSnapshotEXT if the application includes XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID in XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes . This component is specific to discovery snapshots.
Depth Raycast Spatial Capability
Configuration
The XrSpatialCapabilityConfigurationDepthRaycastANDROID structure is defined as:
typedef struct XrSpatialCapabilityConfigurationDepthRaycastANDROID {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationDepthRaycastANDROID;
Member Descriptions
typeis the XrStructureType of this structure.nextisNULLor a pointer to the next structure in a structure chain.capabilityis an XrSpatialCapabilityEXT and must beXR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID.enabledComponentCountis auint32_tdescribing the count of elements in theenabledComponentsarray. It must be greater than 0.enabledComponentsis a pointer to an array of XrSpatialComponentTypeEXT .
Anpplications can enable the XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID spatial capability by including a pointer to an XrSpatialCapabilityConfigurationDepthRaycastANDROID structure in XrSpatialContextCreateInfoEXT :: capabilityConfigs .
The runtime must return XR_ERROR_VALIDATION_FAILURE if capability is not XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID .
The ID of entities discovered via this capability is always XR_NULL_SPATIAL_ENTITY_ID_EXT . This also means that application can not create an XrSpatialEntityEXT handle for these entities, and thus they can not be included in XrSpatialUpdateSnapshotCreateInfoEXT :: entities to create a update snapshot
Valid Usage (Implicit)
- The
XR_ANDROID_spatial_discovery_raycastextension must be enabled prior to using XrSpatialCapabilityConfigurationDepthRaycastANDROID -
typemust beXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROID -
nextmust beNULLor a valid pointer to the next structure in a structure chain -
capabilitymust be a valid XrSpatialCapabilityEXT value -
enabledComponentsmust be a pointer to an array ofenabledComponentCountvalid XrSpatialComponentTypeEXT values - The
enabledComponentCountparameter must be greater than0
Guaranteed Components
A runtime that supports XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID , must support the following spatial components as guaranteed components of the entities discovered by this capability and must enumerate them in xrEnumerateSpatialCapabilityComponentTypesEXT -
XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID
Synchronous Raycast
The xrCreateSpatialRaycastSnapshotANDROID function is defined as:
XrResult xrCreateSpatialRaycastSnapshotANDROID(
XrSpatialContextEXT spatialContext,
const XrSpatialRaycastSnapshotCreateInfoANDROID* createInfo,
XrSpatialSnapshotEXT* snapshot);
Parameter Descriptions
spatialContextis an XrSpatialContextEXT previously created by using xrCreateSpatialContextAsyncEXT .createInfois a pointer to an XrSpatialRaycastSnapshotCreateInfoANDROID .snapshotis a pointer to an XrSpatialSnapshotEXT .
While xrCreateSpatialDiscoverySnapshotAsyncEXT is sufficient for most use cases, it is considered slow for applications that require instant raycast results. xrCreateSpatialRaycastSnapshotANDROID starts a synchronous raycasting to create a snapshot, which allows applications to start querying raycast results immediately.
The runtime must return XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT if any of the XrSpatialComponentTypeEXT in XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes are not enabled for the spatial capabilities passed to XrSpatialContextCreateInfoEXT :: capabilityConfigs when creating spatialContext .
If the application does not provide a list of spatial component types in XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes , the runtime must include all the spatial entities in the snapshot that have the set of components which are enumerated in XrSpatialCapabilityConfigurationBaseHeaderEXT ::enabledComponents for raycast supported capabilities configured for spatialContext . The runtime must include the data for all the enabled components of the raycast supported capabilities configured for spatialContext .
Valid Usage (Implicit)
- The
XR_ANDROID_spatial_discovery_raycastextension must be enabled prior to calling xrCreateSpatialRaycastSnapshotANDROID -
spatialContextmust be a valid XrSpatialContextEXT handle -
createInfomust be a pointer to a valid XrSpatialRaycastSnapshotCreateInfoANDROID structure -
snapshotmust be a pointer to an XrSpatialSnapshotEXT handle
Return Codes
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_LIMIT_REACHEDXR_ERROR_OUT_OF_MEMORYXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXTXR_ERROR_TIME_INVALIDXR_ERROR_VALIDATION_FAILURE
The XrSpatialRaycastSnapshotCreateInfoANDROID structure is defined as:
typedef struct XrSpatialRaycastSnapshotCreateInfoANDROID {
XrStructureType type;
const void* next;
uint32_t componentTypeCount;
const XrSpatialComponentTypeEXT* componentTypes;
const XrSpatialRaycastInfoANDROID* raycastInfo;
} XrSpatialRaycastSnapshotCreateInfoANDROID;
Member Descriptions
typeis the XrStructureType of this structure.nextisNULLor a pointer to the next structure in a structure chain. No such structures are defined in core OpenXR or this extension.componentTypeCountis auint32_tdescribing the count of elements in thecomponentTypesarray.componentTypesis an array of XrSpatialComponentTypeEXT .raycastInfois the XrSpatialRaycastInfoANDROID structure describing the information of a ray.
Valid Usage (Implicit)
- The
XR_ANDROID_spatial_discovery_raycastextension must be enabled prior to using XrSpatialRaycastSnapshotCreateInfoANDROID -
typemust beXR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID -
nextmust beNULLor a valid pointer to the next structure in a structure chain - If
componentTypeCountis not0,componentTypesmust be a pointer to an array ofcomponentTypeCountvalid XrSpatialComponentTypeEXT values -
raycastInfomust be a pointer to a valid XrSpatialRaycastInfoANDROID structure
Example code
Configure Depth Raycast and Plane Tracking Capability
The following example code demonstrates how to create a spatial context with capabilities that support raycast functionality. For this example, XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID and XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT are used.
// 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))
Discover Spatial Entities & Query Component Data
The following example code demonstrates how to discover spatial entities for a context configured with XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID & XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT and query its component data.
// 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);
Create Raycast Snapshot
The following example code demonstrates how to create synchronous raycast snapshot.
// 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);
New Commands
New Structures
- XrSpatialCapabilityConfigurationDepthRaycastANDROID
- XrSpatialRaycastResultDataANDROID
- XrSpatialRaycastSnapshotCreateInfoANDROID
Extending XrSpatialComponentDataQueryResultEXT :
Extending XrSpatialDiscoverySnapshotCreateInfoEXT :
New Enum Constants
XR_ANDROID_SPATIAL_DISCOVERY_RAYCAST_EXTENSION_NAMEXR_ANDROID_spatial_discovery_raycast_SPEC_VERSIONExtending XrSpatialCapabilityEXT :
XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID
Extending XrSpatialComponentTypeEXT :
XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID
Extending XrStructureType :
XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_DEPTH_RAYCAST_ANDROIDXR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROIDXR_TYPE_SPATIAL_RAYCAST_INFO_ANDROIDXR_TYPE_SPATIAL_RAYCAST_SNAPSHOT_CREATE_INFO_ANDROID
Issues
Version History
Revision 1, 2025-07-15 (Brian Chen)
- Initial extension description.