1. Introduction
2. Initialization
2.1. Feature descriptor
In order for the applications to signal their interest in using plane detection during a session, the session must be requested with appropriate feature descriptor . The string plane-detection is introduced by this module as a new valid feature descriptor for plane detection feature.
A device is capable of supporting the plane-detection feature if the device’s tracking system exposes a native plane detection capability. The inline XR device MUST NOT be treated as capable of supporting the plane-detection feature.
When a session is created with plane-detection feature enabled, the update planes algorithm MUST be added to the list of frame updates of that session.
const session= await navigator. xr. requestSession( "immersive-ar" , { requiredFeatures: [ "plane-detection" ] });
3. Planes
3.1. XRPlaneOrientation
enum {XRPlaneOrientation "horizontal" ,"vertical" };
-
A plane orientation of
"horizontal"indicates that the plane is primarily oriented horizontally (according to the conventions of the underlying platform). -
A plane orientation of
"vertical"indicates that the plane is primarily oriented vertically (according to the conventions of the underlying platform).
3.2. XRPlane
[Exposed =Window ]interface { [XRPlane SameObject ]readonly attribute XRSpace ;planeSpace readonly attribute FrozenArray <DOMPointReadOnly >;polygon readonly attribute XRPlaneOrientation ?;orientation readonly attribute DOMHighResTimeStamp ;lastChangedTime readonly attribute DOMString ?; };semanticLabel
An
XRPlane
represents
a
single,
flat
surface
detected
by
the
underlying
XR
system.
The
planeSpace
is
an
XRSpace
that
establishes
the
coordinate
system
of
the
plane.
The
native
origin
of
the
planeSpace
tracks
plane’s
center.
The
underlying
XR
system
defines
the
exact
meaning
of
the
plane
center.
The
Y
axis
of
the
coordinate
system
defined
by
planeSpace
MUST
represent
the
plane’s
normal
vector.
Each
XRPlane
has
an
associated
native
entity
.
Each
XRPlane
has
an
associated
frame
.
The
polygon
is
an
array
of
vertices
that
describe
the
shape
of
the
plane.
They
are
returned
in
the
form
of
a
loop
of
points
at
the
edges
of
the
polygon,
expressed
in
the
coordinate
system
defined
by
planeSpace
.
The
Y
coordinate
of
each
vertex
MUST
be
0.0
.
The
semanticLabel
attribute
is
a
string
that
describes
the
semantic
label
of
the
polygon.
This
string
MAY
be
either
null
or
empty
if
there
is
no
semantic
information.
The
XRSystem
SHOULD
populate
this
with
the
semantic
label
it
has
knowledge
of.
A
semantic
label
is
an
ASCII
lowercase
DOMString
that
describes
the
name
in
the
real
world
of
the
XRPlane
as
known
by
the
XRSystem
.
The
list
of
semantic
labels
is
defined
in
the
semantic
label
registry
.
The
orientation
describes
orientation
of
the
plane,
as
classified
by
the
underlying
XR
system.
In
case
the
orientation
cannot
be
classified
into
"horizontal"
or
"vertical"
by
the
underlying
XR
system,
this
attribute
will
be
set
to
null
.
The
lastChangedTime
is
the
last
time
some
of
the
plane
attributes
have
been
changed.
Note:
The
pose
of
a
plane
is
not
considered
a
plane
attribute
and
therefore
updates
to
plane
pose
will
not
cause
the
lastChangedTime
to
change.
This
is
because
plane
pose
is
a
property
that
is
derived
from
two
different
entities
-
planeSpace
and
the
XRSpace
relative
to
which
the
pose
is
to
be
computed
via
getPose()
function.
4. Obtaining detected planes
4.1. XRPlaneSet
[Exposed =Window ]interface {XRPlaneSet readonly setlike <XRPlane >; };
An
XRPlaneSet
is
a
collection
of
XRPlane
s.
It
is
the
primary
mechanism
of
obtaining
the
collection
of
planes
detected
in
an
XRFrame
.
partial interface XRFrame {readonly attribute XRPlaneSet ; };detectedPlanes
XRFrame
is
extended
to
contain
detectedPlanes
attribute
which
contains
all
planes
that
are
still
tracked
in
the
frame.
The
set
is
initially
empty
and
will
be
populated
by
the
update
planes
algorithm.
If
this
attribute
is
accessed
when
the
frame
is
not
active
,
the
user
agent
MUST
throw
InvalidStateError
.
partial interface XRSession {Promise <undefined >(); };initiateRoomCapture
XRSession
is
extended
to
contain
associated
set
of
tracked
planes
,
which
is
initially
empty.
The
elements
of
the
set
will
be
of
XRPlane
type.
XRSession
is
extended
to
contain
a
boolean
room
capture
completed
,
which
is
initially
false.
If XR device supports manual capture, it has an async room capture method which returns a boolean.
XRSession
is
also
extended
to
contain
the
initiateRoomCapture
method
which,
if
supported,
will
ask
the
XR
device
to
capture
the
current
room
layout.
It
is
up
to
the
XR
device
if
this
will
replace
or
augment
the
set
of
tracked
planes
.
-
Let session be this
-
Let promise be a new Promise in the relevant realm of session .
-
If the
endedvalue of session is `true`, reject promise with a "InvalidStateError"DOMExceptionand return promise . -
If room capture completed is `true`, reject promise with a "
InvalidStateError"DOMExceptionand return promise . -
If plane-detection feature descriptor is not contained in session ’s XR device ’s list of enabled features for session ’s mode , reject promise with a "
NotSupportedError"DOMExceptionand return promise . -
If the session ’s XR device doesn’t support manual capture or if the
XRSystemdetermines that room capture isn’t needed:-
Set session ’s room capture completed to `true`.
-
Resolve promise .
-
Return promise .
-
-
Queue a task to perform the following steps:
-
Invoke and wait for the result of session ’s XR device ’s room capture method , which is assigned to result .
-
Run the following steps:
- If result is `true`:
-
Resolve promise
- Otherwise:
-
reject promise with an "
OperationError"DOMException
-
Set session ’s room capture completed to `true`.
-
-
Return promise .
-
Let session be a frame ’s session .
-
Let device be a session ’s XR device .
-
If plane-detection feature descriptor is not contained in device ’s list of enabled features for session ’s mode , abort these steps.
-
Let trackedPlanes be a result of calling into device ’s native plane detection capability to obtain tracked planes at frame ’s time .
-
For each native plane in trackedPlanes , run:
-
If desired, treat the native plane as if it were not present in trackedPlanes and continue to the next entry. See § 6 Privacy & Security Considerations for criteria that could be used to determine whether an entry should be ignored in this way.
-
If session ’s set of tracked planes contains an object plane that corresponds to native plane , invoke update plane object algorithm with plane , native plane , and frame , and continue to the next entry.
-
Let plane be the result of invoking the create plane object algorithm with native plane and frame .
-
Add plane to session ’s set of tracked planes .
-
-
Remove each object in session ’s set of tracked planes that was neither created nor updated during the invocation of this algorithm.
-
Set frame ’s
detectedPlanesto set of tracked planes .
XRFrame
frame
,
the
user
agent
MUST
run
the
following
steps:
-
Let result be a new instance of
XRPlane. -
Set result ’s native entity to native plane .
-
Set result ’s
planeSpaceto a newXRSpaceobject created with session set to frame ’ssessionand native origin set to track native plane ’s native origin. -
Invoke update plane object algorithm with result , native plane , and frame .
-
Return result .
A plane object, result , created in such way is said to correspond to the passed in native plane object native plane .
XRFrame
frame
,
the
user
agent
MUST
run
the
following
steps:
-
Set plane ’s frame to frame .
-
If native plane is classified by the underlying system as vertical, set plane ’s
orientationto"vertical". Otherwise, if native plane is classified by the underlying system as horizontal, set plane ’sorientationto"horizontal". Otherwise, set plane ’sorientationtonull. -
Set plane ’s
polygonto the new array of vertices representing native plane ’s polygon, performing all necessary conversions to account for differences in native plane polygon representation. -
Set plane ’s
semanticLabelto a new string with the semantic labels . -
If desired, reduce the level of detail of the plane ’s
polygonas described in § 6 Privacy & Security Considerations . -
Set plane ’s
lastChangedTimeto time .
The following example demonstrates how an application could obtain information about detected planes and act on it. The code that can be used to render a graphical representation of the planes is not shown.
// `planes` will track all detected planes that the application is aware of, // and at what timestamp they were updated. Initially, this is an empty map. const planes= Map(); function onXRFrame( timestamp, frame) { const detectedPlanes= frame. detectedPlanes; // First, let's check if any of the planes we knew about is no longer tracked: for ( const [ plane, timestamp] of planes) { if ( ! detectedPlanes. has( plane)) { // Handle removed plane - `plane` was present in previous frame, // but is no longer tracked. // We know the plane no longer exists, remove it from the map: planes. delete ( plane); } } // Then, let's handle all the planes that are still tracked. // This consists both of tracked planes that we have previously seen (may have // been updated), and new planes. detectedPlanes. forEach( plane=> { if ( planes. has( plane)) { // Handle previously-seen plane: if ( plane. lastChangedTime> planes. get( plane)) { // Handle previously seen plane that was updated. // It means that one of the plane's properties is different than // it used to be - most likely, the polygon has changed. ... // Render / prepare the plane for rendering, etc. // Update the time when we have updated the plane: planes. set( plane, plane. lastChangedTime); } else { // Handle previously seen plane that was not updated in current frame. // Note that plane's pose relative to some other space MAY have changed. } } else { // Handle new plane. // Set the time when we have updated the plane: planes. set( plane, plane. lastChangedTime); } // Irrespective of whether the plane was previously seen or not, // & updated or not, its pose MAY have changed: const planePose= frame. getPose( plane. planeSpace, xrReferenceSpace); }); frame. session. requestAnimationFrame( onXRFrame); }
5. Native device concepts
5.1. Native plane detection
The
plane
detection
API
provides
information
about
flat
surfaces
detected
in
users'
environment.
It
is
assumed
in
this
specification
that
user
agents
can
rely
on
native
plane
detection
capabilities
provided
by
the
underlying
platform
for
their
implementation
of
plane-detection
features.
Specifically,
the
underlying
XR
device
should
provide
a
way
to
query
all
planes
that
are
tracked
at
a
time
that
corresponds
to
the
time
of
a
specific
XRFrame
.
Moreover,
it
is
assumed
that
the
tracked
planes,
known
as
native
plane
objects
,
maintain
their
identity
across
frames
-
that
is,
given
a
plane
object
P
returned
by
the
underlying
system
at
time
t0
,
and
a
plane
object
Q
returned
by
the
underlying
system
at
time
t1
,
it
is
possible
for
the
user
agent
to
query
the
underlying
system
about
whether
P
and
Q
correspond
to
the
same
logical
plane
object.
The
underlying
system
is
also
expected
to
provide
a
native
origin
that
can
be
used
to
query
the
location
of
a
pose
at
time
t
,
although
it
is
not
guaranteed
that
plane
pose
will
always
be
known
(for
example
for
planes
that
are
still
tracked
but
not
localizable
at
a
given
time).
In
addition,
the
native
plane
object
should
expose
a
polygon
describing
approximate
shape
of
the
detected
plane.
In
addition,
the
underlying
system
should
recognize
native
planes
as
native
entities
for
the
purposes
of
XRAnchor
creation.
For
more
information,
see
WebXR
Anchors
Module
§ native-anchor
section.
6. Privacy & Security Considerations
The
plane
detection
API
exposes
information
about
users'
physical
environment.
The
exposed
plane
information
(such
as
plane’s
polygon)
may
be
limited
if
the
user
agent
so
chooses.
Some
of
the
ways
in
which
the
user
agent
can
reduce
the
exposed
information
are:
decreasing
the
level
of
detail
of
the
plane’s
polygon
in
update
plane
object
algorithm
(for
example
by
decreasing
the
number
of
vertices,
or
by
rounding
/
quantizing
the
coordinates
of
the
vertices),
or
removing
the
plane
altogether
by
behaving
as
if
the
plane
object
was
not
present
in
trackedPlanes
collection
in
update
planes
algorithm
(this
could
be
done
for
example
if
the
detected
plane
is
deemed
to
small
/
too
detailed
to
be
surfaced
and
the
mechanisms
to
reduce
details
exposed
on
planes
are
not
implemented
by
the
user
agent).
The
poses
of
the
planes
(obtainable
from
planeSpace
)
could
also
be
quantized
.
Since concepts from plane detection API can be used in methods exposed by [webxr-anchors-module] specification, some of the privacy & security considerations that are relevant to WebXR Anchors Module also apply here. For details, see WebXR Anchors Module § privacy-security section.
Due to how plane detection API extends WebXR Device API, the section WebXR Device API § 13. Security, Privacy, and Comfort Considerations is also applicable to the features exposed by the WebXR Plane Detection Module.
7. Acknowledgements
The following individuals have contributed to the design of the WebXR Plane Detection specification: