Develop
Develop
Select your platform

Spatial Anchors OpenXR API Reference

Updated: May 21, 2025

Spatial entity extension and API overview

Overview

The XR_FB_spatial_entity extension allows applications to utilize anchors based on world-locked frames of reference. This extension also defines the Entity-Components, outlining the capabilities or attributes of an entity. All Meta spatial entity extensions depend on this extension. Spatial anchors, representing a single rigid transform in physical space, are the most basic type of anchor. For more information about additional kinds of anchors with more components, see the Scene documentation.
Manage spatial anchors using their anchor handle, an (XrSpace). This handle holds a reference to all the data for the spatial anchor while it’s active in the runtime. Once it’s no longer active, you can identify it by its UUID. The OpenXR XrSpace handles are used to grant applications access to spatial anchors. Note that these will be cleaned up when the OpenXR session ends. Any operation that involves spatial anchors uses either XrSpace handles, UUIDs, or both, to identify the impacted spatial anchors.
This extension allows:
  • An application to create a spatial anchor.
  • An application to enumerate an anchor’s supported components (spatial anchor or otherwise).
  • An application to enable or disable a component.
    Note
    not all components are mutable
  • An application to get the status of a component.
Prerequisite for using this extension:

Entity components

The architectural pattern of entity/component offers specialization through composition, not inheritance. This approach prevents the potential exponential growth of types that may occur when various entity types have shared characteristics but differ in other aspects.
Components represent the interfaces that are available to the anchor. Every anchor supports a specific set of components, and enabling these components allows access to the associated operations/behaviors. Each anchor’s component support and state are unique.
Anchors may support any subset of the components given in the XrSpaceComponentTypeFB enum. Operations supported on components are:
  • xrEnumerateSpaceSupportedComponentsFB.
  • xrSetSpaceComponentStatusFB.
  • xrGetSpaceComponentStatusFB.

Component types

XrSpaceComponentTypeFB specifies the component interfaces that could be enabled or are already enabled by the system on spatial entities.
typedef enum XrSpaceComponentTypeFB {
    XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB = 0,
    XR_SPACE_COMPONENT_TYPE_STORABLE_FB = 1,
    XR_SPACE_COMPONENT_TYPE_SHARABLE_FB = 2,
    XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB = 3,
    XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB = 4,
    XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB = 5,
    XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB = 6,
    XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB = 7,
    XR_SPACE_COMPONENT_TYPE_TRIANGLE_MESH_META = 1000269000,
    XR_SPACE_COMPONENT_TYPE_MAX_ENUM_FB = 0x7FFFFFFF
} XrSpaceComponentTypeFB;
  • XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB: Enables tracking the 6 DOF pose of the spatial anchor with xrLocateSpace.
  • XR_SPACE_COMPONENT_TYPE_STORABLE_FB: Enables persistence operations: save and erase.
  • XR_SPACE_COMPONENT_TYPE_SHARABLE_FB: Enables sharing operation: share.
  • XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB: 2D Plane component, see Scene documentation for more.
  • XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB: 3D Plane component, see Scene documentation for more.
  • XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB: Label for an entity, see Scene documentation for more.
  • XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB: Room layout information, see Scene documentation for more.
  • XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB: Entity container, see Scene documentation for more.
  • XR_SPACE_COMPONENT_TYPE_TRIANGLE_MESH_META: Mesh component, see Scene documentation for more.

APIs

For more information on the API signatures and runtime guarantees, see the OpenXR Specification.

xrEnumerateSpaceSupportedComponentsFB

The xrEnumerateSpaceSupportedComponentsFB function discovers any component interfaces that an entity supports. The list of supported components does not change as long as the entity exists. The list of component interfaces available for an entity may depend on which extensions are enabled. Component interfaces are not enumerated unless the corresponding extension that defines them is also enabled. The list does not contain which components are currently enabled on an entity. This API is synchronous and uses a two-call idiom to get back the list of XrComponentTypeFB.
XrResult xrEnumerateSpaceSupportedComponentsFB(
    XrSpace               space,
    uint32_t              componentTypesCapacityInput,
    uint32_t*             componentTypesCountOutput,
    XrComponentTypeFB*    componentTypes);
Parameters
  • space: The XrSpace handle to the anchor.
  • componentTypesCapacityInput: The maximum number of component types expected by the caller. The caller uses this maximum value to ensure the array returned through the componentTypes out-parameter does not exceed the bounds of the array allocated by the caller.
  • componentTypesCountOutput: An output parameter showing the number of enumerated component types.
  • componentTypes: An output parameter providing an array of the component types supported by the specified anchor.
Success
  • XR_SUCCESS
Failure
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID

xrSetSpaceComponentStatusFB

The xrSetSpaceComponentStatusFB function enables or disables the specified component for the specified anchor. This operation is asynchronous.
XrResult xrSetSpaceComponentStatusFB(
    XrSpace                                space,
    const XrSpaceComponentStatusSetInfoFB* request,
    XrAsyncRequestIdFB*                    requestId);
Parameters
  • space: The XrSpace handle to the anchor.
  • request: The pointer to an XrSpaceComponentStatusSetInfoFB structure containing information about the component to be enabled.
  • requestID: The output parameter that points to the ID of this asynchronous request.
Success
  • XR_SUCCESS
Failure
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_SPACE_COMPONENT_NOT_SUPPORTED_FB
  • XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB
  • XR_ERROR_SPACE_COMPONENT_STATUS_PENDING_FB
  • XR_ERROR_SPACE_COMPONENT_ALREADY_ENABLED_FB

xrGetSpaceComponentStatusFB

The xrGetSpaceComponentStatusFB function gets the current status of the specified component for the specified anchor.
XrResult xrGetSpaceComponentStatusFB(
    XrSpace                   space,
    XrSpaceComponentTypeFB    componentType,
    XrSpaceComponentStatusFB* status);
Parameters
  • space: A pointer to the returned XrSpace handle of the new spatial anchor.
  • componentType: The component type you want to query.
  • status: An output parameter showing information about the status of the component you queried.
Success
  • XR_SUCCESS
Failure
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID

xrCreateSpatialAnchorFB

xrCreateSpatialAnchorFB asynchronously creates a spatial anchor using the specified tracking origin and pose. The anchor is locatable at creation. You can query its 6 DOF pose relative to the tracking origin using xrLocateSpace.
XrResult xrCreateSpatialAnchorFB(
    XrSession           session,
    const               XrSpatialAnchorCreateInfoFB* info,
    XrAsyncRequestIdFB* requestId);
Parameters
  • session: A handle to an XrSession.
  • info: Pointer to an XrSpatialAnchorCreateInfoFB structure containing information about how to create the anchor.
  • requestId: A pointer to the returned XrAsyncRequestIdFB handle of the operation that was started.
Success
  • XR_SUCCESS
Failure
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_RUNTIME_FAILURE

xrDestroySpace

The xrCreateSpatialAnchorFB operation creates an ephemeral anchor represented by an XrSpace, which is trackable in the current session. To destroy this anchor and remove it from the runtime, call the xrDestroySpace API on the XrSpace. If the anchor was ephemeral (not already successfully persisted - for more information, see the Persistence section) then it won’t be recoverable across sessions via the Discovery API. For more information, see the Discovery section.

