Alembic: rotation mode issue in copy_m44_axis_swap, and added unit tests.
authorSybren A. Stüvel <sybren@stuvel.eu>
Wed, 5 Apr 2017 15:07:24 +0000 (17:07 +0200)
committerSybren A. Stüvel <sybren@stuvel.eu>
Thu, 6 Apr 2017 14:47:01 +0000 (16:47 +0200)
source/blender/alembic/intern/abc_util.cc
tests/gtests/alembic/abc_matrix_test.cc

index 87ba0fc9cc83151cebb49e314c89a58a248c2f1e..224e0eccd003e1d90e01d1d805ec4ddfda93a07e 100644 (file)
@@ -200,7 +200,7 @@ void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMod
        mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat);
 
        /* Get euler angles from rotation matrix. */
-       mat3_to_eulO(euler, ROT_MODE_XYZ, src_rot);
+       mat3_to_eulO(euler, ROT_MODE_XZY, src_rot);
 
        /* Create X, Y, Z rotation matrices from euler angles. */
        create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode);
@@ -210,7 +210,7 @@ void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMod
        mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat);
        mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat);
 
-       mat3_to_eulO(euler, ROT_MODE_XYZ, dst_rot);
+       mat3_to_eulO(euler, ROT_MODE_XZY, dst_rot);
 
        /* Start construction of dst_mat from rotation matrix */
        unit_m4(dst_mat);
