XR_ANDROID_spatial_discovery_raycast

سلسلة الاسم

XR_ANDROID_spatial_discovery_raycast

نوع الإضافة

إضافة مثيل

رقم الإضافة المسجَّل

787

المراجعة

1

حالة التصديق

لم تتم المصادقة

الاعتماديات على الإضافات والإصدارات

XR_EXT_spatial_entity

تاريخ آخر تعديل

2025-08-12

حالة عنوان IP

ما مِن مطالبات معروفة بملكية الملكية الفكرية.

المساهمون

"براين تشين"، Google
"ليفانا تشين"، Google
"كايل تشين"، Google
"نيهاف جاين"، Google
"سبنسر كوين"، Google
"ناتالي فلوري"، Meta
"يويتشي تاغوتشي"، Meta
"جيمي ألامبارامبيل"، ByteDance
"زيبينغ ليو"، ByteDance

نظرة عامة

تستند هذه الإضافة إلى XR_EXT_spatial_entity وتوفّر وظيفة raycast للإمكانات المكانية الحالية، مثل XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT، لاكتشاف الكيانات المكانية.

توفّر هذه الإضافة أيضًا إمكانية مكانية جديدة لإجراء عملية raycasting مقابل مخزن العمق المؤقت.

الأذونات

الأذونات المطلوبة حسب الإمكانات التي يستخدمها تطبيق 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 من الأذونات الخطيرة.

(مستوى الحماية: خطير)

إتاحة وقت التشغيل

إذا كان وقت التشغيل يتيح رصد الكيانات المكانية من خلال تتبُّع الأشعة، يجب الإشارة إلى ذلك من خلال تعداد XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID في xrEnumerateSpatialCapabilityComponentTypesEXT للإمكانات التي تتيح الرصد من خلال تتبُّع الأشعة.

إذا كان وقت التشغيل يتيح إجراء عملية raycasting على مخزن العمق المؤقت، يجب أن يدرج XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID في xrEnumerateSpatialCapabilitiesEXT .

استكشاف الكيانات المكانية من خلال تتبُّع الأشعة

يتم تعريف بنية 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 هو XrSpace الذي سيتم فيه تحديد موضع XrSpatialRaycastResultDataANDROID.
  • time هي XrTime يتم فيها تحديد وضع XrSpatialRaycastResultDataANDROID.
  • origin هو XrVector3f يصف مصدر الشعاع.
  • direction هو XrVector3f يصف اتجاه الشعاع.
  • maxDistance هي المسافة بالأمتار التي يمكن للتطبيق تحديدها اختياريًا للحدّ من رصد الكيانات التي تقع ضمن المسافة المحدّدة من origin، على طول direction .

يمكن أن يتضمّن التطبيق XrSpatialRaycastInfoANDROID في سلسلة XrSpatialDiscoverySnapshotCreateInfoEXT :: next لاكتشاف الكيانات المكانية التي تتقاطع مع الشعاع المحدّد في هذا البنية.

إذا كان أحد التطبيقات يستخدم XrSpatialRaycastInfoANDROID مع XrSpatialContextEXT تم إعداده بدون تفعيل XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID لأي إمكانية، يجب أن يعرض وقت التشغيل XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT من xrCreateSpatialDiscoverySnapshotAsyncEXT أو xrCreateSpatialRaycastSnapshotANDROID .

يجب أن يتضمّن وقت التشغيل بيانات المكوّن ومعرّفات الكيانات المكانية فقط في XrSpatialSnapshotEXT التي تأتي من الإمكانات التي تتوافق مع المكوّن XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID.

إذا ضبط أحد التطبيقات قيمة maxDistance على قيمة موجبة، يجب ألا يتضمّن وقت التشغيل أي كيانات مكانية في اللقطة تكون أبعد من maxDistance عن panme:origin على طول direction . إذا تم ضبط maxDistance على 0 أو قيمة سالبة، يجب أن يعتبر وقت التشغيل الشعاع غير محدود.

الاستخدام الصحيح (الضمني)

Raycast Result Component

يتم تعريف بنية XrSpatialRaycastResultDataANDROID على النحو التالي:

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

