Auto merge of #23055 - Manishearth:xrspace, r=asajeffrey

Some XRSpace improvements

Proper XRSpace support is blocked on https://github.com/immersive-web/webxr/issues/565 , but in the meantime this improves XRSpace support a little bit, preparing both for support in getViewerPose and getPose as well as handling input spaces eventually.

r? @jdm

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23055)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2019-03-20 21:37:52 -04:00 committed by GitHub
commit e58226814f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 206 additions and 53 deletions

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
use crate::dom::bindings::codegen::Bindings::DOMPointReadOnlyBinding::{
DOMPointReadOnlyMethods, Wrap,
};
@ -50,6 +51,10 @@ impl DOMPointReadOnly {
) -> Fallible<DomRoot<DOMPointReadOnly>> {
Ok(DOMPointReadOnly::new(global, x, y, z, w))
}
pub fn new_from_init(global: &GlobalScope, p: &DOMPointInit) -> DomRoot<DOMPointReadOnly> {
DOMPointReadOnly::new(global, p.x, p.y, p.z, p.w)
}
}
impl DOMPointReadOnlyMethods for DOMPointReadOnly {

View file

@ -8,6 +8,6 @@
interface XRFrame {
readonly attribute XRSession session;
XRViewerPose? getViewerPose(optional XRReferenceSpace referenceSpace);
XRViewerPose? getViewerPose(XRReferenceSpace referenceSpace);
// XRInputPose? getInputPose(XRInputSource inputSource, optional XRReferenceSpace referenceSpace);
};

View file

@ -4,18 +4,8 @@
// https://immersive-web.github.io/webxr/#xrreferencespace-interface
enum XRReferenceSpaceType {
"stationary",
"bounded",
"unbounded"
};
dictionary XRReferenceSpaceOptions {
required XRReferenceSpaceType type;
};
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
interface XRReferenceSpace : XRSpace {
// attribute XRRigidTransform originOffset;
attribute XRRigidTransform originOffset;
// attribute EventHandler onreset;
};

View file

@ -4,10 +4,10 @@
// https://immersive-web.github.io/webxr/#xrrigidtransform-interface
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
// [Constructor(optional DOMPointInit position, optional DOMPointInit orientation)]
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled",
Constructor(optional DOMPointInit position, optional DOMPointInit orientation)]
interface XRRigidTransform {
// readonly attribute DOMPointReadOnly position;
// readonly attribute DOMPointReadOnly orientation;
readonly attribute DOMPointReadOnly position;
readonly attribute DOMPointReadOnly orientation;
// readonly attribute Float32Array matrix;
};

View file

