XR_ANDROID_spatial_entity_bound_anchor
Name String
XR_ANDROID_spatial_entity_bound_anchor
Uzantı Türü
Örnek uzantısı
Kayıtlı Uzantı Numarası
791
Düzeltme
2
Onay durumu
Onaylanmadı
Uzantı ve Sürüm Bağımlılıkları
XR_EXT_spatial_anchor
Son Değiştirilme Tarihi
2025-08-18
IP Durumu
Bilinen IP hak talebi yok.
Katkıda bulunanlar
YuSheng Chang, Google
Kyle Chen, Google
Nihav Jain, Google
Levana Chen, Google
Spencer Quin, Google
Genel Bakış
Bu uzantı, uygulamaların uzamsal varlıklara bağlayıcılar oluşturmasına ve eklemesine olanak tanır. Bu uzantıda bu bağlayıcılara "varlığa bağlı bağlayıcılar" adı verilir.
Varlığa bağlı bir sabit öğe, XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT bileşeni ve XR_SPATIAL_COMPONENT_TYPE_PARENT_EXT bileşeni olan (veya "sahip olan") bir uzamsal varlık olarak gösterilir. XR_SPATIAL_COMPONENT_TYPE_PARENT_EXT bileşeni, bağlantının eklendiği ana varlığın XrSpatialEntityIdEXT değerini depolar.
Bir varlığa bağlı sabitin pozu, her zaman ana varlığın "temeli" olarak düşünülen üst öğesinden sabit bir uzaklıkla gösterilir. Örneğin, bir kullanıcının duvara bağlı sanal bir resim çerçevesi olduğunu, kullanıcının sanal resim çerçevesini temsil etmek için öğeye bağlı bir sabitleyici kullandığını ve bunu duvar öğesine bağladığını düşünün. Bu sayede, fiziksel duvarın izleme tahminleri iyileştikçe duvar ile resim çerçevesi arasındaki göreceli konum her zaman tutarlı olur.
Çalışma Zamanı Desteği
Çalışma zamanı, en az bir uzamsal izleme uzantısını (ör. XR_EXT_spatial_plane_tracking) desteklemelidir. Çalışma zamanı, uzamsal öğe sınırına bağlı sabitlemeyi destekliyorsa xrEnumerateSpatialAnchorAttachableComponentsANDROID işlevini numaralandırarak en az bir eklenebilir bileşen sağlaması gerekir. Uygulama, xrEnumerateSpatialAnchorAttachableComponentsANDROID kullanarak eklenebilir bileşenleri numaralandırabilir .
xrEnumerateSpatialAnchorAttachableComponentsANDROID işlevi şu şekilde tanımlanır:
XrResult xrEnumerateSpatialAnchorAttachableComponentsANDROID(
XrInstance instance,
XrSystemId systemId,
uint32_t attachableComponentCapacityInput,
uint32_t* attachableComponentCountOutput,
XrSpatialComponentTypeEXT* attachableComponents);
Parametre Açıklamaları
instance, XrInstance için bir tutamaktır .systemId, uzamsal kalıcılık depolarının numaralandırılacağıXrSystemId'dır.attachableComponentCapacityInput,attachableComponentsdizisinin kapasitesidir veya gerekli kapasitenin alınması için istek olduğunu belirtmek üzere 0'dır.attachableComponentCountOutput, eklenebilir bileşenlerin sayısıdır veyaattachableComponentCapacityInputyeterli değilse gereken kapasitedir.attachableComponents, XrSpatialComponentTypeEXT dizisidir .attachableComponentCapacityInput0 ise sonuçNULLolabilir.- Gerekli
attachableComponentsboyutunun alınmasıyla ilgili ayrıntılı açıklama için Arabellek Boyutu Parametreleri bölümüne bakın.
Çalışma zamanları, örnek kullanım süresi boyunca belirli systemId için bu numaralandırmadan her zaman aynı arabellek içeriklerini döndürmelidir.
Geçerli Kullanım (Dolaylı)
-
XR_ANDROID_spatial_entity_bound_anchoruzantısı, xrEnumerateSpatialAnchorAttachableComponentsANDROID çağrılmadan önce etkinleştirilmelidir. -
instancegeçerli bir XrInstance işleyeni olmalıdır. -
attachableComponentCountOutput,uint32_tdeğerine yönelik bir işaretçi olmalıdır. -
attachableComponentCapacityInputdeğeri0değilseattachableComponents,attachableComponentCapacityInputXrSpatialComponentTypeEXT değerleri dizisine yönelik bir işaretçi olmalıdır.
Dönüş Kodları
XR_SUCCESS
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SIZE_INSUFFICIENTXR_ERROR_SYSTEM_INVALIDXR_ERROR_VALIDATION_FAILURE
Mekansal öğeye bağlı bir bağlantı oluşturma
Uygulamalar, xrCreateSpatialAnchorEXT işlevini kullanarak bir bağlantı oluşturur. Bir uygulama, uzamsal bir öğeye bağlı öğe sınırlı bir bağlantı oluşturmak istiyorsa xrCreateSpatialAnchorEXT işlevi çağrıldığında XrSpatialAnchorParentANDROID yapısını XrSpatialAnchorCreateInfoEXT yapısının sonraki işaretçisine zincirleyebilir.
XrSpatialAnchorParentANDROID yapısı şu şekilde tanımlanır:
typedef struct XrSpatialAnchorParentANDROID {
XrStructureType type;
const void* next;
XrSpatialEntityIdEXT parentId;
} XrSpatialAnchorParentANDROID;
Üye Açıklamaları
type, bu yapının XrStructureType'ıdır.next,NULLveya bir yapı zincirindeki sonraki yapının işaretçisidir.parentId, bağlantının ekleneceği öğeninXrSpatialEntityIdEXTdeğeridir.
Çalışma zamanı, üst öğe ile sabitleme noktası arasındaki mesafenin her zaman tutarlı olmasını sağlamalıdır. Mesafe, sabitleme noktasının yüzeyin normali boyunca üst öğenin en yakın yüzeyine olan pozudur. Sabitleyicinin duruşu, ana varlığın kaç tane eklenebilir bileşeni olduğuna bakılmaksızın ana varlığın konumuna ve ana varlığın yüzeyine olan mesafeye göre güncellenir.
Çalışma zamanı, XrSpatialAnchorParentANDROID ::parentId, xrCreateSpatialAnchorEXT :: spatialContext için geçerli bir kimlik değilse xrCreateSpatialAnchorEXT'den XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT döndürmelidir.
Çalışma zamanı, xrEnumerateSpatialAnchorAttachableComponentsANDROID tarafından numaralandırılan bileşenlerden hiçbiri ana varlıkta değilse xrCreateSpatialAnchorEXT işlevinden XR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID değerini döndürmelidir.
Geçerli Kullanım (Dolaylı)
- XrSpatialAnchorParentANDROID kullanılmadan önce
XR_ANDROID_spatial_entity_bound_anchoruzantısı etkinleştirilmelidir. -
typeXR_TYPE_SPATIAL_ANCHOR_PARENT_ANDROIDolmalıdır. -
nextzorunlu olarakNULLveya bir yapı zincirindeki sonraki yapıya yönelik geçerli bir işaretçi olmalıdır.
Örnek kod
Mekansal öğeye bağlı çapa oluşturma
Aşağıdaki örnek kodda, öğeye bağlı bir bağlantının nasıl oluşturulacağı ve uzamsal düzlem izleme öğesine nasıl ekleneceği gösterilmektedir.
XrFutureEXT future {XR_NULL_FUTURE_EXT};
std::vector<XrSpatialEntityEXT> entityBoundAnchorEntities;
// We want to look for entities that have the plane tracking components.
std::vector<XrSpatialComponentTypeEXT> snapshotComponents = {
XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
XR_SPATIAL_COMPONENT_TYPE_PLANE_ALIGNMENT_EXT,
};
auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{
.type = XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT,
.componentTypeCount = static_cast<uint32_t>(snapshotComponents.size()),
.componentTypes = snapshotComponents.data(),
};
CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &snapshotCreateInfo, &future));
waitUntilReady(future);
XrCreateSpatialDiscoverySnapshotCompletionInfoEXT completionInfo{
.type = XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT,
.baseSpace = localSpace,
.time = time,
.future = future,
};
XrCreateSpatialDiscoverySnapshotCompletionEXT completion{
.type = XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT,
};
CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(spatialContext, &completionInfo, &completion));
if (completion.futureResult == XR_SUCCESS) {
XrSpatialComponentDataQueryConditionEXT queryCond{
.type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT,
.componentTypeCount = static_cast<uint32_t>(snapshotComponents.size()),
.componentTypes = snapshotComponents.data(),
};
XrSpatialComponentDataQueryResultEXT queryResult{
.type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT,
};
CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));
std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
queryResult.entityIdCapacityInput = entityIds.size();
queryResult.entityIds = entityIds.data();
queryResult.entityStateCapacityInput = entityStates.size();
queryResult.entityStates = entityStates.data();
std::vector<XrSpatialBounded2DDataEXT> bounded2D(queryResult.entityIdCountOutput);
XrSpatialComponentBounded2DListEXT bounded2DList{
.type = XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT,
.boundCount = static_cast<uint32_t>(bounded2D.size()),
.bounds = bounded2D.data(),
};
queryResult.next = &bounded2DList;
CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));
entityBoundAnchorEntities.reserve(queryResult.entityIdCountOutput);
// Create anchors attached to the plane entities
for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
if (entityStates[i] != XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
continue;
}
// Parent ID info the chained to spatial anchor create info next
XrSpatialAnchorParentANDROID parentIdCreateInfo{
.type = XR_TYPE_SPATIAL_ANCHOR_PARENT_ANDROID,
.parentId = entityIds[i],
};
// spatial anchor create info
XrSpatialAnchorCreateInfoEXT createInfo{
.type = XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT,
// assign Parent ID to anchor create info next, and the pose to the bounded2D center
.next = &parentIdCreateInfo,
.baseSpace = localSpace,
.time = time,
.pose = bounded2D[i].center,
};
XrSpatialEntityIdEXT entityBoundAnchorEntityId {XR_NULL_SPATIAL_ENTITY_ID_EXT};
XrSpatialEntityEXT entityBoundAnchorEntity {XR_NULL_HANDLE};
CHK_XR(xrCreateSpatialAnchorEXT(spatialContext, &createInfo, &entityBoundAnchorEntityId, &entityBoundAnchorEntity));
entityBoundAnchorEntities.push_back(entityBoundAnchorEntity);
}
CHK_XR(xrDestroySpatialSnapshotEXT(completion.snapshot));
}
};
while (1) {
// ...
// For every frame in frame loop
// ...
XrFrameState frameState; // previously returned from xrWaitFrame
const XrTime time = frameState.predictedDisplayTime;
// Poll for the XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT event
XrEventDataBuffer event = {
.type = XR_TYPE_EVENT_DATA_BUFFER,
};
XrResult result = xrPollEvent(instance, &event);
if (result == XR_SUCCESS) {
if (event.type == XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT) {
const XrEventDataSpatialDiscoveryRecommendedEXT& eventdata =
*reinterpret_cast<XrEventDataSpatialDiscoveryRecommendedEXT*>(&event);
// Discover spatial entities for the context that we received the "discovery
// recommended" event for.
discoverSpatialEntities(eventdata.spatialContext, time);
break;
}
}
// ...
// Finish frame loop
// ...
}
Varlığa bağlı bağlantı pozu ve üst varlık kimliğini alma
Aşağıdaki örnek kodda, öğeye bağlı bir sabitleme noktasının duruşunun ve üst öğesinin kimliğinin nasıl alınacağı gösterilmektedir.
std::vector<XrSpatialEntityEXT> entities;
auto updateEntityBoundAnchorInfo = [&](XrSpatialContextEXT spatialContext, XrTime time) {
// We want to get updated data for all components of the entities, so skip specifying componentTypes.
XrSpatialUpdateSnapshotCreateInfoEXT snapshotCreateInfo{
.type = XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT,
.entityCount = static_cast<uint32_t>(entities.size()),
.entities = entities.data(),
.baseSpace = localSpace,
.time = time,
};
XrSpatialSnapshotEXT snapshot {XR_NULL_HANDLE};
CHK_XR(xrCreateSpatialUpdateSnapshotEXT(spatialContext, &snapshotCreateInfo, &snapshot));
// Query for the entities that have the anchor component and parent component on them.
std::array<XrSpatialComponentTypeEXT, 2> componentsToQuery {XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT, XR_SPATIAL_COMPONENT_TYPE_PARENT_EXT};
XrSpatialComponentDataQueryConditionEXT queryCond{
.type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT,
.componentTypeCount = componentsToQuery.size(),
.componentTypes = componentsToQuery.data(),
};
XrSpatialComponentDataQueryResultEXT queryResult{
.type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT,
};
CHK_XR(xrQuerySpatialComponentDataEXT(snapshot, &queryCond, &queryResult));
std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
queryResult.entityIdCapacityInput = entityIds.size();
queryResult.entityIds = entityIds.data();
queryResult.entityStateCapacityInput = entityStates.size();
queryResult.entityStates = entityStates.data();
// query for the pose data
std::vector<XrPosef> locations(queryResult.entityIdCountOutput);
XrSpatialComponentAnchorListEXT locationList{
.type = XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT,
.locationCount = static_cast<uint32_t>(locations.size()),
.locations = locations.data(),
};
queryResult.next = &locationList;
// query for the parent entity ID data
std::vector<XrSpatialEntityIdEXT> parentIds(queryResult.entityIdCountOutput);
XrSpatialComponentParentListEXT parentList{
.type = XR_TYPE_SPATIAL_COMPONENT_PARENT_LIST_EXT,
.parentCount = static_cast<uint32_t>(parentIds.size()),
.parents = parentIds.data(),
};
queryResult.next = &parentList;
CHK_XR(xrQuerySpatialComponentDataEXT(snapshot, &queryCond, &queryResult));
for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
if (entityStates[i] == XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
// Pose for entity entityIds[i] is locations[i].
// Parent entity ID for entity entityIds[i] is parentIds[i].
}
}
CHK_XR(xrDestroySpatialSnapshotEXT(snapshot));
};
while (1) {
// ...
// For every frame in frame loop
// ...
XrFrameState frameState; // previously returned from xrWaitFrame
const XrTime time = frameState.predictedDisplayTime;
updateEntityBoundAnchorInfo(spatialContext, time);
// ...
// Finish frame loop
// ...
}
Eklenebilir bileşenleri numaralandırma ve varlığa bağlı sabitleme özelliğini kontrol etme
Aşağıdaki örnek kod, eklenebilir bileşenlerin nasıl numaralandırılacağını ve çalışma zamanının, varlığa bağlı bağlantı özelliğini destekleyip desteklemediğini nasıl kontrol edeceğinizi gösterir.
// Check spatial capability
uint32_t capabilityCount = 0;
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, 0, &capabilityCount, nullptr));
std::vector<XrSpatialCapabilityEXT> capabilities(capabilityCount);
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, capabilityCount, &capabilityCount, capabilities.data()));
// Check if anchor capability is supported
if (std::find(capabilities.begin(), capabilities.end(), XR_SPATIAL_CAPABILITY_ANCHOR_EXT) == capabilities.end()) {
return;
}
// Check if plane tracking capability is supported
if (std::find(capabilities.begin(), capabilities.end(), XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT) == capabilities.end()) {
return;
}
// The supported spatial tracking components
std::vector<XrSpatialComponentTypeEXT> spatialTrackingCapabilityComponents;
// Enumerate supported components for plane tracking capability
XrSpatialCapabilityComponentTypesEXT planeComponents{
.type = XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT,
};
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, &planeComponents));
std::vector<XrSpatialComponentTypeEXT> planeCapabilityComponents(planeComponents.componentTypeCountOutput);
planeComponents.componentTypes = planeCapabilityComponents.data();
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, &planeComponents));
// Add plane supported components to spatial tracking supported components
spatialTrackingCapabilityComponents.insert(spatialTrackingCapabilityComponents.end(), planeCapabilityComponents.begin(), planeCapabilityComponents.end());
// Enumerate supported attachable components for anchor
uint32_t attachableComponentCount = 0;
CHK_XR(xrEnumerateSpatialAnchorAttachableComponentsANDROID(instance, systemId, 0, &attachableComponentCount, nullptr));
std::vector<XrSpatialComponentTypeEXT> attachableComponents(attachableComponentCount);
CHK_XR(xrEnumerateSpatialAnchorAttachableComponentsANDROID(instance, systemId, attachableComponentCount, &attachableComponentCount, attachableComponents.data()));
// Check if at least one spatial tracking component is supported
const auto supportsComponent = [&spatialTrackingCapabilityComponents](XrSpatialComponentTypeEXT component) {
return std::find(spatialTrackingCapabilityComponents.begin(), spatialTrackingCapabilityComponents.end(), component) != spatialTrackingCapabilityComponents.end();
};
bool atLeastOneComponentSupported = false;
for (int32_t i = 0; i < attachableComponentCount; ++i) {
if(supportsComponent(attachableComponents[i])) {
atLeastOneComponentSupported = true;
break;
}
}
// No spatial tracking component supported for anchor attachment
if(!atLeastOneComponentSupported) return;
// ...
// Create spatial entity anchors and get their latest pose in the frame loop.
// ...
Yeni Komutlar
Yeni Yapılar
XrSpatialAnchorCreateInfoEXT uzatılıyor :
Yeni Enum Sabitleri
XR_ANDROID_SPATIAL_ENTITY_BOUND_ANCHOR_EXTENSION_NAMEXR_ANDROID_spatial_entity_bound_anchor_SPEC_VERSIONXrResult'ı genişletme :
XR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID
XrStructureType uzatma :
XR_TYPE_SPATIAL_ANCHOR_PARENT_ANDROID
Sayılar
Sürüm Geçmişi
Düzeltme 1, 2025-08-18 (YuSheng Chang)
- İlk uzantı açıklaması.
Düzeltme 2, 2025-12-16 (Kyle Chen)
- API'nin belirli davranışlarına daha fazla kuralcı dil ekleyin.
- xrEnumerateSpatialAnchorAttachableComponentsANDROID örnek kodunu ekleyin .