servo/components/shared/webxr/view.rs
Martin Robinson 5466c27f6f
Finish the integration of webxr into the Cargo workspace (#35229)
- Run `cargo fmt` on `webxr` and `webxr-api`
- Fix clippy warnings in the existing `webxr` code
- Integrate the new crates into the workspace
- Expose `webxr` via the libservo API rather than requiring embedders to
  depend on it explicitly.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-01-31 16:41:57 +00:00

168 lines
5.8 KiB
Rust

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! This crate uses `euclid`'s typed units, and exposes different coordinate spaces.
use std::marker::PhantomData;
use euclid::{Rect, RigidTransform3D, Transform3D};
#[cfg(feature = "ipc")]
use serde::{Deserialize, Serialize};
/// The coordinate space of the viewer
/// <https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-viewer>
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum Viewer {}
/// The coordinate space of the floor
/// <https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-local-floor>
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum Floor {}
/// The coordinate space of the left eye
/// <https://immersive-web.github.io/webxr/#dom-xreye-left>
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum LeftEye {}
/// The coordinate space of the right eye
/// <https://immersive-web.github.io/webxr/#dom-xreye-right>
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum RightEye {}
/// The coordinate space of the left frustrum of a cubemap
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum CubeLeft {}
/// The coordinate space of the right frustrum of a cubemap
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum CubeRight {}
/// The coordinate space of the top frustrum of a cubemap
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum CubeTop {}
/// The coordinate space of the bottom frustrum of a cubemap
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum CubeBottom {}
/// The coordinate space of the back frustrum of a cubemap
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum CubeBack {}
/// Pattern-match on eyes
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub struct SomeEye<Eye>(u8, PhantomData<Eye>);
pub const LEFT_EYE: SomeEye<LeftEye> = SomeEye(0, PhantomData);
pub const RIGHT_EYE: SomeEye<RightEye> = SomeEye(1, PhantomData);
pub const VIEWER: SomeEye<Viewer> = SomeEye(2, PhantomData);
pub const CUBE_LEFT: SomeEye<CubeLeft> = SomeEye(3, PhantomData);
pub const CUBE_RIGHT: SomeEye<CubeRight> = SomeEye(4, PhantomData);
pub const CUBE_TOP: SomeEye<CubeTop> = SomeEye(5, PhantomData);
pub const CUBE_BOTTOM: SomeEye<CubeBottom> = SomeEye(6, PhantomData);
pub const CUBE_BACK: SomeEye<CubeBack> = SomeEye(7, PhantomData);
impl<Eye1, Eye2> PartialEq<SomeEye<Eye2>> for SomeEye<Eye1> {
fn eq(&self, rhs: &SomeEye<Eye2>) -> bool {
self.0 == rhs.0
}
}
/// The native 3D coordinate space of the device
/// This is not part of the webvr specification.
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum Native {}
/// The normalized device coordinate space, where the display
/// is from (-1,-1) to (1,1).
// TODO: are we OK assuming that we can use the same coordinate system for all displays?
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum Display {}
/// The unnormalized device coordinate space, where the display
/// is from (0,0) to (w,h), measured in pixels.
// TODO: are we OK assuming that we can use the same coordinate system for all displays?
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum Viewport {}
/// The coordinate space of an input device
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum Input {}
/// The coordinate space of a secondary capture view
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub enum Capture {}
/// For each eye, the pose of that eye,
/// its projection onto its display.
/// For stereo displays, we have a `View<LeftEye>` and a `View<RightEye>`.
/// For mono displays, we hagve a `View<Viewer>`
/// <https://immersive-web.github.io/webxr/#xrview>
#[derive(Clone, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub struct View<Eye> {
pub transform: RigidTransform3D<f32, Eye, Native>,
pub projection: Transform3D<f32, Eye, Display>,
}
impl<Eye> Default for View<Eye> {
fn default() -> Self {
View {
transform: RigidTransform3D::identity(),
projection: Transform3D::identity(),
}
}
}
impl<Eye> View<Eye> {
pub fn cast_unit<NewEye>(&self) -> View<NewEye> {
View {
transform: self.transform.cast_unit(),
projection: Transform3D::from_untyped(&self.projection.to_untyped()),
}
}
}
/// Whether a device is mono or stereo, and the views it supports.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
#[allow(clippy::large_enum_variant)]
pub enum Views {
/// Mono view for inline VR, viewport and projection matrices are calculated by client
Inline,
Mono(View<Viewer>),
Stereo(View<LeftEye>, View<RightEye>),
StereoCapture(View<LeftEye>, View<RightEye>, View<Capture>),
Cubemap(
View<Viewer>,
View<CubeLeft>,
View<CubeRight>,
View<CubeTop>,
View<CubeBottom>,
View<CubeBack>,
),
}
/// A list of viewports per-eye in the order of fields in Views.
///
/// Not all must be in active use.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
pub struct Viewports {
pub viewports: Vec<Rect<i32, Viewport>>,
}