diff --git a/Cargo.lock b/Cargo.lock index 5eb3242356c..ac22c158761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6391,7 +6391,7 @@ dependencies = [ [[package]] name = "webxr" version = "0.0.1" -source = "git+https://github.com/servo/webxr#b223bc02b04c8ce0905f34a58802af323457bef4" +source = "git+https://github.com/servo/webxr#a098d39811ad73a070b578d62606aef169aef8e9" dependencies = [ "bindgen", "euclid", @@ -6412,7 +6412,7 @@ dependencies = [ [[package]] name = "webxr-api" version = "0.0.1" -source = "git+https://github.com/servo/webxr#b223bc02b04c8ce0905f34a58802af323457bef4" +source = "git+https://github.com/servo/webxr#a098d39811ad73a070b578d62606aef169aef8e9" dependencies = [ "euclid", "ipc-channel", diff --git a/components/script/dom/fakexrdevice.rs b/components/script/dom/fakexrdevice.rs index d76c94751c0..d3a09741d9b 100644 --- a/components/script/dom/fakexrdevice.rs +++ b/components/script/dom/fakexrdevice.rs @@ -134,7 +134,7 @@ impl FakeXRDeviceMethods for FakeXRDevice { Ok(()) } - /// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md + /// https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-setviewerorigin fn SetViewerOrigin( &self, origin: &FakeXRRigidTransformInit, @@ -142,7 +142,25 @@ impl FakeXRDeviceMethods for FakeXRDevice { ) -> Fallible<()> { let _ = self .sender - .send(MockDeviceMsg::SetViewerOrigin(get_origin(origin)?)); + .send(MockDeviceMsg::SetViewerOrigin(Some(get_origin(origin)?))); + Ok(()) + } + + /// https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-clearviewerorigin + fn ClearViewerOrigin(&self) { + let _ = self.sender.send(MockDeviceMsg::SetViewerOrigin(None)); + } + + /// https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-clearfloororigin + fn ClearFloorOrigin(&self) { + let _ = self.sender.send(MockDeviceMsg::SetFloorOrigin(None)); + } + + /// https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-setfloororigin + fn SetFloorOrigin(&self, origin: &FakeXRRigidTransformInit) -> Fallible<()> { + let _ = self + .sender + .send(MockDeviceMsg::SetFloorOrigin(Some(get_origin(origin)?))); Ok(()) } diff --git a/components/script/dom/webidls/FakeXRDevice.webidl b/components/script/dom/webidls/FakeXRDevice.webidl index bb008bdc73f..058f52e3d1e 100644 --- a/components/script/dom/webidls/FakeXRDevice.webidl +++ b/components/script/dom/webidls/FakeXRDevice.webidl @@ -13,8 +13,11 @@ interface FakeXRDevice { // // behaves as if device was disconnected // Promise disconnect(); - // Sets the origin of the viewer [Throws] void setViewerOrigin(FakeXRRigidTransformInit origin, optional boolean emulatedPosition = false); + void clearViewerOrigin(); + + [Throws] void setFloorOrigin(FakeXRRigidTransformInit origin); + void clearFloorOrigin(); // // Simulates devices focusing and blurring sessions. // void simulateVisibilityChange(XRVisibilityState); diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs index 6c67d896f81..9a752abf759 100644 --- a/components/script/dom/xrframe.rs +++ b/components/script/dom/xrframe.rs @@ -77,7 +77,11 @@ impl XRFrameMethods for XRFrame { return Err(Error::InvalidState); } - let pose = reference.get_viewer_pose(&self.data); + let pose = if let Some(pose) = reference.get_viewer_pose(&self.data) { + pose + } else { + return Ok(None); + }; Ok(Some(XRViewerPose::new(&self.global(), &self.session, pose))) } diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs index 35e106d1125..c62bd9b4283 100644 --- a/components/script/dom/xrreferencespace.rs +++ b/components/script/dom/xrreferencespace.rs @@ -80,8 +80,8 @@ 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) -> ApiViewerPose { - let pose = self.get_unoffset_viewer_pose(base_pose); + pub fn get_viewer_pose(&self, base_pose: &Frame) -> Option { + let pose = self.get_unoffset_viewer_pose(base_pose)?; // in column-vector notation, // get_viewer_pose(space) = get_pose(space).inverse() * get_pose(viewer_space) // = (get_unoffset_pose(space) * offset).inverse() * get_pose(viewer_space) @@ -89,14 +89,14 @@ impl XRReferenceSpace { // = offset.inverse() * get_unoffset_viewer_pose(space) let offset = self.offset.transform(); let inverse = offset.inverse(); - inverse.pre_transform(&pose) + Some(inverse.pre_transform(&pose)) } /// 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) -> ApiViewerPose { - let viewer_pose: ApiViewerPose = cast_transform(base_pose.transform); + pub fn get_unoffset_viewer_pose(&self, base_pose: &Frame) -> Option { + 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) @@ -107,7 +107,7 @@ impl XRReferenceSpace { // = viewer_pose // we get viewer poses in eye-level space by default - viewer_pose + Some(viewer_pose) }, XRReferenceSpaceType::Local_floor => { // XXXManishearth support getting floor info from stage parameters @@ -118,12 +118,12 @@ impl XRReferenceSpace { // assume approximate user height of 2 meters let floor_to_eye: ApiRigidTransform = Vector3D::new(0., 2., 0.).into(); - floor_to_eye.pre_transform(&viewer_pose) + Some(floor_to_eye.pre_transform(&viewer_pose)) }, XRReferenceSpaceType::Viewer => { // This reference space follows the viewer around, so the viewer is // always at an identity transform with respect to it - RigidTransform3D::identity() + Some(RigidTransform3D::identity()) }, _ => unimplemented!(), } @@ -134,34 +134,34 @@ impl XRReferenceSpace { /// The reference origin used is common between all /// get_pose calls for spaces from the same device, so this can be used to compare /// with other spaces - pub fn get_pose(&self, base_pose: &Frame) -> ApiPose { - let pose = self.get_unoffset_pose(base_pose); + pub fn get_pose(&self, base_pose: &Frame) -> Option { + let pose = self.get_unoffset_pose(base_pose)?; let offset = self.offset.transform(); // pose is a transform from the unoffset space to native space, // offset is a transform from offset space to unoffset space, // we want a transform from unoffset space to native space, // which is pose * offset in column vector notation - pose.pre_transform(&offset) + Some(pose.pre_transform(&offset)) } /// Gets pose represented by this space /// /// Does not apply originOffset, use get_viewer_pose instead if you need it - pub fn get_unoffset_pose(&self, base_pose: &Frame) -> ApiPose { + pub fn get_unoffset_pose(&self, base_pose: &Frame) -> Option { match self.ty { XRReferenceSpaceType::Local => { // The eye-level pose is basically whatever the headset pose was at t=0, which // for most devices is (0, 0, 0) - RigidTransform3D::identity() + Some(RigidTransform3D::identity()) }, XRReferenceSpaceType::Local_floor => { // XXXManishearth support getting floor info from stage parameters // Assume approximate height of 2m // the floor-level space is 2m below the eye-level space, which is (0, 0, 0) - Vector3D::new(0., -2., 0.).into() + Some(Vector3D::new(0., -2., 0.).into()) }, - XRReferenceSpaceType::Viewer => cast_transform(base_pose.transform), + XRReferenceSpaceType::Viewer => base_pose.transform.map(cast_transform), _ => unimplemented!(), } } diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs index 29d81fa6afe..652a4345ce2 100644 --- a/components/script/dom/xrspace.rs +++ b/components/script/dom/xrspace.rs @@ -68,7 +68,7 @@ impl XRSpace { /// with other spaces pub fn get_pose(&self, base_pose: &Frame) -> Option { if let Some(reference) = self.downcast::() { - Some(reference.get_pose(base_pose)) + reference.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 diff --git a/components/script/dom/xrtest.rs b/components/script/dom/xrtest.rs index b40807b25d5..b00a69b8fca 100644 --- a/components/script/dom/xrtest.rs +++ b/components/script/dom/xrtest.rs @@ -21,7 +21,6 @@ use crate::dom::promise::Promise; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use dom_struct::dom_struct; -use euclid::RigidTransform3D; use ipc_channel::ipc::IpcSender; use ipc_channel::router::ROUTER; use profile_traits::ipc; @@ -75,26 +74,26 @@ impl XRTestMethods for XRTest { let origin = if let Some(ref o) = init.viewerOrigin { match get_origin(&o) { - Ok(origin) => origin, + Ok(origin) => Some(origin), Err(e) => { p.reject_error(e); return p; }, } } else { - RigidTransform3D::identity() + None }; let floor_origin = if let Some(ref o) = init.floorOrigin { match get_origin(&o) { - Ok(origin) => origin, + Ok(origin) => Some(origin), Err(e) => { p.reject_error(e); return p; }, } } else { - RigidTransform3D::identity() + None }; let views = match get_views(&init.views) {