XR_ML_spatial_anchors
This API is still an experimental extension not included in the official OpenXR registry and is subject to change.
12.109. XR_ML_spatial_anchors
- Name String
- XR_ML_spatial_anchors
- Extension Type
- Instance extension 
- Registered Extension Number
- 141 
- Revision
- 1 
- Extension and Version Dependencies
- Last Modified Date
- 2023-06-09 
- Contributors
- Ron Bessems, Magic Leap 
 Karthik Kadappan, Magic Leap
12.109.1. Overview
Spatial anchors are XrSpace entities tied to a physical location. This allows the developer to place virtual content in real world locations.
The runtime should then adjust the XrSpace over time as needed, independently of all other spaces and anchors, to ensure that it maintains its original mapping to the real world.
| Caution If head pose is lost and regained, spatial anchors may also be lost. It is therefore strongly recommended that once an anchor is created, it is also persisted using the  | 
| Permissions Android applications must have the com.magicleap.permission.SPATIAL_ANCHOR permission listed in their manifest to use this extension. (protection level: normal) | 
12.109.2. Begin spatial anchor creation
xrCreateSpatialAnchorsAsyncML is used to create spatial anchors. It can create anchors in different ways depending on the parameter passed in. This extension defines one way to create single anchors using theXrSpatialAnchorsCreateInfoFromPoseML structure.XR_ML_spatial_anchors_storage
The xrCreateSpatialAnchorsAsyncML function is defined as:
// Provided by XR_ML_spatial_anchors
XrResult xrCreateSpatialAnchorsAsyncML(
    XrSession                                   session,
    const XrSpatialAnchorsCreateInfoBaseHeaderML* createInfo,
    XrFutureEXT*                                future);This function starts an asynchronous spatial anchor creation. Call one of the xrPollFutureEXT functions to check the ready state on the future. Once the future is in ready state, callxrCreateSpatialAnchorsCompleteML to retrieve the results.
The XrSpatialAnchorsCreateInfoFromPoseML structure can be used to create an spatial anchor from a pose in an XrSpace.
// Provided by XR_ML_spatial_anchors
typedef struct XrSpatialAnchorsCreateInfoFromPoseML {
    XrStructureType    type;
    const void*        next;
    XrSpace            baseSpace;
    XrPosef            poseInBaseSpace;
    XrTime             time;
} XrSpatialAnchorsCreateInfoFromPoseML;Note that xrCreateSpatialAnchorsCompleteML must be called withXrCreateSpatialAnchorsCompletionML::spaceCount set to 1 when using XrSpatialAnchorsCreateInfoFromPoseML to create a spatial anchor.
The base structure for XrSpatialAnchorsCreateInfoFromPoseML isXrSpatialAnchorsCreateInfoBaseHeaderML.
The XrSpatialAnchorsCreateInfoBaseHeaderML structure is defined as:
// Provided by XR_ML_spatial_anchors
typedef struct XrSpatialAnchorsCreateInfoBaseHeaderML {
    XrStructureType    type;
    const void*        next;
} XrSpatialAnchorsCreateInfoBaseHeaderML;This structure is not directly used in the API, please seeXrSpatialAnchorsCreateInfoFromPoseML for an example of a child structure.
12.109.3. Complete spatial anchor operation
xrCreateSpatialAnchorsCompleteML completes the asynchronous operation started by xrCreateSpatialAnchorsAsyncML. The XrFutureEXT must be in ready state before calling the completion function.
The xrCreateSpatialAnchorsCompleteML function is defined as:
// Provided by XR_ML_spatial_anchors
XrResult xrCreateSpatialAnchorsCompleteML(
    XrSession                                   session,
    XrFutureEXT                                 future,
    XrCreateSpatialAnchorsCompletionML*         completion);The completion structure is XrCreateSpatialAnchorsCompletionML.
The XrCreateSpatialAnchorsCompletionML structure is defined as:
// Provided by XR_ML_spatial_anchors
typedef struct XrCreateSpatialAnchorsCompletionML {
    XrStructureType    type;
    void*              next;
    XrResult           futureResult;
    uint32_t           spaceCount;
    XrSpace*           spaces;
} XrCreateSpatialAnchorsCompletionML;12.109.4. Retrieve spatial anchor state
Spatial anchor state can be queried using xrGetSpatialAnchorStateML.
The xrGetSpatialAnchorStateML function is defined as:
// Provided by XR_ML_spatial_anchors
XrResult xrGetSpatialAnchorStateML(
    XrSpace                                     anchor,
    XrSpatialAnchorStateML*                     state);The runtime must return XR_ERROR_VALIDATION_FAILURE if theXrSpace is not an spatial anchor.
