The open source OpenXR runtime
at v21.0.0 9.6 kB view raw
1// Copyright 2018-2020, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Input transform tests. 6 * @author Ryan Pavlik <ryan.pavlik@collabora.com> 7 */ 8 9#include "catch/catch.hpp" 10 11#include <xrt/xrt_defines.h> 12 13#include <oxr/oxr_input_transform.h> 14#include <oxr/oxr_logger.h> 15#include <oxr/oxr_objects.h> 16 17using Catch::Generators::values; 18 19TEST_CASE("input_transform") 20{ 21 struct oxr_logger log; 22 oxr_log_init(&log, "test"); 23 struct oxr_sink_logger slog = {}; 24 25 struct oxr_input_transform *transforms = NULL; 26 size_t num_transforms = 0; 27 28 oxr_input_value_tagged input = {}; 29 oxr_input_value_tagged output = {}; 30 31 SECTION("Float action") 32 { 33 XrActionType action_type = XR_ACTION_TYPE_FLOAT_INPUT; 34 35 SECTION("From Vec1 -1 to 1 identity") 36 { 37 input.type = XRT_INPUT_TYPE_VEC1_MINUS_ONE_TO_ONE; 38 39 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, "float_action", 40 "/dummy_float", &transforms, &num_transforms)); 41 42 // Just identity 43 CHECK(num_transforms == 1); 44 CHECK(transforms != nullptr); 45 46 SECTION("Roundtrip") 47 { 48 auto value = GENERATE(values({-1.f, -0.5f, 0.f, -0.f, 0.5f, 1.f})); 49 input.value.vec1.x = value; 50 51 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 52 CHECK(input.value.vec1.x == output.value.vec1.x); 53 } 54 } 55 56 SECTION("From Vec1 0 to 1 identity") 57 { 58 input.type = XRT_INPUT_TYPE_VEC1_ZERO_TO_ONE; 59 60 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, "float_action", 61 "/dummy_float", &transforms, &num_transforms)); 62 63 // Just identity 64 CHECK(num_transforms == 1); 65 CHECK(transforms != nullptr); 66 67 SECTION("Roundtrip") 68 { 69 auto value = GENERATE(values({0.f, -0.f, 0.5f, 1.f})); 70 input.value.vec1.x = value; 71 72 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 73 CHECK(input.value.vec1.x == output.value.vec1.x); 74 } 75 } 76 77 SECTION("From Vec2 input") 78 { 79 input.type = XRT_INPUT_TYPE_VEC2_MINUS_ONE_TO_ONE; 80 input.value.vec2.x = -1; 81 input.value.vec2.y = 1; 82 83 SECTION("path component x") 84 { 85 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, 86 "float_action", "/dummy_vec2/x", &transforms, 87 &num_transforms)); 88 89 // A get-x 90 CHECK(num_transforms == 1); 91 CHECK(transforms != nullptr); 92 93 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 94 CHECK(input.value.vec2.x == output.value.vec1.x); 95 } 96 97 SECTION("path component y") 98 { 99 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, 100 "float_action", "/dummy_vec2/y", &transforms, 101 &num_transforms)); 102 103 // A get-y 104 CHECK(num_transforms == 1); 105 CHECK(transforms != nullptr); 106 107 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 108 CHECK(input.value.vec2.y == output.value.vec1.x); 109 } 110 111 SECTION("no component") 112 { 113 CHECK_FALSE(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, 114 "float_action", "/dummy_vec2", &transforms, 115 &num_transforms)); 116 117 // Shouldn't make a transform, not possible 118 CHECK(num_transforms == 0); 119 CHECK(transforms == nullptr); 120 121 // shouldn't do anything, but shouldn't explode. 122 CHECK_FALSE(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 123 } 124 } 125 126 SECTION("From bool input") 127 { 128 input.type = XRT_INPUT_TYPE_BOOLEAN; 129 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, "float_action", 130 "/dummy_bool", &transforms, &num_transforms)); 131 132 // A bool-to-float 133 CHECK(num_transforms == 1); 134 CHECK(transforms != nullptr); 135 136 SECTION("False") 137 { 138 input.value.boolean = false; 139 140 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 141 CHECK(0.0f == output.value.vec1.x); 142 } 143 144 SECTION("True") 145 { 146 input.value.boolean = true; 147 148 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 149 CHECK(1.0f == output.value.vec1.x); 150 } 151 } 152 } 153 154 SECTION("Bool action") 155 { 156 XrActionType action_type = XR_ACTION_TYPE_BOOLEAN_INPUT; 157 SECTION("From Bool identity") 158 { 159 input.type = XRT_INPUT_TYPE_BOOLEAN; 160 161 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, "bool_action", 162 "/dummy_bool", &transforms, &num_transforms)); 163 CHECK(num_transforms == 1); 164 CHECK(transforms != nullptr); 165 166 SECTION("Roundtrip") 167 { 168 auto value = GENERATE(values({0, 1})); 169 input.value.boolean = bool(value); 170 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 171 CHECK(input.value.boolean == output.value.boolean); 172 } 173 } 174 175 SECTION("From Vec1 -1 to 1") 176 { 177 input.type = XRT_INPUT_TYPE_VEC1_MINUS_ONE_TO_ONE; 178 179 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, "bool_action", 180 "/dummy_float", &transforms, &num_transforms)); 181 CHECK(num_transforms == 1); 182 CHECK(transforms != nullptr); 183 184 SECTION("True") 185 { 186 auto value = GENERATE(values({0.5f, 1.f})); 187 input.value.vec1.x = value; 188 189 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 190 CHECK(output.value.boolean == true); 191 } 192 193 SECTION("False") 194 { 195 auto value = GENERATE(values({0.0f, -1.f})); 196 input.value.vec1.x = value; 197 198 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 199 CHECK(output.value.boolean == false); 200 } 201 } 202 203 SECTION("From Vec1 0 to 1") 204 { 205 input.type = XRT_INPUT_TYPE_VEC1_ZERO_TO_ONE; 206 207 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, "bool_action", 208 "/dummy_float", &transforms, &num_transforms)); 209 // A bool to float 210 CHECK(num_transforms == 1); 211 CHECK(transforms != nullptr); 212 213 SECTION("True") 214 { 215 auto value = GENERATE(values({0.95f, 1.f})); 216 input.value.vec1.x = value; 217 218 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 219 CHECK(output.value.boolean == true); 220 } 221 222 SECTION("False") 223 { 224 auto value = GENERATE(values({0.0f, 0.5f})); 225 input.value.vec1.x = value; 226 227 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 228 CHECK(output.value.boolean == false); 229 } 230 } 231 232 SECTION("From Vec2") 233 { 234 input.type = XRT_INPUT_TYPE_VEC2_MINUS_ONE_TO_ONE; 235 input.value.vec2.x = -1; 236 input.value.vec2.y = 1; 237 238 SECTION("x") 239 { 240 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, 241 "float_action", "/dummy_vec2/x", &transforms, 242 &num_transforms)); 243 CHECK(num_transforms == 2); 244 CHECK(transforms != nullptr); 245 246 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 247 CHECK(false == output.value.boolean); 248 } 249 250 SECTION("y") 251 { 252 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, 253 "float_action", "/dummy_vec2/y", &transforms, 254 &num_transforms)); 255 CHECK(num_transforms == 2); 256 CHECK(transforms != nullptr); 257 258 CHECK(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 259 CHECK(true == output.value.boolean); 260 } 261 262 SECTION("no component") 263 { 264 CHECK_FALSE(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, 265 "float_action", "/dummy", &transforms, 266 &num_transforms)); 267 268 // Shouldn't make a transform, not possible 269 CHECK(num_transforms == 0); 270 CHECK(transforms == nullptr); 271 272 // shouldn't do anything, but shouldn't explode. 273 CHECK_FALSE(oxr_input_transform_process(transforms, num_transforms, &input, &output)); 274 } 275 } 276 } 277 278 SECTION("Pose action") 279 { 280 XrActionType action_type = XR_ACTION_TYPE_POSE_INPUT; 281 282 SECTION("From Pose identity") 283 { 284 input.type = XRT_INPUT_TYPE_POSE; 285 CHECK(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, "pose_action", 286 "/dummy_pose", &transforms, &num_transforms)); 287 // Identity, just so this binding doesn't get culled. 288 CHECK(num_transforms == 1); 289 } 290 291 SECTION("From other input") 292 { 293 auto input_type = GENERATE(values({ 294 XRT_INPUT_TYPE_BOOLEAN, 295 XRT_INPUT_TYPE_VEC1_MINUS_ONE_TO_ONE, 296 XRT_INPUT_TYPE_VEC1_ZERO_TO_ONE, 297 XRT_INPUT_TYPE_VEC2_MINUS_ONE_TO_ONE, 298 XRT_INPUT_TYPE_VEC3_MINUS_ONE_TO_ONE, 299 })); 300 301 CAPTURE(input_type); 302 input.type = input_type; 303 304 CHECK_FALSE(oxr_input_transform_create_chain(&log, &slog, input.type, action_type, 305 "pose_action", "/dummy", &transforms, 306 &num_transforms)); 307 308 // not possible 309 CHECK(num_transforms == 0); 310 CHECK(transforms == nullptr); 311 } 312 } 313 314 oxr_log_slog(&log, &slog); 315 oxr_input_transform_destroy(&transforms); 316 CHECK(NULL == transforms); 317}