Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some XRSpace improvements #23055

Merged
merged 8 commits into from Mar 21, 2019
@@ -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 {
@@ -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);
};
@@ -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;
};
@@ -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;
};
@@ -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;
};
@@ -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;
@@ -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))
}
}
@@ -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()
}
}
@@ -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)
}
}
@@ -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
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.