xrLocateSpace

To track an anchor which has the XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB component enabled, call the xrLocateSpace API per-frame. The Reference Space which you locate with respect to is the same that you created the spatial anchor with, for example XR_REFERENCE_SPACE_TYPE_VIEW, XR_REFERENCE_SPACE_TYPE_LOCAL, XR_REFERENCE_SPACE_TYPE_STAGE. Read more about XrSpace and the different Reference Spaces in the OpenXR Specification.

Structs

xrSpaceComponentStatusSetFB
The xrSpaceComponentStatusSetFB operation attempts sets a component’s status to the given value and will return an error if that component is not toggleable for that spatial entity.
typedef struct XrSpaceComponentStatusSetFB {
    XrStructureType        type;
    const void*            next;
    XrSpaceComponentTypeFB componentType;
    XrBool32               enable;
    XrDuration             timeout;
} XrSpaceComponentStatusSetFB;
Parameters
  • type: The XrStructureType of this structure.
  • next: Is either NULL or a pointer to the next structure in a structure chain. Core OpenXR doesn’t define these structures.
  • componentType: The component whose status you want to set.
  • enable: The value to which you want to set the component.
  • timeout: The number of nanoseconds before the operation should timeout. A value of 0.0 indicates no timeout.
xrSpatialAnchorCreateInfoFB
The XrSpatialAnchorCreateInfoFB structure is defined as:
typedef struct XrSpatialAnchorCreateInfoFB {
    XrStructureType    type;
    void*              next;
    XrSpace            space;
    XrPosef            poseInSpace;
    XrTime             time;
} XrSpatialAnchorCreateInfoFB;
Parameters
  • type: The XrStructureType of this structure.
  • next: Must be NULL or a pointer to the next structure in a structure chain. Core OpenXR doesn’t define such structures.
  • space: The XrSpace handle to the reference space defining the poseInSpace of the anchor you created.
  • poseInSpace: The XrPosef location and orientation of the spatial anchor in the specified reference space.
  • time: The XrTime timestamp associated with the specified pose.

Extended XrResult for spatial entities

  • XR_ERROR_SPACE_COMPONENT_NOT_SUPPORTED_FB: This component is not supported for this XrSpace
  • XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB: This component is not enabled for this XrSpace
  • XR_ERROR_SPACE_COMPONENT_STATUS_PENDING_FB: There is an ongoing operation to enable this component for this XrSpace
  • XR_ERROR_SPACE_COMPONENT_STATUS_ALREADY_SET_FB: This component has already been set for this XrSpace

Persistence extension and API overview

XR_META_spatial_entity_persistence overview

The XR_META_spatial_entity_persistence extension provides long-term persistence for spatial entities, allowing them to be stored for retrieval even after the device is restarted or powered off. It also provides the ability to manage storage through erasing anchors. This extension uses a storage agnostic approach, meaning it can work with different types of storage solutions. This capability is vital for applications that need to ‘remember’ the position of spatial entities (for example, for the purposes of rendering specific content in a world-locked position) across different sessions.
Note
Associated content is not stored using this extension, that is the responsibility of the application.
This extension works together with XR_META_spatial_entity_discovery for single-user experiences, and XR_FB_spatial_entity_query plus XR_META_spatial_entity_sharing for sharing experiences, to provide robust and flexible capabilities for developers building AR/VR applications.
Key features of the XR_META_spatial_entity_persistence extension include:
  • Long-Term Storage: Spatial entities are stored indefinitely until explicitly erased.
  • Session Independence: The XR_META_spatial_entity_persistence extension allows spatial entities to persist across different user sessions. In other words, once a spatial entity is persisted, it remains available for retrieval, and should be unchanged in subsequent user sessions until it is explicitly erased.
  • Implicit Storage Management: This extension does not require storage management/synchronization, it is handled on behalf of the developer by the system.
The Persistence extension can be used with the Discovery extension for single-user experiences. Alternatively the Persistence extension can be used with the Query and Sharing extensions for multi-user colocated experiences. The Persistence extension aims to provide more robust, easy-to-use, and efficient storage management of spatial entities for XR applications. Through persistence, sharing, and enhanced discovery, the experiences with world-locked content can be made more seamless and user-friendly.
The XR_META_spatial_entity_persistence extension is the next version of the following spatial entity extensions, and as a result, the following extensions are now obsolete:
  • XR_FB_spatial_entity_storage
  • XR_FB_spatial_entity_storage_batch
Prerequisites for the Persistence APIs to be successful:
  • End user enabled local file system access for the application: End users need to have opted-in to let the application access the device’s file system.

APIs

For more information on the API signatures and runtime guarantees, see the OpenXR Specification.

xrSaveSpacesMETA

The xrSaveSpacesMETA function saves the provided anchors. This function will return an error if the save call fails.
XRAPI_ATTR XrResult XRAPI_CALL xrSaveSpacesMETA(
    XrSession session,
    const XrSpacesSaveInfoMETA* info,
    XrAsyncRequestIdFB* requestId);
Parameters
  • session: The XrSession object representing the current XR session.
  • info: A pointer to the XrSpacesSaveInfoMETA struct containing the spatial entities to be saved.
  • requestId: An XrAsyncRequestIdFB atom that represents the request ID for the save operation for async event handling.
  • Synchronous Returns: The xrSaveSpacesMETA function returns an XrResult indicating the success or failure of triggering the async operation.
  • Asynchronous Returns: The async event will be returned as a callback, and that struct contains another XrResult, indicating the success or failure of the operation as a whole.
XrResult result = xrSaveSpacesMETA(session, &info, &requestId);
if (XR_SUCCESS == result)
{
    // Save operation was successfully triggered.
} else {
    // Save operation failed to trigger.
}

xrEraseSpacesMETA

The xrEraseSpacesMETA function erases the provided anchors from all storage locations enabled. This function will return an error if the erase call fails.
Note
This operation does not remove the `XrSpace`s from the runtime or disable tracking, they turn a persisted anchor into an ephemeral anchor such that it won't be discoverable across sessions anymore.
To remove the anchor from tracking, see the xrDestroySpace API.
XRAPI_ATTR XrResult XRAPI_CALL xrEraseSpacesMETA(
    XrSession session,
    const XrSpacesEraseInfoMETA* info,
    XrAsyncRequestIdFB* requestId);
Parameters
  • session: The XrSession object representing the current XR session.
  • info: A pointer to the XrSpacesEraseInfoMETA struct containing the anchors to be erased (either via XrSpace handle or via UUID).
  • requestId: An XrAsyncRequestIdFB atom that represents the request ID for the erase operation for async event handling.
Returns The xrEraseSpacesMETA function returns an XrResult indicating the success or failure of the operation.
XrResult result = xrEraseSpacesMETA(session, &info, &requestId);
if (XR_SUCCESS == result)
{
    // Erase operation was successfully triggered.
} else {
    // Erase operation failed to trigger.
}

Structs

/**
 * Structure representing the anchor information to be saved.
 */
struct XrSpacesSaveInfoMETA {
    XrStructureType type; // XR_TYPE_SPACES_SAVE_INFO_META
    const void* XR_MAY_ALIAS next;
    uint32_t spaceCount;
    XrSpace* spaces;
};

