diff options
author | Manish Goregaokar <manishsmail@gmail.com> | 2019-03-21 14:50:02 -0700 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2019-03-25 15:35:20 -0700 |
commit | d1d8e97c304b31f292c17d8d8f84a13cf12f74cd (patch) | |
tree | 3f4628bfcc3638821647e4ebbc355d558f3f621b /components/script | |
parent | 1e1f527c8271463adea170eb9e93508fa0c261b5 (diff) | |
download | servo-d1d8e97c304b31f292c17d8d8f84a13cf12f74cd.tar.gz servo-d1d8e97c304b31f292c17d8d8f84a13cf12f74cd.zip |
Add XRSpace::get_viewer_pose()
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/xrreferencespace.rs | 34 | ||||
-rw-r--r-- | components/script/dom/xrrigidtransform.rs | 21 | ||||
-rw-r--r-- | components/script/dom/xrspace.rs | 26 | ||||
-rw-r--r-- | components/script/dom/xrstationaryreferencespace.rs | 22 |
4 files changed, 103 insertions, 0 deletions
diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs index a24ab48d0c1..1c137d575ce 100644 --- a/components/script/dom/xrreferencespace.rs +++ b/components/script/dom/xrreferencespace.rs @@ -4,6 +4,7 @@ use crate::dom::bindings::codegen::Bindings::XRReferenceSpaceBinding; use crate::dom::bindings::codegen::Bindings::XRReferenceSpaceBinding::XRReferenceSpaceMethods; +use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::{DomRoot, MutDom}; use crate::dom::dompointreadonly::DOMPointReadOnly; @@ -11,7 +12,10 @@ use crate::dom::window::Window; use crate::dom::xrrigidtransform::XRRigidTransform; use crate::dom::xrsession::XRSession; use crate::dom::xrspace::XRSpace; +use crate::dom::xrstationaryreferencespace::XRStationaryReferenceSpace; use dom_struct::dom_struct; +use euclid::Transform3D; +use webvr_traits::WebVRFrameData; #[dom_struct] pub struct XRReferenceSpace { @@ -64,3 +68,33 @@ impl XRReferenceSpaceMethods for XRReferenceSpace { self.transform.get() } } + +impl XRReferenceSpace { + /// Gets viewer pose represented by this space + pub fn get_viewer_pose(&self, base_pose: &WebVRFrameData) -> Transform3D<f64> { + let pose = self.get_pose(base_pose); + + // This may change, see https://github.com/immersive-web/webxr/issues/567 + let offset = self.transform.get().matrix(); + // XXXManishearth we can directly compute the inverse from the transform parameters + // (and perhaps cache it) + // XXXManishearth we can also optimize for the unset/identity offset case + let inverse = offset + .inverse() + .expect("rigid transforms are always invertible"); + inverse.pre_mul(&pose) + } + + /// Gets pose represented by this space + /// + /// Does not apply originOffset, use get_viewer_pose instead if you need it + pub fn get_pose(&self, base_pose: &WebVRFrameData) -> Transform3D<f64> { + if let Some(stationary) = self.downcast::<XRStationaryReferenceSpace>() { + stationary.get_pose(base_pose) + } else { + // non-subclassed XRReferenceSpaces exist, obtained via the "identity" + // type. The pose does not depend on the base pose. + Transform3D::identity() + } + } +} diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs index 3f726475517..2999ce7a1b1 100644 --- a/components/script/dom/xrrigidtransform.rs +++ b/components/script/dom/xrrigidtransform.rs @@ -3,6 +3,7 @@ * 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::DOMPointReadOnlyBinding::DOMPointReadOnlyMethods; use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding; use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding::XRRigidTransformMethods; use crate::dom::bindings::error::Fallible; @@ -12,6 +13,7 @@ use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::dompointreadonly::DOMPointReadOnly; use crate::dom::window::Window; use dom_struct::dom_struct; +use euclid::{Rotation3D, Transform3D}; #[dom_struct] pub struct XRRigidTransform { @@ -65,6 +67,7 @@ impl XRRigidTransform { ) -> Fallible<DomRoot<Self>> { let global = window.global(); let position = DOMPointReadOnly::new_from_init(&global, &position); + // XXXManishearth normalize this let orientation = DOMPointReadOnly::new_from_init(&global, &orientation); Ok(XRRigidTransform::new(window, &position, &orientation)) } @@ -80,3 +83,21 @@ impl XRRigidTransformMethods for XRRigidTransform { DomRoot::from_ref(&self.orientation) } } + +impl XRRigidTransform { + pub fn matrix(&self) -> Transform3D<f64> { + // XXXManishearth compute this during initialization + let translate = Transform3D::create_translation( + self.position.X(), + self.position.Y(), + self.position.Z(), + ); + let rotation = Rotation3D::unit_quaternion( + self.orientation.X(), + self.orientation.Y(), + self.orientation.Z(), + self.orientation.W(), + ); + translate.pre_mul(&rotation.to_transform()) + } +} diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs index e0d4ce75cf3..95ebb2625b3 100644 --- a/components/script/dom/xrspace.rs +++ b/components/script/dom/xrspace.rs @@ -3,12 +3,16 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 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::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::xrreferencespace::XRReferenceSpace; use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; +use euclid::Transform3D; +use webvr_traits::WebVRFrameData; #[dom_struct] pub struct XRSpace { @@ -33,3 +37,25 @@ impl XRSpace { ) } } + +impl XRSpace { + /// Gets viewer pose represented by this space + pub fn get_viewer_pose(&self, base_pose: &WebVRFrameData) -> Transform3D<f64> { + if let Some(reference) = self.downcast::<XRReferenceSpace>() { + reference.get_viewer_pose(base_pose) + } else { + unreachable!() + } + } + + /// Gets pose represented by this space + /// + /// Does not apply originOffset, use get_viewer_pose instead if you need it + pub fn get_pose(&self, base_pose: &WebVRFrameData) -> Transform3D<f64> { + if let Some(reference) = self.downcast::<XRReferenceSpace>() { + reference.get_pose(base_pose) + } else { + unreachable!() + } + } +} diff --git a/components/script/dom/xrstationaryreferencespace.rs b/components/script/dom/xrstationaryreferencespace.rs index 33d96f1488f..e8349ef3581 100644 --- a/components/script/dom/xrstationaryreferencespace.rs +++ b/components/script/dom/xrstationaryreferencespace.rs @@ -11,6 +11,8 @@ use crate::dom::xrreferencespace::XRReferenceSpace; use crate::dom::xrrigidtransform::XRRigidTransform; use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; +use euclid::{Rotation3D, Transform3D}; +use webvr_traits::WebVRFrameData; #[dom_struct] pub struct XRStationaryReferenceSpace { @@ -46,3 +48,23 @@ impl XRStationaryReferenceSpace { ) } } + +impl XRStationaryReferenceSpace { + /// Gets pose represented by this space + /// + /// Does not apply originOffset, use get_viewer_pose instead + pub fn get_pose(&self, base_pose: &WebVRFrameData) -> Transform3D<f64> { + // XXXManishearth add floor-level transform for floor-level and disable position in position-disabled + let pos = base_pose.pose.position.unwrap_or([0., 0., 0.]); + let translation = + Transform3D::create_translation(pos[0] as f64, pos[1] as f64, pos[2] as f64); + let orient = base_pose.pose.orientation.unwrap_or([0., 0., 0., 0.]); + let rotation = Rotation3D::quaternion( + orient[0] as f64, + orient[1] as f64, + orient[2] as f64, + orient[3] as f64, + ); + translation.pre_mul(&rotation.to_transform()) + } +} |