Blender  V3.3
armature_test.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
4 #include "BKE_armature.hh"
5 
6 #include "BLI_listbase.h"
7 #include "BLI_math.h"
8 
9 #include "DNA_armature_types.h"
10 
11 #include "testing/testing.h"
12 
13 namespace blender::bke::tests {
14 
15 static const float FLOAT_EPSILON = 1.2e-7;
16 
17 static const float SCALE_EPSILON = 3.71e-5;
18 static const float ORTHO_EPSILON = 5e-5;
19 
21 static double EXPECT_M3_ORTHOGONAL(const float mat[3][3],
22  double epsilon_scale,
23  double epsilon_ortho)
24 {
25  /* Do the checks in double precision to avoid precision issues in the checks themselves. */
26  double dmat[3][3];
27  copy_m3d_m3(dmat, mat);
28 
29  /* Check individual axis scaling. */
30  EXPECT_NEAR(len_v3_db(dmat[0]), 1.0, epsilon_scale);
31  EXPECT_NEAR(len_v3_db(dmat[1]), 1.0, epsilon_scale);
32  EXPECT_NEAR(len_v3_db(dmat[2]), 1.0, epsilon_scale);
33 
34  /* Check orthogonality. */
35  EXPECT_NEAR(dot_v3v3_db(dmat[0], dmat[1]), 0.0, epsilon_ortho);
36  EXPECT_NEAR(dot_v3v3_db(dmat[0], dmat[2]), 0.0, epsilon_ortho);
37  EXPECT_NEAR(dot_v3v3_db(dmat[1], dmat[2]), 0.0, epsilon_ortho);
38 
39  /* Check determinant to detect flipping and as a secondary volume change check. */
40  double determinant = determinant_m3_array_db(dmat);
41 
42  EXPECT_NEAR(determinant, 1.0, epsilon_ortho);
43 
44  return determinant;
45 }
46 
47 TEST(mat3_vec_to_roll, UnitMatrix)
48 {
49  float unit_matrix[3][3];
50  float roll;
51 
52  unit_m3(unit_matrix);
53 
54  /* Any vector with a unit matrix should return zero roll. */
55  mat3_vec_to_roll(unit_matrix, unit_matrix[0], &roll);
56  EXPECT_FLOAT_EQ(0.0f, roll);
57 
58  mat3_vec_to_roll(unit_matrix, unit_matrix[1], &roll);
59  EXPECT_FLOAT_EQ(0.0f, roll);
60 
61  mat3_vec_to_roll(unit_matrix, unit_matrix[2], &roll);
62  EXPECT_FLOAT_EQ(0.0f, roll);
63 
64  {
65  /* Non-unit vector. */
66  float vector[3] = {1.0f, 1.0f, 1.0f};
67  mat3_vec_to_roll(unit_matrix, vector, &roll);
68  EXPECT_NEAR(0.0f, roll, FLOAT_EPSILON);
69 
70  /* Normalized version of the above vector. */
72  mat3_vec_to_roll(unit_matrix, vector, &roll);
73  EXPECT_NEAR(0.0f, roll, FLOAT_EPSILON);
74  }
75 }
76 
77 TEST(mat3_vec_to_roll, Rotationmatrix)
78 {
79  float rotation_matrix[3][3];
80  float roll;
81 
82  const float rot_around_x[3] = {1.234f, 0.0f, 0.0f};
83  eul_to_mat3(rotation_matrix, rot_around_x);
84 
85  {
86  const float unit_axis_x[3] = {1.0f, 0.0f, 0.0f};
87  mat3_vec_to_roll(rotation_matrix, unit_axis_x, &roll);
88  EXPECT_NEAR(1.234f, roll, FLOAT_EPSILON);
89  }
90 
91  {
92  const float unit_axis_y[3] = {0.0f, 1.0f, 0.0f};
93  mat3_vec_to_roll(rotation_matrix, unit_axis_y, &roll);
94  EXPECT_NEAR(0, roll, FLOAT_EPSILON);
95  }
96 
97  {
98  const float unit_axis_z[3] = {0.0f, 0.0f, 1.0f};
99  mat3_vec_to_roll(rotation_matrix, unit_axis_z, &roll);
100  EXPECT_NEAR(0, roll, FLOAT_EPSILON);
101  }
102 
103  {
104  const float between_x_and_y[3] = {1.0f, 1.0f, 0.0f};
105  mat3_vec_to_roll(rotation_matrix, between_x_and_y, &roll);
106  EXPECT_NEAR(0.57158958f, roll, FLOAT_EPSILON);
107  }
108 }
109 
111 static double test_vec_roll_to_mat3_normalized(const float input[3],
112  float roll,
113  const float expected_roll_mat[3][3],
114  bool normalize = true)
115 {
116  float input_normalized[3];
117  float roll_mat[3][3];
118 
119  if (normalize) {
120  /* The vector is re-normalized to replicate the actual usage. */
121  normalize_v3_v3(input_normalized, input);
122  }
123  else {
124  copy_v3_v3(input_normalized, input);
125  }
126 
127  vec_roll_to_mat3_normalized(input_normalized, roll, roll_mat);
128 
129  EXPECT_V3_NEAR(roll_mat[1], input_normalized, FLT_EPSILON);
130 
131  if (expected_roll_mat) {
132  EXPECT_M3_NEAR(roll_mat, expected_roll_mat, FLT_EPSILON);
133  }
134 
136 }
137 
139 static double find_flip_boundary(double x, double z)
140 {
141  /* Irrational scale factor to ensure values aren't 'nice', have a lot of rounding errors,
142  * and can't accidentally produce the exact result returned by the special case. */
143  const double scale = M_1_PI / 10;
144  double theta = x * x + z * z;
145  double minv = 0, maxv = 1e-2;
146 
147  while (maxv - minv > FLT_EPSILON * 1e-3) {
148  double mid = (minv + maxv) / 2;
149 
150  float roll_mat[3][3];
151  float input[3] = {float(x * mid * scale),
152  -float(sqrt(1 - theta * mid * mid) * scale),
153  float(z * mid * scale)};
154 
156  vec_roll_to_mat3_normalized(input, 0, roll_mat);
157 
158  /* The special case assigns exact constants rather than computing. */
159  if (roll_mat[0][0] == -1 && roll_mat[0][1] == 0 && roll_mat[2][1] == 0) {
160  minv = mid;
161  }
162  else {
163  maxv = mid;
164  }
165  }
166 
167  return sqrt(theta) * (minv + maxv) * 0.5;
168 }
169 
171 {
172  EXPECT_NEAR(find_flip_boundary(0, 1), 2.50e-4, 0.01e-4);
173 }
174 
176 {
177  EXPECT_NEAR(find_flip_boundary(1, 1), 2.50e-4, 0.01e-4);
178 }
179 
180 /* Test cases close to the -Y axis. */
182 {
183  /* If normalized_vector is -Y, simple symmetry by Z axis. */
184  const float input[3] = {0.0f, -1.0f, 0.0f};
185  const float expected_roll_mat[3][3] = {
186  {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}};
187  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat, false);
188 }
189 
191 {
192  /* If normalized_vector is close to -Y and
193  * it has X and Z values below a threshold,
194  * simple symmetry by Z axis. */
195  const float input[3] = {1e-24, -0.999999881, 0};
196  const float expected_roll_mat[3][3] = {
197  {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}};
198  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat, false);
199 }
200 
202 {
203  /* If normalized_vector is in a critical range close to -Y, apply the special case. */
204  const float input[3] = {2.5e-4f, -0.999999881f, 2.5e-4f}; /* Corner Case. */
205  const float expected_roll_mat[3][3] = {{0.000000f, -2.5e-4f, -1.000000f},
206  {2.5e-4f, -0.999999881f, 2.5e-4f},
207  {-1.000000f, -2.5e-4f, 0.000000f}};
208  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat, false);
209 }
210 
211 /* Test 90 degree rotations. */
213 {
214  /* Rotate 90 around Z. */
215  const float input[3] = {1, 0, 0};
216  const float expected_roll_mat[3][3] = {{0, -1, 0}, {1, 0, 0}, {0, 0, 1}};
217  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
218 }
219 
221 {
222  /* Rotate 90 around Z. */
223  const float input[3] = {-1, 0, 0};
224  const float expected_roll_mat[3][3] = {{0, 1, 0}, {-1, 0, 0}, {0, 0, 1}};
225  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
226 }
227 
229 {
230  /* Rotate 90 around X. */
231  const float input[3] = {0, 0, -1};
232  const float expected_roll_mat[3][3] = {{1, 0, 0}, {0, 0, -1}, {0, 1, 0}};
233  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
234 }
235 
237 {
238  /* Rotate 90 around X. */
239  const float input[3] = {0, 0, 1};
240  const float expected_roll_mat[3][3] = {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}};
241  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
242 }
243 
244 /* Test the general case when the vector is far enough from -Y. */
246 {
247  const float input[3] = {1.0f, 1.0f, 1.0f}; /* Arbitrary Value. */
248  const float expected_roll_mat[3][3] = {{0.788675129f, -0.577350259f, -0.211324856f},
249  {0.577350259f, 0.577350259f, 0.577350259f},
250  {-0.211324856f, -0.577350259f, 0.788675129f}};
251  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
252 }
253 
255 {
256  const float input[3] = {1.0f, -1.0f, 1.0f}; /* Arbitrary Value. */
257  const float expected_roll_mat[3][3] = {{0.211324856f, -0.577350259f, -0.788675129f},
258  {0.577350259f, -0.577350259f, 0.577350259f},
259  {-0.788675129f, -0.577350259f, 0.211324856f}};
260  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
261 }
262 
264 {
265  const float input[3] = {-1.0f, -1.0f, 1.0f}; /* Arbitrary Value. */
266  const float expected_roll_mat[3][3] = {{0.211324856f, 0.577350259f, 0.788675129f},
267  {-0.577350259f, -0.577350259f, 0.577350259f},
268  {0.788675129f, -0.577350259f, 0.211324856f}};
269  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
270 }
271 
273 {
274  const float input[3] = {-1.0f, -1.0f, -1.0f}; /* Arbitrary Value. */
275  const float expected_roll_mat[3][3] = {{0.211324856f, 0.577350259f, -0.788675129f},
276  {-0.577350259f, -0.577350259f, -0.577350259f},
277  {-0.788675129f, 0.577350259f, 0.211324856f}};
278  test_vec_roll_to_mat3_normalized(input, 0.0f, expected_roll_mat);
279 }
280 
281 /* Test roll. */
283 {
284  const float input[3] = {1.0f, 1.0f, 1.0f}; /* Arbitrary Value. */
285  const float expected_roll_mat[3][3] = {{0.211324856f, 0.577350259f, -0.788675129f},
286  {0.577350259f, 0.577350259f, 0.577350259f},
287  {0.788675129f, -0.577350259f, -0.211324856f}};
288  test_vec_roll_to_mat3_normalized(input, float(M_PI_2), expected_roll_mat);
289 }
290 
292 static double test_vec_roll_to_mat3_orthogonal(double s, double x, double z)
293 {
294  const float input[3] = {float(x), float(s * sqrt(1 - x * x - z * z)), float(z)};
295 
296  return test_vec_roll_to_mat3_normalized(input, 0.0f, nullptr);
297 }
298 
300 static void test_vec_roll_to_mat3_orthogonal(double s, double x1, double x2, double y1, double y2)
301 {
302  const int count = 5000;
303  double delta = 0;
304  double tmax = 0;
305 
306  for (int i = 0; i <= count; i++) {
307  double t = double(i) / count;
308  double det = test_vec_roll_to_mat3_orthogonal(s, interpd(x2, x1, t), interpd(y2, y1, t));
309 
310  /* Find and report maximum error in the matrix determinant. */
311  double curdelta = abs(det - 1);
312  if (curdelta > delta) {
313  delta = curdelta;
314  tmax = t;
315  }
316  }
317 
318  printf(" Max determinant deviation %.10f at %f.\n", delta, tmax);
319 }
320 
321 #define TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(name, s, x1, x2, y1, y2) \
322  TEST(vec_roll_to_mat3_normalized, name) \
323  { \
324  test_vec_roll_to_mat3_orthogonal(s, x1, x2, y1, y2); \
325  }
326 
327 /* Moving from -Y towards X. */
328 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_000_005, -1, 0, 0, 3e-4, 0.005)
329 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_000_010, -1, 0, 0, 0.005, 0.010)
330 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_000_050, -1, 0, 0, 0.010, 0.050)
331 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_000_100, -1, 0, 0, 0.050, 0.100)
332 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_000_200, -1, 0, 0, 0.100, 0.200)
333 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_000_300, -1, 0, 0, 0.200, 0.300)
334 
335 /* Moving from -Y towards X and Y. */
336 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_005_005, -1, 3e-4, 0.005, 3e-4, 0.005)
337 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_010_010, -1, 0.005, 0.010, 0.005, 0.010)
338 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_050_050, -1, 0.010, 0.050, 0.010, 0.050)
339 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_100_100, -1, 0.050, 0.100, 0.050, 0.100)
340 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoN_200_200, -1, 0.100, 0.200, 0.100, 0.200)
341 
342 /* Moving from +Y towards X. */
343 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoP_000_005, 1, 0, 0, 0, 0.005)
344 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoP_000_100, 1, 0, 0, 0.005, 0.100)
345 
346 /* Moving from +Y towards X and Y. */
347 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoP_005_005, 1, 0, 0.005, 0, 0.005)
348 TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(OrthoP_100_100, 1, 0.005, 0.100, 0.005, 0.100)
349 
350 class BKE_armature_find_selected_bones_test : public testing::Test {
351  protected:
353  Bone bone1, bone2, bone3;
354 
355  void SetUp() override
356  {
357  strcpy(bone1.name, "bone1");
358  strcpy(bone2.name, "bone2");
359  strcpy(bone3.name, "bone3");
360 
361  arm.bonebase = {nullptr, nullptr};
362  bone1.childbase = {nullptr, nullptr};
363  bone2.childbase = {nullptr, nullptr};
364  bone3.childbase = {nullptr, nullptr};
365 
366  BLI_addtail(&arm.bonebase, &bone1); /* bone1 is root bone. */
367  BLI_addtail(&arm.bonebase, &bone2); /* bone2 is root bone. */
368  BLI_addtail(&bone2.childbase, &bone3); /* bone3 has bone2 as parent. */
369 
370  /* Make sure the armature & its bones are visible, to make them selectable. */
371  arm.layer = bone1.layer = bone2.layer = bone3.layer = 1;
372  }
373 };
374 
376 {
377  bone1.flag = BONE_SELECTED;
378  bone2.flag = 0;
379  bone3.flag = BONE_SELECTED;
380 
381  std::vector<Bone *> seen_bones;
382  auto callback = [&](Bone *bone) { seen_bones.push_back(bone); };
383 
385 
386  ASSERT_EQ(seen_bones.size(), 2) << "Expected 2 selected bones, got " << seen_bones.size();
387  EXPECT_EQ(seen_bones[0], &bone1);
388  EXPECT_EQ(seen_bones[1], &bone3);
389 
390  EXPECT_FALSE(result.all_bones_selected); /* Bone 2 was not selected. */
391  EXPECT_FALSE(result.no_bones_selected); /* Bones 1 and 3 were selected. */
392 }
393 
395 {
396  bone1.flag = bone2.flag = bone3.flag = 0;
397 
398  std::vector<Bone *> seen_bones;
399  auto callback = [&](Bone *bone) { seen_bones.push_back(bone); };
400 
402 
403  EXPECT_TRUE(seen_bones.empty()) << "Expected no selected bones, got " << seen_bones.size();
404  EXPECT_FALSE(result.all_bones_selected);
405  EXPECT_TRUE(result.no_bones_selected);
406 }
407 
409 {
410  bone1.flag = bone2.flag = bone3.flag = BONE_SELECTED;
411 
412  std::vector<Bone *> seen_bones;
413  auto callback = [&](Bone *bone) { seen_bones.push_back(bone); };
414 
416 
417  ASSERT_EQ(seen_bones.size(), 3) << "Expected 3 selected bones, got " << seen_bones.size();
418  EXPECT_EQ(seen_bones[0], &bone1);
419  EXPECT_EQ(seen_bones[1], &bone2);
420  EXPECT_EQ(seen_bones[2], &bone3);
421 
422  EXPECT_TRUE(result.all_bones_selected);
423  EXPECT_FALSE(result.no_bones_selected);
424 }
425 
426 } // namespace blender::bke::tests
typedef float(TangentPoint)[2]
void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll)
Definition: armature.c:2067
void vec_roll_to_mat3_normalized(const float nor[3], float roll, float r_mat[3][3])
Definition: armature.c:2082
sqrt(x)+1/max(0
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
#define M_1_PI
Definition: BLI_math_base.h:41
MINLINE double interpd(double a, double b, double t)
#define M_PI_2
Definition: BLI_math_base.h:23
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
double determinant_m3_array_db(const double m[3][3])
Definition: math_matrix.c:1112
void copy_m3d_m3(double m1[3][3], const float m2[3][3])
Definition: math_matrix.c:165
void eul_to_mat3(float mat[3][3], const float eul[3])
MINLINE float normalize_v3(float r[3])
MINLINE double len_v3_db(const double a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE double dot_v3v3_db(const double a[3], const double b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3_v3(float r[3], const float a[3])
typedef double(DMatrix)[4][4]
@ BONE_SELECTED
_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 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 GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_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 GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_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 GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define TEST_VEC_ROLL_TO_MAT3_ORTHOGONAL(name, s, x1, x2, y1, y2)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
btScalar determinant() const
Return the determinant of the matrix.
Definition: btMatrix3x3.h:1022
DEGForeachIDComponentCallback callback
int count
ccl_global KernelShaderEvalInput * input
static double find_flip_boundary(double x, double z)
static const float SCALE_EPSILON
TEST_F(BKE_armature_find_selected_bones_test, some_bones_selected)
static double test_vec_roll_to_mat3_orthogonal(double s, double x, double z)
static double EXPECT_M3_ORTHOGONAL(const float mat[3][3], double epsilon_scale, double epsilon_ortho)
static const float ORTHO_EPSILON
TEST(action_groups, ReconstructGroupsWithReordering)
Definition: action_test.cc:17
static const float FLOAT_EPSILON
static double test_vec_roll_to_mat3_normalized(const float input[3], float roll, const float expected_roll_mat[3][3], bool normalize=true)
SelectedBonesResult BKE_armature_find_selected_bones(const bArmature *armature, SelectedBoneCallback callback)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
T abs(const T &a)
char name[64]
ListBase childbase
ListBase bonebase
unsigned int layer