Create anchors with ARCore for Jetpack XR

Applicable XR devices
This guidance helps you build experiences for these types of XR devices.
XR Headsets
Wired XR Glasses

An anchor describes a location and orientation in the real world. Attaching an object to an anchor helps objects appear realistically placed in the real world and helps your app save power by not having to run logic every frame.

Access a session

Create anchors through an ARCore for Jetpack XR Session. If you're enhancing spatial UI using Jetpack Compose for XR, access a session from Jetpack Compose for XR. If you're working with spatialized entities from the Jetpack SceneCore library, access a session from Jetpack XR Runtime.

Configure the session

Creating and loading anchors does not require the session to be configured. However, anchor persistence is not enabled by default on XR sessions. To persist and load anchors from local storage, configure the session and set the AnchorPersistenceMode.LOCAL mode:

val newConfig = Config.Builder(session.config)
    .setAnchorPersistence(AnchorPersistenceMode.LOCAL)
    .build()
when (val result = session.configure(newConfig)) {
    is SessionConfigureSuccess -> TODO(/* Success! */)
    else ->
        TODO(/* The session could not be configured. See SessionConfigureResult for possible causes. */)
}

Anchor content to a location in space

An anchor is created using a Pose, which can be interpreted relative to an existing Anchorable or fixed in the world. An Anchorable is a Trackable that can have anchors attached to it.

Create an anchor relative to an Anchorable

When an anchor is created relative to an Anchorable, such as a Plane, this makes the anchor follow the attached Anchorable when it moves through space.

val anchor = plane.createAnchor(pose)

Create an anchor fixed in the world

To create an anchor that's fixed in the world, don't attach it to an Anchorable. Only use this type of anchor for points that are floating in space because the session's estimate of where immovable objects are changes over time:

val anchor = Anchor.create(session, pose)

Attach an entity to an anchor

To render a model at this location, create a GltfModel and set its parent to an AnchorSpace.

AnchorSpace.create(session, anchor).apply {
    parent = session.scene.activitySpace
    addChild(entity)
}

Understand TrackingState

Each Trackable has a TrackingState that should be checked before being used. A Trackable that has a TrackableState of Tracking has its Pose actively updated by the system. A Trackable that is Paused may become Tracking in the future, whereas one that is Stopped will never become Tracking.

Persist an Anchor throughout sessions

An anchor that is not persisted disappears after a session is destroyed. By persisting an anchor, your app remembers that anchor's position in its private app data. This anchor can be retrieved in a subsequent session and is anchored in the same location in the world.

To persist an anchor, use Anchor.persist() as shown here:

val uuid = anchor.persist()

Your app can retrieve the anchor by using the UUID in a future session:

when (val result = Anchor.load(session, uuid)) {
    is AnchorCreateSuccess -> {
        // Loading was successful. The anchor is stored in result.anchor.
    }
    else -> {
        // handle failure
    }
}

When you don't need an anchor anymore, call unpersist(). This removes the anchor from your app's storage and makes the given UUID unretrievable for calls to Anchor.load().

Anchor.unpersist(session, uuid)

Your app can also request a list of all anchors that have been persisted that are still present in your app's storage:

val uuids = Anchor.getPersistedAnchorUuids(session)