webxr_api/
view.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! This crate uses `euclid`'s typed units, and exposes different coordinate spaces.
6
7use std::marker::PhantomData;
8
9use euclid::{Rect, RigidTransform3D, Transform3D};
10#[cfg(feature = "ipc")]
11use serde::{Deserialize, Serialize};
12
13/// The coordinate space of the viewer
14/// <https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-viewer>
15#[derive(Clone, Copy, Debug)]
16#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
17pub enum Viewer {}
18
19/// The coordinate space of the floor
20/// <https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-local-floor>
21#[derive(Clone, Copy, Debug)]
22#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
23pub enum Floor {}
24
25/// The coordinate space of the left eye
26/// <https://immersive-web.github.io/webxr/#dom-xreye-left>
27#[derive(Clone, Copy, Debug)]
28#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
29pub enum LeftEye {}
30
31/// The coordinate space of the right eye
32/// <https://immersive-web.github.io/webxr/#dom-xreye-right>
33#[derive(Clone, Copy, Debug)]
34#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
35pub enum RightEye {}
36
37/// The coordinate space of the left frustrum of a cubemap
38#[derive(Clone, Copy, Debug)]
39#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
40pub enum CubeLeft {}
41
42/// The coordinate space of the right frustrum of a cubemap
43#[derive(Clone, Copy, Debug)]
44#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
45pub enum CubeRight {}
46
47/// The coordinate space of the top frustrum of a cubemap
48#[derive(Clone, Copy, Debug)]
49#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
50pub enum CubeTop {}
51
52/// The coordinate space of the bottom frustrum of a cubemap
53#[derive(Clone, Copy, Debug)]
54#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
55pub enum CubeBottom {}
56
57/// The coordinate space of the back frustrum of a cubemap
58#[derive(Clone, Copy, Debug)]
59#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
60pub enum CubeBack {}
61
62/// Pattern-match on eyes
63#[derive(Clone, Copy, Debug)]
64#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
65pub struct SomeEye<Eye>(u8, PhantomData<Eye>);
66pub const LEFT_EYE: SomeEye<LeftEye> = SomeEye(0, PhantomData);
67pub const RIGHT_EYE: SomeEye<RightEye> = SomeEye(1, PhantomData);
68pub const VIEWER: SomeEye<Viewer> = SomeEye(2, PhantomData);
69pub const CUBE_LEFT: SomeEye<CubeLeft> = SomeEye(3, PhantomData);
70pub const CUBE_RIGHT: SomeEye<CubeRight> = SomeEye(4, PhantomData);
71pub const CUBE_TOP: SomeEye<CubeTop> = SomeEye(5, PhantomData);
72pub const CUBE_BOTTOM: SomeEye<CubeBottom> = SomeEye(6, PhantomData);
73pub const CUBE_BACK: SomeEye<CubeBack> = SomeEye(7, PhantomData);
74
75impl<Eye1, Eye2> PartialEq<SomeEye<Eye2>> for SomeEye<Eye1> {
76    fn eq(&self, rhs: &SomeEye<Eye2>) -> bool {
77        self.0 == rhs.0
78    }
79}
80
81/// The native 3D coordinate space of the device
82/// This is not part of the webvr specification.
83#[derive(Clone, Copy, Debug)]
84#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
85pub enum Native {}
86
87/// The normalized device coordinate space, where the display
88/// is from (-1,-1) to (1,1).
89// TODO: are we OK assuming that we can use the same coordinate system for all displays?
90#[derive(Clone, Copy, Debug)]
91#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
92pub enum Display {}
93
94/// The unnormalized device coordinate space, where the display
95/// is from (0,0) to (w,h), measured in pixels.
96// TODO: are we OK assuming that we can use the same coordinate system for all displays?
97#[derive(Clone, Copy, Debug)]
98#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
99pub enum Viewport {}
100
101/// The coordinate space of an input device
102#[derive(Clone, Copy, Debug)]
103#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
104pub enum Input {}
105
106/// The coordinate space of a secondary capture view
107#[derive(Clone, Copy, Debug)]
108#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
109pub enum Capture {}
110
111/// For each eye, the pose of that eye,
112/// its projection onto its display.
113/// For stereo displays, we have a `View<LeftEye>` and a `View<RightEye>`.
114/// For mono displays, we hagve a `View<Viewer>`
115/// <https://immersive-web.github.io/webxr/#xrview>
116#[derive(Clone, Debug)]
117#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
118pub struct View<Eye> {
119    pub transform: RigidTransform3D<f32, Eye, Native>,
120    pub projection: Transform3D<f32, Eye, Display>,
121}
122
123impl<Eye> Default for View<Eye> {
124    fn default() -> Self {
125        View {
126            transform: RigidTransform3D::identity(),
127            projection: Transform3D::identity(),
128        }
129    }
130}
131
132impl<Eye> View<Eye> {
133    pub fn cast_unit<NewEye>(&self) -> View<NewEye> {
134        View {
135            transform: self.transform.cast_unit(),
136            projection: Transform3D::from_untyped(&self.projection.to_untyped()),
137        }
138    }
139}
140
141/// Whether a device is mono or stereo, and the views it supports.
142#[derive(Clone, Debug)]
143#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
144#[allow(clippy::large_enum_variant)]
145pub enum Views {
146    /// Mono view for inline VR, viewport and projection matrices are calculated by client
147    Inline,
148    Mono(View<Viewer>),
149    Stereo(View<LeftEye>, View<RightEye>),
150    StereoCapture(View<LeftEye>, View<RightEye>, View<Capture>),
151    Cubemap(
152        View<Viewer>,
153        View<CubeLeft>,
154        View<CubeRight>,
155        View<CubeTop>,
156        View<CubeBottom>,
157        View<CubeBack>,
158    ),
159}
160
161/// A list of viewports per-eye in the order of fields in Views.
162///
163/// Not all must be in active use.
164#[derive(Clone, Debug)]
165#[cfg_attr(feature = "ipc", derive(Serialize, Deserialize))]
166pub struct Viewports {
167    pub viewports: Vec<Rect<i32, Viewport>>,
168}