index c9a79a73f60971a5d1defe128fdaaf7456c5cf78..08bce1ed50f054e24359f3705cd44a128a75ba24 100644 (file)
@@ -69,7 +69,7 @@ TEST(abc_matrix, CreateRotationMatrixXYZ_YfromZ) {
        float rot_y_mat[3][3];
        float rot_z_mat[3][3];
        // in degrees: X=10, Y=20, Z=30
-       float euler[3] = {0.1745329201221466f, 0.3490658104419708f, 0.5235987901687622f};
+       float euler[3] = {0.17453292012214f, 0.34906581044197f, 0.52359879016876f};
 
        // Construct expected matrices
        float rot_x_p10[3][3];  // rotation of +10 degrees over x-axis
@@ -142,3 +142,141 @@ TEST(abc_matrix, CreateRotationMatrixXYZ_ZfromY) {
        EXPECT_M3_NEAR(rot_y_mat, rot_y_m30, 1e-5f);
        EXPECT_M3_NEAR(rot_z_mat, rot_z_p20, 1e-5f);
 }
+
+TEST(abc_matrix, CopyM44AxisSwap_YfromZ) {
+       float result[4][4];
+
+       /* Construct an input matrix that performs a rotation like the tests
+        * above. This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */
+       float input[4][4] = {
+           { 0.81379765272f, 0.4698463380336f, -0.342020124197f, 0.f},
+           {-0.44096961617f, 0.8825641274452f,  0.163175910711f, 0.f},
+           { 0.37852230668f, 0.0180283170193f,  0.925416588783f, 0.f},
+           {1.f, 2.f, 3.f, 1.f},
+       };
+
+       copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP);
+
+       /* Check the resulting rotation & translation. */
+       float trans[4] = {1.f, 3.f, -2.f, 1.f};
+       EXPECT_V4_NEAR(trans, result[3], 1e-5f);
+
+       /* This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */
+       float expect[4][4] = {
+           {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.f},
+           {0.378522306680f,  0.925416588783f, -0.018028317019f, 0.f},
+           {0.440969616174f, -0.163175910711f,  0.882564127445f, 0.f},
+           {1.f, 3.f, -2.f, 1.f},
+       };
+       EXPECT_M4_NEAR(expect, result, 1e-5f);
+}
+
+TEST(abc_matrix, CopyM44AxisSwapWithScale_YfromZ) {
+       float result[4][4];
+
+       /* Construct an input matrix that performs a rotation like the tests
+        * above. This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3),
+        * and scaling by (4, 5, 6). */
+       float input[4][4] = {
+           { 3.25519061088f, 1.8793853521347f, -1.368080496788f, 0.f},
+           {-2.20484805107f, 4.4128208160400f,  0.815879583358f, 0.f},
+           { 2.27113389968f, 0.1081698983907f,  5.552499771118f, 0.f},
+           {1.f, 2.f, 3.f, 1.f},
+       };
+
+       copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP);
+
+       /* This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2)
+        * and scaling over (4, 6, 5). */
+       float expect[4][4] = {
+           {3.255190610885f, -1.368080496788f, -1.879385352134f, 0.f},
+           {2.271133899688f,  5.552499771118f, -0.108169898390f, 0.f},
+           {2.204848051071f, -0.815879583358f,  4.412820816040f, 0.f},
+           {1.f, 3.f, -2.f, 1.f},
+       };
+       EXPECT_M4_NEAR(expect, result, 1e-5f);
+}
+
+TEST(abc_matrix, CopyM44AxisSwap_ZfromY) {
+       float result[4][4];
+
+       /* This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */
+       float input[4][4] = {
+           {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.f},
+           {0.378522306680f,  0.925416588783f, -0.018028317019f, 0.f},
+           {0.440969616174f, -0.163175910711f,  0.882564127445f, 0.f},
+           {1.f, 3.f, -2.f, 1.f},
+       };
+
+       copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP);
+
+       /* This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */
+       float expect[4][4] = {
+           {0.813797652721f, 0.469846338033f, -0.342020124197f, 0.f},
+           {-0.44096961617f, 0.882564127445f,  0.163175910711f, 0.f},
+           {0.378522306680f, 0.018028317019f,  0.925416588783f, 0.f},
+           {1.f, 2.f, 3.f, 1.f},
+       };
+
+       EXPECT_M4_NEAR(expect, result, 1e-5f);
+}
+
+TEST(abc_matrix, CopyM44AxisSwapWithScale_ZfromY) {
+       float result[4][4];
+
+       /* This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2)
+        * and scaling over (4, 6, 5). */
+       float input[4][4] = {
+           {3.2551906108f, -1.36808049678f, -1.879385352134f, 0.f},
+           {2.2711338996f,  5.55249977111f, -0.108169898390f, 0.f},
+           {2.2048480510f, -0.81587958335f,  4.412820816040f, 0.f},
+           {1.f, 3.f, -2.f, 1.f},
+       };
+
+       copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP);
+
+       /* This matrix was created by rotating a cube in Blender over
+        * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3),
+        * and scaling by (4, 5, 6). */
+       float expect[4][4] = {
+           {3.25519061088f, 1.879385352134f, -1.36808049678f, 0.f},
+           {-2.2048480510f, 4.412820816040f,  0.81587958335f, 0.f},
+           {2.27113389968f, 0.108169898390f,  5.55249977111f, 0.f},
+           {1.f, 2.f, 3.f, 1.f},
+       };
+
+       EXPECT_M4_NEAR(expect, result, 1e-5f);
+}
+
+TEST(abc_matrix, CopyM44AxisSwapWithScale_gimbal_ZfromY) {
+       float result[4][4];
+
+       /* This matrix represents a rotation over (-90, -0, -0) degrees,
+        * and a translation over (-0, -0.1, -0). It is in Y=up. */
+       float input[4][4] = {
+           { 1.000f, 0.000f, 0.000f, 0.000f},
+           { 0.000f, 0.000f,-1.000f, 0.000f},
+           { 0.000f, 1.000f, 0.000f, 0.000f},
+           {-0.000f,-0.100f,-0.000f, 1.000f},
+       };
+
+       copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP);
+
+       /* Since the rotation is only over the X-axis, it should not change.
+        * The translation does change. */
+       float expect[4][4] = {
+           { 1.000f, 0.000f, 0.000f, 0.000f},
+           { 0.000f, 0.000f,-1.000f, 0.000f},
+           { 0.000f, 1.000f, 0.000f, 0.000f},
+           {-0.000f, 0.000f,-0.100f, 1.000f},
+       };
+
+       EXPECT_M4_NEAR(expect, result, 1e-5f);
+}