أوصاف الأعضاء

  • hitPose هو XrPosef يحدّد النقطة التي يتقاطع فيها الشعاع مع الكيان المكاني.
  • distanceSquared هو مربع المسافة من نقطة انطلاق الشعاع إلى نقطة التقاطع.

لن يتوفّر المكوّن XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID إلا في XrSpatialSnapshotEXT تم إنشاؤه من xrCreateSpatialDiscoverySnapshotAsyncEXT حيث يتم تضمين XrSpatialRaycastInfoANDROID في السلسلة XrSpatialDiscoverySnapshotCreateInfoEXT :: next أو في XrSpatialSnapshotEXT تم إنشاؤه من xrCreateSpatialRaycastSnapshotANDROID .

يجب ألا يتضمّن وقت التشغيل هذا المكوّن في أي XrSpatialSnapshotEXT يتم إنشاؤه باستخدام xrCreateSpatialUpdateSnapshotEXT .

يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_VALIDATION_FAILURE من xrCreateSpatialUpdateSnapshotEXT إذا كان التطبيق يتضمّن XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID في XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes .

إذا تم تفعيل XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID لإمكانات معيّنة فقط، يجب أن يتضمّن وقت التشغيل فقط الكيانات المكانية التي توفّرها هذه الإمكانات في اللقطة. على سبيل المثال، إذا كان هناك عنصر وطائرة محاذيان في الاتجاه نفسه وتم تفعيل XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID للطائرة XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT فقط، سيتم رصد الطائرة فقط.

سيتم العثور على hitPose الخاص بـ XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID في 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 هو uint32_t يصف عدد العناصر في مصفوفة raycastResults.
  • raycastResults هي مصفوفة من XrSpatialRaycastResultDataANDROID .

للاستعلام عن مكوّن نتيجة raycast الخاص بالكيانات المكانية في XrSpatialSnapshotEXT، أدرِج XR_TYPE_SPATIAL_COMPONENT_RAYCAST_RESULT_LIST_ANDROID في XrSpatialComponentDataQueryConditionEXT :: componentTypes وأضِف XrSpatialComponentRaycastResultListANDROID إلى سلسلة XrSpatialComponentDataQueryResultEXT :: next.

يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_VALIDATION_FAILURE من xrQuerySpatialComponentDataEXT إذا كان XrSpatialComponentRaycastResultListANDROID في السلسلة XrSpatialComponentDataQueryResultEXT :: next ولكن لم يتم تضمين XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID في XrSpatialComponentDataQueryConditionEXT :: componentTypes .

يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_SIZE_INSUFFICIENT من xrQuerySpatialComponentDataEXT إذا كانت قيمة raycastResultCount أقل من XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

لا يتم ترتيب raycastResults التي يتم إرجاعها. يمكن للتطبيق استخدام XrSpatialRaycastResultDataANDROID :: distanceSquared لترتيب النتائج حسب المسافة.

الاستخدام الصحيح (الضمني)

الإعداد

إذا تم تعداد XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID في XrSpatialCapabilityComponentTypesEXT :: componentTypes لبعض الإمكانات، يمكن للتطبيق تفعيلها من خلال تضمين قيمة التعداد في قائمة XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents. لا يتطلّب هذا المكوّن أي إعدادات خاصة ليتم تضمينه في السلسلة التالية من XrSpatialCapabilityConfigurationBaseHeaderEXT .

يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_VALIDATION_FAILURE من xrCreateSpatialUpdateSnapshotEXT إذا كان التطبيق يتضمّن XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID في XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes . هذا المكوّن خاص باللقطات الموجزة عن الاكتشافات.

إمكانية تحديد الموقع المكاني باستخدام ميزة "تتبُّع الأشعة" للعمق

الإعداد

يتم تعريف بنية 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 هو uint32_t يصف عدد العناصر في مصفوفة enabledComponents. يجب أن تكون القيمة أكبر من 0.
  • enabledComponents هو مؤشر إلى مصفوفة من XrSpatialComponentTypeEXT .