/**
 * Structure representing the result of a space save operation.
 */
struct XrEventDataSpacesSaveResultMETA {
    XrStructureType type; // XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META
    const void* XR_MAY_ALIAS next;
    XrAsyncRequestIdFB requestId;
    XrResult result;
};

/**
 * Structure representing the information for a spaces erase operation.
 */
struct XrSpacesEraseInfoMETA {
    XrStructureType type; // XR_TYPE_SPACES_ERASE_INFO_META
    const void* XR_MAY_ALIAS next;
    uint32_t spaceCount;
    XrSpace* spaces;
    uint32_t uuidCount;
    XrUuidEXT* uuids;
};

/**
 * Structure representing the result of a spaces erase operation.
 */
struct XrEventDataSpacesEraseResultMETA {
    XrStructureType type; // XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META
    const void* XR_MAY_ALIAS next;
    XrAsyncRequestIdFB requestId;
    XrResult result;
};

Events

  • XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META
  • XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META
Handling Anchor Persistence events
// Called per-frame
void handleOpenXrAnchorEvents() {
    XrEventDataBuffer eventDataBuffer = {};
    // Poll for events.
    while (true) {
        XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
        baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
        baseEventHeader->next = nullptr;
        XrResult result = xrPollEvent(instance, &eventDataBuffer);
        if (result != XR_SUCCESS) {
            break;
        }

        ...

        if (baseEventHeader->type == XR_TYPE_EVENT_DATA_SPACES_SAVE_RESULT_META) {
                const XrEventDataSpacesSaveResultMETA* saveAnchorResult =
                    (XrEventDataSpacesSaveResultMETA*)(baseEventHeader);

                // Find the requestId provided during the sync phase earlier and any associated data

                if (saveAnchorResult->result < XR_SUCCESS) {
                    ...
                } else {
                    ...
                }
        } else if (baseEventHeader->type == XR_TYPE_EVENT_DATA_SPACES_ERASE_RESULT_META) {
            const XrEventDataSpacesEraseResultMETA* eraseAnchorResult =
                (XrEventDataSpacesEraseResultMETA*)(baseEventHeader);

            // Find the requestId provided during the sync phase earlier and any associated data

            if (eraseAnchorResult->result < XR_SUCCESS) {
                ...
            } else {
                ...
            }
        }

        ...
    }
}

Standard XrResult values

The following are standard XrResult values that can be returned from the synchronous API call:
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_SESSION_NOT_RUNNING
  • XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB
  • XR_ERROR_INITIALIZATION_FAILED
  • XR_ERROR_SPACE_RATE_LIMITED_META
  • XR_SUCCESS

Extended XrResult for persistence

  • XR_ERROR_SPACE_INSUFFICIENT_RESOURCES_META: Resource limitation prevented this operation from executing. Recommend retrying, perhaps after a short delay and/or reducing memory consumption.
  • XR_ERROR_SPACE_STORAGE_AT_CAPACITY_META: Operation could not be completed until resources used are reduced or storage expanded.
  • XR_ERROR_SPACE_INSUFFICIENT_VIEW_META: Look around the environment more for sufficient space tracking to complete the operation.
  • XR_ERROR_SPACE_PERMISSION_INSUFFICIENT_META: Space operation permission insufficient. Recommend confirming the status of the required permissions needed for using spatial anchor APIs.
  • XR_ERROR_SPACE_RATE_LIMITED_META: Operation cancelled due to rate limiting. Recommend retrying after a short delay.
  • XR_ERROR_SPACE_TOO_DARK_META: Environment too dark for tracking to complete operation.
  • XR_ERROR_SPACE_TOO_BRIGHT_META: Environment too bright for tracking to complete operation.

Discovery extension and API overview

XR_META_spatial_entity_discovery overview

The XR_META_spatial_entity_discovery extension streamlines the discovery mechanism to support larger areas to retrieve locatable spatial entities. With this extension, the device can discover efficiently in larger spatial areas to retrieve relevant spatial entities. There are filtering capabilities offered, by anchor UUID or by anchor component, which allows for more efficient and targeted discovery of spatial entities.
This extension works together with XR_META_spatial_entity_persistence in much the same way as what XR_FB_spatial_entity_query does today, to provide a robust and flexible suite of Anchor APIs for developers building AR/VR applications. XR_META_spatial_entity_persistence does not yet support discovery of shared spatial entities.
Key features of the XR_META_spatial_entity_discovery extension include:
  • UUID Filter: The discovery mechanism can filter spatial entities based on their UUID (Universally Unique Identifier). This aids in targeted retrieval of specific spatial entities.
  • Component Filter: The discovery mechanism can filter spatial entities based on certain immutable components. These components that anchors are discoverable by are as follows:
    • XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB
    • XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB
    • XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB
    • XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB
    • XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB
    • XR_SPACE_COMPONENT_TYPE_TRIANGLE_MESH_META
  • No Filter: The discovery mechanism can also be used with no filters specified. This will return any and all spatial entities the device can find that are locatable in the user’s physical space.
  • Support for Larger Spaces: The discovery operation is more efficient than the Query APIs, and is effective in larger spatial areas.
Together with the Persistence extension, the Discovery extension aims to provide a more robust and efficient handling of spatial entities in XR applications. Through persistent storage and enhanced discovery, the XR experience can be made more seamless and user-friendly.
Prerequisites for the Discovery APIs to be successful:
  • End user enabled local file system access for the application: End users need to have opted-in to let the application access the device’s file system.
  • [Optional] Enhanced Spatial Services: In order for discovery to retrieve non-local data (for example, anchors on Meta’s infrastructure), the discoverer would need to have enabled the Enhanced Spatial Services permission.

APIs

For more information on the API signatures and runtime guarantees, see the OpenXR Specification.

xrDiscoverSpacesMETA

The xrDiscoverSpacesMETA operation is used to discover spaces from all available and permitted sources. It will return an XrResult indicating the success or failure of initiating the asynchronous discovery operation. If successfully initiated, discovery results are pushed to the runtime asynchronously.
Signature
XRAPI_ATTR XrResult XRAPI_CALL xrDiscoverSpacesMETA(
    XrSession session,
    const XrSpaceDiscoveryInfoMETA* info,
    XrAsyncRequestIdFB* requestId
);
Parameters
  • session: An XrSession for the current application instance.
  • info: A pointer to the discovery information, XrSpaceDiscoveryInfoMETA*.
  • requestId: A pointer to the request ID, XrAsyncRequestIdFB*. This is an out parameter that will be populated by the API call.
  • Synchronous Returns: The xrDiscoverSpacesMETA function returns an XrResult indicating the success or failure of triggering the async operation.
  • Asynchronous Returns: The async event will be returned as a callback, and the Complete event struct contains another XrResult, indicating the success or failure of the operation as a whole.
  • Filters: The xrDiscoverSpacesMETA API is designed to accept a list of filters, subject to certain constraints.
  • Array Format: The filters are structured in the form of an array of a base type, to accommodate potential future filter enhancements. For reference, the filter will act as a pointer to struct pointers.
  • Filter Types: The array of struct pointers may contain multiple instances of each of the following filter types:
    • XrSpaceUuidFilterInfoMETA
    • XrSpaceComponentFilterInfoMETA The behaviour of filter interaction can be thought of like distinct filter types behaving like AND and like filter types behaving like OR.
  • Batched Operation Support: The XrSpaceUuidFilterInfoMETA is capable of accepting an array of UUIDs, enabling the API to perform batch operations effectively.
    Note
    There is a limit to the number of UUIDs the system can accept for any given call, 50. However the system is capable of providing any number of anchors. That is, a no-filter discovery call may return >50 anchors but a discovery call with UUID filter(s) specified can return at most 50.