The XrSpatialAnchorStateML structure is defined as:
// Provided by XR_ML_spatial_anchors
typedef struct XrSpatialAnchorStateML {
    XrStructureType                type;
    void*                          next;
    XrSpatialAnchorConfidenceML    confidence;
} XrSpatialAnchorStateML;// Provided by XR_ML_spatial_anchors
typedef enum XrSpatialAnchorConfidenceML {
    XR_SPATIAL_ANCHOR_CONFIDENCE_LOW_ML = 0,
    XR_SPATIAL_ANCHOR_CONFIDENCE_MEDIUM_ML = 1,
    XR_SPATIAL_ANCHOR_CONFIDENCE_HIGH_ML = 2,
    XR_SPATIAL_ANCHOR_CONFIDENCE_MAX_ENUM_ML = 0x7FFFFFFF
} XrSpatialAnchorConfidenceML;| Enum | Description | 
|---|---|
| 
 | Low quality, this anchor can be expected to move significantly. | 
| 
 | Medium quality, this anchor may move slightly. | 
| 
 | High quality, this anchor is stable and suitable for digital content attachment. | 
12.109.5. Example code
This code shows how to create a spatial anchor in a synchronous manner. This can be changed to be completely asynchronous by changing thewaitInfo.duration to 0 and checking it during the frame loop until the function returns ready.
XrInstance instance;                // previously initialized
XrSession session;                  // previously initialized
// these are setup to match the location and time
// of the position in the world you wish to set the
// spatial anchor for.
XrSpace baseSpace;                  // previously initialized
XrTime time;                        // previously initialized
XrPosef pose;                       // previously initialized
// Get function pointer for xrCreateSpatialAnchorsAsyncML
PFN_xrCreateSpatialAnchorsAsyncML xrCreateSpatialAnchorsAsyncML;
CHK_XR(xrGetInstanceProcAddr(instance, "xrCreateSpatialAnchorsAsyncML",
                             reinterpret_cast<PFN_xrVoidFunction*>(
                             &xrCreateSpatialAnchorsAsyncML)))
// Get function pointer for xrCreateSpatialAnchorsCompleteML
PFN_xrCreateSpatialAnchorsCompleteML xrCreateSpatialAnchorsCompleteML;
CHK_XR(xrGetInstanceProcAddr(instance, "xrCreateSpatialAnchorsCompleteML",
                             reinterpret_cast<PFN_xrVoidFunction*>(
                             &xrCreateSpatialAnchorsCompleteML)));
// Get function pointer for xrPollFutureEXT
PFN_xrPollFutureEXT xrPollFutureEXT;
CHK_XR(xrGetInstanceProcAddr(instance, "xrPollFutureEXT",
                             reinterpret_cast<PFN_xrVoidFunction*>(
                             &xrPollFutureEXT)));
XrSpatialAnchorsCreateInfoFromPoseML createInfo{XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML};
XrFutureEXT future;
createInfo.baseSpace = baseSpace;
createInfo.poseInBaseSpace = pose;
createInfo.time = time;
CHK_XR(xrCreateSpatialAnchorsAsyncML(session, reinterpret_cast<const XrSpatialAnchorsCreateInfoBaseHeaderML*>(&createInfo), &future));
XrFuturePollInfoEXT pollInfo{XR_TYPE_FUTURE_POLL_INFO_EXT};
XrFuturePollResultEXT pollResult{XR_TYPE_FUTURE_POLL_RESULT_EXT};
pollInfo.future = future;
pollResult.state = XR_FUTURE_STATE_PENDING_EXT;
while(pollResult.state==XR_FUTURE_STATE_PENDING_EXT) {
  // Ideally this check is done in your game loop
  // instead of busy waiting, this is just an
  // example.
  // If you do choose busy wait sleep to avoid
  // CPU overloading.
  CHK_XR(xrPollFutureEXT(instance, &pollInfo, &pollResult));
}
XrSpace anchor;
XrCreateSpatialAnchorsCompletionML completion{XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML};
completion.spaceCount = 1;
completion.spaces = &anchor;
CHK_XR(xrCreateSpatialAnchorsCompleteML(session, future, &completion));
// Check the future completion result as well!
CHK_XR(completion.futureResult);
// Now the anchor is usable!12.109.9. New Enum Constants
- XR_ML_SPATIAL_ANCHORS_EXTENSION_NAME
- XR_ML_spatial_anchors_SPEC_VERSION
- Extending XrResult: - XR_ERROR_SPATIAL_ANCHORS_NOT_LOCALIZED_ML
- XR_ERROR_SPATIAL_ANCHORS_OUT_OF_MAP_BOUNDS_ML
- XR_ERROR_SPATIAL_ANCHORS_PERMISSION_DENIED_ML
- XR_ERROR_SPATIAL_ANCHORS_SPACE_NOT_LOCATABLE_ML
 
- Extending XrStructureType: - XR_TYPE_CREATE_SPATIAL_ANCHORS_COMPLETION_ML
- XR_TYPE_SPATIAL_ANCHORS_CREATE_INFO_FROM_POSE_ML
- XR_TYPE_SPATIAL_ANCHOR_STATE_ML