From d4a6a4987da86e363ccef6f3eaeeeee0cd8593aa Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 29 Apr 2019 20:27:07 -0700 Subject: [PATCH] Add XRInputSource.targetRaySpace --- .../script/dom/webidls/XRInputSource.webidl | 2 +- components/script/dom/xrinputsource.rs | 21 ++++++++-- components/script/dom/xrreferencespace.rs | 2 +- components/script/dom/xrspace.rs | 39 ++++++++++++++++--- .../script/dom/xrstationaryreferencespace.rs | 4 +- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/components/script/dom/webidls/XRInputSource.webidl b/components/script/dom/webidls/XRInputSource.webidl index 9270ff50823..5ad1e48628f 100644 --- a/components/script/dom/webidls/XRInputSource.webidl +++ b/components/script/dom/webidls/XRInputSource.webidl @@ -20,7 +20,7 @@ enum XRTargetRayMode { interface XRInputSource { readonly attribute XRHandedness handedness; // [SameObject] readonly attribute XRTargetRayMode targetRayMode; - // [SameObject] readonly attribute XRSpace targetRaySpace; + [SameObject] readonly attribute XRSpace targetRaySpace; // [SameObject] readonly attribute XRSpace? gripSpace; // [SameObject] readonly attribute Gamepad? gamepad; }; diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs index dcb86a23622..2b623864d56 100644 --- a/components/script/dom/xrinputsource.rs +++ b/components/script/dom/xrinputsource.rs @@ -7,12 +7,13 @@ use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding; use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{ XRHandedness, XRInputSourceMethods, }; -use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::globalscope::GlobalScope; use crate::dom::xrsession::XRSession; +use crate::dom::xrspace::XRSpace; use dom_struct::dom_struct; -use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState}; +use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState, WebVRPose}; #[dom_struct] pub struct XRInputSource { @@ -22,6 +23,7 @@ pub struct XRInputSource { data: WebVRGamepadData, #[ignore_malloc_size_of = "Defined in rust-webvr"] state: DomRefCell, + target_ray_space: MutNullableDom, } impl XRInputSource { @@ -35,6 +37,7 @@ impl XRInputSource { session: Dom::from_ref(session), data, state: DomRefCell::new(state), + target_ray_space: Default::default(), } } @@ -54,6 +57,10 @@ impl XRInputSource { pub fn update_state(&self, state: WebVRGamepadState) { *self.state.borrow_mut() = state; } + + pub fn pose(&self) -> WebVRPose { + self.state.borrow().pose + } } impl XRInputSourceMethods for XRInputSource { @@ -65,4 +72,12 @@ impl XRInputSourceMethods for XRInputSource { WebVRGamepadHand::Right => XRHandedness::Right, } } + + /// https://immersive-web.github.io/webxr/#dom-xrinputsource-targetrayspace + fn TargetRaySpace(&self) -> DomRoot { + self.target_ray_space.or_init(|| { + let global = self.global(); + XRSpace::new_inputspace(&global, &self.session, &self) + }) + } } diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs index 664dc4f0e23..932f917b5a5 100644 --- a/components/script/dom/xrreferencespace.rs +++ b/components/script/dom/xrreferencespace.rs @@ -110,7 +110,7 @@ impl XRReferenceSpace { // non-subclassed XRReferenceSpaces exist, obtained via the "identity" // type. These are equivalent to the viewer pose and follow the headset // around - XRSpace::viewer_pose_from_frame_data(base_pose) + XRSpace::pose_to_transform(&base_pose.pose) } } } diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs index 8948ac03c8e..30f9246c354 100644 --- a/components/script/dom/xrspace.rs +++ b/components/script/dom/xrspace.rs @@ -5,20 +5,22 @@ use crate::dom::bindings::codegen::Bindings::XRSpaceBinding; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::reflect_dom_object; -use crate::dom::bindings::root::{Dom, DomRoot}; +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::xrreferencespace::XRReferenceSpace; use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; use euclid::{RigidTransform3D, Rotation3D, Vector3D}; -use webvr_traits::WebVRFrameData; +use webvr_traits::{WebVRFrameData, WebVRPose}; #[dom_struct] pub struct XRSpace { eventtarget: EventTarget, session: Dom, is_viewerspace: bool, + input_source: MutNullableDom, } impl XRSpace { @@ -27,6 +29,7 @@ impl XRSpace { eventtarget: EventTarget::new_inherited(), session: Dom::from_ref(session), is_viewerspace: false, + input_source: Default::default(), } } @@ -35,6 +38,7 @@ impl XRSpace { eventtarget: EventTarget::new_inherited(), session: Dom::from_ref(session), is_viewerspace: true, + input_source: Default::default(), } } @@ -45,6 +49,27 @@ impl XRSpace { XRSpaceBinding::Wrap, ) } + + fn new_inputspace_inner(session: &XRSession, input: &XRInputSource) -> XRSpace { + XRSpace { + eventtarget: EventTarget::new_inherited(), + session: Dom::from_ref(session), + is_viewerspace: false, + input_source: MutNullableDom::new(Some(input)), + } + } + + pub fn new_inputspace( + global: &GlobalScope, + session: &XRSession, + input: &XRInputSource, + ) -> DomRoot { + reflect_dom_object( + Box::new(XRSpace::new_inputspace_inner(session, input)), + global, + XRSpaceBinding::Wrap, + ) + } } impl XRSpace { @@ -57,16 +82,18 @@ impl XRSpace { if let Some(reference) = self.downcast::() { reference.get_pose(base_pose) } else if self.is_viewerspace { - XRSpace::viewer_pose_from_frame_data(base_pose) + XRSpace::pose_to_transform(&base_pose.pose) + } else if let Some(source) = self.input_source.get() { + XRSpace::pose_to_transform(&source.pose()) } else { unreachable!() } } - pub fn viewer_pose_from_frame_data(data: &WebVRFrameData) -> RigidTransform3D { - let pos = data.pose.position.unwrap_or([0., 0., 0.]); + pub fn pose_to_transform(pose: &WebVRPose) -> RigidTransform3D { + let pos = pose.position.unwrap_or([0., 0., 0.]); let translation = Vector3D::new(pos[0] as f64, pos[1] as f64, pos[2] as f64); - let orient = data.pose.orientation.unwrap_or([0., 0., 0., 0.]); + let orient = pose.orientation.unwrap_or([0., 0., 0., 0.]); let rotation = Rotation3D::quaternion( orient[0] as f64, orient[1] as f64, diff --git a/components/script/dom/xrstationaryreferencespace.rs b/components/script/dom/xrstationaryreferencespace.rs index a867aa0d976..65a0aebb790 100644 --- a/components/script/dom/xrstationaryreferencespace.rs +++ b/components/script/dom/xrstationaryreferencespace.rs @@ -55,7 +55,7 @@ impl XRStationaryReferenceSpace { /// /// Does not apply originOffset, use get_viewer_pose on XRReferenceSpace instead pub fn get_unoffset_viewer_pose(&self, viewer_pose: &WebVRFrameData) -> RigidTransform3D { - let viewer_pose = XRSpace::viewer_pose_from_frame_data(viewer_pose); + let viewer_pose = XRSpace::pose_to_transform(&viewer_pose.pose); // all math is in column-vector notation // we use the following equation to verify correctness here: // get_viewer_pose(space) = get_pose(space).inverse() * get_pose(viewer_space) @@ -113,7 +113,7 @@ impl XRStationaryReferenceSpace { }, XRStationaryReferenceSpaceSubtype::Position_disabled => { // This space follows the user around, but does not mirror the user's orientation - let viewer_pose = XRSpace::viewer_pose_from_frame_data(viewer_pose); + let viewer_pose = XRSpace::pose_to_transform(&viewer_pose.pose); viewer_pose.translation.into() }, }