std::vector<const XrSpaceFilterBaseHeaderMETA*> filters;

// Initialize UUID filter
const XrSpaceFilterUuidMETA uuidFilter = XrSpaceFilterUuidMETA{
    XR_TYPE_SPACE_FILTER_UUID_META,
    nullptr,
    static_cast<uint32_t>(uuids.size()),
    uuids.data()};
uuidFilterPtr = reinterpret_cast<const XrSpaceFilterBaseHeaderMETA*>(&uuidFilter);
filters.push_back(uuidFilterPtr);

// Initialize Component Filter
const XrSpaceFilterComponentMETA componentFilter = XrSpaceFilterComponentMETA{
    XR_TYPE_SPACE_FILTER_COMPONENT_META, nullptr, componentType};
componentFilterPtr =
    reinterpret_cast<const XrSpaceFilterBaseHeaderMETA*>(&componentFilter);
filters.push_back(componentFilterPtr);

XrSpaceDiscoveryInfoMETA info = {
    XR_TYPE_SPACE_DISCOVERY_INFO_META, nullptr, 2, filters.data()};
XrResult result = xrDiscoverSpacesMETA(session, &info, &requestId);
if (XR_SUCCESS == result)
{
    // Discover operation was successfully triggered.
} else {
    // Discover operation failed to trigger.
}

xrRetrieveSpaceDiscoveryResultsMETA

The xrRetrieveSpaceDiscoveryResultsMETA operation is used to retrieve available results for a request synchronously. The results become available after an XrEventDataSpaceDiscoveryResultsAvailableMETA event from xrPollEvent() is fired. They will be purged from the runtime once they have been copied into the application’s buffer. The application should call this function twice: once to populate resultCount and again to actually retrieve the results after enough memory has been allocated (Two-Call Idiom).
Signature
XRAPI_ATTR XrResult XRAPI_CALL xrRetrieveSpaceDiscoveryResultsMETA(
    XrSession session,
    XrAsyncRequestIdFB requestId,
    XrSpaceDiscoveryResultsMETA* results
);
See an example usage in the Event section below.
Parameters
  • session: An XrSession for the current application instance.
  • requestId: The XrAsyncRequestIdFB request ID for which results are being retrieved.
  • results: A pointer to the XrSpaceDiscoveryResultsMETA struct where the discovery results will be stored.

Structs

This section provides an overview of the key structs used in the API.
XrSpaceDiscoveryInfoMETA
This struct may be used to discover spaces. The filter info provided to the filter member of the struct will be used as an inclusive list of filters. What this means is all filter structs of the same type will be OR’ed together, while all filter structs of distinct types will be AND’ed together. All spaces discoverable by the system that match the criteria provided in the filter member will be included in the results available event(s).
Supported filters:
  • XR_TYPE_SPACE_UUID_FILTER_INFO_META
  • XR_TYPE_SPACE_COMPONENT_FILTER_INFO_META
static const XrStructureType XR_TYPE_SPACE_DISCOVERY_INFO_META = (XrStructureType) 1000247001;
typedef struct XrSpaceDiscoveryInfoMETA {
    XrStructureType                               type;
    const void* XR_MAY_ALIAS                      next;
    uint32_t                                      filterCount;
    const XrSpaceFilterBaseHeaderMETA* const *    filters;
} XrSpaceDiscoveryInfoMETA;
XrSpaceDiscoveryResultMETA
This struct is a discovery result to be returned in the results array of xrRetrieveSpaceDiscoveryResultsMETA. No type or next pointer is included to save space in the results array.
typedef struct XrSpaceDiscoveryResultMETA {
    XrSpace      space;
    XrUuidEXT    uuid;
} XrSpaceDiscoveryResultMETA;
XrSpaceDiscoveryResultsMETA
This struct is used in the xrRetrieveSpaceDiscoveryResultsMETA API, using a two-call idiom. In the first call, 0 should be passed for the resultCapacityInput field, and the system will populate the resultCountOutput field. In the second call, the resultCapacityInput field can be as much as what was returned in the resultCountOutput field, and the application can allocate the same length buffer for the results field, which will be populated.
static const XrStructureType XR_TYPE_SPACE_DISCOVERY_RESULTS_META = (XrStructureType) 1000247006;
typedef struct XrSpaceDiscoveryResultsMETA {
    XrStructureType                type;
    const void* XR_MAY_ALIAS       next;
    uint32_t                       resultCapacityInput;
    uint32_t                       resultCountOutput;
    XrSpaceDiscoveryResultMETA*    results;
} XrSpaceDiscoveryResultsMETA;

Events

This section provides an overview of the key events used in the API.

XrEventDataSpaceDiscoveryResultsAvailableMETA

There is potential for multiple Results Available events to be returned.
static const XrStructureType XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_RESULTS_AVAILABLE_META = (XrStructureType) 1000247007;
typedef struct XrEventDataSpaceDiscoveryResultsAvailableMETA {
    XrStructureType             type;
    const void* XR_MAY_ALIAS    next;
    XrAsyncRequestIdFB          requestId;
} XrEventDataSpaceDiscoveryResultsAvailableMETA;

XrEventSpaceDiscoveryCompleteMETA

For the Complete event, that indicates that discovery is finished and no more Results Available events should be returned for this discovery operation.
static const XrStructureType XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_COMPLETE_META = (XrStructureType) 1000247008;
typedef struct XrEventDataSpaceDiscoveryCompleteMETA {
    XrStructureType             type;
    const void* XR_MAY_ALIAS    next;
    XrAsyncRequestIdFB          requestId;
    XrResult                    result;
} XrEventDataSpaceDiscoveryCompleteMETA;

Example of handling anchor Discovery events

