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
ไม่มีการอ้างสิทธิ์ใน 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
เมื่อรันไทม์ได้รับข้อมูลสภาพแวดล้อมเพียงพอที่จะตรวจพบว่าเครื่องบิน 2 ลำที่ติดตามนั้นเป็นลำเดียวกันจริง ระบบจะแนบคอมโพเนนต์ subsumed_by ที่มีรหัสของเครื่องบินลำใดลำหนึ่งเข้ากับเครื่องบินอีกเครื่อง
ส่วนขยายนี้ยังเปิดตัวตัวกรองใหม่ ซึ่งแอปพลิเคชันสามารถเชื่อมโยงกับ XrSpatialDiscoverySnapshotCreateInfoEXT เพื่อกรองเอนทิตีที่มีคอมโพเนนต์ subsumed_by แนบอยู่
สิทธิ์
แอปพลิเคชัน Android ต้องมีสิทธิ์ android.permission.SCENE_UNDERSTANDING_COARSE แสดงอยู่ในไฟล์ Manifest เนื่องจากส่วนขยายนี้ติดตามระนาบในสภาพแวดล้อม สิทธิ์ 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หรือ Pointer ไปยังโครงสร้างถัดไปในเชนโครงสร้างsubsumedUniqueIdCountคือuint32_tที่อธิบายจำนวนองค์ประกอบในอาร์เรย์subsumedUniqueIdssubsumedUniqueIdsเป็นอาร์เรย์ของ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หรือ Pointer ที่ถูกต้องไปยังโครงสร้างถัดไปในห่วงโซ่โครงสร้าง -
subsumedUniqueIdsต้องเป็น Pointer ไปยังอาร์เรย์ของค่าsubsumedUniqueIdCountXrSpatialEntityIdEXT - พารามิเตอร์
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หรือ Pointer ไปยังโครงสร้างถัดไปในเชนโครงสร้าง
แอปพลิเคชันสามารถรวม 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_ANDROID_spatial_component_subsumed_byก่อนจึงจะใช้ XrSpatialDiscoveryUniqueEntitiesFilterANDROID ได้ -
typeต้องเป็นXR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID -
nextต้องเป็นNULLหรือ Pointer ที่ถูกต้องไปยังโครงสร้างถัดไปในห่วงโซ่โครงสร้าง
โค้ดตัวอย่าง
กำหนดค่าความสามารถในการติดตามระนาบ
โค้ดตัวอย่างต่อไปนี้แสดงวิธีสร้างบริบทเชิงพื้นที่ที่มีความสามารถ 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);
โครงสร้างใหม่
การขยาย XrSpatialComponentDataQueryResultEXT :
การขยาย XrSpatialDiscoverySnapshotCreateInfoEXT :
ค่าคงที่ Enum ใหม่
XR_ANDROID_SPATIAL_COMPONENT_SUBSUMED_BY_EXTENSION_NAMEXR_ANDROID_spatial_component_subsumed_by_SPEC_VERSIONการขยาย XrSpatialComponentTypeEXT :
XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID
การขยาย XrStructureType :
XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROIDXR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID
ปัญหา
ประวัติเวอร์ชัน
การแก้ไขครั้งที่ 1, 19-11-2025 (Brian Chen)
- คำอธิบายส่วนขยายเริ่มต้น