The open source OpenXR runtime
at main 2.7 kB view raw
1// Copyright 2021, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Test C++ quatexpmap interface. 6 * @author Mateo de Mayo <mateo.demayo@collabora.com> 7 */ 8 9#include "catch_amalgamated.hpp" 10#include "math/m_api.h" 11#include "math/m_vec3.h" 12#include <vector> 13 14using std::vector; 15 16TEST_CASE("m_quatexpmap") 17{ 18 xrt_vec3 axis1 = m_vec3_normalize({4, -7, 3}); 19 xrt_vec3 axis2 = m_vec3_normalize({-1, -2, -3}); 20 xrt_vec3 axis3 = m_vec3_normalize({1, -1, 1}); 21 xrt_vec3 axis4 = m_vec3_normalize({-11, 23, 91}); 22 SECTION("Test integrate velocity and finite difference mappings") 23 { 24 vector<xrt_vec3> q1_axes{{axis1, axis2}}; 25 float q1_angle = (float)GENERATE(M_PI, -M_PI / 6); 26 vector<xrt_vec3> vel_axes{{axis3, axis4}}; 27 float vel_angle = (float)GENERATE(-M_PI, M_PI / 5); 28 float dt = (float)GENERATE(0.01, 0.1, 1); 29 30 for (xrt_vec3 q1_axis : q1_axes) { 31 for (xrt_vec3 vel_axis : vel_axes) { 32 // First orientation q1 33 xrt_quat q1{}; 34 math_quat_from_angle_vector(q1_angle, &q1_axis, &q1); 35 36 // Second orientation q2: q1 rotated by vel_angle*dt radians around its local vel_axis 37 xrt_quat q2{}; 38 xrt_vec3 vel = vel_axis * vel_angle; 39 math_quat_integrate_velocity(&q1, &vel, dt, &q2); 40 41 // Global velocity vector from q1 to q2 42 xrt_vec3 new_global_vel{}; 43 math_quat_finite_difference(&q1, &q2, dt, &new_global_vel); 44 45 // Adjust global velocity back to local (w.r.t. q1) 46 xrt_quat inv_q1{}; 47 xrt_vec3 new_vel{}; 48 math_quat_invert(&q1, &inv_q1); 49 math_quat_rotate_derivative(&inv_q1, &new_global_vel, &new_vel); 50 51 INFO("vel=" << vel.x << ", " << vel.y << ", " << vel.z); 52 INFO("new_vel=" << new_vel.x << ", " << new_vel.y << ", " << new_vel.z); 53 CHECK(m_vec3_len(new_vel - vel) <= 0.001); 54 } 55 } 56 } 57 58 SECTION("Test quat_exp and quat_ln are inverses") 59 { 60 // We use rotations with less than PI radians as quat_ln will return the negative rotation otherwise 61 vector<xrt_vec3> aas = { 62 {0, 0, 0}, 63 axis1 * (float)M_PI * 0.01f, 64 axis2 * (float)M_PI * 0.5f, 65 axis3 * (float)M_PI * 0.99f, 66 }; 67 68 for (xrt_vec3 aa : aas) { 69 xrt_quat quat{}; 70 math_quat_exp(&aa, &quat); 71 72 xrt_vec3 expected_aa{}; 73 math_quat_ln(&quat, &expected_aa); 74 75 CHECK(m_vec3_len(expected_aa - aa) <= 0.001); 76 } 77 } 78 79//! @todo Fix quat_exp 80#if 0 81 SECTION("Test quat_exp(angle_axis) returns the appropriate quaternion") 82 { 83 float angle = M_PI_2; 84 xrt_vec3 axis = axis4; 85 xrt_vec3 aa = axis * angle; 86 xrt_quat q{}; 87 math_quat_exp(&aa, &q); 88 89 CHECK(q.x == Approx(axis.x * sin(angle / 2))); 90 CHECK(q.y == Approx(axis.y * sin(angle / 2))); 91 CHECK(q.z == Approx(axis.z * sin(angle / 2))); 92 CHECK(q.w == Approx(cos(angle / 2))); 93 } 94#endif 95}