Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various webxr WPT fixes #25259

Merged
merged 11 commits into from Dec 13, 2019

Support nullable origins and floors

  • Loading branch information
Manishearth committed Dec 12, 2019
commit 322463450d5677c588662f8df965614afe3e23f2

Some generated files are not rendered by default. Learn more.

@@ -134,15 +134,33 @@ 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,
_emulated_position: bool,
) -> 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(())
}

@@ -13,8 +13,11 @@ interface FakeXRDevice {
// // behaves as if device was disconnected
// Promise<void> 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);
@@ -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)))
}

@@ -80,23 +80,23 @@ 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<ApiViewerPose> {
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)
// = offset.inverse() * get_unoffset_pose(space).inverse() * get_pose(viewer_space)
// = 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<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)
@@ -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<ApiPose> {
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<ApiPose> {
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!(),
}
}
@@ -68,7 +68,7 @@ impl XRSpace {
/// with other spaces
pub fn get_pose(&self, base_pose: &Frame) -> Option<ApiPose> {
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() {
// XXXManishearth we should be able to request frame information
// for inputs when necessary instead of always loading it
@@ -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) {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.