Skip to main content

script/dom/webxr/
xrviewerpose.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
5use dom_struct::dom_struct;
6use euclid::RigidTransform3D;
7use js::context::JSContext;
8use js::jsapi::Heap;
9use js::jsval::{JSVal, UndefinedValue};
10use js::rust::MutableHandleValue;
11use script_bindings::conversions::SafeToJSValConvertible;
12use script_bindings::reflector::reflect_dom_object_with_cx;
13use webxr_api::{Viewer, ViewerPose, Views};
14
15use crate::dom::bindings::codegen::Bindings::XRViewBinding::XREye;
16use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding::XRViewerPoseMethods;
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::window::Window;
19use crate::dom::xrpose::XRPose;
20use crate::dom::xrrigidtransform::XRRigidTransform;
21use crate::dom::xrsession::{BaseSpace, BaseTransform, XRSession, cast_transform};
22use crate::dom::xrview::XRView;
23use crate::realms::enter_auto_realm;
24
25#[dom_struct]
26pub(crate) struct XRViewerPose {
27    pose: XRPose,
28    #[ignore_malloc_size_of = "mozjs"]
29    views: Heap<JSVal>,
30}
31
32impl XRViewerPose {
33    fn new_inherited(transform: &XRRigidTransform) -> XRViewerPose {
34        XRViewerPose {
35            pose: XRPose::new_inherited(transform),
36            views: Heap::default(),
37        }
38    }
39
40    pub(crate) fn new(
41        cx: &mut JSContext,
42        window: &Window,
43        session: &XRSession,
44        to_base: BaseTransform,
45        viewer_pose: &ViewerPose,
46    ) -> DomRoot<XRViewerPose> {
47        let mut realm = enter_auto_realm(cx, window);
48        let cx = &mut realm.current_realm();
49        rooted_vec!(let mut views);
50        match &viewer_pose.views {
51            Views::Inline => views.push(XRView::new(
52                cx,
53                window,
54                session,
55                &session.inline_view(),
56                XREye::None,
57                0,
58                &to_base,
59            )),
60            Views::Mono(view) => views.push(XRView::new(
61                cx,
62                window,
63                session,
64                view,
65                XREye::None,
66                0,
67                &to_base,
68            )),
69            Views::Stereo(left, right) => {
70                views.push(XRView::new(
71                    cx,
72                    window,
73                    session,
74                    left,
75                    XREye::Left,
76                    0,
77                    &to_base,
78                ));
79                views.push(XRView::new(
80                    cx,
81                    window,
82                    session,
83                    right,
84                    XREye::Right,
85                    1,
86                    &to_base,
87                ));
88            },
89            Views::StereoCapture(left, right, third_eye) => {
90                views.push(XRView::new(
91                    cx,
92                    window,
93                    session,
94                    left,
95                    XREye::Left,
96                    0,
97                    &to_base,
98                ));
99                views.push(XRView::new(
100                    cx,
101                    window,
102                    session,
103                    right,
104                    XREye::Right,
105                    1,
106                    &to_base,
107                ));
108                views.push(XRView::new(
109                    cx,
110                    window,
111                    session,
112                    third_eye,
113                    XREye::None,
114                    2,
115                    &to_base,
116                ));
117            },
118            Views::Cubemap(front, left, right, top, bottom, back) => {
119                views.push(XRView::new(
120                    cx,
121                    window,
122                    session,
123                    front,
124                    XREye::None,
125                    0,
126                    &to_base,
127                ));
128                views.push(XRView::new(
129                    cx,
130                    window,
131                    session,
132                    left,
133                    XREye::None,
134                    1,
135                    &to_base,
136                ));
137                views.push(XRView::new(
138                    cx,
139                    window,
140                    session,
141                    right,
142                    XREye::None,
143                    2,
144                    &to_base,
145                ));
146                views.push(XRView::new(
147                    cx,
148                    window,
149                    session,
150                    top,
151                    XREye::None,
152                    3,
153                    &to_base,
154                ));
155                views.push(XRView::new(
156                    cx,
157                    window,
158                    session,
159                    bottom,
160                    XREye::None,
161                    4,
162                    &to_base,
163                ));
164                views.push(XRView::new(
165                    cx,
166                    window,
167                    session,
168                    back,
169                    XREye::None,
170                    5,
171                    &to_base,
172                ));
173            },
174        };
175        let transform: RigidTransform3D<f32, Viewer, BaseSpace> =
176            viewer_pose.transform.then(&to_base);
177        let transform = XRRigidTransform::new(cx, window, cast_transform(transform));
178        let pose = reflect_dom_object_with_cx(
179            Box::new(XRViewerPose::new_inherited(&transform)),
180            window,
181            cx,
182        );
183
184        rooted!(&in(cx) let mut jsval = UndefinedValue());
185        views.safe_to_jsval(cx, jsval.handle_mut());
186        pose.views.set(jsval.get());
187
188        pose
189    }
190}
191
192impl XRViewerPoseMethods<crate::DomTypeHolder> for XRViewerPose {
193    /// <https://immersive-web.github.io/webxr/#dom-xrviewerpose-views>
194    fn Views(&self, mut retval: MutableHandleValue) {
195        retval.set(self.views.get())
196    }
197}