You can choose to retrieve the discovery results after receiving a Results Available event, or after receiving a Discovery Complete event. In this example, it’s done during the Results Available event.
// Called per-frame
void handleOpenXrAnchorEvents() {
    XrEventDataBuffer eventDataBuffer = {};
    // Poll for events.
    while (true) {
        XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
        baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
        baseEventHeader->next = nullptr;
        XrResult result = xrPollEvent(instance, &eventDataBuffer);
        if (result != XR_SUCCESS) {
            // Handle any errors
        }
        ...
        if (baseEventHeader->type ==
            XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_RESULTS_AVAILABLE_META) {
            const XrEventDataSpaceDiscoveryResultsAvailableMETA*
                discoverAnchorResultsAvailable = (XrEventDataSpaceDiscoveryResultsAvailableMETA*)(baseEventHeader);

            XrResult res = XR_SUCCESS;
            XrSpaceDiscoveryResultsMETA discoveryResults{XR_TYPE_SPACE_DISCOVERY_RESULTS_META};
            discoveryResults.resultCapacityInput = 0;
            discoveryResults.resultCountOutput = 0;
            discoveryResults.results = nullptr;

            // Call once to find the number of results (as resultCountOutput).
            res = xrRetrieveSpaceDiscoveryResultsMETA(
                xrSession, discoverAnchorResultsAvailable->requestId, &discoveryResults);
            if (res != XR_SUCCESS) {
                // Handle any errors
            }

            // Call it again to get the actual result objects.
            std::vector<XrSpaceDiscoveryResultMETA> results(discoveryResults.resultCountOutput);
            discoveryResults.resultCapacityInput = results.size();
            discoveryResults.results = results.data();
            res = xrRetrieveSpaceDiscoveryResultsMETA(
                xrSession, discoverAnchorResultsAvailable->requestId, &discoveryResults);
            if (res != XR_SUCCESS) {
                // Handle any errors
            }

            for (auto result : results) {
                // Use the results: App-specific magic
                ...
            }
        } else if (
            baseEventHeader->type == XR_TYPE_EVENT_DATA_SPACE_DISCOVERY_COMPLETE_META) {
            const XrEventDataSpaceDiscoveryCompleteMETA* discoverAnchorComplete =
                (XrEventDataSpaceDiscoveryCompleteMETA*)(baseEventHeader);
            if (discoverAnchorComplete->result < XR_SUCCESS) {
                // Handle any errors
            }
            ...
        }
        ...
    }
}

Standard XrResult values

The following are standard XrResult values that can be returned from the synchronous API call:
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_SESSION_NOT_RUNNING
  • XR_SUCCESS

Extended XrResult for discovery

  • XR_ERROR_SPACE_INSUFFICIENT_RESOURCES_META: Resource limitation prevented this operation from executing. Recommend retrying, perhaps after a short delay and/or reducing memory consumption.
  • XR_ERROR_SPACE_STORAGE_AT_CAPACITY_META: Operation could not be completed until resources used are reduced or storage expanded.
  • XR_ERROR_SPACE_INSUFFICIENT_VIEW_META: Look around the environment more for space tracking to function.
  • XR_ERROR_SPACE_PERMISSION_INSUFFICIENT_META: Space operation permission insufficient. Recommend confirming the status of the required permissions needed for using Space APIs.
  • XR_ERROR_SPACE_RATE_LIMITED_META: Operation cancelled due to rate limiting. Recommend retrying after a short delay.
  • XR_ERROR_SPACE_TOO_DARK_META: Environment too dark for tracking to complete operation.
  • XR_ERROR_SPACE_TOO_BRIGHT_META: Environment too bright for tracking to complete operation.

Query extension and API overview

XR_FB_spatial_entity_query overview

The XR_FB_spatial_entity_query extension is part of the original suite of Anchor APIs. Query is still the recommended mechanism for retrieving shared anchors.
Query offers filtering mechanisms similar to Discovery. To retrieve shared anchors it’s required that the UUID filter is used (populated with UUIDs communicated to you from the sharer) with the STORAGE_LOCATION set to CLOUD.
If your usecase doesn’t need sharing, the recommended mechanism to retrieve anchors is the Discovery API since it supports larger areas to retrieve locatable spatial entities.
This extension works together with XR_META_spatial_entity_persistence and XR_META_spatial_entity_sharing to achieve colocated shared AR/VR applications.
Prerequisites for the Query APIs to be successful:
  • End user enabled local file system access for the application: End users need to have opted-in to let the application access the device’s file system.
  • Enhanced Spatial Services: In order for query to retrieve non-local data (for example anchors on Meta’s infrastructure), the discoverer would need to have enabled the Enhanced Spatial Services system-wide permission.

APIs

For more information on the API signatures and runtime guarantees, see the OpenXR Specification.

xrQuerySpacesFB

This function is used to query for spaces from a specified storage location and with particular filters provided. It will return immediately with an XrResult indicating the success/failure of initiating the asynchronous query operation. If successful, asynchronous query results are pushed to the runtime asynchronously.
Signature
XRAPI_ATTR XrResult XRAPI_CALL xrQuerySpacesFB(
    XrSession session,
    const XrSpaceQueryInfoBaseHeaderFB* info,
    XrAsyncRequestIdFB* requestId
);
Parameters
  • session: A XrSession for the current application instance.
  • info: A pointer to the base type of the query information, XrSpaceQueryInfoBaseHeaderFB. See the XrSpaceQueryInfoFB struct.
  • requestId: A pointer to the XrAsyncRequestIdFB request ID. This is an out parameter that will be populated by the API call.
  • Synchronous Returns: The xrQuerySpacesFB function returns an XrResult indicating the success or failure of triggering the async operation.
  • Asynchronous Returns: The async event will be returned as a callback, and the Complete event struct contains another XrResult, indicating the success or failure of the operation as a whole.
  • Filters: The xrQuerySpacesFB API is designed to accept a list of filters, subject to certain constraints.
  • Linked-List Format: The filters are structured in the form of a linked list of objects utilizing the next* for multi-filter chaining.
  • Filter Types: The linked list may contain at most one instance of each of the following filter types:
    • XrSpaceStorageLocationFilterInfoFB the location to retrieve spatial entities from. (To retrieve shared entities, initialize this with the cloud storage location)
    • XrSpaceUuidFilterInfoFB an optional filter for indicating specific spatial entities to be retrieved.
    • XrSpaceGroupUuidFilterInfoMETA an optional filter for indicating specific sharing groups to query. (Please see the Sharing section below for more details on Group Sharing.). Note, if a Group UUID filter is provided with no Space UUID filter, all entities shared with the Group must be successfully retrieved for the Query to succeed.
    • XrSpaceComponentFilterInfoFB
  • Batched Operation Support: The XrSpaceUuidFilterInfoFB accepts an array of UUIDs, enabling the API to perform batch operations effectively.
    Note
    To retrieve shared entities, apps must provide at least one `XrSpaceUuidFilterInfoFB` or `XrSpaceGroupUuidFilterInfoMETA`, in addition to an `XrSpaceStorageLocationFilterInfoFB` set to `XR_SPACE_STORAGE_LOCATION_CLOUD_FB`
    Note
    There is a limit to the number of UUIDs the system can accept for any given call, 50.
// Initialize the Storage Location filter to query from Cloud
XrSpaceStorageLocationFilterInfoFB storageLocationFilter = XrSpaceStorageLocationFilterInfoFB{
    XR_TYPE_SPACE_STORAGE_LOCATION_FILTER_INFO_FB, nullptr, XR_SPACE_STORAGE_LOCATION_CLOUD_FB};
XrSpaceFilterInfoBaseHeaderFB* storageLocationFilterPtr =
    reinterpret_cast<XrSpaceFilterInfoBaseHeaderFB*>(&storageLocationFilter);

// Initialize the UUID filter with the spatial entity UUIDs you'd like to query for
XrSpaceUuidFilterInfoFB uuidFilter = XrSpaceUuidFilterInfoFB{
    XR_TYPE_SPACE_UUID_FILTER_INFO_FB,
    nullptr,
    static_cast<uint32_t>(uuids.size()),
    uuids.data()};
XrSpaceFilterInfoBaseHeaderFB* uuidFilterPtr = reinterpret_cast<XrSpaceFilterInfoBaseHeaderFB*>(&uuidFilter);
storageLocationFilterPtr->next = uuidFilterPtr;