@ -24,8 +24,7 @@ interface XRSession : EventTarget {
attribute XRLayer? baseLayer;
// // Methods
// Promise<XRReferenceSpace> requestReferenceSpace(XRReferenceSpaceType type,
// optional XRReferenceSpaceOptions options);
Promise<XRReferenceSpace> requestReferenceSpace(XRReferenceSpaceOptions options);
// FrozenArray<XRInputSource> getInputSources();
@ -43,3 +42,15 @@ interface XRSession : EventTarget {
// attribute EventHandler onselectstart;
// attribute EventHandler onselectend;
};
enum XRReferenceSpaceType {
"identity",
"stationary",
"bounded",
"unbounded"
};
dictionary XRReferenceSpaceOptions {
required XRReferenceSpaceType type;
XRStationaryReferenceSpaceSubtype subtype;
};

View file

@ -10,10 +10,6 @@ enum XRStationaryReferenceSpaceSubtype {
"position-disabled"
};
dictionary XRStationaryReferenceSpaceOptions : XRReferenceSpaceOptions {
required XRStationaryReferenceSpaceSubtype subtype;
};
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
interface XRStationaryReferenceSpace: XRReferenceSpace {
// readonly attribute XRStationaryReferenceSpaceSubtype subtype;

View file

@ -5,11 +5,13 @@
use crate::dom::bindings::codegen::Bindings::XRFrameBinding;
use crate::dom::bindings::codegen::Bindings::XRFrameBinding::XRFrameMethods;
use crate::dom::bindings::codegen::Bindings::XRViewBinding::XREye;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::globalscope::GlobalScope;
use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrsession::XRSession;
use crate::dom::xrstationaryreferencespace::XRStationaryReferenceSpace;
use crate::dom::xrview::XRView;
use crate::dom::xrviewerpose::XRViewerPose;
use dom_struct::dom_struct;
@ -52,16 +54,17 @@ impl XRFrameMethods for XRFrame {
}
/// https://immersive-web.github.io/webxr/#dom-xrframe-getviewerpose
fn GetViewerPose(&self, reference: Option<&XRReferenceSpace>) -> Option<DomRoot<XRViewerPose>> {
// We assume the reference space is eye level for now
// since it's the only one 3DOF devices support
if reference.is_some() {
// it's not possible to obtain a reference
// space at all yet
return None;
fn GetViewerPose(&self, reference: &XRReferenceSpace) -> Option<DomRoot<XRViewerPose>> {
if let Some(_) = reference.downcast::<XRStationaryReferenceSpace>() {
// For 3DOF devices all three kinds of reference spaces are identical
// FIXME(#23070, Manishearth) support originOffset
let left = XRView::new(&self.global(), &self.session, XREye::Left, &self.data);
let right = XRView::new(&self.global(), &self.session, XREye::Right, &self.data);
Some(XRViewerPose::new(&self.global(), &left, &right))
} else {
// FIXME(#23070, Manishearth) support identity reference spaces
// depends on https://github.com/immersive-web/webxr/issues/565
None
}
let left = XRView::new(&self.global(), &self.session, XREye::Left, &self.data);
let right = XRView::new(&self.global(), &self.session, XREye::Right, &self.data);
Some(XRViewerPose::new(&self.global(), &left, &right))
}
}

View file

@ -3,30 +3,64 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::codegen::Bindings::XRReferenceSpaceBinding;
use crate::dom::bindings::codegen::Bindings::XRReferenceSpaceBinding::XRReferenceSpaceMethods;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::bindings::root::{DomRoot, MutDom};
use crate::dom::dompointreadonly::DOMPointReadOnly;
use crate::dom::window::Window;
use crate::dom::xrrigidtransform::XRRigidTransform;
use crate::dom::xrsession::XRSession;
use crate::dom::xrspace::XRSpace;
use dom_struct::dom_struct;
#[dom_struct]
pub struct XRReferenceSpace {
xrspace: XRSpace,
transform: MutDom<XRRigidTransform>,
}
impl XRReferenceSpace {
pub fn new_inherited() -> XRReferenceSpace {
pub fn new_inherited(session: &XRSession, transform: &XRRigidTransform) -> XRReferenceSpace {
XRReferenceSpace {
xrspace: XRSpace::new_inherited(),
xrspace: XRSpace::new_inherited(session),
transform: MutDom::new(transform),
}
}
#[allow(unused)]
pub fn new(global: &GlobalScope) -> DomRoot<XRReferenceSpace> {
pub fn new(
global: &Window,
session: &XRSession,
position: &DOMPointReadOnly,
orientation: &DOMPointReadOnly,
) -> DomRoot<XRReferenceSpace> {
let transform = XRRigidTransform::new(global, position, orientation);
reflect_dom_object(
Box::new(XRReferenceSpace::new_inherited()),
Box::new(XRReferenceSpace::new_inherited(session, &transform)),
global,
XRReferenceSpaceBinding::Wrap,
)
}
#[allow(unused)]
pub fn identity(global: &Window, session: &XRSession) -> DomRoot<XRReferenceSpace> {
let transform = XRRigidTransform::identity(global);
reflect_dom_object(
Box::new(XRReferenceSpace::new_inherited(session, &transform)),
global,
XRReferenceSpaceBinding::Wrap,
)
}
}
impl XRReferenceSpaceMethods for XRReferenceSpace {
/// https://immersive-web.github.io/webxr/#dom-xrreferencespace-originoffset
fn SetOriginOffset(&self, transform: &XRRigidTransform) {
self.transform.set(transform);
}
/// https://immersive-web.github.io/webxr/#dom-xrreferencespace-originoffset
fn OriginOffset(&self) -> DomRoot<XRRigidTransform> {
self.transform.get()
}
}

View file

@ -2,30 +2,81 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding;
use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding::XRRigidTransformMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::dompointreadonly::DOMPointReadOnly;
use crate::dom::window::Window;
use dom_struct::dom_struct;
#[dom_struct]
pub struct XRRigidTransform {
reflector_: Reflector,
position: Dom<DOMPointReadOnly>,
orientation: Dom<DOMPointReadOnly>,
}
impl XRRigidTransform {
fn new_inherited() -> XRRigidTransform {
fn new_inherited(
position: &DOMPointReadOnly,
orientation: &DOMPointReadOnly,
) -> XRRigidTransform {
XRRigidTransform {
reflector_: Reflector::new(),
position: Dom::from_ref(position),
orientation: Dom::from_ref(orientation),
}
}
#[allow(unused)]
pub fn new(global: &GlobalScope) -> DomRoot<XRRigidTransform> {
pub fn new(
global: &Window,
position: &DOMPointReadOnly,
orientation: &DOMPointReadOnly,
) -> DomRoot<XRRigidTransform> {
reflect_dom_object(
Box::new(XRRigidTransform::new_inherited()),
Box::new(XRRigidTransform::new_inherited(position, orientation)),
global,
XRRigidTransformBinding::Wrap,
)
}
#[allow(unused)]
pub fn identity(window: &Window) -> DomRoot<XRRigidTransform> {
let global = window.global();
let position = DOMPointReadOnly::new(&global, 0., 0., 0., 1.);
let orientation = DOMPointReadOnly::new(&global, 0., 0., 0., 1.);
reflect_dom_object(
Box::new(XRRigidTransform::new_inherited(&position, &orientation)),
window,
XRRigidTransformBinding::Wrap,
)
}
// https://immersive-web.github.io/webxr/#dom-xrrigidtransform-xrrigidtransform
pub fn Constructor(
window: &Window,
position: &DOMPointInit,
orientation: &DOMPointInit,
) -> Fallible<DomRoot<Self>> {
let global = window.global();
let position = DOMPointReadOnly::new_from_init(&global, &position);
let orientation = DOMPointReadOnly::new_from_init(&global, &orientation);
Ok(XRRigidTransform::new(window, &position, &orientation))
}
}
impl XRRigidTransformMethods for XRRigidTransform {
// https://immersive-web.github.io/webxr/#dom-xrrigidtransform-position
fn Position(&self) -> DomRoot<DOMPointReadOnly> {
DomRoot::from_ref(&self.position)
}
// https://immersive-web.github.io/webxr/#dom-xrrigidtransform-orientation
fn Orientation(&self) -> DomRoot<DOMPointReadOnly> {
DomRoot::from_ref(&self.orientation)
}
}

View file

@ -7,17 +7,23 @@ use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionMode;
use crate::dom::bindings::codegen::Bindings::XRSessionBinding;
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XREnvironmentBlendMode;
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCallback;
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRReferenceSpaceOptions;
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRReferenceSpaceType;
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
use crate::dom::bindings::error::Error;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::dom::vrdisplay::VRDisplay;
use crate::dom::xrlayer::XRLayer;
use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrstationaryreferencespace::XRStationaryReferenceSpace;
use crate::dom::xrwebgllayer::XRWebGLLayer;
use dom_struct::dom_struct;
use std::rc::Rc;
@ -111,4 +117,42 @@ impl XRSessionMethods for XRSession {
fn EnvironmentBlendMode(&self) -> XREnvironmentBlendMode {
self.blend_mode
}
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestreferencespace
fn RequestReferenceSpace(&self, options: &XRReferenceSpaceOptions) -> Rc<Promise> {
let p = Promise::new(&self.global());
// https://immersive-web.github.io/webxr/#create-a-reference-space
// XXXManishearth reject based on session type
// https://github.com/immersive-web/webxr/blob/master/spatial-tracking-explainer.md#practical-usage-guidelines
match options.type_ {
XRReferenceSpaceType::Identity => {
p.resolve_native(&XRReferenceSpace::identity(
&self.global().as_window(),
self,
));
},
XRReferenceSpaceType::Stationary => {
if let Some(subtype) = options.subtype {
p.resolve_native(&XRStationaryReferenceSpace::new(
&self.global().as_window(),
self,
subtype,
));
} else {
p.reject_error(Error::Type(format!(
"stationary XRReferenceSpaces must specify a subtype"
)))
}
},
XRReferenceSpaceType::Bounded | XRReferenceSpaceType::Unbounded => {
// XXXManishearth eventually support these
p.reject_error(Error::NotSupported)
},
}
p
}
}

View file

@ -4,27 +4,30 @@
use crate::dom::bindings::codegen::Bindings::XRSpaceBinding;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::xrsession::XRSession;
use dom_struct::dom_struct;
#[dom_struct]
pub struct XRSpace {
eventtarget: EventTarget,
session: Dom<XRSession>,
}
impl XRSpace {
pub fn new_inherited() -> XRSpace {
pub fn new_inherited(session: &XRSession) -> XRSpace {
XRSpace {
eventtarget: EventTarget::new_inherited(),
session: Dom::from_ref(session),
}
}
#[allow(unused)]
pub fn new(global: &GlobalScope) -> DomRoot<XRSpace> {
pub fn new(global: &GlobalScope, session: &XRSession) -> DomRoot<XRSpace> {
reflect_dom_object(
Box::new(XRSpace::new_inherited()),
Box::new(XRSpace::new_inherited(session)),
global,
XRSpaceBinding::Wrap,
)

View file

@ -3,29 +3,45 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::codegen::Bindings::XRStationaryReferenceSpaceBinding;
use crate::dom::bindings::codegen::Bindings::XRStationaryReferenceSpaceBinding::XRStationaryReferenceSpaceSubtype;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrrigidtransform::XRRigidTransform;
use crate::dom::xrsession::XRSession;
use dom_struct::dom_struct;
#[dom_struct]
pub struct XRStationaryReferenceSpace {
xrreferencespace: XRReferenceSpace,
ty: XRStationaryReferenceSpaceSubtype,
}
#[allow(unused)]
impl XRStationaryReferenceSpace {
pub fn new_inherited() -> XRStationaryReferenceSpace {
pub fn new_inherited(
session: &XRSession,
ty: XRStationaryReferenceSpaceSubtype,
transform: &XRRigidTransform,
) -> XRStationaryReferenceSpace {
XRStationaryReferenceSpace {
xrreferencespace: XRReferenceSpace::new_inherited(),
xrreferencespace: XRReferenceSpace::new_inherited(session, transform),
ty,
}
}
pub fn new(global: &GlobalScope) -> DomRoot<XRStationaryReferenceSpace> {
pub fn new(
window: &Window,
session: &XRSession,
ty: XRStationaryReferenceSpaceSubtype,
) -> DomRoot<XRStationaryReferenceSpace> {
let transform = XRRigidTransform::identity(window);
reflect_dom_object(
Box::new(XRStationaryReferenceSpace::new_inherited()),
global,
Box::new(XRStationaryReferenceSpace::new_inherited(
session, ty, &transform,
)),
window,
XRStationaryReferenceSpaceBinding::Wrap,
)
}