XR_ANDROID_spatial_component_subsumed_by

מחרוזת שם

XR_ANDROID_spatial_component_subsumed_by

סוג התוסף

הרחבת המכונה

מספר שלוחה רשום

792

Revision

1

סטטוס האישור

לא אושר

תלות בתוסף ובגרסה

XR_EXT_spatial_entity
וגם
XR_EXT_spatial_plane_tracking

תאריך השינוי האחרון

2025-08-19

סטטוס כתובת ה-IP

לא ידוע על תלונות על הפרת זכויות יוצרים שקשורות לכתובות IP.

שותפים ביצירת התוכן

Brian Chen, Google
Kyle Chen, Google
Levana Chen, Google
Nihav Jain, Google
Spencer Quin, 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 הישות המצורפת חייבים להיות זהים לישות שמכילה אותה.

נכלל ברכיב

נתוני רכיבים

ב-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, האפליקציה יכולה להפעיל אותה על ידי הכללת ה-enum ברשימה 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 , סביבת זמן הריצה חייבת להחזיר את 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);

מבנים חדשים

New Enum Constants

  • 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 (Brian Chen)

    • התיאור הראשוני של התוסף.