XrSpaceQueryInfoFB info = {
    XR_TYPE_SPACE_QUERY_INFO_FB,
    nullptr,
    XR_SPACE_QUERY_ACTION_LOAD_FB,
    maxResultCount,
    0,
    storageLocationFilterPtr,
    nullptr};

XrAsyncRequestIdFB requestId;
XrResult res = xrQuerySpacesFB(openXrSession_, (XrSpaceQueryInfoBaseHeaderFB*)&info, &requestId);
if (res < XrResult::XR_SUCCESS) {
    // Handle Query failed at input validation stage
} else {
    // Async Query operation successfully initiated
}

xrRetrieveSpaceQueryResultsFB

This function is used to retrieve available results for a request synchronously. The results become available after an XrEventDataSpaceQueryResultsAvailableFB event from xrPollEvent() is fired. They will be purged from the runtime once they have been copied into the application’s buffer. The application should call this function twice: once to populate resultCount and again to actually retrieve the results after enough memory has been allocated (Two-Call Idiom).
Signature
XRAPI_ATTR XrResult XRAPI_CALL xrRetrieveSpaceQueryResultsFB(
    XrSession session,
    XrAsyncRequestIdFB requestId,
    XrSpaceQueryResultsFB* results
);
See an example usage in the Event section below.
Parameters
  • session: A XrSession for the current application instance.
  • requestId: The XrAsyncRequestIdFB request ID for which results are being retrieved.
  • results: A pointer to the XrSpaceQueryResultsFB struct where the query results will be stored.

Structs

This section provides an overview of the key structs used in the API.
XrSpaceQueryInfoFB
This struct is used to query for spaces. The filter info provided to the filter member of the struct will be used as an inclusive list of filters. All spaces that match these criteria will be included in the results returned.
Suggested filters:
  • XR_TYPE_SPACE_STORAGE_LOCATION_FILTER_INFO_FB
  • XR_TYPE_SPACE_UUID_FILTER_INFO_FB
static const XrStructureType XR_TYPE_SPACE_QUERY_INFO_FB = (XrStructureType)1000156001;
typedef struct XrSpaceQueryInfoFB {
  XrStructureType type;
  const void* XR_MAY_ALIAS next;
  XrSpaceQueryActionFB queryAction;
  uint32_t maxResultCount;
  XrDuration timeout;
  const XrSpaceFilterInfoBaseHeaderFB* filter;
  const XrSpaceFilterInfoBaseHeaderFB* excludeFilter;
} XrSpaceQueryInfoFB;
Note
The `excludeFilter` field is ignored. Additionally, the `XrSpaceQueryActionFB queryAction` field should always be set to `XR_SPACE_QUERY_ACTION_LOAD_FB`.
XrSpaceQueryResultFB
This struct is a single query result to be returned in the results array of xrRetrieveSpaceQueryResultsFB. No type or next pointer is included to save space in the results array.
typedef struct XrSpaceQueryResultFB {
  XrSpace space;
  XrUuidEXT uuid;
} XrSpaceQueryResultFB;
XrSpaceQueryResultsFB
static const XrStructureType XR_TYPE_SPACE_QUERY_RESULTS_FB = (XrStructureType)1000156002;
typedef struct XrSpaceQueryResultsFB {
  XrStructureType type;
  const void* XR_MAY_ALIAS next;
  uint32_t resultCapacityInput;
  uint32_t resultCountOutput;
  XrSpaceQueryResultFB* results;
} XrSpaceQueryResultsFB;

Events

This section provides an overview of the key events used in the API.

XrEventDataSpaceQueryResultsAvailableFB

Indicates that there will be results retrievable from a Query operation upon a call to xrRetrieveSpaceQueryResultsFB.
static const XrStructureType XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB =
    (XrStructureType)1000156103;
typedef struct XrEventDataSpaceQueryResultsAvailableFB {
  XrStructureType type;
  const void* XR_MAY_ALIAS next;
  XrAsyncRequestIdFB requestId;
} XrEventDataSpaceQueryResultsAvailableFB;

XrEventDataSpaceQueryCompleteFB

For the Complete event, that indicates that query is finished and no more Results Available events should be returned for this query operation.
static const XrStructureType XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB =
    (XrStructureType)1000156104;
typedef struct XrEventDataSpaceQueryCompleteFB {
  XrStructureType type;
  const void* XR_MAY_ALIAS next;
  XrAsyncRequestIdFB requestId;
  XrResult result;
} XrEventDataSpaceQueryCompleteFB;

Example of handling anchor query events

You can choose to retrieve the query results after receiving a Results Available event, or after receiving a Complete event. In this example, it’s done during the Results Available event.
// Called per-frame
void handleOpenXrAnchorEvents() {
    XrEventDataBuffer eventDataBuffer = {};
    // Poll for events.
    while (true) {
        XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
        baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
        baseEventHeader->next = nullptr;
        XrResult result = xrPollEvent(instance, &eventDataBuffer);
        if (result != XR_SUCCESS) {
            // Handle any errors
        }
        ...
        if (baseEventHeader->type == XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB) {
            const XrEventDataSpaceQueryCompleteFB* completeEvent =
                (XrEventDataSpaceQueryCompleteFB*)(baseEventHeader);
            if (completeEvent->result < XR_SUCCESS) {
                // Handle any errors
            }
        } else if (baseEventHeader->type == XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB) {
            const XrEventDataSpaceQueryResultsAvailableFB* querySpacesResultsAvailable =
                (XrEventDataSpaceQueryResultsAvailableFB*)baseEventHeader;

            XrResult res = XR_SUCCESS;
            XrSpaceQueryResultsFB queryResults{XR_TYPE_SPACE_QUERY_RESULTS_FB};
            queryResults.resultCapacityInput = 0;
            queryResults.resultCountOutput = 0;
            queryResults.results = nullptr;

            // First call in the two-call idiom
            res = xrRetrieveSpaceQueryResultsFB(
                openXrSession, querySpacesResultsAvailable->requestId, &queryResults);
            if (res < XR_SUCCESS) {
                // Handle any errors
            }

            // Second call in the two-call idiom
            std::vector<XrSpaceQueryResultFB> results(queryResults.resultCountOutput);
            queryResults.resultCapacityInput = results.size();
            queryResults.results = results.data();
            res = xrRetrieveSpaceQueryResultsFB(
                openXrSession, querySpacesResultsAvailable->requestId, &queryResults);
            if (res < XR_SUCCESS || queryResults.resultCountOutput < results.size()) {
                // Handle any errors
            }

            // Do things with the anchor(s)! Insert App magic here
        }
        ...
    }
}

Standard XrResult values

The following are standard XrResult values that can be returned from the synchronous API call:
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_SESSION_NOT_RUNNING
  • XR_SUCCESS

Sharing extension and API overview

