XR_ANDROID_spatial_component_subsumed_by

Name String

XR_ANDROID_spatial_component_subsumed_by

نوع الإضافة

إضافة مثيل

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

792

المراجعة

1

حالة التصديق

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

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

XR_EXT_spatial_entity
و
XR_EXT_spatial_plane_tracking

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

2025-08-19

حالة عنوان IP

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

المساهمون

براين تشين، Google
كايل تشين، Google
ليفانا تشين، Google
نيهاف جاين، Google
سبنسر كوين، Google

نظرة عامة

تستند هذه الإضافة إلى XR_EXT_spatial_entity وتوفّر مكوّنًا جديدًا لـ XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT، وذلك لعرض السمة subsumed_by.

عندما يحصل وقت التشغيل على معلومات كافية عن البيئة لرصد أنّ مستويَين متتبّعَين هما في الواقع المستوى نفسه، سيتم إرفاق المكوّن subsumed_by الذي يتضمّن رقم تعريف أحد المستويَين بالمستوى الآخر.

يضيف هذا الامتداد أيضًا فلترًا جديدًا يمكن للتطبيق ربطه بـ XrSpatialDiscoverySnapshotCreateInfoEXT لاستبعاد أي كيانات تم إرفاق المكوّن subsumed_by بها.

الأذونات

يجب أن تتضمّن تطبيقات Android الإذن android.permission.SCENE_UNDERSTANDING_COARSE في ملف البيان الخاص بها لأنّ هذه الإضافة تتتبّع الطائرات في البيئة. يُعدّ الإذن android.permission.SCENE_UNDERSTANDING_COARSE إذنًا خطيرًا.

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

دعم وقت التشغيل

إذا كان وقت التشغيل يتيح استخدام subumed_by، يجب أن يتيح إمكانية تتبُّع الطائرة، وأن يشير إلى ذلك من خلال تعداد XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT في xrEnumerateSpatialCapabilitiesEXT .

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

يجب أن تكون جميع بيانات XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID الكيان المرفق متطابقة مع الكيان الذي يندرج تحته.

Subsumed By Component

بيانات المكوّن

تستخدم XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID بنية XrSpatialEntityIdEXT لبياناتها، وهي تمثّل معرّف الكيان الشامل.

بنية قائمة المكوّنات لطلب البيانات

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

typedef struct XrSpatialComponentSubsumedByListANDROID {
    XrStructureType          type;
    void*                    next;
    uint32_t                 subsumedUniqueIdCount;
    XrSpatialEntityIdEXT*    subsumedUniqueIds;
} XrSpatialComponentSubsumedByListANDROID;

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

  • type هو XrStructureType لهذه البنية.
  • next هو NULL أو مؤشر إلى البنية التالية في سلسلة البنية.
  • subsumedUniqueIdCount هو uint32_t يصف عدد العناصر في مصفوفة subsumedUniqueIds.
  • subsumedUniqueIds هو صفيف من XrSpatialEntityIdEXT .

يمكن للتطبيق الاستعلام عن عنصر subsumed_by الخاص بالكيانات المكانية في XrSpatialSnapshotEXT من خلال إضافة XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID إلى السلسلة التالية من XrSpatialComponentDataQueryResultEXT .

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

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

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

  • يجب تفعيل الإضافة XR_ANDROID_spatial_component_subsumed_by قبل استخدام XrSpatialComponentSubsumedByListANDROID
  • يجب أن يكون type XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID
  • يجب أن تكون قيمة next هي NULL أو مؤشرًا صالحًا إلى البنية التالية في سلسلة البِنى
  • يجب أن يكون subsumedUniqueIds مؤشرًا إلى مصفوفة من قيم subsumedUniqueIdCount XrSpatialEntityIdEXT
  • يجب أن تكون قيمة المَعلمة subsumedUniqueIdCount أكبر من 0

الإعدادات

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

فلترة الكيانات المضمّنة

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

typedef struct XrSpatialDiscoveryUniqueEntitiesFilterANDROID {
    XrStructureType    type;
    const void*        next;
} XrSpatialDiscoveryUniqueEntitiesFilterANDROID;

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

  • type هو XrStructureType لهذه البنية.
  • next هو NULL أو مؤشر إلى البنية التالية في سلسلة البنية.

يمكن أن يتضمّن التطبيق XrSpatialDiscoveryUniqueEntitiesFilterANDROID في السلسلة التالية من XrSpatialDiscoverySnapshotCreateInfoEXT للحصول على لقطة تتضمّن كيانات لا يندرج بعضها تحت كيانات أخرى.

إذا كانت سلاسل التطبيقات XrSpatialDiscoveryUniqueEntitiesFilterANDROID إلى XrSpatialDiscoverySnapshotCreateInfoEXT مع تضمين المكوّن XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID في XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes ، يجب أن تعرض وقت التشغيل must XR_ERROR_VALIDATION_FAILURE .

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

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

مثال على الرمز

ضبط إمكانية تتبُّع الطائرات

يوضّح نموذج الرمز البرمجي التالي كيفية إنشاء سياق مكاني بإمكانية XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT تتوافق مع subsumed_by.

// 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_PLANE_TRACKING_EXT) == capabilities.end()) {
  return;
}

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

