1. Introduction
WebXR Anchors module enables applications to ask the underlying XR system to track changes to a particular three-dimensional pose (position and orientation) as the system’s understanding of the world changes. This allows the application to adjust the location of the virtual objects that it placed in the scene in a way that helps with maintaining the illusion that the placed objects are really present in the user’s environment.
1.1. Terminology
Pose, as understood by this document, signifies a position and orientation in 3D space.
Anchor, as understood by this document, is an entity that keeps track of the pose that is fixed relative to the real world, and is created by the application.
2. Initialization
2.1. Feature descriptor
In order for the applications to signal their interest in using anchors during a session, the session must be requested with appropriate feature descriptor . The string anchors is introduced by this module as a new valid feature descriptor for anchors feature.
A
device
is
capable
of
supporting
the
anchors
feature
if
the
device’s
tracking
system
exposes
a
native
anchors
capability.
The
inline
XR
device
MUST
NOT
be
treated
as
capable
of
supporting
the
anchors
feature.
The
user
agents
SHOULD
attempt
to
support
anchors
feature
for
sessions
with
mode
equal
to
"immersive-ar"
.
Note:
Even
though
anchors
feature
support
is
not
required,
anchors
are
one
of
the
basic
features
needed
by
the
AR-enabled
applications
to
provide
good
user
experience.
Therefore,
it
is
*highly*
recommended
that
the
user
agents
support
them
for
"immersive-ar"
sessions.
3. Anchors
3.1. XRAnchor
In only one current engine.
Opera ? Edge 85+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
In only one current engine.
Opera ? Edge 85+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
In only one current engine.
Opera ? Edge 85+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
[SecureContext ,Exposed =Window ]interface {XRAnchor readonly attribute XRSpace ;anchorSpace Promise <DOMString >();requestPersistentHandle undefined (); };delete
An
XRAnchor
contains
anchorSpace
that
can
be
used
to
locate
the
anchor
relative
to
other
XRSpaces
.
If
this
attribute
is
accessed
when
deleted
is
set
to
true
,
the
user
agent
MUST
throw
an
InvalidStateError
.
Each
XRAnchor
has
an
associated
deleted
boolean
value
that
is
initially
set
to
false
.
Each
XRAnchor
has
an
associated
native
origin
.
Each
XRAnchor
has
an
associated
session
.
-
Let anchor be a new
XRAnchor. -
Set anchor ’s native origin to native origin .
-
Set anchor ’s session to session .
-
Set anchor ’s deleted to
false. -
Set anchor ’s
anchorSpaceto a newXRSpaceobject created with session set to anchor ’s session and native origin set to native origin . -
Return anchor .
requestPersistentHandle()
method,
when
invoked
on
an
XRAnchor
anchor
,
MUST
run
the
following
steps:
-
Let promise be a new Promise in the relevant realm of this
XRSystem. -
If anchor ’s deleted is
true, reject promise withInvalidStateError, return promise , and abort these steps. -
Let session be anchor ’s session .
-
If session ’s map of persistent anchors contains the value anchor , run the following steps:
-
Let uuid be the key of the mapping of the anchor value on session ’s map of persistent anchors .
-
Resolve promise with uuid .
-
Return promise .
-
Abort these steps.
-
-
Let uuid be the empty string.
-
Generate a UUID [RFC4122] as a string and append it to uuid .
-
Add uuid and anchor to session ’s map of persistent anchors .
-
Resolve promise with uuid .
-
Return promise .
Note:
when
the
XRSystem
creates
the
unique
ID,
it
MUST
be
unique
and
only
known
to
the
current
origin.
4. Anchor creation
The
XRSession
is
extended
to
contain
an
associated
set
of
tracked
anchors
.
The
XRSession
is
extended
to
contain
an
associated
map
of
persistent
anchors
that
is
keyed
with
a
UUID
string
and
maps
to
an
XRAnchor
.
The
size
of
this
map
is
determined
by
the
user
agent.
The
user
agent
MAY
delete
entries
from
this
map
for
any
reason.
For
instance,
if
the
maximum
number
of
system
anchors
is
reached
for
all
maps
for
all
origins,
the
user
agent
MAY
free
up
an
entry
to
make
space
for
the
newly
requested
anchor.
The
XRSession
is
extended
to
contain
an
associated
map
of
new
anchors
that
is
keyed
with
XRAnchor
object
and
maps
to
object.
Promise
<
XRAnchor
>
In only one current engine.
Opera ? Edge 85+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
In only one current engine.
Opera ? Edge 85+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
partial interface XRFrame {Promise <XRAnchor >(createAnchor XRRigidTransform ,pose XRSpace ); };space partial interface XRSession {Promise <XRAnchor >(restorePersistentAnchor DOMString );uuid Promise <undefined >(deletePersistentAnchor DOMString ); };uuid partial interface XRHitTestResult {Promise <XRAnchor >(); };createAnchor
The
XRHitTestResult
is
extended
to
contain
an
associated
native
entity
.
If
the
underlying
system
does
not
provide
information
about
native
entity
that
resulted
in
computing
the
result,
it
will
be
assumed
that
native
entity
is
set
to
null
.
The application can create an anchor using one of the 2 ways:
-
By creating an anchor from frame - created anchor will not be attached to any particular real world object.
-
By creating an anchor from hit test result - created anchor will be attached to a real world object if the underlying XR device supports it.
In
order
to
create
an
anchor
from
frame
,
the
application
can
call
XRFrame
's
createAnchor(pose,
space)
method.
createAnchor(pose,
space)
method,
when
invoked
on
an
XRFrame
frame
with
pose
and
space
,
MUST
run
the
following
steps:
-
Let promise be a new Promise .
-
If frame ’s active boolean is
false, reject promise withInvalidStateError, return promise , and abort these steps. -
Let session be frame ’s session .
-
Add update anchors algorithm to session ’s list of frame updates if it is not already present there.
-
Let device be session ’s XR device .
-
Let effective origin be space ’s effective origin .
-
Let anchor native origin be a new native origin returned from the device ’s call to create a new anchor using pose , interpreted as if expressed relative to effective origin at the frame ’s time .
-
Create new anchor object anchor using anchor native origin and session .
-
Add anchor to session ’s set of tracked anchors .
-
Add a mapping from anchor to promise to session ’s map of new anchors .
-
Return promise .
Note:
It
is
the
responsibility
of
user
agents
to
ensure
that
the
physical
origin
tracked
by
the
anchor
returned
by
each
createAnchor(pose,
space)
call
aligns
as
closely
as
possible
with
the
physical
location
of
pose
within
space
at
the
time
represented
by
the
frame
on
which
the
method
is
called.
Specifically,
this
means
that
for
spaces
that
are
dynamically
changing,
user
agents
should
attempt
to
capture
the
native
origin
of
such
spaces
at
the
app’s
specified
time.
This
text
is
non-normative,
but
expresses
the
intent
of
the
specification
author(s)
and
contributors
and
thus
it
is
highly
recommended
that
it
is
followed
by
the
implementations
to
ensure
consistent
behavior
across
different
vendors.
restorePersistentAnchor(uuid)
method,
when
invoked
on
an
XRSession
session
with
uuid
,
MUST
run
the
following
steps:
-
Let promise be a new Promise in the relevant realm of this
XRSystem. -
If session ’s map of persistent anchors does not contain a mapping from uuid to an
XRAnchor, reject promise withInvalidStateError, return promise , and abort these steps. -
If session ’s ended value is `true`, reject promise with
InvalidStateError, return promise , and abort these steps. -
Let anchor be the value of mapping from uuid on session ’s map of persistent anchors .
-
If session ’s map of new anchors contains a mapping from anchor to promise , reject the promise with
InvalidStateError, return promise , and abort these steps. -
If session ’s map of new anchors has reached a user agent maximum size, reject promise with
InvalidStateError, return promise , and abort these steps. Add anchor to session ’s set of tracked anchors .
-
Add a mapping from anchor to promise to session ’s map of new anchors .
-
Return promise .
deletePersistentAnchor()
method,
when
invoked
on
an
XRSession
session
with
uuid
,
MUST
run
the
following
steps:
-
Let promise be a new Promise in the relevant realm of this
XRSystem. -
If session ’s map of persistent anchors does not contain a mapping to anchor , reject promise with
InvalidStateError, return promise , and abort these steps. -
Let anchor be the value of mapping from uuid on session ’s map of persistent anchors .
-
Remove the mapping from session ’s map of persistent anchors .
-
Invoke {{XRAnchor/delete()} on anchor .
-
Return promise .
In
order
to
create
an
anchor
from
hit
test
result
,
the
application
can
call
XRHitTestResult
's
createAnchor()
method.
createAnchor()
method,
when
invoked
on
an
XRHitTestResult
hitTestResult
,
MUST
run
the
following
steps:
-
Let promise be a new Promise .
-
Let frame be hitTestResult ’s frame .
-
If frame ’s active boolean is
false, reject promise withInvalidStateError, return promise , and abort these steps. -
Let session be frame ’s session .
-
Add update anchors algorithm to session ’s list of frame updates if it is not already present there.
-
Let device be session ’s XR device .
-
Let nativeEntity be the hitTestResult ’s native entity .
-
Let anchor native origin be a new native origin returned from the device ’s call to create a new anchor located at hitTestResult ’s native origin and attached to nativeEntity , at the frame ’s time .
-
Create new anchor object anchor using anchor native origin and session .
-
Add anchor to session ’s set of tracked anchors .
-
Add a mapping from anchor to promise to session ’s map of new anchors .
-
Return promise .
Note:
The
same
remark
that
is
present
on
createAnchor(pose,
space)
method
applies
here
as
well.
Session’s "list of frame updates" might need to have a way of specifying ordering - some algorithms may depend on others.
5. Anchor updates
In only one current engine.
Opera ? Edge 85+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
In only one current engine.
Opera ? Edge 85+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
[Exposed =Window ]interface {XRAnchorSet readonly setlike <XRAnchor >; };partial interface XRFrame { [SameObject ]readonly attribute XRAnchorSet ; };trackedAnchors
An
XRAnchorSet
interface
is
introduced
as
a
way
to
expose
a
collection
of
anchors.
An
XRFrame
is
extended
to
contain
a
trackedAnchors
attribute
which
contains
all
anchors
still
tracked
in
the
frame.
At
XRFrame
creation,
the
set
is
initially
empty
and
will
be
populated
by
the
update
anchors
algorithm.
-
Let session be a frame ’s session .
-
Let device be a session ’s XR device .
-
For each anchor in session ’s set of tracked anchors , run:
-
Query the device ’s tracking system for the anchor ’s native origin information.
-
If the device ’s tracking system no longer tracks the anchor , run the following steps:
-
Remove anchor from the session ’s set of tracked anchors .
-
If session ’s map of new anchors contains a mapping from anchor to promise , reject the promise and remove the mapping.
-
Continue to the next entry in session ’s set of tracked anchors .
-
-
Add anchor to frame ’s
trackedAnchorsset. -
If session ’s map of new anchors contains a mapping from anchor to promise , resolve the promise with anchor and remove the mapping.
-
6. Anchor removal
When
an
application
is
no
longer
interested
in
receiving
updates
to
an
anchor,
it
can
delete
an
anchor
by
calling
delete()
.
delete()
method,
when
invoked
on
an
XRAnchor
anchor
,
MUST
delete
an
anchor
by
running
the
following
steps:
-
If anchor ’s deleted is
true, abort these steps. -
Set anchor ’s
anchorSpacetonull. -
Set anchor ’s deleted to
true. -
Let session be an anchor ’s session .
-
Let device be a session ’s XR device .
-
Let native origin be an anchor ’s native origin .
-
Inform the device ’s tracking system that the native origin is no longer to be tracked.
-
Remove anchor from session ’s set of tracked anchors .
7. Native device concepts
In order for the user agents to be able to implement the anchors API, the underlying XR device should provide native support of this feature. This section describes requirements placed on the underlying XR system, and is by necessity under-specified to allow the implementation of anchors API on top of various frameworks / devices.
7.1. Native anchor
The underlying XR device is capable of supporting the anchors feature if it supports the following capabilities related to anchors:
-
Native anchor creation is possible, with the following requirements:
-
The native anchors API attempts to maintain the pose of the anchor as if it were fixed relative to the real world.
-
It accepts pose of the newly created anchor at some specific time
t. -
It optionally accepts a native entity information in order to express the intent of attaching newly created anchor to the given entity. If the underlying XR system does not support attaching anchors to a native entity (i.e. does not accept a native entity), the newly created anchor will be free-floating.
-
It returns a result that can be treated as a native origin by the user agents.
-
-
Native anchors are continuously tracked by the underlying XR system and can be queried for their most up-to-date state. When the underlying system deems that the native anchor’s location is never going to be known, it SHOULD report that the native anchor is no longer tracked.
-
Optionally, native anchors can be attached to native entities. A native anchor that is attached to a native entity attempts to maintain its position fixed relative to the entity to which it is attached (as opposed to the real world in case of free-floating anchors). When the device detects that the pose of the object to which the anchor is attached changes, the anchor will be updated accordingly. This does not imply that the object itself moved - it may be that the system’s understanding of its location changed. If the underlying system is capable of tracking moving objects, the native anchors attached to moving objects should be updated as well.
In
case
the
underlying
device
does
not
support
native
anchors,
the
user
agents
MAY
decide
to
implement
the
anchors
API
through
emulated
native
anchors
.
This
approach
assumes
that
anchors,
once
created,
never
change
their
pose,
and
their
pose
is
the
pose
passed
in
by
the
application
to
the
anchor
creation
methods
such
as
XRFrame
's
createAnchor(pose,
space)
or
XRHitTestResult
's
createAnchor()
.
Note:
The
emulated
native
anchors
approach
is
equivalent
to
the
applications
emulating
the
anchors
feature
themselves
and
can
help
reduce
the
number
of
different
cases
that
the
applications
need
to
handle.
It
might
also
allow
the
applications
to
re-use
the
same
code
for
"immersive-ar"
and
"immersive-vr"
sessions.
8. Privacy & Security Considerations
The anchors API does not directly expose access to the information about the user environment. In case the session was created with hit-test support enabled and the device supports tracking moving objects, it may be possible for the application to infer the layout of the user’s environment by observing changes to anchor poses of objects that are, for example, carried around. This offers similar level of information about user’s environment as hit-testing API. Anchor feature has to be declared when creating an XR session, which will allow the user agents to notify the users about potential privacy implications of allowing the anchors API to be used by the website.
I’m not aware of devices that support tracking general objects that move - should they be considered by the spec at all? Are there any examples of such devices?
9. Acknowledgements
The following individuals have contributed to the design of the WebXR Anchors specification: