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

  • type là XrStructureType của cấu trúc này.
  • next là NULL hoặc con trỏ trỏ đến cấu trúc tiếp theo trong chuỗi cấu trúc.
  • capability là một XrSpatialCapabilityEXT .
  • enabledComponentCount là một uint32_t mô tả số lượng phần tử trong mảng enabledComponents.
  • enabledComponents là 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)

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

  • type là XrStructureType của cấu trúc này.
  • next là NULL hoặc con trỏ trỏ đến cấu trúc tiếp theo trong chuỗi cấu trúc.
  • locationCount là một uint32_t mô tả số lượng phần tử trong mảng locations.
  • locations là 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)

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ố

Ứ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_anchor phải được bật trước khi gọi xrCreateSpatialAnchorEXT
  • spatialContext phải là một tay điều khiển XrSpatialContextEXT hợp lệ
  • createInfo phải là con trỏ đến cấu trúc XrSpatialAnchorCreateInfoEXT hợp lệ
  • anchorEntityId phải là một con trỏ đến giá trị XrSpatialEntityIdEXT
  • anchorEntity phải là một con trỏ đến một tay điều khiển XrSpatialEntityEXT

Mã trả về

Thành công

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Không thành công

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_POSE_INVALID
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_TIME_INVALID
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID (nếu XR_ANDROID_spatial_entity_bound_anchor được bật)
  • XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT (nếu XR_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

  • type là XrStructureType của cấu trúc này.
  • next là NULL hoặc con trỏ trỏ đến cấu trúc tiếp theo trong chuỗi cấu trúc.
  • baseSpace là XrSpace áp dụng pose.
  • time là XrTime nơi baseSpace đặt trụ sở (và pose được áp dụng).
  • pose là vị trí của thực thể neo.

Cách sử dụng hợp lệ (Ngầm ẩn)

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

Hằng số enum mới

  • XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAME
  • XR_EXT_spatial_anchor_SPEC_VERSION
  • Mở 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_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT
    • XR_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