1. Introduction
In order to allow Web Platform Tests for WebXR there are some basic functions which are common across all tests, such as adding a fake test device and specifying poses. Below is an API which attempts to capture the necessary functions, based off what was defined in the spec. Different browser vendors can implement this API in whatever way is most compatible with their browser. For example, some browsers may back the interface with a WebDriver API while others may use HTTP or IPC mechanisms to communicate with an out of process fake backend.
These initialization object and control interfaces do not represent a complete set of WebXR functionality, and are expected to be expanded on as the WebXR spec grows.
2. Conformance
Interfaces and functionality exposed by this specification SHOULD NOT be exposed to typical browsing experiences, and instead SHOULD only be used when running Web Platform Tests .
3. Simulated devices
3.1. Simulated XR Device
This API gives tests the ability to spin up a simulated XR device which is an XR device which from the point of view of the WebXR API behaves like a normal XR device . These simulated XR devices can be controlled by the associated
FakeXRDevice
object.
Every
simulated
XR
device
may
have
an
native
bounds
geometry
which
is
an
array
of
DOMPointReadOnly
s,
used
to
initialize
the
native
bounds
geometry
of
any
XRBoundedReferenceSpace
s
created
for
the
device.
If
null
,
the
device
is
treated
as
if
it
is
not
currently
tracking
a
bounded
reference
space.
Every
simulated
XR
device
may
have
a
floor
origin
which
is
an
XRRigidTransform
used
to
note
the
position
of
the
physical
floor.
If
null
,
the
device
is
treated
as
if
it
is
unable
to
identify
the
physical
floor.
Every
simulated
XR
device
may
have
an
viewer
origin
which
is
an
XRRigidTransform
used
to
set
the
position
and
orientation
of
the
viewer
.
If
null
,
the
device
is
treated
as
if
it
has
lost
tracking.
Every
simulated
XR
device
has
an
emulated
position
boolean
which
is
a
boolean
used
to
set
the
emulatedPosition
of
any
XRPose
s
produced
involving
the
viewer
.
This
is
initially
false
.
Every
simulated
XR
device
has
an
visibility
state
which
is
an
XRVisibilityState
used
to
set
the
visibilityState
of
any
XRSession
s
associated
with
the
simulated
XR
device
.
This
is
initially
"visible"
.
When
it
is
changed,
the
associated
changes
must
be
reflected
on
the
XRSession
,
including
triggering
onvisibilitychange
events
if
necessary.
Every simulated XR device has a list of primary views which is a list of views that must be rendered to for an immersive experience. There must be at least one primary view.
Every simulated XR device may have a list of secondary views which is a list of views that may or may not be rendered to. There may be any number of secondary views.
Every
view
for
a
simulated
XR
device
has
an
associated
device
resolution
,
which
is
an
instance
of
FakeXRDeviceResolution
.
This
resolution
must
be
used
when
constructing
XRViewport
values
for
the
view
,
based
on
the
canvas
size.
Every
view
for
a
simulated
XR
device
has
an
associated
id
,
which
is
the
index
of
the
view
in
the
views
list,
and
thus
matches
the
index
.
Every
view
for
a
simulated
XR
device
may
have
an
associated
field
of
view
,
which
is
an
instance
of
FakeXRFieldOfViewInit
used
to
calculate
projection
matrices
using
depth
values.
If
the
field
of
view
is
set,
projection
matrix
values
are
calculated
using
the
field
of
view
and
depthNear
and
depthFar
values.
Every
view
for
a
simulated
XR
device
may
have
an
associated
visibility
mask
which
is
an
instance
of
FakeXRVisibilityMask
used
to
describe
the
visible
region
of
the
view.
If
it
is
missing,
the
entire
view
is
visible.
Changes
to
this
value
should
result
in
firing
a
XRVisibilityMaskChangeEvent
no
later
than
the
next
animation
frame
.
Every
simulated
XR
device
has
a
supported
depth
types
which
is
a
list
of
XRDepthType
values,
initially
empty.
If
this
list
is
empty,
it
implies
all
XRDepthType
values
are
supported.
Every
simulated
XR
device
has
a
supported
depth
formats
which
is
a
list
of
XRDepthFormat
values,
initially
empty.
If
this
list
is
empty,
it
implies
all
XRDepthFormat
values
are
supported.
Every
simulated
XR
device
has
a
supported
depth
usages
which
is
a
list
of
XRDepthUsage
values,
initially
empty.
If
this
list
is
empty,
it
implies
all
XRDepthUsage
values
are
supported.
3.2. Simulated Input Device
This
API
gives
tests
the
ability
to
spin
up
a
simulated
XR
input
source
which
is
an
XR
input
source
which
from
the
point
of
view
of
the
WebXR
API
behaves
like
a
normal
XR
input
source
.
These
simulated
XR
input
sources
can
be
controlled
by
the
associated
FakeXRInputController
object.
Every
simulated
XR
input
source
has
a
handedness
which
is
an
XRHandedness
value
that
MUST
be
returned
for
the
corresponding
XR
input
source’s
handedness
attribute.
Every
simulated
XR
input
source
has
a
targetRayMode
which
is
an
XRTargetRayMode
value
that
MUST
be
returned
for
the
corresponding
XR
input
source’s
targetRayMode
attribute.
Every
simulated
XR
input
source
has
a
pointerOrigin
which
is
an
XRRigidTransform
used
to
note
the
origin
of
the
targetRaySpace
.
A
simulated
XR
input
source
may
have
a
gripOrigin
which
is
an
XRRigidTransform
used
to
note
the
origin
of
the
gripSpace
.
If
this
is
null
the
simulated
XR
input
source
is
not
tracked.
Every
simulated
XR
input
source
has
a
profiles
array
which
is
an
array
of
DOMString
s
which
MUST
be
returned
for
the
corresponding
XR
input
source’s
profiles
attribute.
Every
simulated
XR
input
source
has
a
buttonState
array
which
is
an
array
of
FakeXRButtonStateInit
s.
If
a
"grip"
button
is
specified,
it
SHOULD
drive
the
primary
squeeze
action
.
If
a
UA
implements
the
WebXR
Gamepads
Module
buttonState
SHOULD
be
used
to
set
the
state
for
the
corresponding
XR
input
source’s
gamepad
object,
which
SHOULD
be
of
type
"xr-standard"
if
enough
buttons
are
specified
to
support
it.
Every
simulated
XR
input
source
has
a
connectionState
which
is
a
boolean
that
is
initially
true
and
indicates
whether
the
associated
XR
input
source
should
appear
in
inputSources
.
When
it
is
changed
the
associated
changes
must
be
reflected
on
the
XRSession,
including
triggering
the
inputsourceschange
event
if
necessary
by
the
next
animation
frame
.
Every
simulated
XR
input
source
has
a
primaryActionStarted
which
is
a
boolean,
initially
set
to
false
,
that
indicates
whether
or
not
the
primary
action
of
the
XR
input
source
has
been
started.
4. Initialization
4.1. navigator.xr.test
partial interface XRSystem { [SameObject ]readonly attribute XRTest test ; };
The
test
attribute’s
getter
MUST
return
the
XRTest
object
that
is
associated
with
it.
This
object
MAY
be
lazily
created.
4.2. XRTest
The
XRTest
object
is
the
entry
point
for
all
testing.
interface {XRTest Promise <FakeXRDevice >simulateDeviceConnection (FakeXRDeviceInit );init undefined simulateUserActivation (Function );f Promise <undefined >disconnectAllDevices (); };
simulateDeviceConnection(
init
)
method
creates
a
new
simulated
XR
device
.
When this method is invoked, the user agent MUST run the following steps:
-
Let promise be a new Promise .
-
Run the following steps in parallel :
-
Let device be a new simulated XR device .
-
Run the following steps to set device ’s view s.
-
Let l be the result of running parse a list of views on
views. -
If running parse a list of views threw an error, reject promise with this error and abort these steps.
-
Set device ’s list of primary views to l .
-
If init ’s
secondaryViewsis set:-
Let sl be the result of running parse a list of views on
secondaryViews. -
If running parse a list of views threw an error, reject promise with this error and abort these steps.
-
Set device ’s list of secondary views to sl .
-
-
If init ’s
boundsCoordinatesis set, perform the following steps:-
If init ’s
boundsCoordinateshas less than 3 elements, reject promise withTypeErrorand abort these steps. -
Set device ’s native bounds geometry to init ’s
boundsCoordinates.
-
-
If init ’s
floorOriginis set, set device ’s floor origin to init ’sfloorOrigin. -
If init ’s
viewerOriginis set, set device ’s viewer origin to init ’sviewerOrigin. -
Let supportedModes be an empty list of
XRSessionModes. -
Modify supportedModes as follows:
-
If
init
’s
supportedModesis present: -
-
Append the contents of init ’s
supportedModesto supportedModes . -
If supportedModes is empty, append
"inline"to it.
-
- Else
-
-
Append
"inline"to supportedModes . -
If init ’s
supportsImmersiveistrue, append"immersive-vr"to supportedModes .
-
-
If
init
’s
-
If init ’s
supportedFeaturesis set, for each mode in supportedModes : -
Associate init ’s
supportedFeaturesto mode -
If init ’s
depthSupportis present:-
Let depthConfig be init ’s
depthSupport. -
If depthConfig ’s
depthTypesis present and its size is greater than 0, set device ’s supported depth types to a copy of depthConfig ’sdepthTypes. -
If depthConfig ’s
depthFormatsis present and its size is greater than 0, set device ’s supported depth formats to a copy of depthConfig ’sdepthFormats. -
If depthConfig ’s
depthUsagesis present and its size is greater than 0, set device ’s supported depth usages to a copy of depthConfig ’sdepthUsages.
-
-
NOTE:
each
device
stores
a
list
of
features
it
is
capable
of
supporting
per
XRSessionMode
.
Most
tests
only
test
one
mode
anyway
so
there
isn’t
much
to
be
gained
by
splitting
features
per
mode
in
FakeXRDeviceInit
.
Users
wishing
different
modes
supporting
different
features
should
create
multiple
devices
instead.
-
Set device ’s list of supported modes to supportedModes .
-
Register device based on the following:
-
If supportedModes contains
"immersive-vr"or"immersive-ar", append device to thexr’s list of immersive XR devices . -
If supportedModes contains
"inline", set the inline XR device to device .
-
-
Let d be a new
FakeXRDeviceobject with device as device . -
Resolve promise with d .
-
Return promise .
When
simulateUserActivation(f)
is
called,
invoke
f
as
if
it
had
transient
activation
.
When
disconnectAllDevices()
is
called,
remove
all
simulated
XR
devices
from
the
xr
’s
list
of
immersive
XR
devices
as
if
they
were
disconnected.
If
the
inline
XR
device
is
a
simulated
XR
device
,
reset
it
to
the
default
inline
XR
device
.
4.3. FakeXRDeviceInit
dictionary {FakeXRDeviceInit required boolean ;supportsImmersive sequence <XRSessionMode >;supportedModes required sequence <FakeXRViewInit >;views sequence <FakeXRViewInit >;secondaryViews sequence <any >;supportedFeatures sequence <FakeXRBoundsPoint >;boundsCoordinates FakeXRRigidTransformInit ;floorOrigin FakeXRRigidTransformInit ; // Hit test extensions:viewerOrigin FakeXRWorldInit ; // Depth sensing extensions:world FakeXRDepthSensingDataInit ;depthSensingData FakeXRDepthConfigurationSupport ; };depthSupport dictionary {FakeXRViewInit required XREye ;eye required sequence <float >;projectionMatrix required FakeXRDeviceResolution ;resolution required FakeXRRigidTransformInit ;viewOffset FakeXRFieldOfViewInit ;fieldOfView FakeXRVisibilityMask ; // Raw camera access extensions:visibilityMask FakeXRCameraImage ; };cameraImageInit dictionary {FakeXRFieldOfViewInit required float ;upDegrees required float ;downDegrees required float ;leftDegrees required float ; };rightDegrees dictionary {FakeXRDeviceResolution required long ;width required long ; };height dictionary {FakeXRBoundsPoint double ;x double ; };z dictionary {FakeXRRigidTransformInit required sequence <float >;position required sequence <float >; };orientation dictionary {FakeXRVisibilityMask required sequence <float >;vertices required sequence <uint32 >; };indices
The
supportsImmersive
is
deprecated
in
favor
of
supportedModes
and
will
be
removed
in
future
revisions
of
the
specification.
FakeXRRigidTransformInit
init
,
perform
the
following
steps:
-
Let p be init ’s
position. -
If p does not have three elements, throw a
TypeError. -
Let o be init ’s
orientation. -
If o does not have four elements, throw a
TypeError. -
Let position be a
DOMPointInitwithx,yandzequal to the three elements of p in order, andwequal to1. -
Let orientation be a
DOMPointInitwithx,y,z, andwequal to the four elements of o in order. -
Construct an XRRigidTransformtransform withpositionposition andorientationorientation . -
Return transform .
FakeXRViewInit
init
,
and
`uint32_t`
id
perform
the
following
steps:
-
Let view be a new view .
-
Set view ’s id to id .
-
If init ’s
projectionMatrixdoes not have 16 elements, throw aTypeError. -
Set view ’s projection matrix to init ’s
projectionMatrix. -
Set view ’s view offset to the result of running parse a rigid transform init ’s
viewOffset. -
Set view ’s device resolution to init ’s
resolution. -
If init ’s
fieldOfViewis set, perform the following steps:-
Set view ’s field of view to init ’s
fieldOfView. -
Set view ’s projection matrix to the projection matrix corresponding to this field of view, and depth values equal to
depthNearanddepthFarof anyXRSessionassociated with the device. If there currently is none, use the default values ofnear=0.1, far=1000.0.
-
-
If init ’s
visibilityMaskis set, set view ’s visibility mask to init ’svisibilityMask -
Return view .
4.4. FakeXRRigidTransformInit
The WebXR API never exposes native origins directly, instead exposing transforms between them, so we need to specify a base reference space for
FakeXRRigidTransformInit
s
so
that
we
can
have
consistent
numerical
values
across
implementations.
When
used
as
an
origin,
FakeXRRigidTransformInit
s
are
in
the
base
reference
space
where
the
viewer
’s
native
origin
is
identity
at
initialization,
unless
otherwise
specified.
In
this
space,
the
"local"
reference
space
has
a
native
origin
of
identity.
This
is
an
arbitrary
choice:
changing
this
reference
space
doesn’t
affect
the
data
returned
by
the
WebXR
API,
but
we
must
make
such
a
choice
so
that
the
tests
produce
the
same
results
across
different
UAs.
When
used
as
an
origin
it
is
logically
a
transform
from
the
origin’s
space
to
the
underlying
base
reference
space
described
above.
5. Mocking
5.1. FakeXRDevice
interface :FakeXRDevice EventTarget {undefined setViews (sequence <FakeXRViewInit >,views optional sequence <FakeXRViewInit >);secondaryViews Promise <undefined >disconnect ();undefined setViewerOrigin (FakeXRRigidTransformInit ,origin optional boolean =emulatedPosition false );undefined clearViewerOrigin ();undefined setFloorOrigin (FakeXRRigidTransformInit );origin undefined clearFloorOrigin ();undefined setBoundsGeometry (sequence <FakeXRBoundsPoint >);boundsCoordinates undefined simulateResetPose ();undefined simulateVisibilityChange (XRVisibilityState );state FakeXRInputController simulateInputSourceConnection (FakeXRInputSourceInit ); // Hit test extensions:init undefined (setWorld FakeXRWorldInit );world undefined (); // Depth sensing extensions:clearWorld undefined (setDepthSensingData FakeXRDepthSensingDataInit );depthSensingData undefined (); };clearDepthSensingData
Each
FakeXRDevice
object
has
an
associated
device
,
which
is
a
simulated
XR
device
that
it
is
able
to
control.
Operations
on
the
FakeXRDevice
’s
device
typically
take
place
on
the
next
animation
frame
,
i.e.
they
are
not
immediately
observable
until
a
future
requestAnimationFrame()
callback.
To determine when this frame is, for a given operation, choose a frame based on the following:
- If such an operation is triggered within an XR animation frame :
- Choose the next XR animation frame , whenever it may occur
- If such an operation is triggered outside of an XR animation frame :
- Choose either the next or next-to-next XR animation frame . The precise choice is up to the user agent and may be dependent on the exact timing of these events.
NOTE:
The
reason
we
defer
an
extra
frame
when
there
are
pending
animation
frame
callbacks
is
to
avoid
having
to
deal
with
potential
race
conditions
when
the
device
is
ready
to
trigger
an
animation
frame
callback,
but
has
not
yet.
In
practice,
this
means
that
tests
should
be
written
so
that
they
wait
until
they
have
performed
all
such
operations
before
calling
the
next
requestAnimationFrame()
,
and
in
case
they
are
running
outside
of
an
XR
animation
frame
,
should
always
wait
two
frames
before
expecting
any
updates
to
take
effect.
-
Let l be an empty list
-
let offset be `0`
-
For each view in views :
-
Let v be the result of running parse a view on view and offset .
-
Append v to l .
-
Increase offset by `1`.
-
-
Return l .
setViews(
views
,
secondaryViews
)
method
performs
the
following
steps:
-
On the next animation frame , run the following steps:
-
Let p be the result of running parse a list of views on views .
-
Set device ’s list of primary views to p .
-
If secondaryViews is set, let s be the result of running parse a list of views on secondaryViews .
-
Set device ’s list of secondary views to s .
-
-
When
disconnect()
method
is
called,
perform
the
following
steps:
-
Remove device from the
xr’s list of immersive XR devices as if it were disconnected. -
If the inline XR device is equal to the
FakeXRDevice, reset it to the default inline XR device .
setViewerOrigin(
origin
,
emulatedPosition
)
performs
the
following
steps:
-
Let o be the result of running parse a rigid transform on origin .
-
On the next animation frame , perform the following steps:
-
Set device ’s viewer origin to o .
-
Set device ’s emulated position boolean to emulatedPosition .
-
The
clearViewerOrigin()
method
will,
on
the
next
animation
frame
,
set
device
’s
viewer
origin
to
null
.
The
simulateVisibilityChange(
state
)
method
will,
as
soon
as
possible,
set
device
’s
visibility
state
to
state
.
setFloorOrigin(
origin
)
performs
the
following
steps:
-
Let o be the result of running parse a rigid transform on origin .
-
On the next animation frame , set device ’s floor origin to o .
The
clearFloorOrigin()
method
will,
on
the
next
animation
frame
,
set
device
’s
floor
origin
to
null
.
setBoundsGeometry(
boundsCoordinates
)
performs
the
following
steps:
-
If boundsCoordinates has fewer than 3 elements, throw a
TypeError. -
On the next animation frame , set device ’s native bounds geometry to boundsCoordinates .
The
simulateResetPose()
method
will,
as
soon
as
possible,
behave
as
if
the
device
’s
viewer
’s
native
origin
had
a
discontinuity,
triggering
appropriate
reset
events.
simulateInputSourceConnection(
init
)
method
creates
a
new
simulated
XR
input
source
.
When this method is invoked, the user agent MUST run the following steps:
-
Let inputSource be a new simulated XR input source .
-
Set inputSource ’s handedness to init ’s
handedness. -
Set inputSource ’s targetRayMode to init ’s
targetRayMode. -
If init ’s
gripOriginis set, set inputSource ’s gripOrigin to the result of running parse a rigid transform on init ’sgripOrigin -
Set inputSource ’s pointerOrigin to the result of running parse a rigid transform on init ’s
pointerOrigin -
If init ’s
supportedButtonsis set, set inputSource ’s buttonState to the result of running parse supported buttons on init ’ssupportedButtons -
If init ’s
selectionClickedis set totrue, run simulate a full primary action on inputSource . -
If init ’s
selectionStartedis set totrue, run start a primary action on inputSource . -
By the next animation frame notify
XRSessionof the new XR input source . -
Let c be a new
FakeXRInputControllerobject with { inputSource as inputSource . -
Return c .
5.2. FakeXRInputController
dictionary {FakeXRInputSourceInit required XRHandedness ;handedness required XRTargetRayMode ;targetRayMode required FakeXRRigidTransformInit ;pointerOrigin required sequence <DOMString >;profiles boolean =selectionStarted false ;boolean =selectionClicked false ;sequence <FakeXRButtonStateInit >;supportedButtons FakeXRRigidTransformInit ; };gripOrigin interface {FakeXRInputController undefined setHandedness (XRHandedness );handedness undefined setTargetRayMode (XRTargetRayMode );targetRayMode undefined setProfiles (sequence <DOMString >);profiles undefined setGripOrigin (FakeXRRigidTransformInit ,gripOrigin optional boolean =emulatedPosition false );undefined clearGripOrigin ();undefined setPointerOrigin (FakeXRRigidTransformInit ,pointerOrigin optional boolean =emulatedPosition false );undefined disconnect ();undefined reconnect ();undefined startSelection ();undefined endSelection ();undefined simulateSelect ();undefined setSupportedButtons (sequence <FakeXRButtonStateInit >);supportedButtons undefined updateButtonState (FakeXRButtonStateInit ); };buttonState enum {FakeXRButtonType ,"grip" ,"touchpad" ,"thumbstick" ,"optional-button" };"optional-thumbstick" dictionary {FakeXRButtonStateInit required FakeXRButtonType ;buttonType required boolean ;pressed required boolean ;touched required float ;pressedValue float = 0.0;xValue float = 0.0; };yValue
Each
FakeXRInputController
object
has
an
associated
inputSource
,
which
is
a
simulated
XR
input
source
that
it
is
able
to
control.
Since
user
agents
may
opt
to
send
input
events
on
a
per-frame
basis,
the
results
of
all
FakeXRInputController
methods
and
simulateInputSourceConnection()
are
not
guaranteed
to
be
visible
(via,
e.g.
inputSources
or
oninputsourceschange
events)
until
the
next
animation
frame
.
-
If primaryActionStarted is true, abort these steps.
-
Set primaryActionStarted to true.
-
By the next animation frame indicate to the
XRSessionthat the corresponding XR input source’s primary action has started.
-
If primaryActionStarted is false, abort these steps.
-
Set primaryActionStarted to false.
-
By the next animation frame indicate to the
XRSessionthat the corresponding XR input source’s primary action has stopped.
-
Let current be the current value of primaryActionStarted .
-
Run start a primary action on source
-
Run stop a primary action on source
-
If current is
truerun start a primary action on source
Note: If a gamepad is attached to the simulated XR input source , then running start a primary action or stop a primary action should also ensure that the primary input’s corresponding gamepad button is updated accordingly.
Note:
If
both
start
a
primary
action
and
stop
a
primary
action
are
run
in
the
same
frame,
then
by
the
next
animation
frame
It
is
expected
that
onselect
and
onselectend
events
will
fire.
FakeXRButtonStateInit
s,
buttons
run
the
following
steps:
-
Let l be an empty list of
FakeXRButtonStateInits -
For each button in buttons :
-
If l does not contain a
FakeXRButtonStateInitwhosebuttonTypematches button ’sbuttonType, append button to l .
-
-
Return l
The
setHandedness(
handedness
)
method
will,
by
the
next
animation
frame
,
set
inputSource
’s
handedness
to
handedness
.
The
setTargetRayMode(
targetRayMode
)
method
will,
by
the
next
animation
frame
,
set
inputSource
’s
targetRayMode
to
targetRayMode
.
The
setProfiles(
profiles
)
method
will,
by
the
next
animation
frame
,
set
inputSource
’s
profiles
to
profiles
.
The
setGripOrigin(
gripOrigin
)
method
will,
by
the
next
animation
frame
,
set
inputSource
’s
gripOrigin
to
the
result
of
running
parse
a
rigid
transform
on
gripOrigin
.
The
clearGripOrigin()
method
will,
by
the
next
animation
frame
,
set
inputSource
’s
gripOrigin
to
null
.
The
setPointerOrigin(
pointerOrigin
)
method
will,
by
the
next
animation
frame
,
set
inputSource
’s
pointerOrigin
to
the
result
of
running
parse
a
rigid
transform
on
pointerOrigin
.
disconnect()
method
will
run
the
following
steps:
-
If inputSource ’s connectionState is
false, abort these steps. -
Set inputSource ’s connectionState to
false. -
By the next animation frame , notify the
XRSessionthat this XR input source has been removed.
reconnect()
method
will
run
the
following
steps:
-
If inputSource ’s connectionState is
true, abort these steps. -
Set inputSource ’s connectionState to
true. -
By the next animation frame , notify the
XRSessionthat this XR input source has been added.
The
startSelection()
method
will
run
start
a
primary
action
on
inputSource
.
The
endSelection()
method
will
run
stop
a
primary
action
on
inputSource
.
The
simulateSelect()
method
will
run
simulate
a
full
primary
action
on
inputSource
.
The
setSupportedButtons(
supportedButtons
)
will,
by
the
next
animation
frame
,
set
inputSource
’s
buttonState
to
the
result
of
running
parse
supported
buttons
on
supportedButtons
.
Note:
As
user
agents
may
recreate
the
XRInputSource
or
gamepad
objects
on
buttons
being
changed,
this
method
SHOULD
NOT
be
used
to
simulate
changes
to
button
state.
updateButtonState(
buttonState
)
will
run
the
following
steps:
-
Let validState equal the results of running validate a button state on buttonState .
-
Let foundState be
null. -
For every state in inputSource ’s buttonState array:
-
If state ’s
buttonTypematches buttonState ’sbuttonType:-
Set foundState to a reference of state
-
Break out of this loop
-
-
-
If foundState is
nullthrow aNotFoundError -
Update foundState ’s attributes in inputSource ’s buttonState to match those of validState . Note: If
buttonTypeisgrip, then XR input source ’s primary squeeze action should be updated.
FakeXRButtonStateInit
buttonState
run
the
following
steps:
-
Let validState equal buttonState .
-
If
pressedistrueandtouchedisfalse, throw aTypeError. -
If
pressedValueis less than0.0, throw aTypeError. -
If
pressedValueis greater than0.0andtouchedisfalsethrow aTypeError. -
If
buttonTypeis not one of:"touchpad","thumbstick", or"optional-thumbstick": -
Return validState .
6. Hit test extensions
The hit test extensions for test API SHOULD be implemented by all user agents that implement WebXR Hit Test Module .
dictionary {FakeXRWorldInit required sequence <FakeXRRegionInit >; };hitTestRegions
FakeXRWorldInit
dictionary
describes
the
state
of
the
world
that
will
be
used
when
computing
hit
test
results
on
a
FakeXRDevice
.
hitTestRegions
contains
a
collection
of
FakeXRRegionInit
s
that
are
used
to
describe
specific
regions
of
the
fake
world.
The
order
of
the
regions
does
not
matter.
dictionary {FakeXRRegionInit required sequence <FakeXRTriangleInit >;faces required FakeXRRegionType ; };type
FakeXRRegionInit
dictionary
describes
the
contents
of
a
specific
region
of
the
world.
faces
contains
a
collection
of
FakeXRTriangleInit
s
that
enumerate
all
the
faces
contained
by
the
region.
The
order
of
the
faces
does
not
matter.
type
contains
a
type
of
the
region
that
will
be
used
during
computation
of
hit
test
results.
dictionary {FakeXRTriangleInit required sequence <DOMPointInit >; // size = 3 };vertices
FakeXRTriangleInit
dictionary
describes
a
single
face
of
a
region.
vertices
contains
a
collection
of
DOMPointInit
s
that
comprise
the
face.
The
face
will
be
considered
as
solid
when
computing
hit
test
results
and
as
such,
the
winding
order
of
the
vertices
does
not
matter.
enum {FakeXRRegionType ,"point" ,"plane" };"mesh"
FakeXRRegionType
enum
is
used
to
describe
a
type
of
the
world
region.
7. DOM overlay extensions
The DOM Overlay extensions for test API SHOULD be implemented by all user agents that implement WebXR DOM Overlay Module .
partial interface FakeXRInputController {undefined setOverlayPointerPosition (float ,x float ); };y
When
setOverlayPointerPosition(x,
y)
is
called,
it
sets
a
position
within
the
DOM
overlay
in
DOM
coordinates
for
the
next
XR
animation
frame
,
and
is
cleared
after
that
frame.
It
is
intended
to
be
used
along
with
a
primary
action
for
that
frame,
simulating
that
the
user
is
interacting
with
the
DOM
overlay.
The
UA
will
emit
a
beforexrselect
event
at
this
location
before
generating
XR
select
events.
8. Anchors extensions
The anchors extensions for test API SHOULD be implemented by all user agents that implement WebXR Anchors .
dictionary {FakeXRAnchorCreationParameters FakeXRRigidTransformInit ;requestedAnchorOrigin boolean ; };isAttachedToEntity callback =FakeXRAnchorCreationCallback Promise <boolean > (FakeXRAnchorCreationParameters ,parameters FakeXRAnchorController );anchorController partial interface FakeXRDevice {undefined (setAnchorCreationCallback FakeXRAnchorCreationCallback ?); };callback
The
FakeXRAnchorCreationCallback
callback
can
be
used
by
the
Web
Platform
Tests
to
control
the
result
of
a
call
to
create
an
anchor,
and
to
be
able
to
subsequently
control
the
newly
created
anchor.
The
FakeXRDevice
interface
is
extended
with
internal
anchorCreationCallback
,
initially
set
to
null
.
When
the
device
receives
a
request
to
create
an
anchor,
it
MUST
run
the
determine
if
the
anchor
creation
succeeded
algorithm.
In
order
to
determine
if
the
anchor
creation
succeeded
,
the
FakeXRDevice
device
MUST
run
the
following
steps:
-
If the device ’s anchorCreationCallback is
null, returnfalseand abort these steps. -
Let promise be the result of invoking anchorCreationCallback with parameters set so that they reflect the parameters passed to anchor creation request.
-
React to promise :
-
If promise was fulfilled with value v , then return v and abort these steps.
-
If promise was rejected, then return
falseand abort these steps.
-
The
WPTs
can
set
the
anchor
creation
callback
by
calling
setAnchorCreationCallback(callback)
.
The
requestedAnchorOrigin
attribute
represents
a
transform
expressed
relative
to
base
reference
space
used
by
the
device.
The
isAttachedToEntity
attribute
will
be
set
to
true
if
the
created
anchor
should
be
treated
as
attached
to
some
entity.
If
so,
the
tests
could
emulate
entity
changing
location
by
appropriately
controlling
the
anchor
via
anchorController
.
The
anchorController
parameter
passed
in
to
FakeXRAnchorCreationCallback
can
be
used
to
update
the
state
of
the
anchor,
assuming
that
the
creation
request
was
deemed
successful.
Tests
SHOULD
store
it
and
issue
commands
to
it
for
the
entire
duration
of
controlled
anchor’s
lifetime.
interface {FakeXRAnchorController readonly attribute boolean ; // Controlling anchor state:deleted undefined ();pauseTracking undefined ();resumeTracking undefined (); // Controlling anchor location:stopTracking undefined (setAnchorOrigin FakeXRRigidTransformInit ); };anchorOrigin
Successfully
created
anchors
can
be
controlled
by
the
test
through
the
use
of
FakeXRAnchorController
interface.
The
FakeXRAnchorController
has
an
associated
internal
anchor
origin
,
which
is
a
FakeXRRigidTransformInit
describing
the
current
state
of
the
anchor’s
native
origin
.
The
deleted
attribute
will
be
set
to
true
when
the
application
has
invoked
an
delete()
method
on
the
anchor
-
in
that
case,
the
changes
to
the
fake
anchor
controller
will
be
ignored.
The
pauseTracking()
method
can
be
used
by
the
tests
to
signal
that
the
controlled
anchor
is
temporarily
untracked
(i.e.
its
location
will
be
unknown).
Calling
this
method
does
not
modify
anchor
origin
of
the
controller.
The
resumeTracking()
method
can
be
used
by
the
tests
to
signal
that
the
controlled
anchor
should
have
its
tracking
resumed,
if
it
was
temporarily
untracked.
Calling
this
method
does
not
modify
anchor
origin
of
the
controller.
The
stopTracking()
method
can
be
used
by
the
tests
to
signal
that
the
controlled
anchor
is
no
longer
tracked
and
that
anchor
tracking
will
not
be
resumed.
After
calling
this
method,
the
other
calls
on
anchor
controller
will
be
ignored.
The
setAnchorOrigin(anchorOrigin)
method
can
be
used
to
set
the
controller’s
anchor
origin
.
Tests
can
use
this
method
to
simulate
updates
in
anchor
pose.
9. Lighting estimation extensions
The lighting estimation extensions for test API SHOULD be implemented by all user agents that implement WebXR Lighting Estimation .
dictionary {FakeXRLightEstimateInit required sequence <float >;sphericalHarmonicsCoefficients DOMPointInit ;primaryLightDirection DOMPointInit ; };primaryLightIntensity partial interface FakeXRDevice {undefined setLightEstimate (FakeXRLightEstimateInit ); };init
The
FakeXRDevice
is
extended
with
internal
light
estimate
which
is
a
FakeXRLightEstimateInit
,
used
to
supply
data
for
any
requested
XRLightEstimate
.
setLightEstimate(
init
)
method
is
invoked
on
FakeXRDevice
device
,
run
the
following
steps:
-
Let c be init ’s
sphericalHarmonicsCoefficients. -
If c does not have 27 elements, throw a
TypeErrorand abort these steps. -
Let d be init ’s
primaryLightDirection. -
If d is set and d ’s
wvalue does not equal0, throw aTypeErrorand abort these steps. -
Let i be init ’s
primaryLightIntensity. -
If i is set and i ’s
wvalue does not equal1, throw aTypeErrorand abort these steps. -
Set device ’s light estimate to init by the next animation frame .
10. Depth sensing extensions
The depth sensing extensions for test API SHOULD be implemented by all user agents that implement WebXR Depth Sensing Module .
The
FakeXRDevice
is
extended
with
internal
depth
sensing
data
which
is
a
FakeXRDepthSensingDataInit
,
used
to
supply
data
for
requests
to
native
depth
sensing
.
dictionary {FakeXRDepthConfigurationSupport sequence <XRDepthType >;depthTypes sequence <XRDepthFormat >;depthFormats sequence <XRDepthUsage >; };depthUsages
The
FakeXRDepthConfigurationSupport
dictionary
is
used
to
define
the
native
depth
sensing
capabilities
of
a
simulated
XR
device
.
Missing
or
empty
sequences
for
depthTypes
,
depthFormats
,
or
depthUsages
indicate
that
all
possible
values
for
that
respective
enumeration
are
supported
by
the
simulated
XR
device
.
If
a
User
Agent
does
not
support
a
particular
value
for
any
real
device
that
it
supports,
it
SHOULD
ignore
the
presence
of
that
value
in
any
of
these
lists,
in
order
to
generate
a
more
appropriate
failure.
Note: For simplicity, the simulated XR device is presumed to support the cross-product of all supported types, formats, and usages. There is currently no mechanism in this test API to specify support for only specific combinations (e.g., a particular format and type only with a particular usage).
dictionary {FakeXRDepthSensingDataInit required ArrayBuffer ;depthData required XRDepthFormat ;depthFormat required FakeXRRigidTransformInit ;normDepthBufferFromNormView required float ;rawValueToMeters required unsigned long ;width required unsigned long ;height sequence <float >;projectionMatrix FakeXRRigidTransformInit ; };viewOffset
FakeXRDepthSensingDataInit
dictionary
describes
the
state
of
the
depth
sensing
data
that
should
be
used
when
returning
latest
depth
information
in
creating
a
CPU
depth
information
instance
and
creating
a
GPU
depth
information
instance
algorithms.
All
keys
present
in
FakeXRDepthSensingDataInit
correspond
to
the
data
required
to
be
returned
by
native
depth
sensing
capabilities
of
the
device.
depthData
corresponds
to
the
desired
depth
buffer
that
is
to
be
set
on
native
depth
information
returned
from
querying
the
native
device.
Not
setting
depthData
key
in
the
dictionary
signals
that
the
returned
native
depth
information
should
be
null
.
depthFormat
indicates
the
XRDepthFormat
of
the
data
set
in
depthData
.
normDepthBufferFromNormView
corresponds
to
the
desired
depth
coordinates
transformation
matrix
that
is
to
be
set
on
native
depth
information
returned
from
querying
the
native
device.
rawValueToMeters
corresponds
to
the
desired
conversion
factor
that
is
to
be
set
on
native
depth
information
returned
from
querying
the
native
device.
width
and
height
correspond
to
the
desired
dimensions
of
the
depth
buffer
that
are
to
be
set
on
native
depth
information
returned
from
querying
the
native
device.
projectionMatrix
is
an
optional
16-element
sequence
of
floats
representing
a
projection
matrix.
If
present,
this
matrix
is
intended
to
define
the
projection
matrix
for
the
sensor
’s
XRViewGeometry
.
If
not
present,
the
sensor
geometry’s
projection
matrix
is
assumed
to
be
aligned
with
the
projection
matrix
of
the
XRViewGeometry
of
the
view
for
which
the
depth
information
is
being
created.
viewOffset
is
an
optional
FakeXRRigidTransformInit
.
If
present,
this
transform
is
intended
to
define
the
view
offset
for
the
sensor
’s
XRViewGeometry
,
relative
to
the
base
reference
space
.
If
not
present,
the
sensor
geometry’s
transform
is
assumed
to
be
aligned
with
the
view
offset
of
the
XRViewGeometry
of
the
view
for
which
the
depth
information
is
being
created.
When
the
setDepthSensingData()
method
is
invoked
on
FakeXRDevice
device
with
depthSensingData
,
run
the
following
steps:
-
If depthSensingData ’s
depthDataisnull, throw aTypeErrorand abort these steps. -
If depthSensingData ’s
projectionMatrixis set and its size is not 16, throw aTypeErrorand abort these steps. -
If depthSensingData ’s
viewOffsetis set, run parse a rigid transform on depthSensingData ’sviewOffset. -
Set device ’s depth sensing data to depthSensingData .
When
the
clearDepthSensingData()
method
is
invoked
on
FakeXRDevice
device
,
run
the
following
steps:
-
Set device ’s depth sensing data to
null.
11. Raw camera access extensions
The raw camera access extensions for test API SHOULD be implemented by all user agents that implement WebXR Raw Camera Access Module .
The
FakeXRViewInit
dictionary
is
extended
with
cameraImageInit
dictionary
of
type
FakeXRDeviceResolution
.
This
dictionary
carries
information
about
the
camera
image,
and
is
intended
to
affect
the
camera
image
variable
in
obtain
camera
algorithm.
If
the
cameraImageInit
key
is
not
present
in
the
FakeXRViewInit
dictionary,
the
obtain
camera
algorithm
should
treat
this
as
null
camera
image
(and
thus
the
algorithm
will
return
null
).
dictionary {FakeXRCameraImage required long ;width required long ;height Uint32Array ; };pixels
The
width
controls
the
width
of
the
camera
image
buffer
in
obtain
camera
algorithm.
The
height
controls
the
height
of
the
camera
image
buffer
in
obtain
camera
algorithm.
The
pixels
control
the
camera
image
contents
in
obtain
camera
algorithm.
The
pixels
will
be
used
to
initialize
the
camera
image
texture.
The
camera
image
will
be
initialized
as
if
by
a
call
to
gl.texImage2D(gl.TEXTURE_2D,
0,
gl.RGBA,
width,
height,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
pixels)
,
where
width
,
height
,
and
pixels
are,
respectively,
width
,
height
,
and
pixels
.
In
case
pixels
key
is
not
present
in
the
dictionary,
the
behavior
would
be
as
if
a
call
to
gl.texImage2D()
variant
that
omits
the
pixels
parameter
was
made.
Any
time
a
simulated
XR
device
’s
list
of
primary
views
and
list
of
secondary
views
is
set,
the
user
agent
MUST
verify
that
the
camera
images
associated
with
the
views
present
across
both
of
those
lists
are
all
equal
to
each
other.
Camera
images
are
considered
equal
when
their
width
s
and
height
s
are
equal,
and
their
pixels
are
the
same
instance
(if
present).
If
they
are
not
equal,
the
user
agent
MUST
throw
an
error
from
within
the
algorithm
that
attempted
to
set
them.