1use 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 fn Views(&self, mut retval: MutableHandleValue) {
195 retval.set(self.views.get())
196 }
197}