Support nullable origins and floors

This commit is contained in:
Manish Goregaokar 2019-12-11 18:16:41 -08:00
parent 0bace66f70
commit 322463450d
7 changed files with 51 additions and 27 deletions

4
Cargo.lock generated
View file

@ -6391,7 +6391,7 @@ dependencies = [
[[package]] [[package]]
name = "webxr" name = "webxr"
version = "0.0.1" version = "0.0.1"
source = "git+https://github.com/servo/webxr#b223bc02b04c8ce0905f34a58802af323457bef4" source = "git+https://github.com/servo/webxr#a098d39811ad73a070b578d62606aef169aef8e9"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"euclid", "euclid",
@ -6412,7 +6412,7 @@ dependencies = [
[[package]] [[package]]
name = "webxr-api" name = "webxr-api"
version = "0.0.1" version = "0.0.1"
source = "git+https://github.com/servo/webxr#b223bc02b04c8ce0905f34a58802af323457bef4" source = "git+https://github.com/servo/webxr#a098d39811ad73a070b578d62606aef169aef8e9"
dependencies = [ dependencies = [
"euclid", "euclid",
"ipc-channel", "ipc-channel",

View file

@ -134,7 +134,7 @@ impl FakeXRDeviceMethods for FakeXRDevice {
Ok(()) 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( fn SetViewerOrigin(
&self, &self,
origin: &FakeXRRigidTransformInit, origin: &FakeXRRigidTransformInit,
@ -142,7 +142,25 @@ impl FakeXRDeviceMethods for FakeXRDevice {
) -> Fallible<()> { ) -> Fallible<()> {
let _ = self let _ = self
.sender .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(()) Ok(())
} }

View file

@ -13,8 +13,11 @@ interface FakeXRDevice {
// // behaves as if device was disconnected // // behaves as if device was disconnected
// Promise<void> disconnect(); // Promise<void> disconnect();
// Sets the origin of the viewer
[Throws] void setViewerOrigin(FakeXRRigidTransformInit origin, optional boolean emulatedPosition = false); [Throws] void setViewerOrigin(FakeXRRigidTransformInit origin, optional boolean emulatedPosition = false);
void clearViewerOrigin();
[Throws] void setFloorOrigin(FakeXRRigidTransformInit origin);
void clearFloorOrigin();
// // Simulates devices focusing and blurring sessions. // // Simulates devices focusing and blurring sessions.
// void simulateVisibilityChange(XRVisibilityState); // void simulateVisibilityChange(XRVisibilityState);

View file

@ -77,7 +77,11 @@ impl XRFrameMethods for XRFrame {
return Err(Error::InvalidState); 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))) Ok(Some(XRViewerPose::new(&self.global(), &self.session, pose)))
} }

View file

@ -80,8 +80,8 @@ impl XRReferenceSpace {
/// ///
/// This is equivalent to `get_pose(self).inverse() * get_pose(viewerSpace)` (in column vector notation), /// This is equivalent to `get_pose(self).inverse() * get_pose(viewerSpace)` (in column vector notation),
/// however we specialize it to be efficient /// however we specialize it to be efficient
pub fn get_viewer_pose(&self, base_pose: &Frame) -> ApiViewerPose { pub fn get_viewer_pose(&self, base_pose: &Frame) -> Option<ApiViewerPose> {
let pose = self.get_unoffset_viewer_pose(base_pose); let pose = self.get_unoffset_viewer_pose(base_pose)?;
// in column-vector notation, // in column-vector notation,
// get_viewer_pose(space) = get_pose(space).inverse() * get_pose(viewer_space) // get_viewer_pose(space) = get_pose(space).inverse() * get_pose(viewer_space)
// = (get_unoffset_pose(space) * offset).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) // = offset.inverse() * get_unoffset_viewer_pose(space)
let offset = self.offset.transform(); let offset = self.offset.transform();
let inverse = offset.inverse(); let inverse = offset.inverse();
inverse.pre_transform(&pose) Some(inverse.pre_transform(&pose))
} }
/// Gets pose of the viewer with respect to this space /// Gets pose of the viewer with respect to this space
/// ///
/// Does not apply originOffset, use get_viewer_pose instead if you need it /// Does not apply originOffset, use get_viewer_pose instead if you need it
pub fn get_unoffset_viewer_pose(&self, base_pose: &Frame) -> ApiViewerPose { pub fn get_unoffset_viewer_pose(&self, base_pose: &Frame) -> Option<ApiViewerPose> {
let viewer_pose: ApiViewerPose = cast_transform(base_pose.transform); let viewer_pose: ApiViewerPose = cast_transform(base_pose.transform?);
// all math is in column-vector notation // all math is in column-vector notation
// we use the following equation to verify correctness here: // we use the following equation to verify correctness here:
// get_viewer_pose(space) = get_pose(space).inverse() * get_pose(viewer_space) // get_viewer_pose(space) = get_pose(space).inverse() * get_pose(viewer_space)
@ -107,7 +107,7 @@ impl XRReferenceSpace {
// = viewer_pose // = viewer_pose
// we get viewer poses in eye-level space by default // we get viewer poses in eye-level space by default
viewer_pose Some(viewer_pose)
}, },
XRReferenceSpaceType::Local_floor => { XRReferenceSpaceType::Local_floor => {
// XXXManishearth support getting floor info from stage parameters // XXXManishearth support getting floor info from stage parameters
@ -118,12 +118,12 @@ impl XRReferenceSpace {
// assume approximate user height of 2 meters // assume approximate user height of 2 meters
let floor_to_eye: ApiRigidTransform = Vector3D::new(0., 2., 0.).into(); 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 => { XRReferenceSpaceType::Viewer => {
// This reference space follows the viewer around, so the viewer is // This reference space follows the viewer around, so the viewer is
// always at an identity transform with respect to it // always at an identity transform with respect to it
RigidTransform3D::identity() Some(RigidTransform3D::identity())
}, },
_ => unimplemented!(), _ => unimplemented!(),
} }
@ -134,34 +134,34 @@ impl XRReferenceSpace {
/// The reference origin used is common between all /// The reference origin used is common between all
/// get_pose calls for spaces from the same device, so this can be used to compare /// get_pose calls for spaces from the same device, so this can be used to compare
/// with other spaces /// with other spaces
pub fn get_pose(&self, base_pose: &Frame) -> ApiPose { pub fn get_pose(&self, base_pose: &Frame) -> Option<ApiPose> {
let pose = self.get_unoffset_pose(base_pose); let pose = self.get_unoffset_pose(base_pose)?;
let offset = self.offset.transform(); let offset = self.offset.transform();
// pose is a transform from the unoffset space to native space, // pose is a transform from the unoffset space to native space,
// offset is a transform from offset space to unoffset space, // offset is a transform from offset space to unoffset space,
// we want a transform from unoffset space to native space, // we want a transform from unoffset space to native space,
// which is pose * offset in column vector notation // which is pose * offset in column vector notation
pose.pre_transform(&offset) Some(pose.pre_transform(&offset))
} }
/// Gets pose represented by this space /// Gets pose represented by this space
/// ///
/// Does not apply originOffset, use get_viewer_pose instead if you need it /// 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<ApiPose> {
match self.ty { match self.ty {
XRReferenceSpaceType::Local => { XRReferenceSpaceType::Local => {
// The eye-level pose is basically whatever the headset pose was at t=0, which // The eye-level pose is basically whatever the headset pose was at t=0, which
// for most devices is (0, 0, 0) // for most devices is (0, 0, 0)
RigidTransform3D::identity() Some(RigidTransform3D::identity())
}, },
XRReferenceSpaceType::Local_floor => { XRReferenceSpaceType::Local_floor => {
// XXXManishearth support getting floor info from stage parameters // XXXManishearth support getting floor info from stage parameters
// Assume approximate height of 2m // Assume approximate height of 2m
// the floor-level space is 2m below the eye-level space, which is (0, 0, 0) // 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!(), _ => unimplemented!(),
} }
} }

View file

@ -68,7 +68,7 @@ impl XRSpace {
/// with other spaces /// with other spaces
pub fn get_pose(&self, base_pose: &Frame) -> Option<ApiPose> { pub fn get_pose(&self, base_pose: &Frame) -> Option<ApiPose> {
if let Some(reference) = self.downcast::<XRReferenceSpace>() { if let Some(reference) = self.downcast::<XRReferenceSpace>() {
Some(reference.get_pose(base_pose)) reference.get_pose(base_pose)
} else if let Some(source) = self.input_source.get() { } else if let Some(source) = self.input_source.get() {
// XXXManishearth we should be able to request frame information // XXXManishearth we should be able to request frame information
// for inputs when necessary instead of always loading it // for inputs when necessary instead of always loading it

View file

@ -21,7 +21,6 @@ use crate::dom::promise::Promise;
use crate::script_thread::ScriptThread; use crate::script_thread::ScriptThread;
use crate::task_source::TaskSource; use crate::task_source::TaskSource;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::RigidTransform3D;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use ipc_channel::router::ROUTER; use ipc_channel::router::ROUTER;
use profile_traits::ipc; use profile_traits::ipc;
@ -75,26 +74,26 @@ impl XRTestMethods for XRTest {
let origin = if let Some(ref o) = init.viewerOrigin { let origin = if let Some(ref o) = init.viewerOrigin {
match get_origin(&o) { match get_origin(&o) {
Ok(origin) => origin, Ok(origin) => Some(origin),
Err(e) => { Err(e) => {
p.reject_error(e); p.reject_error(e);
return p; return p;
}, },
} }
} else { } else {
RigidTransform3D::identity() None
}; };
let floor_origin = if let Some(ref o) = init.floorOrigin { let floor_origin = if let Some(ref o) = init.floorOrigin {
match get_origin(&o) { match get_origin(&o) {
Ok(origin) => origin, Ok(origin) => Some(origin),
Err(e) => { Err(e) => {
p.reject_error(e); p.reject_error(e);
return p; return p;
}, },
} }
} else { } else {
RigidTransform3D::identity() None
}; };
let views = match get_views(&init.views) { let views = match get_views(&init.views) {