Blender  V2.93
BLI_math_rotation_test.cc
Go to the documentation of this file.
1 /* Apache License, Version 2.0 */
2 
3 #include "testing/testing.h"
4 
5 #include "BLI_math_base.h"
6 #include "BLI_math_rotation.h"
7 
8 #include <cmath>
9 
10 /* Test that quaternion converts to itself via matrix. */
11 static void test_quat_to_mat_to_quat(float w, float x, float y, float z)
12 {
13  float in_quat[4] = {w, x, y, z};
14  float norm_quat[4], matrix[3][3], out_quat[4];
15 
16  normalize_qt_qt(norm_quat, in_quat);
17  quat_to_mat3(matrix, norm_quat);
18  mat3_normalized_to_quat(out_quat, matrix);
19 
20  /* The expected result is flipped (each orientation corresponds to 2 quats) */
21  if (w < 0) {
22  mul_qt_fl(norm_quat, -1);
23  }
24 
25  EXPECT_V4_NEAR(norm_quat, out_quat, FLT_EPSILON);
26 }
27 
28 TEST(math_rotation, quat_to_mat_to_quat_rot180)
29 {
30  test_quat_to_mat_to_quat(1, 0, 0, 0);
31  test_quat_to_mat_to_quat(0, 1, 0, 0);
32  test_quat_to_mat_to_quat(0, 0, 1, 0);
33  test_quat_to_mat_to_quat(0, 0, 0, 1);
34 }
35 
36 TEST(math_rotation, quat_to_mat_to_quat_rot180n)
37 {
38  test_quat_to_mat_to_quat(-1.000f, 0, 0, 0);
39  test_quat_to_mat_to_quat(-1e-20f, -1, 0, 0);
40  test_quat_to_mat_to_quat(-1e-20f, 0, -1, 0);
41  test_quat_to_mat_to_quat(-1e-20f, 0, 0, -1);
42 }
43 
44 TEST(math_rotation, quat_to_mat_to_quat_rot90)
45 {
46  const float s2 = 1 / sqrtf(2);
47  test_quat_to_mat_to_quat(s2, s2, 0, 0);
48  test_quat_to_mat_to_quat(s2, -s2, 0, 0);
49  test_quat_to_mat_to_quat(s2, 0, s2, 0);
50  test_quat_to_mat_to_quat(s2, 0, -s2, 0);
51  test_quat_to_mat_to_quat(s2, 0, 0, s2);
52  test_quat_to_mat_to_quat(s2, 0, 0, -s2);
53 }
54 
55 TEST(math_rotation, quat_to_mat_to_quat_rot90n)
56 {
57  const float s2 = 1 / sqrtf(2);
58  test_quat_to_mat_to_quat(-s2, s2, 0, 0);
59  test_quat_to_mat_to_quat(-s2, -s2, 0, 0);
60  test_quat_to_mat_to_quat(-s2, 0, s2, 0);
61  test_quat_to_mat_to_quat(-s2, 0, -s2, 0);
62  test_quat_to_mat_to_quat(-s2, 0, 0, s2);
63  test_quat_to_mat_to_quat(-s2, 0, 0, -s2);
64 }
65 
66 TEST(math_rotation, quat_to_mat_to_quat_bad_T83196)
67 {
68  test_quat_to_mat_to_quat(0.0032f, 0.9999f, -0.0072f, -0.0100f);
69  test_quat_to_mat_to_quat(0.0058f, 0.9999f, -0.0090f, -0.0101f);
70  test_quat_to_mat_to_quat(0.0110f, 0.9998f, -0.0140f, -0.0104f);
71  test_quat_to_mat_to_quat(0.0142f, 0.9997f, -0.0192f, -0.0107f);
72  test_quat_to_mat_to_quat(0.0149f, 0.9996f, -0.0212f, -0.0107f);
73 }
74 
75 TEST(math_rotation, quat_to_mat_to_quat_bad_negative)
76 {
77  /* This shouldn't produce a negative q[0]. */
78  test_quat_to_mat_to_quat(0.5f - 1e-6f, 0, -sqrtf(3) / 2 - 1e-6f, 0);
79 }
80 
81 TEST(math_rotation, quat_to_mat_to_quat_near_1000)
82 {
83  test_quat_to_mat_to_quat(0.9999f, 0.01f, -0.001f, -0.01f);
84  test_quat_to_mat_to_quat(0.9999f, 0.02f, -0.002f, -0.02f);
85  test_quat_to_mat_to_quat(0.9999f, 0.03f, -0.003f, -0.03f);
86  test_quat_to_mat_to_quat(0.9999f, 0.04f, -0.004f, -0.04f);
87  test_quat_to_mat_to_quat(0.9999f, 0.05f, -0.005f, -0.05f);
88  test_quat_to_mat_to_quat(0.999f, 0.10f, -0.010f, -0.10f);
89  test_quat_to_mat_to_quat(0.99f, 0.15f, -0.015f, -0.15f);
90  test_quat_to_mat_to_quat(0.98f, 0.20f, -0.020f, -0.20f);
91  test_quat_to_mat_to_quat(0.97f, 0.25f, -0.025f, -0.25f);
92  test_quat_to_mat_to_quat(0.95f, 0.30f, -0.030f, -0.30f);
93 }
94 
95 TEST(math_rotation, quat_to_mat_to_quat_near_0100)
96 {
97  test_quat_to_mat_to_quat(0.01f, 0.9999f, -0.001f, -0.01f);
98  test_quat_to_mat_to_quat(0.02f, 0.9999f, -0.002f, -0.02f);
99  test_quat_to_mat_to_quat(0.03f, 0.9999f, -0.003f, -0.03f);
100  test_quat_to_mat_to_quat(0.04f, 0.9999f, -0.004f, -0.04f);
101  test_quat_to_mat_to_quat(0.05f, 0.9999f, -0.005f, -0.05f);
102  test_quat_to_mat_to_quat(0.10f, 0.999f, -0.010f, -0.10f);
103  test_quat_to_mat_to_quat(0.15f, 0.99f, -0.015f, -0.15f);
104  test_quat_to_mat_to_quat(0.20f, 0.98f, -0.020f, -0.20f);
105  test_quat_to_mat_to_quat(0.25f, 0.97f, -0.025f, -0.25f);
106  test_quat_to_mat_to_quat(0.30f, 0.95f, -0.030f, -0.30f);
107 }
108 
109 TEST(math_rotation, quat_to_mat_to_quat_near_0010)
110 {
111  test_quat_to_mat_to_quat(0.01f, -0.001f, 0.9999f, -0.01f);
112  test_quat_to_mat_to_quat(0.02f, -0.002f, 0.9999f, -0.02f);
113  test_quat_to_mat_to_quat(0.03f, -0.003f, 0.9999f, -0.03f);
114  test_quat_to_mat_to_quat(0.04f, -0.004f, 0.9999f, -0.04f);
115  test_quat_to_mat_to_quat(0.05f, -0.005f, 0.9999f, -0.05f);
116  test_quat_to_mat_to_quat(0.10f, -0.010f, 0.999f, -0.10f);
117  test_quat_to_mat_to_quat(0.15f, -0.015f, 0.99f, -0.15f);
118  test_quat_to_mat_to_quat(0.20f, -0.020f, 0.98f, -0.20f);
119  test_quat_to_mat_to_quat(0.25f, -0.025f, 0.97f, -0.25f);
120  test_quat_to_mat_to_quat(0.30f, -0.030f, 0.95f, -0.30f);
121 }
122 
123 TEST(math_rotation, quat_to_mat_to_quat_near_0001)
124 {
125  test_quat_to_mat_to_quat(0.01f, -0.001f, -0.01f, 0.9999f);
126  test_quat_to_mat_to_quat(0.02f, -0.002f, -0.02f, 0.9999f);
127  test_quat_to_mat_to_quat(0.03f, -0.003f, -0.03f, 0.9999f);
128  test_quat_to_mat_to_quat(0.04f, -0.004f, -0.04f, 0.9999f);
129  test_quat_to_mat_to_quat(0.05f, -0.005f, -0.05f, 0.9999f);
130  test_quat_to_mat_to_quat(0.10f, -0.010f, -0.10f, 0.999f);
131  test_quat_to_mat_to_quat(0.15f, -0.015f, -0.15f, 0.99f);
132  test_quat_to_mat_to_quat(0.20f, -0.020f, -0.20f, 0.98f);
133  test_quat_to_mat_to_quat(0.25f, -0.025f, -0.25f, 0.97f);
134  test_quat_to_mat_to_quat(0.30f, -0.030f, -0.30f, 0.95f);
135 }
136 
137 TEST(math_rotation, quat_split_swing_and_twist_negative)
138 {
139  const float input[4] = {-0.5f, 0, sqrtf(3) / 2, 0};
140  const float expected_swing[4] = {1.0f, 0, 0, 0};
141  const float expected_twist[4] = {0.5f, 0, -sqrtf(3) / 2, 0};
142  float swing[4], twist[4];
143 
144  float twist_angle = quat_split_swing_and_twist(input, 1, swing, twist);
145 
146  EXPECT_NEAR(twist_angle, -M_PI * 2 / 3, FLT_EPSILON);
147  EXPECT_V4_NEAR(swing, expected_swing, FLT_EPSILON);
148  EXPECT_V4_NEAR(twist, expected_twist, FLT_EPSILON);
149 }
#define M_PI
Definition: BLI_math_base.h:38
void mul_qt_fl(float q[4], const float f)
float normalize_qt_qt(float r[4], const float q[4])
void quat_to_mat3(float mat[3][3], const float q[4])
float quat_split_swing_and_twist(const float q[4], int axis, float r_swing[4], float r_twist[4])
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
TEST(math_rotation, quat_to_mat_to_quat_rot180)
static void test_quat_to_mat_to_quat(float w, float x, float y, float z)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define sqrtf(x)