The open source OpenXR runtime
1// Copyright 2022, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Test xrt_relation_chain functions.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 */
8
9#include "xrt/xrt_compiler.h"
10
11#include "math/m_api.h"
12#include "math/m_space.h"
13
14#include "catch_amalgamated.hpp"
15
16
17/*
18 *
19 * Constants
20 *
21 */
22
23constexpr xrt_pose kPoseIdentity = XRT_POSE_IDENTITY;
24
25constexpr xrt_pose kPoseOneY = {
26 XRT_QUAT_IDENTITY,
27 {0.0f, 1.0f, 0.0f},
28};
29
30constexpr xrt_space_relation_flags kFlagsNotValid = {};
31
32constexpr xrt_space_relation_flags kFlagsValid = (xrt_space_relation_flags)( //
33 XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | //
34 XRT_SPACE_RELATION_POSITION_VALID_BIT); //
35
36constexpr xrt_space_relation_flags kFlagsValidTracked = (xrt_space_relation_flags)( //
37 XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | //
38 XRT_SPACE_RELATION_POSITION_VALID_BIT | //
39 XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT | //
40 XRT_SPACE_RELATION_POSITION_TRACKED_BIT); //
41
42
43constexpr xrt_space_relation kSpaceRelationNotValid = {
44 kFlagsNotValid,
45 kPoseOneY,
46 XRT_VEC3_ZERO,
47 XRT_VEC3_ZERO,
48};
49
50constexpr xrt_space_relation kSpaceRelationOneY = {
51 kFlagsValid,
52 kPoseOneY,
53 XRT_VEC3_ZERO,
54 XRT_VEC3_ZERO,
55};
56
57constexpr xrt_space_relation kSpaceRelationOneYTracked = {
58 kFlagsValidTracked,
59 kPoseOneY,
60 XRT_VEC3_ZERO,
61 XRT_VEC3_ZERO,
62};
63
64constexpr xrt_space_relation kSpaceRelationOnlyOrientation = {
65 XRT_SPACE_RELATION_ORIENTATION_VALID_BIT,
66 {XRT_QUAT_IDENTITY, XRT_VEC3_ZERO},
67 XRT_VEC3_ZERO,
68 XRT_VEC3_ZERO,
69};
70
71constexpr xrt_space_relation kSpaceRelationOnlyPosition = {
72 XRT_SPACE_RELATION_POSITION_VALID_BIT,
73 {
74 {0.0f, 0.0f, 0.0f, 0.0f}, // Invalid
75 {0.0f, 1.0f, 0.0f},
76 },
77 XRT_VEC3_ZERO,
78 XRT_VEC3_ZERO,
79};
80
81
82/*
83 *
84 * For flags testing
85 *
86 */
87
88enum Functions
89{
90 NV, // (Non-Identity) (Space Relation) Neither Position/Orientation Valid, Not Tracked
91 VT, // (Non-Identity) (Space Relation) Position/Orientation Valid, Tracked
92 VNT, // (Non-Identity) (Space Relation) Position/Orientation Valid, Not Tracked
93 P, // (Non-Identity) Pose
94 IP, // Identity Pose
95 ONLY_ORIENTATION, // (Non-Identity) (Space Relation) Only orientation Valid, Not Tracked
96 ONLY_POSITION, // (Non-Identity) (Space Relation) Only position Valid, Not Tracked
97};
98
99static void
100stringify(std::string &str, Functions fn)
101{
102 if (str.size() > 0) {
103 str += ", ";
104 }
105
106 switch (fn) {
107 case NV: str += "NV"; break;
108 case VT: str += "VT"; break;
109 case VNT: str += "VNT"; break;
110 case P: str += "P"; break;
111 case IP: str += "IP"; break;
112 case ONLY_ORIENTATION: str += "ONLY_ORIENTATION"; break;
113 case ONLY_POSITION: str += "ONLY_POSITION"; break;
114 default: assert(false);
115 }
116}
117
118static void
119run_func(struct xrt_relation_chain *xrc, Functions fn)
120{
121 switch (fn) {
122 case NV: m_relation_chain_push_relation(xrc, &kSpaceRelationNotValid); return;
123 case VT: m_relation_chain_push_relation(xrc, &kSpaceRelationOneYTracked); return;
124 case VNT: m_relation_chain_push_relation(xrc, &kSpaceRelationOneY); return;
125 case P: m_relation_chain_push_pose_if_not_identity(xrc, &kPoseOneY); return;
126 case IP: m_relation_chain_push_pose_if_not_identity(xrc, &kPoseIdentity); return;
127 case ONLY_ORIENTATION: m_relation_chain_push_relation(xrc, &kSpaceRelationOnlyOrientation); return;
128 case ONLY_POSITION: m_relation_chain_push_relation(xrc, &kSpaceRelationOnlyPosition); return;
129 default: assert(false);
130 }
131}
132
133/**
134 * The first argument is the expected relation flags.
135 * The following arguments are `enum Functions` values that get translated to one of the kSpaceRelation*
136 * xrt_space_relations each and pushed in order to the relation chain.
137 */
138#define TEST_FLAGS(EXPECTED, ...) \
139 do { \
140 struct xrt_space_relation result = XRT_STRUCT_INIT; \
141 struct xrt_relation_chain xrc = XRT_STRUCT_INIT; \
142 Functions fns[] = {__VA_ARGS__}; \
143 std::string str = {}; \
144 for (Functions fn : fns) { \
145 run_func(&xrc, fn); \
146 stringify(str, fn); \
147 } \
148 CAPTURE(str); \
149 m_relation_chain_resolve(&xrc, &result); \
150 CHECK(result.relation_flags == EXPECTED); \
151 } while (false)
152
153
154/*
155 *
156 * Tests
157 *
158 */
159
160TEST_CASE("Relation Chain Flags")
161{
162 SECTION("Not Valid")
163 {
164 TEST_FLAGS(kFlagsNotValid, VT, NV, VT);
165 TEST_FLAGS(kFlagsNotValid, VT, VT, VT, NV);
166 TEST_FLAGS(kFlagsNotValid, P, NV, VNT);
167
168 TEST_FLAGS(kFlagsNotValid, NV, ONLY_ORIENTATION);
169 TEST_FLAGS(kFlagsNotValid, NV, ONLY_POSITION);
170 TEST_FLAGS(kFlagsNotValid, ONLY_ORIENTATION, NV);
171 TEST_FLAGS(kFlagsNotValid, ONLY_POSITION, NV);
172 }
173
174 SECTION("Not Wrongly Tracked")
175 {
176 TEST_FLAGS(kFlagsValid, VNT, IP, VT);
177 TEST_FLAGS(kFlagsValid, VNT, P, VT);
178 TEST_FLAGS(kFlagsValid, P, VT, P, VNT);
179 TEST_FLAGS(kFlagsValid, VT, VT, VNT, VT);
180 TEST_FLAGS(kFlagsValid, IP, VT, P, VNT, P, VT);
181
182 // ONLY_ORIENTATION relation is upgraded to position valid
183 TEST_FLAGS(kFlagsValid, VT, ONLY_ORIENTATION);
184 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, VT, ONLY_POSITION);
185 // ONLY_ORIENTATION relation is upgraded to position valid
186 TEST_FLAGS(kFlagsValid, ONLY_ORIENTATION, VT);
187 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, ONLY_POSITION, VT);
188
189 // ONLY_ORIENTATION relation is upgraded to position valid
190 TEST_FLAGS(kFlagsValid, P, VT, ONLY_ORIENTATION, P);
191 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, P, VT, ONLY_POSITION, P);
192 // ONLY_ORIENTATION relation is upgraded to position valid
193 TEST_FLAGS(kFlagsValid, P, ONLY_ORIENTATION, VT, P);
194 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, P, ONLY_POSITION, VT, P);
195 }
196
197 SECTION("Tracked")
198 {
199 TEST_FLAGS(kFlagsValidTracked, P, VT, P);
200 TEST_FLAGS(kFlagsValidTracked, P, VT, P, VT);
201 TEST_FLAGS(kFlagsValidTracked, VT, IP, P);
202 TEST_FLAGS(kFlagsValidTracked, IP, VT, P);
203 TEST_FLAGS(kFlagsValidTracked, P, VT, IP, P);
204 TEST_FLAGS(kFlagsValidTracked, P, IP, VT, P);
205 TEST_FLAGS(kFlagsValidTracked, IP, IP, VT, IP, IP);
206 }
207
208 SECTION("Non-Tracked")
209 {
210 TEST_FLAGS(kFlagsValid, P, VNT, P);
211 TEST_FLAGS(kFlagsValid, VNT, VNT, VNT);
212 TEST_FLAGS(kFlagsValid, VNT, P);
213 TEST_FLAGS(kFlagsValid, P, VNT);
214 TEST_FLAGS(kFlagsValid, VNT, IP);
215 TEST_FLAGS(kFlagsValid, IP, VNT);
216 TEST_FLAGS(kFlagsValid, VNT, IP, P);
217 TEST_FLAGS(kFlagsValid, IP, VNT, P);
218 TEST_FLAGS(kFlagsValid, P, VNT, IP, P);
219 TEST_FLAGS(kFlagsValid, P, IP, VNT, P);
220
221 // ONLY_ORIENTATION relation is upgraded to position valid
222 TEST_FLAGS(kFlagsValid, P, ONLY_ORIENTATION, IP, P);
223 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, P, ONLY_POSITION, IP, P);
224
225 // ONLY_ORIENTATION relation is upgraded to position valid
226 TEST_FLAGS(kFlagsValid, ONLY_ORIENTATION, VNT);
227 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, ONLY_POSITION, VNT);
228 // ONLY_ORIENTATION relation is upgraded to position valid
229 TEST_FLAGS(kFlagsValid, VNT, ONLY_ORIENTATION);
230 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, VNT, ONLY_POSITION);
231
232 // ONLY_ORIENTATION relation is upgraded to position valid
233 TEST_FLAGS(kFlagsValid, ONLY_ORIENTATION, P, VNT);
234 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, ONLY_POSITION, P, VNT);
235 // ONLY_ORIENTATION relation is upgraded to position valid
236 TEST_FLAGS(kFlagsValid, VNT, ONLY_ORIENTATION, P);
237 TEST_FLAGS(XRT_SPACE_RELATION_POSITION_VALID_BIT, VNT, ONLY_POSITION, P);
238 }
239}