From 923b314a7af6494e7d8dade0ffd8dfebd5976f8c Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Mon, 9 Nov 2020 18:57:40 +0100 Subject: Test cases for vec_roll_to_mat3_normalized The function vec_roll_to_mat3_normalized() basically has to handle 3 scenarios: - When a bone is oriented along the negative Y axis - When a bone is very close to the negative Y axis - All other cases The tests in the Differential make sure that all 3 situations are covered. Reviewed By: sybren, mont29 Differential Revision: https://developer.blender.org/D9525 --- source/blender/blenkernel/intern/armature_test.cc | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'source/blender/blenkernel/intern/armature_test.cc') diff --git a/source/blender/blenkernel/intern/armature_test.cc b/source/blender/blenkernel/intern/armature_test.cc index f3c0d2f407a..7beda857a73 100644 --- a/source/blender/blenkernel/intern/armature_test.cc +++ b/source/blender/blenkernel/intern/armature_test.cc @@ -90,4 +90,71 @@ TEST(mat3_vec_to_roll, Rotationmatrix) } } +TEST(vec_roll_to_mat3_normalized, Rotationmatrix) +{ + float negative_y_axis[3][3]; + unit_m3(negative_y_axis); + negative_y_axis[0][0] = negative_y_axis[1][1] = -1.0f; + + const float roll = 0.0f; + float roll_mat[3][3]; + + /* If normalized_vector is -Y, simple symmetry by Z axis. */ + { + const float normalized_vector[3] = {0.0f, -1.0f, 0.0f}; + vec_roll_to_mat3_normalized(normalized_vector, roll, roll_mat); + EXPECT_M3_NEAR(roll_mat, negative_y_axis, FLT_EPSILON); + } + + /* If normalized_vector is far enough from -Y, apply the general case. */ + { + const float expected_roll_mat[3][3] = {{1.000000f, 0.000000f, 0.000000f}, + {0.000000f, -0.999989986f, -0.000000f}, + {0.000000f, 0.000000f, 1.000000f}}; + + const float normalized_vector[3] = {0.0f, -1.0f + 1e-5f, 0.0f}; + vec_roll_to_mat3_normalized(normalized_vector, roll, roll_mat); + EXPECT_M3_NEAR(roll_mat, expected_roll_mat, FLT_EPSILON); + } + +#if 0 + /* TODO: This test will pass after fixing T82455) */ + /* If normalized_vector is close to -Y and + * it has X and Z values above a threshold, + * apply the special case. */ + { + const float expected_roll_mat[3][3] = {{0.000000f, -9.99999975e-06f, 1.000000f}, + {9.99999975e-06f, -0.999999881f, 9.99999975e-06f}, + {1.000000f, -9.99999975e-06, 0.000000f}}; + const float normalized_vector[3] = {1e-24, -0.999999881, 0}; + vec_roll_to_mat3_normalized(normalized_vector, roll, roll_mat); + EXPECT_M3_NEAR(roll_mat, expected_roll_mat, FLT_EPSILON); + } +#endif + + /* If normalized_vector is in a critical range close to -Y, apply the special case. */ + { + const float expected_roll_mat[3][3] = {{0.000000f, -9.99999975e-06f, 1.000000f}, + {9.99999975e-06f, -0.999999881f, 9.99999975e-06f}, + {1.000000f, -9.99999975e-06, 0.000000f}}; + + const float normalized_vector[3] = {1e-5f, -0.999999881f, 1e-5f}; /* Corner Case. */ + vec_roll_to_mat3_normalized(normalized_vector, roll, roll_mat); + EXPECT_M3_NEAR(roll_mat, expected_roll_mat, FLT_EPSILON); + } + + /* If normalized_vector is far enough from -Y, apply the general case. */ + { + const float expected_roll_mat[3][3] = {{0.788675129f, -0.577350259f, -0.211324856f}, + {0.577350259f, 0.577350259f, 0.577350259f}, + {-0.211324856f, -0.577350259f, 0.788675129f}}; + + const float vector[3] = {1.0f, 1.0f, 1.0f}; /* Arbitrary Value. */ + float normalized_vector[3]; + normalize_v3_v3(normalized_vector, vector); + vec_roll_to_mat3_normalized(normalized_vector, roll, roll_mat); + EXPECT_M3_NEAR(roll_mat, expected_roll_mat, FLT_EPSILON); + } +} + } // namespace blender::bke::tests -- cgit v1.2.3