Blender V4.3
abc_matrix_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "testing/testing.h"
6
7/* Keep first since utildefines defines AT which conflicts with STL. */
9
10#include "BLI_math_base.h"
11#include "BLI_math_matrix.h"
12#include "BLI_utildefines.h"
13
14namespace blender::io::alembic {
15
16TEST(abc_matrix, CreateRotationMatrixY_YfromZ)
17{
18 /* Input variables */
19 float rot_x_mat[3][3];
20 float rot_y_mat[3][3];
21 float rot_z_mat[3][3];
22 float euler[3] = {0.0f, M_PI_4, 0.0f};
23
24 /* Construct expected matrices */
25 float unit[3][3];
26 float rot_z_min_quart_pi[3][3]; /* rotation of -pi/4 radians over z-axis */
27
28 unit_m3(unit);
29 unit_m3(rot_z_min_quart_pi);
30 rot_z_min_quart_pi[0][0] = M_SQRT1_2;
31 rot_z_min_quart_pi[0][1] = -M_SQRT1_2;
32 rot_z_min_quart_pi[1][0] = M_SQRT1_2;
33 rot_z_min_quart_pi[1][1] = M_SQRT1_2;
34
35 /* Run tests */
36 create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_YUP_FROM_ZUP);
37
38 EXPECT_M3_NEAR(rot_x_mat, unit, 1e-5f);
39 EXPECT_M3_NEAR(rot_y_mat, unit, 1e-5f);
40 EXPECT_M3_NEAR(rot_z_mat, rot_z_min_quart_pi, 1e-5f);
41}
42
43TEST(abc_matrix, CreateRotationMatrixZ_YfromZ)
44{
45 /* Input variables */
46 float rot_x_mat[3][3];
47 float rot_y_mat[3][3];
48 float rot_z_mat[3][3];
49 float euler[3] = {0.0f, 0.0f, M_PI_4};
50
51 /* Construct expected matrices */
52 float unit[3][3];
53 float rot_y_quart_pi[3][3]; /* rotation of pi/4 radians over y-axis */
54
55 unit_m3(unit);
56 unit_m3(rot_y_quart_pi);
57 rot_y_quart_pi[0][0] = M_SQRT1_2;
58 rot_y_quart_pi[0][2] = -M_SQRT1_2;
59 rot_y_quart_pi[2][0] = M_SQRT1_2;
60 rot_y_quart_pi[2][2] = M_SQRT1_2;
61
62 /* Run tests */
63 create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_YUP_FROM_ZUP);
64
65 EXPECT_M3_NEAR(rot_x_mat, unit, 1e-5f);
66 EXPECT_M3_NEAR(rot_y_mat, rot_y_quart_pi, 1e-5f);
67 EXPECT_M3_NEAR(rot_z_mat, unit, 1e-5f);
68}
69
70TEST(abc_matrix, CreateRotationMatrixXYZ_YfromZ)
71{
72 /* Input variables */
73 float rot_x_mat[3][3];
74 float rot_y_mat[3][3];
75 float rot_z_mat[3][3];
76 /* in degrees: X=10, Y=20, Z=30 */
77 float euler[3] = {0.17453292012214f, 0.34906581044197f, 0.52359879016876f};
78
79 /* Construct expected matrices */
80 float rot_x_p10[3][3]; /* rotation of +10 degrees over x-axis */
81 float rot_y_p30[3][3]; /* rotation of +30 degrees over y-axis */
82 float rot_z_m20[3][3]; /* rotation of -20 degrees over z-axis */
83
84 unit_m3(rot_x_p10);
85 rot_x_p10[1][1] = 0.9848077297210693f;
86 rot_x_p10[1][2] = 0.1736481785774231f;
87 rot_x_p10[2][1] = -0.1736481785774231f;
88 rot_x_p10[2][2] = 0.9848077297210693f;
89
90 unit_m3(rot_y_p30);
91 rot_y_p30[0][0] = 0.8660253882408142f;
92 rot_y_p30[0][2] = -0.5f;
93 rot_y_p30[2][0] = 0.5f;
94 rot_y_p30[2][2] = 0.8660253882408142f;
95
96 unit_m3(rot_z_m20);
97 rot_z_m20[0][0] = 0.9396926164627075f;
98 rot_z_m20[0][1] = -0.3420201241970062f;
99 rot_z_m20[1][0] = 0.3420201241970062f;
100 rot_z_m20[1][1] = 0.9396926164627075f;
101
102 /* Run tests */
103 create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_YUP_FROM_ZUP);
104
105 EXPECT_M3_NEAR(rot_x_mat, rot_x_p10, 1e-5f);
106 EXPECT_M3_NEAR(rot_y_mat, rot_y_p30, 1e-5f);
107 EXPECT_M3_NEAR(rot_z_mat, rot_z_m20, 1e-5f);
108}
109
110TEST(abc_matrix, CreateRotationMatrixXYZ_ZfromY)
111{
112 /* Input variables */
113 float rot_x_mat[3][3];
114 float rot_y_mat[3][3];
115 float rot_z_mat[3][3];
116 /* in degrees: X=10, Y=20, Z=30 */
117 float euler[3] = {0.1745329201221466f, 0.3490658104419708f, 0.5235987901687622f};
118
119 /* Construct expected matrices */
120 float rot_x_p10[3][3]; /* rotation of +10 degrees over x-axis */
121 float rot_y_m30[3][3]; /* rotation of -30 degrees over y-axis */
122 float rot_z_p20[3][3]; /* rotation of +20 degrees over z-axis */
123
124 unit_m3(rot_x_p10);
125 rot_x_p10[1][1] = 0.9848077297210693f;
126 rot_x_p10[1][2] = 0.1736481785774231f;
127 rot_x_p10[2][1] = -0.1736481785774231f;
128 rot_x_p10[2][2] = 0.9848077297210693f;
129
130 unit_m3(rot_y_m30);
131 rot_y_m30[0][0] = 0.8660253882408142f;
132 rot_y_m30[0][2] = 0.5f;
133 rot_y_m30[2][0] = -0.5f;
134 rot_y_m30[2][2] = 0.8660253882408142f;
135
136 unit_m3(rot_z_p20);
137 rot_z_p20[0][0] = 0.9396926164627075f;
138 rot_z_p20[0][1] = 0.3420201241970062f;
139 rot_z_p20[1][0] = -0.3420201241970062f;
140 rot_z_p20[1][1] = 0.9396926164627075f;
141
142 /* Run tests */
143 create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_ZUP_FROM_YUP);
144
145 EXPECT_M3_NEAR(rot_x_mat, rot_x_p10, 1e-5f);
146 EXPECT_M3_NEAR(rot_y_mat, rot_y_m30, 1e-5f);
147 EXPECT_M3_NEAR(rot_z_mat, rot_z_p20, 1e-5f);
148}
149
150TEST(abc_matrix, CopyM44AxisSwap_YfromZ)
151{
152 float result[4][4];
153
154 /* Construct an input matrix that performs a rotation like the tests
155 * above. This matrix was created by rotating a cube in Blender over
156 * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */
157 float input[4][4] = {
158 {0.81379765272f, 0.4698463380336f, -0.342020124197f, 0.0f},
159 {-0.44096961617f, 0.8825641274452f, 0.163175910711f, 0.0f},
160 {0.37852230668f, 0.0180283170193f, 0.925416588783f, 0.0f},
161 {1.0f, 2.0f, 3.0f, 1.0f},
162 };
163
164 copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP);
165
166 /* Check the resulting rotation & translation. */
167 const float trans[4] = {1.0f, 3.0f, -2.0f, 1.0f};
168 EXPECT_V4_NEAR(trans, result[3], 1e-5f);
169
170 /* This matrix was created by rotating a cube in Blender over
171 * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */
172 const float expect[4][4] = {
173 {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.0f},
174 {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.0f},
175 {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.0f},
176 {1.0f, 3.0f, -2.0f, 1.0f},
177 };
178 EXPECT_M4_NEAR(expect, result, 1e-5f);
179}
180
181TEST(abc_matrix, CopyM44AxisSwapWithScale_YfromZ)
182{
183 float result[4][4];
184
185 /* Construct an input matrix that performs a rotation like the tests
186 * above. This matrix was created by rotating a cube in Blender over
187 * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3),
188 * and scaling by (4, 5, 6). */
189 float input[4][4] = {
190 {3.25519061088f, 1.8793853521347f, -1.368080496788f, 0.0f},
191 {-2.20484805107f, 4.4128208160400f, 0.815879583358f, 0.0f},
192 {2.27113389968f, 0.1081698983907f, 5.552499771118f, 0.0f},
193 {1.0f, 2.0f, 3.0f, 1.0f},
194 };
195
196 copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP);
197
198 /* This matrix was created by rotating a cube in Blender over
199 * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2)
200 * and scaling over (4, 6, 5). */
201 const float expect[4][4] = {
202 {3.255190610885f, -1.368080496788f, -1.879385352134f, 0.0f},
203 {2.271133899688f, 5.552499771118f, -0.108169898390f, 0.0f},
204 {2.204848051071f, -0.815879583358f, 4.412820816040f, 0.0f},
205 {1.0f, 3.0f, -2.0f, 1.0f},
206 };
207 EXPECT_M4_NEAR(expect, result, 1e-5f);
208}
209
210TEST(abc_matrix, CopyM44AxisSwap_ZfromY)
211{
212 float result[4][4];
213
214 /* This matrix was created by rotating a cube in Blender over
215 * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */
216 float input[4][4] = {
217 {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.0f},
218 {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.0f},
219 {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.0f},
220 {1.0f, 3.0f, -2.0f, 1.0f},
221 };
222
223 copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP);
224
225 /* This matrix was created by rotating a cube in Blender over
226 * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */
227 const float expect[4][4] = {
228 {0.813797652721f, 0.469846338033f, -0.342020124197f, 0.0f},
229 {-0.44096961617f, 0.882564127445f, 0.163175910711f, 0.0f},
230 {0.378522306680f, 0.018028317019f, 0.925416588783f, 0.0f},
231 {1.0f, 2.0f, 3.0f, 1.0f},
232 };
233
234 EXPECT_M4_NEAR(expect, result, 1e-5f);
235}
236
237TEST(abc_matrix, CopyM44AxisSwapWithScale_ZfromY)
238{
239 float result[4][4];
240
241 /* This matrix was created by rotating a cube in Blender over
242 * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2)
243 * and scaling over (4, 6, 5). */
244 float input[4][4] = {
245 {3.2551906108f, -1.36808049678f, -1.879385352134f, 0.0f},
246 {2.2711338996f, 5.55249977111f, -0.108169898390f, 0.0f},
247 {2.2048480510f, -0.81587958335f, 4.412820816040f, 0.0f},
248 {1.0f, 3.0f, -2.0f, 1.0f},
249 };
250
251 copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP);
252
253 /* This matrix was created by rotating a cube in Blender over
254 * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3),
255 * and scaling by (4, 5, 6). */
256 const float expect[4][4] = {
257 {3.25519061088f, 1.879385352134f, -1.36808049678f, 0.0f},
258 {-2.2048480510f, 4.412820816040f, 0.81587958335f, 0.0f},
259 {2.27113389968f, 0.108169898390f, 5.55249977111f, 0.0f},
260 {1.0f, 2.0f, 3.0f, 1.0f},
261 };
262
263 EXPECT_M4_NEAR(expect, result, 1e-5f);
264}
265
266TEST(abc_matrix, CopyM44AxisSwapWithScale_gimbal_ZfromY)
267{
268 float result[4][4];
269
270 /* This matrix represents a rotation over (-90, -0, -0) degrees,
271 * and a translation over (-0, -0.1, -0). It is in Y=up. */
272 float input[4][4] = {
273 {1.000f, 0.000f, 0.000f, 0.000f},
274 {0.000f, 0.000f, -1.000f, 0.000f},
275 {0.000f, 1.000f, 0.000f, 0.000f},
276 {-0.000f, -0.100f, -0.000f, 1.000f},
277 };
278
279 copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP);
280
281 /* Since the rotation is only over the X-axis, it should not change.
282 * The translation does change. */
283 const float expect[4][4] = {
284 {1.000f, 0.000f, 0.000f, 0.000f},
285 {0.000f, 0.000f, -1.000f, 0.000f},
286 {0.000f, 1.000f, 0.000f, 0.000f},
287 {-0.000f, 0.000f, -0.100f, 1.000f},
288 };
289
290 EXPECT_M4_NEAR(expect, result, 1e-5f);
291}
292
293} // namespace blender::io::alembic
#define M_SQRT1_2
#define M_PI_4
void unit_m3(float m[3][3])
void create_swapped_rotation_matrix(float rot_x_mat[3][3], float rot_y_mat[3][3], float rot_z_mat[3][3], const float euler[3], AbcAxisSwapMode mode)
void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode)
TEST(abc_matrix, CreateRotationMatrixY_YfromZ)