From 89fac8be5cca24b1d67259d8f27bd829e188a632 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Apr 2020 12:25:16 -0700 Subject: [PATCH] Add XRJointSpace --- components/script/dom/bindings/trace.rs | 1 + components/script/dom/mod.rs | 1 + .../script/dom/webidls/XRJointSpace.webidl | 8 +++ components/script/dom/xrjointspace.rs | 60 +++++++++++++++++++ components/script/dom/xrspace.rs | 5 ++ 5 files changed, 75 insertions(+) create mode 100644 components/script/dom/webidls/XRJointSpace.webidl create mode 100644 components/script/dom/xrjointspace.rs diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 7a15870e917c..c2543cc984bd 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -554,6 +554,7 @@ unsafe_no_jsmanaged_fields!( webxr_api::Frame, webxr_api::InputSource, webxr_api::InputId, + webxr_api::Joint, webxr_api::HitTestId, webxr_api::HitTestResult ); diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 5c2ab9783163..7365fe36a18a 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -579,6 +579,7 @@ pub mod xrinputsource; pub mod xrinputsourcearray; pub mod xrinputsourceevent; pub mod xrinputsourceschangeevent; +pub mod xrjointspace; pub mod xrlayer; pub mod xrmediabinding; pub mod xrpose; diff --git a/components/script/dom/webidls/XRJointSpace.webidl b/components/script/dom/webidls/XRJointSpace.webidl new file mode 100644 index 000000000000..0815a73ec58d --- /dev/null +++ b/components/script/dom/webidls/XRJointSpace.webidl @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +// https://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md + +[SecureContext, Exposed=Window, Pref="dom.webxr.hands.enabled"] +interface XRJointSpace: XRSpace {}; diff --git a/components/script/dom/xrjointspace.rs b/components/script/dom/xrjointspace.rs new file mode 100644 index 000000000000..4b31b0bc6a2c --- /dev/null +++ b/components/script/dom/xrjointspace.rs @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use crate::dom::xrsession::{ApiPose, XRSession}; +use crate::dom::xrspace::XRSpace; +use dom_struct::dom_struct; +use euclid::RigidTransform3D; +use webxr_api::{BaseSpace, Frame, InputId, Joint, JointFrame, Space}; + +#[dom_struct] +pub struct XRJointSpace { + xrspace: XRSpace, + #[ignore_malloc_size_of = "defined in rust-webxr"] + input: InputId, + #[ignore_malloc_size_of = "defined in rust-webxr"] + joint: Joint, +} + +impl XRJointSpace { + pub fn new_inherited(session: &XRSession, input: InputId, joint: Joint) -> XRJointSpace { + XRJointSpace { + xrspace: XRSpace::new_inherited(session), + input, + joint, + } + } + + #[allow(unused)] + pub fn new( + global: &GlobalScope, + session: &XRSession, + input: InputId, + joint: Joint, + ) -> DomRoot { + reflect_dom_object(Box::new(Self::new_inherited(session, input, joint)), global) + } + + pub fn space(&self) -> Space { + let base = BaseSpace::Joint(self.input, self.joint); + let offset = RigidTransform3D::identity(); + Space { base, offset } + } + + pub fn frame<'a>(&self, frame: &'a Frame) -> Option<&'a JointFrame> { + frame + .inputs + .iter() + .find(|i| i.id == self.input) + .and_then(|i| i.hand.as_ref()) + .and_then(|h| h.get(self.joint)) + } + + pub fn get_pose(&self, frame: &Frame) -> Option { + self.frame(frame).map(|f| f.pose).map(|t| t.cast_unit()) + } +} diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs index b4a26b7b8bbb..66dd5b44e70f 100644 --- a/components/script/dom/xrspace.rs +++ b/components/script/dom/xrspace.rs @@ -8,6 +8,7 @@ use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::xrinputsource::XRInputSource; +use crate::dom::xrjointspace::XRJointSpace; use crate::dom::xrreferencespace::XRReferenceSpace; use crate::dom::xrsession::{cast_transform, ApiPose, XRSession}; use dom_struct::dom_struct; @@ -61,6 +62,8 @@ impl XRSpace { pub fn space(&self) -> Space { if let Some(rs) = self.downcast::() { rs.space() + } else if let Some(j) = self.downcast::() { + j.space() } else if let Some(source) = self.input_source.get() { let base = if self.is_grip_space { BaseSpace::Grip(source.id()) @@ -86,6 +89,8 @@ impl XRSpace { pub fn get_pose(&self, base_pose: &Frame) -> Option { if let Some(reference) = self.downcast::() { reference.get_pose(base_pose) + } else if let Some(joint) = self.downcast::() { + joint.get_pose(base_pose) } else if let Some(source) = self.input_source.get() { // XXXManishearth we should be able to request frame information // for inputs when necessary instead of always loading it