XR_EXT_spatial_anchor
Name String
XR_EXT_spatial_anchor
Loại tiện ích
Phần mở rộng thực thể
Số máy lẻ đã đăng ký
763
Bản sửa đổi
1
Trạng thái phê chuẩn
Đã phê chuẩn
Phần phụ thuộc của tiện ích và phiên bản
XR_EXT_spatial_entity
Cộng tác viên
Nihav Jain, Google
Natalie Fleury, Meta
Yuichi Taguchi, Meta
Ron Bessems, Meta
Yin Li, Microsoft
Jimmy Alamparambil, ByteDance
Zhipeng Liu, ByteDance
Jun Yan, ByteDance
Tổng quan
Tiện ích này được xây dựng dựa trên XR_EXT_spatial_entity và cho phép các ứng dụng tạo điểm neo không gian, là các điểm tuỳ ý trong môi trường thực tế của người dùng, sau đó sẽ được thời gian chạy theo dõi. Sau đó, thời gian chạy phải điều chỉnh vị trí và hướng của gốc neo theo thời gian nếu cần, độc lập với tất cả các không gian và neo khác, để đảm bảo duy trì mối liên kết ban đầu với thế giới thực.
Một neo theo dõi một vị trí và hướng nhất định trong XrSpatialContextEXT được biểu thị dưới dạng một thực thể không gian có (hoặc "có") thành phần XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT.
Lợi ích của việc sử dụng neo
Khi thông tin của môi trường thời gian chạy về môi trường thực tế của người dùng được cập nhật trong suốt vòng đời của XrSpatialContextEXT , các đối tượng ảo có thể dường như trôi khỏi vị trí mà ứng dụng đặt chúng, điều này ảnh hưởng đến tính chân thực của ứng dụng và chất lượng trải nghiệm của người dùng. Bằng cách tạo một điểm neo gần nơi đặt đối tượng ảo, sau đó luôn kết xuất đối tượng ảo đó tương ứng với điểm neo, ứng dụng có thể đảm bảo rằng mỗi đối tượng ảo dường như luôn ở cùng một vị trí và hướng trong môi trường thực tế. Ngoài ra, không giống như một số không gian tham chiếu nhất định, các neo không bị ảnh hưởng bởi việc căn giữa lại ở cấp hệ thống.
Hỗ trợ thời gian chạy
Nếu môi trường thời gian chạy hỗ trợ neo không gian, thì môi trường đó phải cho biết điều này bằng cách liệt kê XR_SPATIAL_CAPABILITY_ANCHOR_EXT trong xrEnumerateSpatialCapabilitiesEXT .
Cấu hình
Cấu trúc XrSpatialCapabilityConfigurationAnchorEXT được định nghĩa như sau:
typedef struct XrSpatialCapabilityConfigurationAnchorEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationAnchorEXT;
Nội dung mô tả về thành viên
typelà XrStructureType của cấu trúc này.nextlàNULLhoặc con trỏ trỏ đến cấu trúc tiếp theo trong chuỗi cấu trúc.capabilitylà một XrSpatialCapabilityEXT .enabledComponentCountlà mộtuint32_tmô tả số lượng phần tử trong mảngenabledComponents.enabledComponentslà con trỏ đến một mảng XrSpatialComponentTypeEXT .
Ứng dụng có thể bật chức năng không gian XR_SPATIAL_CAPABILITY_ANCHOR_EXT bằng cách thêm một con trỏ vào cấu trúc XrSpatialCapabilityConfigurationAnchorEXT trong XrSpatialContextCreateInfoEXT :: capabilityConfigs .
Thời gian chạy phải trả về XR_ERROR_VALIDATION_FAILURE nếu capability không phải là XR_SPATIAL_CAPABILITY_ANCHOR_EXT .
Cách sử dụng hợp lệ (Ngầm ẩn)
- Bạn phải bật tiện ích
XR_EXT_spatial_anchortrước khi sử dụng XrSpatialCapabilityConfigurationAnchorEXT -
typephải làXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT -
nextphải làNULLhoặc một con trỏ hợp lệ đến cấu trúc tiếp theo trong chuỗi cấu trúc -
capabilityphải là một giá trị XrSpatialCapabilityEXT hợp lệ -
enabledComponentsphải là một con trỏ đến một mảng gồmenabledComponentCountgiá trị XrSpatialComponentTypeEXT hợp lệ - Tham số
enabledComponentCountphải lớn hơn0
Thành phần được đảm bảo
Môi trường thời gian chạy hỗ trợ XR_SPATIAL_CAPABILITY_ANCHOR_EXT phải cung cấp các thành phần không gian sau đây dưới dạng thành phần được đảm bảo của tất cả thực thể do chức năng này tạo hoặc phát hiện và phải liệt kê các thành phần đó trong xrEnumerateSpatialCapabilityComponentTypesEXT :
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
Thành phần neo
Dữ liệu thành phần
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT sử dụng XrPosef cho dữ liệu của mình, cung cấp vị trí và hướng của neo.
Cấu trúc danh sách thành phần để truy vấn dữ liệu
Cấu trúc XrSpatialComponentAnchorListEXT được định nghĩa như sau:
typedef struct XrSpatialComponentAnchorListEXT {
XrStructureType type;
void* next;
uint32_t locationCount;
XrPosef* locations;
} XrSpatialComponentAnchorListEXT;
Nội dung mô tả về thành viên
typelà XrStructureType của cấu trúc này.nextlàNULLhoặc con trỏ trỏ đến cấu trúc tiếp theo trong chuỗi cấu trúc.locationCountlà mộtuint32_tmô tả số lượng phần tử trong mảnglocations.locationslà một mảng XrPosef .
Thời gian chạy phải trả về XR_ERROR_VALIDATION_FAILURE từ xrQuerySpatialComponentDataEXT nếu XrSpatialComponentAnchorListEXT nằm trong chuỗi XrSpatialComponentDataQueryResultEXT :: next nhưng XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT không có trong XrSpatialComponentDataQueryConditionEXT :: componentTypes .
Thời gian chạy phải trả về XR_ERROR_SIZE_INSUFFICIENT từ xrQuerySpatialComponentDataEXT nếu locationCount nhỏ hơn XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .
Cách sử dụng hợp lệ (Ngầm ẩn)
- Bạn phải bật tiện ích
XR_EXT_spatial_anchortrước khi sử dụng XrSpatialComponentAnchorListEXT -
typephải làXR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT -
nextphải làNULLhoặc một con trỏ hợp lệ đến cấu trúc tiếp theo trong chuỗi cấu trúc -
locationsphải là một con trỏ trỏ đến một mảng gồmlocationCountcấu trúc XrPosef - Tham số
locationCountphải lớn hơn0
Cấu hình
Nếu XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT được liệt kê trong XrSpatialCapabilityComponentTypesEXT :: componentTypes cho một số chức năng, thì ứng dụng có thể bật chức năng đó bằng cách đưa giá trị liệt kê vào danh sách XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents của cấu trúc phái sinh XrSpatialCapabilityConfigurationBaseHeaderEXT của chức năng hỗ trợ thành phần này.
Thành phần này không yêu cầu bất kỳ cấu hình đặc biệt nào để được đưa vào chuỗi XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.
Tạo điểm cố định không gian
Hàm xrCreateSpatialAnchorEXT được định nghĩa như sau:
XrResult xrCreateSpatialAnchorEXT(
XrSpatialContextEXT spatialContext,
const XrSpatialAnchorCreateInfoEXT* createInfo,
XrSpatialEntityIdEXT* anchorEntityId,
XrSpatialEntityEXT* anchorEntity);
Nội dung mô tả về tham số
spatialContextlà một XrSpatialContextEXT được tạo trước đó bằng xrCreateSpatialContextAsyncEXT .createInfolà con trỏ đến XrSpatialAnchorCreateInfoEXT .anchorEntityIdlà con trỏ đếnXrSpatialEntityIdEXT, trong đó mã nhận dạng của thực thể neo được trả về.anchorEntitylà con trỏ đến XrSpatialEntityEXT, trong đó tay điều khiển của thực thể neo được trả về.
Ứng dụng có thể tạo một neo không gian bằng cách sử dụng xrCreateSpatialAnchorEXT .
Để nhận dữ liệu thành phần đã cập nhật cho một neo, hãy truyền giá trị được điền sẵn trong anchorEntity vào XrSpatialUpdateSnapshotCreateInfoEXT :: entities khi tạo ảnh chụp nhanh. Ứng dụng có thể sử dụng anchorEntityId để xác định riêng neo này trong mảng XrSpatialComponentDataQueryResultEXT :: entityIds khi sử dụng xrQuerySpatialComponentDataEXT .
Thời gian chạy phải trả về XR_ERROR_VALIDATION_FAILURE từ xrCreateSpatialAnchorEXT nếu XR_SPATIAL_CAPABILITY_ANCHOR_EXT chưa được định cấu hình cho spatialContext . Xem phần Cấu hình để biết cách định cấu hình XrSpatialContextEXT cho chức năng XR_SPATIAL_CAPABILITY_ANCHOR_EXT.
Điểm neo do anchorEntity biểu thị chỉ hợp lệ trong suốt thời gian hoạt động của spatialContext hoặc cho đến khi ứng dụng gọi xrDestroySpatialEntityEXT trên điểm neo đó, tuỳ theo điều kiện nào xảy ra trước. Các tiện ích khác có thể cung cấp các hàm để duy trì điểm neo mới tạo này trên nhiều XrSession hoặc để chia sẻ điểm neo này qua ranh giới quy trình với các ứng dụng khác.
Một neo mới tạo, cho đến khi bị huỷ, phải có thể được phát hiện trong bối cảnh không gian gốc của neo đó. Điều này có nghĩa là thời gian chạy phải bao gồm anchorEntityId trong ảnh chụp nhanh được tạo bằng xrCreateSpatialDiscoverySnapshotAsyncEXT cho spatialContext nếu neo khớp với tiêu chí khám phá được đặt trong XrSpatialDiscoverySnapshotCreateInfoEXT . Điểm neo mới tạo cũng có thể được phát hiện trong các bối cảnh không gian khác được định cấu hình bằng XR_SPATIAL_CAPABILITY_ANCHOR_EXT , mặc dù có XrSpatialEntityIdEXT khác vì một XrSpatialEntityIdEXT cụ thể là duy nhất cho XrSpatialContextEXT của nó.
Cách sử dụng hợp lệ (Ngầm ẩn)
- Tiện ích
XR_EXT_spatial_anchorphải được bật trước khi gọi xrCreateSpatialAnchorEXT -
spatialContextphải là một tay điều khiển XrSpatialContextEXT hợp lệ -
createInfophải là con trỏ đến cấu trúc XrSpatialAnchorCreateInfoEXT hợp lệ -
anchorEntityIdphải là một con trỏ đến giá trịXrSpatialEntityIdEXT -
anchorEntityphải là một con trỏ đến một tay điều khiển XrSpatialEntityEXT
Mã trả về
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_LIMIT_REACHEDXR_ERROR_OUT_OF_MEMORYXR_ERROR_POSE_INVALIDXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_TIME_INVALIDXR_ERROR_VALIDATION_FAILUREXR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID(nếuXR_ANDROID_spatial_entity_bound_anchorđược bật)XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT(nếuXR_ANDROID_spatial_entity_bound_anchorđược bật)
Cấu trúc XrSpatialAnchorCreateInfoEXT được định nghĩa như sau:
typedef struct XrSpatialAnchorCreateInfoEXT {
XrStructureType type;
const void* next;
XrSpace baseSpace;
XrTime time;
XrPosef pose;
} XrSpatialAnchorCreateInfoEXT;
Nội dung mô tả về thành viên
typelà XrStructureType của cấu trúc này.nextlàNULLhoặc con trỏ trỏ đến cấu trúc tiếp theo trong chuỗi cấu trúc.baseSpacelà XrSpace áp dụngpose.timelàXrTimenơibaseSpaceđặt trụ sở (vàposeđược áp dụng).poselà vị trí của thực thể neo.
Cách sử dụng hợp lệ (Ngầm ẩn)
- Tiện ích
XR_EXT_spatial_anchorphải được bật trước khi sử dụng XrSpatialAnchorCreateInfoEXT -
typephải làXR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT -
nextphải làNULLhoặc một con trỏ hợp lệ đến cấu trúc tiếp theo trong chuỗi cấu trúc . Xem thêm: XrSpatialAnchorParentANDROID -
baseSpacephải là một tên người dùng XrSpace hợp lệ
Tư thế của điểm neo truy vấn
Sau khi tạo điểm neo, thời gian chạy sẽ điều chỉnh vị trí và hướng của điểm neo theo thời gian so với các không gian khác để duy trì sự căn chỉnh tốt nhất có thể với vị trí ban đầu trong thế giới thực, ngay cả khi điều đó thay đổi mối quan hệ của điểm neo với XrSpatialAnchorCreateInfoEXT :: baseSpace ban đầu dùng để khởi chạy điểm neo.
Ứng dụng có thể sử dụng xrCreateSpatialUpdateSnapshotEXT với XrSpatialEntityEXT của neo để tạo XrSpatialSnapshotEXT mới, sau đó truy vấn thành phần XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT từ ảnh chụp nhanh đó bằng xrQuerySpatialComponentDataEXT . Ứng dụng có thể thêm XrSpatialComponentAnchorListEXT vào XrSpatialComponentDataQueryResultEXT :: next để truy xuất dữ liệu vị trí mới nhất cho các neo.
Thời gian chạy có thể đặt trạng thái theo dõi của một neo mới tạo thành XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT . Ứng dụng chỉ được đọc trạng thái của thực thể neo được cung cấp trong XrSpatialComponentDataQueryResultEXT :: entityStates và dữ liệu thành phần neo của thực thể nếu trạng thái theo dõi là XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT .
Nguyên tắc sử dụng quảng cáo cố định
- Tư thế của mỗi điểm neo sẽ điều chỉnh độc lập với mọi điểm neo hoặc không gian khác. Các đối tượng ảo được neo riêng biệt có thể dịch chuyển hoặc xoay tương đối với nhau, phá vỡ hệ thống phân cấp không gian trong trường hợp các đối tượng ảo này được dự kiến sẽ giữ nguyên vị trí tương đối với nhau. Trong những trường hợp như vậy, ứng dụng nên sử dụng lại cùng một điểm neo cho tất cả đối tượng ảo không di chuyển tương ứng với nhau.
- Ứng dụng nên huỷ mọi tay điều khiển XrSpatialEntityEXT cho các neo không còn được dùng để giải phóng tài nguyên mà thời gian chạy có thể đang dùng để theo dõi các neo đó.
Mã ví dụ
Định cấu hình chức năng neo
Ví dụ sau đây minh hoạ cách định cấu hình chức năng neo khi tạo bối cảnh không gian.
// Create a spatial spatial context
XrSpatialContextEXT spatialContext{};
{
std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT,
};
XrSpatialCapabilityConfigurationAnchorEXT anchorConfig{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT};
anchorConfig.capability = XR_SPATIAL_CAPABILITY_ANCHOR_EXT;
anchorConfig.enabledComponentCount = enabledComponents.size();
anchorConfig.enabledComponents = enabledComponents.data();
std::array<XrSpatialCapabilityConfigurationBaseHeaderEXT*, 1> capabilityConfigs = {
reinterpret_cast<XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&anchorConfig),
};
XrSpatialContextCreateInfoEXT spatialContextCreateInfo{XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT};
spatialContextCreateInfo.capabilityConfigCount = capabilityConfigs.size();
spatialContextCreateInfo.capabilityConfigs = capabilityConfigs.data();
XrFutureEXT createContextFuture;
CHK_XR(xrCreateSpatialContextAsyncEXT(session, &spatialContextCreateInfo, &createContextFuture));
waitUntilReady(createContextFuture);
XrCreateSpatialContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};
CHK_XR(xrCreateSpatialContextCompleteEXT(session, createContextFuture, &completion));
if (completion.futureResult != XR_SUCCESS) {
return;
}
spatialContext = completion.spatialContext;
}
// ...
// Create spatial anchors and get their latest pose in the frame loop.
// ...
CHK_XR(xrDestroySpatialContextEXT(spatialContext));
Tạo điểm neo không gian và lấy vị trí của điểm neo đó
Ví dụ sau đây minh hoạ cách tạo một neo không gian và lấy tư thế của neo đó trong mỗi khung hình.
XrSpatialAnchorCreateInfoEXT createInfo{XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT};
createInfo.baseSpace = localSpace;
createInfo.time = predictedDisplayTime;
createInfo.pose = {{0, 0, 0, 1}, {1, 1, 1}};
XrSpatialEntityIdEXT spatialAnchorEntityId;
XrSpatialEntityEXT spatialAnchorEntity;
CHK_XR(xrCreateSpatialAnchorEXT(spatialContext, &createInfo, &spatialAnchorEntityId, &spatialAnchorEntity));
auto updateAnchorLocation = [&](XrTime time) {
// We want to get updated data for all components of the entities, so skip specifying componentTypes.
XrSpatialUpdateSnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT};
snapshotCreateInfo.entityCount = 1;
snapshotCreateInfo.entities = &spatialAnchorEntity;
snapshotCreateInfo.baseSpace = localSpace;
snapshotCreateInfo.time = time;
XrSpatialSnapshotEXT snapshot;
CHK_XR(xrCreateSpatialUpdateSnapshotEXT(spatialContext, &snapshotCreateInfo, &snapshot));
// Query for the entities that have the anchor component on them.
std::array<XrSpatialComponentTypeEXT, 1> componentsToQuery {XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT};
XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
queryCond.componentTypeCount = componentsToQuery.size();
queryCond.componentTypes = componentsToQuery.data();
XrSpatialComponentDataQueryResultEXT queryResult{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{XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT};
locationList.locationCount = locations.size();
locationList.locations = locations.data();
queryResult.next = &locationList;
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].
}
}
CHK_XR(xrDestroySpatialSnapshotEXT(snapshot));
};
while (1) {
// ...
// For every frame in frame loop
// ...
XrFrameState frameState; // previously returned from xrWaitFrame
const XrTime time = frameState.predictedDisplayTime;
updateAnchorLocation(time);
// ...
// Finish frame loop
// ...
}
CHK_XR(xrDestroySpatialEntityEXT(spatialAnchorEntity));
Lệnh mới
Cấu trúc mới
- XrSpatialAnchorCreateInfoEXT
- XrSpatialCapabilityConfigurationAnchorEXT
Mở rộng XrSpatialComponentDataQueryResultEXT :
Hằng số enum mới
XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAMEXR_EXT_spatial_anchor_SPEC_VERSIONMở rộng XrSpatialCapabilityEXT :
XR_SPATIAL_CAPABILITY_ANCHOR_EXT
Mở rộng XrSpatialComponentTypeEXT :
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
Mở rộng XrStructureType :
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXTXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXTXR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT
Vấn đề
Tại sao xrCreateSpatialAnchorEXT lại xuất ra cả mã nhận dạng thực thể và tên người dùng thực thể?
- Đã giải quyết
- Đáp: Hàm xrCreateSpatialAnchorEXT có thể chỉ cung cấp mã nhận dạng thực thể làm kết quả đầu ra và các ứng dụng có thể tạo một tay điều khiển thực thể cho mã nhận dạng đó bằng xrCreateSpatialEntityFromIdEXT . Tuy nhiên, do cách sử dụng thông thường của một neo, trong đó các ứng dụng truy vấn tư thế neo ở mọi khung hình, nên neo trở thành một đối tượng phù hợp để sử dụng trong "ảnh chụp nhanh cập nhật", yêu cầu tay điều khiển thực thể làm dữ liệu đầu vào. Để dự đoán trường hợp sử dụng thông thường này, xrCreateSpatialAnchorEXT sẽ thực hiện xrCreateSpatialEntityFromIdEXT thay cho ứng dụng và cung cấp cho ứng dụng tay điều khiển thực thể để sử dụng với xrCreateSpatialUpdateSnapshotEXT .
Danh sách phiên bản
Bản sửa đổi 1, ngày 10 tháng 7 năm 2024 (Nihav Jain, Google)
- Nội dung mô tả ban đầu về tiện ích