diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs index 4e570817fb8..f07ea8e7658 100644 --- a/components/script/dom/xrreferencespace.rs +++ b/components/script/dom/xrreferencespace.rs @@ -10,9 +10,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; use crate::dom::xrrigidtransform::XRRigidTransform; -use crate::dom::xrsession::{ - cast_transform, cast_transform_to_pose, ApiPose, ApiRigidTransform, XRSession, -}; +use crate::dom::xrsession::{cast_transform, ApiPose, ApiRigidTransform, ApiViewerPose, XRSession}; use crate::dom::xrspace::XRSpace; use dom_struct::dom_struct; use euclid::{TypedRigidTransform3D, TypedVector3D}; @@ -82,7 +80,7 @@ impl XRReferenceSpace { /// /// This is equivalent to `get_pose(self).inverse() * get_pose(viewerSpace)` (in column vector notation), /// however we specialize it to be efficient - pub fn get_viewer_pose(&self, base_pose: &Frame) -> ApiRigidTransform { + pub fn get_viewer_pose(&self, base_pose: &Frame) -> ApiViewerPose { let pose = self.get_unoffset_viewer_pose(base_pose); // This may change, see https://github.com/immersive-web/webxr/issues/567 @@ -100,8 +98,8 @@ impl XRReferenceSpace { /// Gets pose of the viewer with respect to this space /// /// Does not apply originOffset, use get_viewer_pose instead if you need it - pub fn get_unoffset_viewer_pose(&self, base_pose: &Frame) -> ApiRigidTransform { - let viewer_pose = cast_transform(base_pose.transform); + pub fn get_unoffset_viewer_pose(&self, base_pose: &Frame) -> ApiViewerPose { + let viewer_pose: ApiViewerPose = cast_transform(base_pose.transform); // 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) @@ -164,7 +162,7 @@ impl XRReferenceSpace { // the floor-level space is 2m below the eye-level space, which is (0, 0, 0) TypedVector3D::new(0., -2., 0.).into() }, - XRReferenceSpaceType::Viewer => cast_transform_to_pose(base_pose.transform), + XRReferenceSpaceType::Viewer => cast_transform(base_pose.transform), _ => unimplemented!(), } } diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 6dde73bcf8e..9a0dfdb3454 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -276,17 +276,14 @@ impl XRSessionMethods for XRSession { pub struct ApiSpace; // The pose of an object in native-space. Should never be exposed. pub type ApiPose = TypedRigidTransform3D; +// The pose of the viewer in some api-space. +pub type ApiViewerPose = TypedRigidTransform3D; // A transform between objects in some API-space pub type ApiRigidTransform = TypedRigidTransform3D; #[allow(unsafe_code)] -pub fn cast_transform_to_pose( - transform: TypedRigidTransform3D, -) -> ApiPose { - unsafe { mem::transmute(transform) } -} - -#[allow(unsafe_code)] -pub fn cast_transform(transform: TypedRigidTransform3D) -> ApiRigidTransform { +pub fn cast_transform( + transform: TypedRigidTransform3D, +) -> TypedRigidTransform3D { unsafe { mem::transmute(transform) } } diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index 122ba83fbbf..5ff8d397bd6 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -9,7 +9,7 @@ use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; use crate::dom::vrframedata::create_typed_array; use crate::dom::xrrigidtransform::XRRigidTransform; -use crate::dom::xrsession::{cast_transform, ApiRigidTransform, XRSession}; +use crate::dom::xrsession::{cast_transform, ApiViewerPose, XRSession}; use dom_struct::dom_struct; use js::jsapi::{Heap, JSContext, JSObject}; use std::ptr::NonNull; @@ -45,13 +45,16 @@ impl XRView { session: &XRSession, view: &View, eye: XREye, - pose: &ApiRigidTransform, + pose: &ApiViewerPose, ) -> DomRoot { // XXXManishearth compute and cache projection matrices on the Display - let offset = cast_transform(view.transform); - let transform = pose.post_mul(&offset.into()); - let transform = XRRigidTransform::new(global, transform); + // this transform is the pose of the viewer in the eye space, i.e. it is the transform + // from the viewer space to the eye space. We invert it to get the pose of the eye in the viewer space. + let offset = view.transform.inverse(); + + let transform = pose.pre_mul(&offset); + let transform = XRRigidTransform::new(global, cast_transform(transform)); let ret = reflect_dom_object( Box::new(XRView::new_inherited(session, &transform, eye)), diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs index 12c8267aa68..609d89765c6 100644 --- a/components/script/dom/xrviewerpose.rs +++ b/components/script/dom/xrviewerpose.rs @@ -10,7 +10,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; use crate::dom::xrpose::XRPose; use crate::dom::xrrigidtransform::XRRigidTransform; -use crate::dom::xrsession::{ApiRigidTransform, XRSession}; +use crate::dom::xrsession::{cast_transform, ApiViewerPose, XRSession}; use crate::dom::xrview::XRView; use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; @@ -37,7 +37,7 @@ impl XRViewerPose { pub fn new( global: &GlobalScope, session: &XRSession, - pose: ApiRigidTransform, + pose: ApiViewerPose, ) -> DomRoot { rooted_vec!(let mut views); session.with_session(|s| match s.views() { @@ -49,7 +49,7 @@ impl XRViewerPose { views.push(XRView::new(global, session, &right, XREye::Right, &pose)); }, }); - let transform = XRRigidTransform::new(global, pose); + let transform = XRRigidTransform::new(global, cast_transform(pose)); let pose = reflect_dom_object( Box::new(XRViewerPose::new_inherited(&transform)), global,