Currently, we provide two options for sharing:
  • [Recommended] Group Sharing - Apps can share spatial entities with any app provided “Group UUID”. Other users running the same app can then query for spatial entities shared with the Group UUID. This option does not require integration with Oculus User IDs, and hence should be simpler for developers. This option is provided by the XR_META_spatial_entity_sharing and XR_META_spatial_entity_group_sharing extensions.
  • User Sharing - Apps can share spatial entities with specific Oculus User IDs. This option is provided by the XR_FB_spatial_entity_sharing extension and xrShareSpacesFB. Given xrShareSpaceFB’s dependency on XrSpaceUserFB, apps will need to retreive Oculus User IDs and exchange them for this option. For more information on User Sharing, please see the XR_FB_spatial_entity_sharing section below.

XR_META_spatial_entity_sharing overview

The XR_META_spatial_entity_sharing extension enables applications to share spatial entities.
XR_META_spatial_entity_sharing itself is a base extension that provides a generic space sharing endpoint. This extension depends on other extensions (such as XR_META_spatial_entity_group_sharing) to define concrete “recipient info” structures, which are passed into the generic xrShareSpacesMETA endpoint introduced in this extension.
Prerequisites for the Share API to be successful:
  • Android manifest permission IMPORT_EXPORT_IOT_MAP_DATA: For more information, see Developer Environment Setup.
  • End user enabled Share Point Cloud Data permission: End users need to have opted-in to Share Point Cloud Data with Meta. This is a system-permission and a popup should appear for them.

APIs

For more information on the API signatures and runtime guarantees, see the OpenXR Specification.

xrShareSpacesMETA

The xrShareSpacesMETA function shares the provided spatial entities with the recipient specified. This function will return an error if the share call fails.
XRAPI_ATTR XrResult XRAPI_CALL xrShareSpacesMETA(
    XrSession session,
    const XrShareSpacesInfoMETA* info,
    XrAsyncRequestIdFB* requestId
);
Parameters
  • session: The XrSession object representing the current XR session.
  • info: A pointer to the XrShareSpacesInfoMETA struct containing the spatial entities to be shared and the recipient to share them with.
  • requestId: An XrAsyncRequestIdFB atom that represents the request ID for the share operation for async event handling.
  • Synchronous Returns: The xrShareSpacesMETA function returns an XrResult indicating the success or failure of triggering the async operation.
  • Asynchronous Returns: The async event will be returned as a callback, and that struct contains another XrResult, indicating the success or failure of the operation as a whole.
XrResult result = xrShareSpacesMETA(session, &info, &requestId);
if (XR_SUCCESS == result) {
    // Share operation was successfully triggered.
} else {
    // Share operation failed to trigger.
}

Structs

/**
 * Structure representing the anchor and recipient information used for sharing.
 */
typedef struct XrShareSpacesInfoMETA {
  XrStructureType type; // XR_TYPE_SHARE_SPACES_INFO_META
  const void* XR_MAY_ALIAS next;
  uint32_t spaceCount;
  XrSpace* spaces;
  const XrShareSpacesRecipientBaseHeaderMETA* recipientInfo;
} XrShareSpacesInfoMETA;

/**
 * Group Sharing structure which extends the
 * XrShareSpacesRecipientBaseHeaderMETA base type
 */
typedef struct XrShareSpacesRecipientGroupsMETA {
    XrStructureType type; // XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META
    const void* XR_MAY_ALIAS next;
    uint32_t groupCount;
    XrUuid* groups;
} XrShareSpacesRecipientGroupsMETA;

/**
 * Structure representing the asynchronous event returned by the share operation including an XrResult.
 */
typedef struct XrEventDataShareSpacesCompleteMETA {
  XrStructureType type; // XR_TYPE_EVENT_DATA_SHARE_SPACES_COMPLETE_META
  const void* XR_MAY_ALIAS next;
  XrAsyncRequestIdFB requestId;
  XrResult result;
} XrEventDataShareSpacesCompleteMETA;

Events

  • XR_TYPE_EVENT_DATA_SHARE_SPACES_COMPLETE_META
An example showing how to handle the anchor sharing event follows:
// Called per-frame
void handleOpenXrAnchorEvents() {
    XrEventDataBuffer eventDataBuffer = {};
    // Poll for events.
    while (true) {
        XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
        baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
        baseEventHeader->next = nullptr;
        XrResult result = xrPollEvent(instance, &eventDataBuffer);
        if (result != XR_SUCCESS) {
            break;
        }
        ...
        if (baseEventHeader->type == XR_TYPE_EVENT_DATA_SHARE_SPACES_COMPLETE_META) {
            const XrEventDataShareSpacesCompleteMETA* shareResult =
                (XrEventDataShareSpacesCompleteMETA*)(baseEventHeader);
            if (shareResult->result < XR_SUCCESS) {
                // Handle errors
            }
            // Optionally communicate the UUID of the shared anchors to the recipients
        }
        ...
    }
}

Standard XrResult values

The following are standard XrResult values that can be returned from the synchronous API call:
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_SESSION_NOT_RUNNING
  • XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_INITIALIZATION_FAILED
  • XR_SUCCESS

Anchor-specific asynchronous XrResults for Sharing

  • XR_SUCCESS
  • XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB: Cloud storage is required for this operation but is currently disabled. Ensure that the end-user has Share Point Cloud Data with Meta permission enabled.
  • XR_ERROR_SPACE_NETWORK_TIMEOUT_FB: Timeout occurred while waiting for network request to complete.
  • XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB: The network request failed.
  • XR_ERROR_SPACE_MAPPING_INSUFFICIENT_FB: Anchor export from device failed.
  • XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB: The required component is not enabled for this space. If the Sharing component is not enabled on an entity and Share is attempted for that entity, this will be returned.

    XR_META_spatial_entity_group_sharing overview

The XR_META_spatial_entity_group_sharing extension, when used with XR_META_spatial_entity_sharing and XR_FB_spatial_entity_query, enables applications to share spatial entities with an app defined “group UUID”.
XR_META_spatial_entity_group_sharing itself provides concrete “recipient” info structure which can be passed into xrShareSpacesMETA, as well as an XrSpaceGroupUuidFilterInfoMETA struct which can be passed into xrQuerySpacesFB to retrieve the shared spatial entities from the group.
Applications can share spatial entities with any application provided group UUID. Applications can randomly generate this UUID themselves, or reuse a UUID from another external source. Once spatial entities are successfully shared with a Group UUID, they will be continue to be retrievable for a limited time. Group UUIDs are scoped to the application. If multiple applications attempt to share spatial entities with the same Group UUID, each application will only be able to retrieve the spatial entities they themselves shared.
Note
Don't use shared anchors as an alternative to saving anchors. To re-use shared anchors across multiple sessions, save the anchor before sharing, and re-share the anchor in subsequent sessions to a new group UUID.

APIs

Structs

/**
 * Group Sharing structure which extends the
 * XrShareSpacesRecipientBaseHeaderMETA base type
 */
typedef struct XrShareSpacesRecipientGroupsMETA {
    XrStructureType type; // XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META
    const void* XR_MAY_ALIAS next;
    uint32_t groupCount;
    XrUuid* groups;
} XrShareSpacesRecipientGroupsMETA;
Here is a simple example of how to share an anchor with a Group UUID:
XrUuidEXT groupuuid = GenerateRandomGroupUUID();

XrShareSpacesRecipientGroupsMETA recipientGroupInfo = {
    XR_TYPE_SHARE_SPACES_RECIPIENT_GROUPS_META, nullptr};