يمكن للتطبيقات تفعيل إمكانية XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID المكانية من خلال تضمين مؤشر إلى بنية XrSpatialCapabilityConfigurationDepthRaycastANDROID في XrSpatialContextCreateInfoEXT :: capabilityConfigs .

يجب أن تعرض قيمة وقت التشغيل XR_ERROR_VALIDATION_FAILURE إذا لم تكن قيمة capability هي XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID .

يكون رقم تعريف العناصر التي يتم اكتشافها من خلال هذه الإمكانية دائمًا XR_NULL_SPATIAL_ENTITY_ID_EXT . يعني هذا أيضًا أنّه لا يمكن للتطبيق إنشاء معرّف XrSpatialEntityEXT لهذه العناصر، وبالتالي لا يمكن تضمينها في XrSpatialUpdateSnapshotCreateInfoEXT :: entities لإنشاء لقطة تعديل.

الاستخدام الصحيح (الضمني)

المكوّنات المضمونة

يجب أن يتيح وقت التشغيل الذي يتيح XR_SPATIAL_CAPABILITY_DEPTH_RAYCAST_ANDROID ، مكوّنات المكان التالية كمكوّنات مضمونة للعناصر التي تكتشفها هذه الإمكانية، ويجب أن يسردها في xrEnumerateSpatialCapabilityComponentTypesEXT -

  • XR_SPATIAL_COMPONENT_TYPE_RAYCAST_RESULT_ANDROID

Synchronous Raycast

يتم تعريف الدالة xrCreateSpatialRaycastSnapshotANDROID على النحو التالي:

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

أوصاف المَعلمات

على الرغم من أنّ الدالة xrCreateSpatialDiscoverySnapshotAsyncEXT كافية لمعظم حالات الاستخدام، إلا أنّها تُعدّ بطيئة بالنسبة إلى التطبيقات التي تتطلّب نتائج فورية لعمليات تتبُّع الأشعة. تبدأ الدالة xrCreateSpatialRaycastSnapshotANDROID عملية تتبُّع أشعة متزامنة لإنشاء لقطة، ما يتيح للتطبيقات بدء طلب نتائج تتبُّع الأشعة على الفور.

يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_SPATIAL_COMPONENT_NOT_ENABLED_EXT إذا لم يتم تفعيل أي من XrSpatialComponentTypeEXT في XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes لإمكانات تحديد الموقع الجغرافي التي تم تمريرها إلى XrSpatialContextCreateInfoEXT :: capabilityConfigs عند إنشاء spatialContext.

إذا لم يوفّر التطبيق قائمة بأنواع المكوّنات المكانية في XrSpatialRaycastSnapshotCreateInfoANDROID :: componentTypes ، على وقت التشغيل يجب تضمين جميع الكيانات المكانية في اللقطة التي تحتوي على مجموعة المكوّنات التي تم تعدادها في XrSpatialCapabilityConfigurationBaseHeaderEXT ::enabledComponents للإمكانات المتوافقة مع عرض الأشعة التي تم ضبطها لـ spatialContext . يجب أن يتضمّن وقت التشغيل جميع بيانات المكوّنات المفعّلة من الإمكانات المتوافقة مع عمليات البحث السريع التي تم ضبطها على spatialContext .

الاستخدام الصحيح (الضمني)

رموز الإرجاع

تم بنجاح

  • 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 هو uint32_t يصف عدد العناصر في مصفوفة componentTypes.
  • componentTypes هي مصفوفة من XrSpatialComponentTypeEXT .
  • raycastInfo هي بنية XrSpatialRaycastInfoANDROID التي تصف معلومات شعاع.

الاستخدام الصحيح (الضمني)

مثال على الشفرة

ضبط ميزتَي "إرسال شعاع العمق" و"تتبُّع المستوى"

يوضّح نموذج الرمز البرمجي التالي كيفية إنشاء سياق مكاني يتضمّن إمكانات تتيح وظيفة raycast. في هذا المثال، يتم استخدام 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);

الأوامر الجديدة

بنى جديدة

ثوابت التعداد الجديدة

  • 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، ‎15-07-2025 (براين تشين)

    • الوصف الأوّلي للإضافة