// 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
std::vector<const XrSpatialCapabilityConfigurationBaseHeaderEXT*> capabilityConfigs;
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))

بيانات مكوّن طلب البحث

يوضّح نموذج الرمز التالي كيفية طلب بيانات المكوّن subsumed_by من السياق الذي تم إعداده باستخدام XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT .

// Create Discovery Snapshot
XrSpatialDiscoverySnapshotCreateInfoEXT discoverySnapshotCreateInfo {
  .type = XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT,
};

CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT (
spatialContext, &discoverySnapshotCreateInfo, &future));

// Poll the state till snapshot it's ready.
waitUntilReady(future);

// Complete async operation.
XrCreateSpatialDiscoverySnapshotCompletionInfoEXT
  createSnapshotCompletionInfo {
    .type   = XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT,
    .baseSpace = space,
    .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 subsumed_by components
std::array<XrSpatialComponentTypeEXT, 1> enabledComponents = {
  XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_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,
};

CHK_XR(xrQuerySpatialComponentDataEXT(
           completion.snapshot, &queryCond, &queryResult));

// Query again with allocated memory
std::vector<XrSpatialEntityIdEXT> subsumedUniqueIds;
subsumedUniqueIds.resize(queryResult.entityIdCountOutput);
XrSpatialComponentSubsumedByListANDROID subsumedByList {
  .type = XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID,
  .subsumedUniqueIdCount = static_cast<uint32_t>(subsumedUniqueIds.size()),
  .subsumedUniqueIds = subsumedUniqueIds.data(),
};

queryResult.next = &subsumedByList;
CHK_XR(xrQuerySpatialComponentDataEXT(
           completion.snapshot, &queryCond, &queryResult));

std::vector<XrSpatialEntityEXT> subsumedEntities;
for(uint32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
    // access planes[i] for merged plane id
    XrSpatialEntityIdEXT entityId = queryResult.entityIds[i];
    XrSpatialEntityIdEXT subsumedUniqueId = subsumedUniqueIds[i];

    // create handle via entityId
  XrSpatialEntityFromIdCreateInfoEXT entityCreateInfo {
    .type = XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT,
    .entityId = entityId,
  };

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

  subsumedEntities.push_back(entity);
}

// Cleanup
xrDestroySpatialSnapshotEXT(completion.snapshot);

استبعاد الكيانات المضمّنة

يوضّح نموذج الرمز البرمجي التالي كيفية فلترة الكيانات التي تم إرفاق المكوّن subsumed_by بها من لقطة البحث باستخدام الفلتر، بالإضافة إلى طلب رقم تعريف الكيانات التي تم دمجها.

// Init filter
XrSpatialDiscoveryUniqueEntitiesFilterANDROID filter {
  .type = XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID,
};

// Chain filter to the snapshot create info
// WARNING: Chain the filter while include subsumed_by component in the
// componentTypes is invalid
XrSpatialDiscoverySnapshotCreateInfoEXT discoverySnapshotCreateInfo {
  .type = XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT,
  .next = &filter
};

waitUntilReady(future);

// Complete async operation.
XrCreateSpatialDiscoverySnapshotCompletionInfoEXT
  createSnapshotCompletionInfo {
    .type   = XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT,
    .baseSpace = space,
    .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;

// Subsumed entities has already been filtered out in this snapshot,now query
// Bounded2D to render subsuming planes
std::vector<XrSpatialComponentTypeEXT> queryComponents {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
};

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

XrSpatialComponentDataQueryResultEXT queryResult {
  .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT,
};

CHK_XR(xrQuerySpatialComponentDataEXT(
           completion.snapshot, &queryCond, &queryResult));

// Chain Bounded2D list
std::vector<XrSpatialBounded2DDataEXT> bounded2dData;
bounded2dData.resize(queryResult.entityIdCountOutput);

XrSpatialComponentBounded2DListEXT bounded2dList {
  .type = XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT,
  .boundCount = static_cast<uint32_t>(bounded2dData.size()),
  .bounds = bounded2dData.data(),
};

// Query again
queryResult.next = &bounded2dList;
CHK_XR(xrQuerySpatialComponentDataEXT(
           completion.snapshot, &queryCond, &queryResult));

std::vector<XrSpatialEntityEXT> subsumingPlanes;
for(uint32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
  // access planes[i] for merged plane id
  XrSpatialEntityIdEXT entityId = queryResult.entityIds[i];

  // create handle via entityId.
  XrSpatialEntityFromIdCreateInfoEXT entityCreateInfo {
    .type = XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT,
    .entityId = entityId,
  };

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

  subsumingPlanes.push_back(entity);
}

// Cleanup
xrDestroySpatialSnapshotEXT(completion.snapshot);

المنشآت الجديدة

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

  • XR_ANDROID_SPATIAL_COMPONENT_SUBSUMED_BY_EXTENSION_NAME
  • XR_ANDROID_spatial_component_subsumed_by_SPEC_VERSION
  • تمديد XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID
  • توسيع XrStructureType :

    • XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID
    • XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID

المشاكل

سجلّ التعديلات

  • المراجعة 1، ‎19-11-2025 (براين تشين)

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