recipientGroupInfo.groupCount = 1;
recipientGroupInfo.groups = &groupuuid;

XrShareSpacesInfoMETA info = {XR_TYPE_SHARE_SPACES_INFO_META};
info.spaceCount = 1;
info.spaces = &anchor;

info.recipientInfo = (const XrShareSpacesRecipientBaseHeaderMETA*)&recipientGroupInfo;

XrAsyncRequestIdFB requestId;
XrResult res = xrShareSpacesMETA(openXrSession_, &info, &requestId);

XR_FB_spatial_entity_sharing overview

The XR_FB_spatial_entity_sharing extension enables applications to share spatial entities with other user ids using Meta cloud infrastructure.
Prerequisites for the Share API to be successful:
  • Android manifest permission IMPORT_EXPORT_IOT_MAP_DATA: For more information, see Developer Environment Setup.
  • End user enabled Enhanced Spatial Services permission: End users need to have opted into the Enhanced Spatial Services permission when prompted.

APIs

For more information on the API signatures and runtime guarantees, see the OpenXR Specification.

xrShareSpacesFB

The xrShareSpacesFB function shares the provided anchors with the users specified. This function will return an error if the share call fails.
XRAPI_ATTR XrResult XRAPI_CALL xrShareSpacesFB(
    XrSession session,
    const XrSpaceShareInfoFB* info,
    XrAsyncRequestIdFB* requestId
);
Parameters
  • session: The XrSession object representing the current XR session.
  • info: A pointer to the XrSpaceShareInfoFB struct containing the spatial entities to be shared and the users to share them with.
  • requestId: An XrAsyncRequestIdFB atom that represents the request ID for the share operation for async event handling.
  • Synchronous Returns: The xrShareSpacesFB function returns an XrResult indicating the success or failure of triggering the async operation.
  • Asynchronous Returns: The async event will be returned as a callback, and that struct contains another XrResult, indicating the success or failure of the operation as a whole.
XrResult result = xrShareSpacesFB(session, &info, &requestId);
if (XR_SUCCESS == result)
{
    // Share operation was successfully triggered.
} else {
    // Share operation failed to trigger.
}

Structs

/**
 * Structure representing the anchor and user information used for sharing.
 */
typedef struct XrSpaceShareInfoFB {
  XrStructureType type; // XR_TYPE_SPACE_SHARE_INFO_FB
  const void* XR_MAY_ALIAS next;
  uint32_t spaceCount;
  XrSpace* spaces;
  uint32_t userCount;
  XrSpaceUserFB* users;
} XrSpaceShareInfoFB;

/**
 * Structure representing the asynchronous event returned by the share operation including an XrResult.
 */
typedef struct XrEventDataSpaceShareCompleteFB {
  XrStructureType type; // XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB
  const void* XR_MAY_ALIAS next;
  XrAsyncRequestIdFB requestId;
  XrResult result;
} XrEventDataSpaceShareCompleteFB;

Events

  • XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB
An example showing how to handle the anchor sharing event follows:
// Called per-frame
void handleOpenXrAnchorEvents() {
    XrEventDataBuffer eventDataBuffer = {};
    // Poll for events.
    while (true) {
        XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
        baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
        baseEventHeader->next = nullptr;
        XrResult result = xrPollEvent(instance, &eventDataBuffer);
        if (result != XR_SUCCESS) {
            break;
        }
        ...
        if (baseEventHeader->type == XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB) {
            const XrEventDataSpaceShareCompleteFB* shareResult =
                (XrEventDataSpaceShareCompleteFB*)(baseEventHeader);
            if (shareResult->result < XR_SUCCESS) {
                // Handle errors
            }
            // Optionally communicate the UUID of the shared anchors to the recipients
        }
        ...
    }
}

Standard XrResult values

The following are standard XrResult values that can be returned from the synchronous API call:
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_SESSION_NOT_RUNNING
  • XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_INITIALIZATION_FAILED
  • XR_SUCCESS

Anchor-specific asynchronous XrResults for Sharing

  • XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB: Cloud storage is required for this operation but is currently disabled. Ensure that the end-user has Enhanced Spatial Services permission enabled.
  • XR_ERROR_SPACE_NETWORK_TIMEOUT_FB: Timeout occurred while waiting for network request to complete.
  • XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB: The network request failed.
  • XR_ERROR_SPACE_MAPPING_INSUFFICIENT_FB: Anchor export from device failed.
  • XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB: The required component is not enabled for this space. If the Sharing component is not enabled on an entity and Share is attempted for that entity, this will be returned.
  • XR_SUCCESS

Errors/result codes

This section provides an overview of the two XrResult outcomes associated with Asynchronous API calls.
  • Initial Synchronous XrResult: This is the XrResult returned directly from the function signature. This XrResult informs whether the API call was initiated successfully or if an issue with the session or input occurred.
  • Final Asynchronous XrResult: This is found in the returned struct and indicates the internal operational status. Ideally it should provide informative, actionable details, such as whether the API call needs to be retried.
Note
Warnings are > `XR_SUCCESS` == 0. A warning is a qualified success, and may provide informative information about the operation.

Known Issues

Shared Spatial Anchor Querying and Alignment

This document outlines two known issues that may occur when querying or aligning shared spatial anchor. It provides repro steps and mitigation strategies to help resolve these issues.
Issue 1 - Guest Device Unable to Query Shared Spatial Anchor
  • Repro Steps
    • Host device: Calls xrShareSpacesMETA to share an Spatial Anchor to a group, or calls xrShareSpacesFB to share an Spatial Anchor to a user.
    • Guest device: Calls xrQuerySpacesFB to query the shared Spatial Anchor.
    • Guest device: May observe that xrQuerySpacesFB does not return the Spatial Anchor shared from the host
  • Mitigation To increase the chances of the guest device being able to query the shared Spatial Anchor, follow these steps:
    • On the host device, before calling xrShareSpacesMETA or xrShareSpacesFB, try to have the device move around more in the area where the Spatial Anchor is created.
    • On the guest device, before calling xrQuerySpacesFB, also try to have the device move around more in the area where the host device created the Spatial Anchor.
    By doing so, both devices will map a more complete and accurate spatial data around the same physical area where the Spatial Anchor is created, which can improve the chances of successful Spatial Anchor querying.
Issue 2 - Misaligned Spatial Anchor on guest device
  • Repro Steps
    • Host device: Calls xrShareSpacesMETA to share an Spatial Anchor to a group, or calls xrShareSpacesFB to share an Spatial Anchor to a user.
    • Guest device: Calls xrQuerySpacesFB to query the shared Spatial Anchor.
    • Guest device: Observes that the orinetation or location of the Spatial Anchor is shifted compared to the one created by the host.
  • Mitigation To resolve the misalignment issue, follow these steps on the guest device:
    • On the guest device, go to Settings > Privacy > Device Permissions > Clear Physical Space History
    • On the guest device, restart the app and call xrQuerySpacesFB again. If the Spatial Anchor cannot be queryed in this step, try to restart the guest device, start the app and call xrQuerySpacesFB again.
    By clearing the physical space history and restarting device, you can ensure that the guest device reloads the shared Spatial Anchor with the correct alignment.
Did you find this page helpful?
Thumbs up icon
Thumbs down icon