Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2020-11-30 19:31:21 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2020-11-30 21:46:45 +0300
commit814b2787caddf5bd81477bd7b5dea8c45c402a72 (patch)
treeb936548e5f84016c6cff1feab96dfbeb7c42dce0 /source/blender/blenlib/tests/BLI_math_rotation_test.cc
parent6022103264cf2e23ad884fce6b5dfadf88b24e05 (diff)
Fix T83196: bad matrix to quaternion precision near 180 degrees rotation.
Adjust the threshold for switching from the base case to trace > 0, based on very similar example code from www.euclideanspace.com to avoid float precision issues when trace is close to -1. Also, remove conversions to and from double, because using double here doesn't really have benefit, especially with the new threshold. Finally, add quaternion-matrix-quaternion round trip tests with full coverage for all 4 branches. Differential Revision: https://developer.blender.org/D9675
Diffstat (limited to 'source/blender/blenlib/tests/BLI_math_rotation_test.cc')
-rw-r--r--source/blender/blenlib/tests/BLI_math_rotation_test.cc128
1 files changed, 128 insertions, 0 deletions
diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
new file mode 100644
index 00000000000..1b1c4ef24a1
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
@@ -0,0 +1,128 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "BLI_math_rotation.h"
+
+#include <math.h>
+
+/* Test that quaternion converts to itself via matrix. */
+static void test_quat_to_mat_to_quat(float w, float x, float y, float z)
+{
+ float in_quat[4] = {w, x, y, z};
+ float norm_quat[4], matrix[3][3], out_quat[4];
+
+ normalize_qt_qt(norm_quat, in_quat);
+ quat_to_mat3(matrix, norm_quat);
+ mat3_normalized_to_quat(out_quat, matrix);
+
+ /* The expected result is flipped (each orientation corresponds to 2 quats) */
+ if (w < 0) {
+ mul_qt_fl(norm_quat, -1);
+ }
+
+ EXPECT_V4_NEAR(norm_quat, out_quat, FLT_EPSILON);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_rot180)
+{
+ test_quat_to_mat_to_quat(1, 0, 0, 0);
+ test_quat_to_mat_to_quat(0, 1, 0, 0);
+ test_quat_to_mat_to_quat(0, 0, 1, 0);
+ test_quat_to_mat_to_quat(0, 0, 0, 1);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_rot180n)
+{
+ test_quat_to_mat_to_quat(-1.000f, 0, 0, 0);
+ test_quat_to_mat_to_quat(-1e-20f, -1, 0, 0);
+ test_quat_to_mat_to_quat(-1e-20f, 0, -1, 0);
+ test_quat_to_mat_to_quat(-1e-20f, 0, 0, -1);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_rot90)
+{
+ const float s2 = 1 / sqrtf(2);
+ test_quat_to_mat_to_quat(s2, s2, 0, 0);
+ test_quat_to_mat_to_quat(s2, -s2, 0, 0);
+ test_quat_to_mat_to_quat(s2, 0, s2, 0);
+ test_quat_to_mat_to_quat(s2, 0, -s2, 0);
+ test_quat_to_mat_to_quat(s2, 0, 0, s2);
+ test_quat_to_mat_to_quat(s2, 0, 0, -s2);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_rot90n)
+{
+ const float s2 = 1 / sqrtf(2);
+ test_quat_to_mat_to_quat(-s2, s2, 0, 0);
+ test_quat_to_mat_to_quat(-s2, -s2, 0, 0);
+ test_quat_to_mat_to_quat(-s2, 0, s2, 0);
+ test_quat_to_mat_to_quat(-s2, 0, -s2, 0);
+ test_quat_to_mat_to_quat(-s2, 0, 0, s2);
+ test_quat_to_mat_to_quat(-s2, 0, 0, -s2);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_bad_T83196)
+{
+ test_quat_to_mat_to_quat(0.0032f, 0.9999f, -0.0072f, -0.0100f);
+ test_quat_to_mat_to_quat(0.0058f, 0.9999f, -0.0090f, -0.0101f);
+ test_quat_to_mat_to_quat(0.0110f, 0.9998f, -0.0140f, -0.0104f);
+ test_quat_to_mat_to_quat(0.0142f, 0.9997f, -0.0192f, -0.0107f);
+ test_quat_to_mat_to_quat(0.0149f, 0.9996f, -0.0212f, -0.0107f);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_near_1000)
+{
+ test_quat_to_mat_to_quat(0.9999f, 0.01f, -0.001f, -0.01f);
+ test_quat_to_mat_to_quat(0.9999f, 0.02f, -0.002f, -0.02f);
+ test_quat_to_mat_to_quat(0.9999f, 0.03f, -0.003f, -0.03f);
+ test_quat_to_mat_to_quat(0.9999f, 0.04f, -0.004f, -0.04f);
+ test_quat_to_mat_to_quat(0.9999f, 0.05f, -0.005f, -0.05f);
+ test_quat_to_mat_to_quat(0.999f, 0.10f, -0.010f, -0.10f);
+ test_quat_to_mat_to_quat(0.99f, 0.15f, -0.015f, -0.15f);
+ test_quat_to_mat_to_quat(0.98f, 0.20f, -0.020f, -0.20f);
+ test_quat_to_mat_to_quat(0.97f, 0.25f, -0.025f, -0.25f);
+ test_quat_to_mat_to_quat(0.95f, 0.30f, -0.030f, -0.30f);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_near_0100)
+{
+ test_quat_to_mat_to_quat(0.01f, 0.9999f, -0.001f, -0.01f);
+ test_quat_to_mat_to_quat(0.02f, 0.9999f, -0.002f, -0.02f);
+ test_quat_to_mat_to_quat(0.03f, 0.9999f, -0.003f, -0.03f);
+ test_quat_to_mat_to_quat(0.04f, 0.9999f, -0.004f, -0.04f);
+ test_quat_to_mat_to_quat(0.05f, 0.9999f, -0.005f, -0.05f);
+ test_quat_to_mat_to_quat(0.10f, 0.999f, -0.010f, -0.10f);
+ test_quat_to_mat_to_quat(0.15f, 0.99f, -0.015f, -0.15f);
+ test_quat_to_mat_to_quat(0.20f, 0.98f, -0.020f, -0.20f);
+ test_quat_to_mat_to_quat(0.25f, 0.97f, -0.025f, -0.25f);
+ test_quat_to_mat_to_quat(0.30f, 0.95f, -0.030f, -0.30f);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_near_0010)
+{
+ test_quat_to_mat_to_quat(0.01f, -0.001f, 0.9999f, -0.01f);
+ test_quat_to_mat_to_quat(0.02f, -0.002f, 0.9999f, -0.02f);
+ test_quat_to_mat_to_quat(0.03f, -0.003f, 0.9999f, -0.03f);
+ test_quat_to_mat_to_quat(0.04f, -0.004f, 0.9999f, -0.04f);
+ test_quat_to_mat_to_quat(0.05f, -0.005f, 0.9999f, -0.05f);
+ test_quat_to_mat_to_quat(0.10f, -0.010f, 0.999f, -0.10f);
+ test_quat_to_mat_to_quat(0.15f, -0.015f, 0.99f, -0.15f);
+ test_quat_to_mat_to_quat(0.20f, -0.020f, 0.98f, -0.20f);
+ test_quat_to_mat_to_quat(0.25f, -0.025f, 0.97f, -0.25f);
+ test_quat_to_mat_to_quat(0.30f, -0.030f, 0.95f, -0.30f);
+}
+
+TEST(math_rotation, quat_to_mat_to_quat_near_0001)
+{
+ test_quat_to_mat_to_quat(0.01f, -0.001f, -0.01f, 0.9999f);
+ test_quat_to_mat_to_quat(0.02f, -0.002f, -0.02f, 0.9999f);
+ test_quat_to_mat_to_quat(0.03f, -0.003f, -0.03f, 0.9999f);
+ test_quat_to_mat_to_quat(0.04f, -0.004f, -0.04f, 0.9999f);
+ test_quat_to_mat_to_quat(0.05f, -0.005f, -0.05f, 0.9999f);
+ test_quat_to_mat_to_quat(0.10f, -0.010f, -0.10f, 0.999f);
+ test_quat_to_mat_to_quat(0.15f, -0.015f, -0.15f, 0.99f);
+ test_quat_to_mat_to_quat(0.20f, -0.020f, -0.20f, 0.98f);
+ test_quat_to_mat_to_quat(0.25f, -0.025f, -0.25f, 0.97f);
+ test_quat_to_mat_to_quat(0.30f, -0.030f, -0.30f, 0.95f);
+}