Spatial Anchors OpenXR API Reference
Updated: May 29, 2024
Spatial entity extension and API 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:
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
.
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.
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
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
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
Failure
XR_ERROR_FUNCTION_UNSUPPORTED
XR_ERROR_HANDLE_INVALID
The xrCreateSpatialAnchorFB
function asynchronously creates a spatial anchor
using the specified tracking origin and pose, relative to the specified tracking
origin. The anchor will be locatable at the time of creation, and you can query
the 6 DOF pose, relative to the tracking origin, using the xrLocateSpace
method.
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
Failure
XR_ERROR_FUNCTION_UNSUPPORTED
XR_ERROR_HANDLE_INVALID
XR_ERROR_VALIDATION_FAILURE
XR_ERROR_RUNTIME_FAILURE
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.
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.
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
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.
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.
}
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.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.
}
/**
* 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;
};
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 {
...
}
}
...
}
}
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
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.
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.
}
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
);
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.
This section provides an overview of the key structs used in the API.
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;
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;
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;
This section provides an overview of the key events used in the API.
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;
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
}
...
}
...
}
}
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.
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
);
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.
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;
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
}
...
}
}
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.
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.
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.
}
/**
* 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;
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
}
...
}
}
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.
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 retrievable for 30 days. 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.
/**
* 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.
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.
}
/**
* 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;
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
}
...
}
}
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
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.