Blender V5.0
math_vector.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10
11#include "BLI_math_base.h"
12#include "BLI_math_vector.h"
13
14#include "BLI_math_base_safe.h"
15#include "BLI_math_geom.h"
16#include "BLI_math_rotation.h"
17
18#include "BLI_strict_flags.h" /* IWYU pragma: keep. Keep last. */
19
20/* -------------------------------------------------------------------- */
23
24void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t)
25{
26 const float s = 1.0f - t;
27
28 r[0] = s * a[0] + t * b[0];
29 r[1] = s * a[1] + t * b[1];
30}
31
33 float r[2], const float a[2], const float b[2], const float c[2], const float t[3])
34{
35 r[0] = a[0] * t[0] + b[0] * t[1] + c[0] * t[2];
36 r[1] = a[1] * t[0] + b[1] * t[1] + c[1] * t[2];
37}
38
39void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
40{
41 const float s = 1.0f - t;
42
43 r[0] = s * a[0] + t * b[0];
44 r[1] = s * a[1] + t * b[1];
45 r[2] = s * a[2] + t * b[2];
46}
47
48void interp_v4_v4v4(float r[4], const float a[4], const float b[4], const float t)
49{
50 const float s = 1.0f - t;
51
52 r[0] = s * a[0] + t * b[0];
53 r[1] = s * a[1] + t * b[1];
54 r[2] = s * a[2] + t * b[2];
55 r[3] = s * a[3] + t * b[3];
56}
57
58bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t)
59{
60 float cosom, w[2];
61
64
65 cosom = dot_v3v3(a, b);
66
67 /* direct opposites */
68 if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
69 return false;
70 }
71
72 interp_dot_slerp(t, cosom, w);
73
74 target[0] = w[0] * a[0] + w[1] * b[0];
75 target[1] = w[0] * a[1] + w[1] * b[1];
76 target[2] = w[0] * a[2] + w[1] * b[2];
77
78 return true;
79}
80
81void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t)
82{
83 if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, b, t))) {
84 /* Axis are aligned so any orthogonal vector is acceptable. */
85 float ab_ortho[3];
86 ortho_v3_v3(ab_ortho, a);
87 normalize_v3(ab_ortho);
88 if (t < 0.5f) {
89 if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, ab_ortho, t * 2.0f))) {
90 BLI_assert(0);
91 copy_v3_v3(target, a);
92 }
93 }
94 else {
95 if (UNLIKELY(!interp_v3_v3v3_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
96 BLI_assert(0);
97 copy_v3_v3(target, b);
98 }
99 }
100 }
101}
102
104 const float v1[2],
105 const float v2[2],
106 const float v3[2],
107 const float v4[2],
108 const float u)
109{
110 float q0[2], q1[2], q2[2], r0[2], r1[2];
111
112 interp_v2_v2v2(q0, v1, v2, u);
113 interp_v2_v2v2(q1, v2, v3, u);
114 interp_v2_v2v2(q2, v3, v4, u);
115
116 interp_v2_v2v2(r0, q0, q1, u);
117 interp_v2_v2v2(r1, q1, q2, u);
118
119 interp_v2_v2v2(p, r0, r1, u);
120}
121
123 float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
124{
125 p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
126 p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
127 p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2];
128}
129
130void interp_v3_v3v3v3v3(float p[3],
131 const float v1[3],
132 const float v2[3],
133 const float v3[3],
134 const float v4[3],
135 const float w[4])
136{
137 p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3];
138 p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3];
139 p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3];
140}
141
143 float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3])
144{
145 p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
146 p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
147 p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2];
148 p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2];
149}
150
151void interp_v4_v4v4v4v4(float p[4],
152 const float v1[4],
153 const float v2[4],
154 const float v3[4],
155 const float v4[4],
156 const float w[4])
157{
158 p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3];
159 p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3];
160 p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3];
161 p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2] + v4[3] * w[3];
162}
163
165 float p[3], const float v1[3], const float v2[3], const float v3[3], const float uv[2])
166{
167 p[0] = v1[0] + ((v2[0] - v1[0]) * uv[0]) + ((v3[0] - v1[0]) * uv[1]);
168 p[1] = v1[1] + ((v2[1] - v1[1]) * uv[0]) + ((v3[1] - v1[1]) * uv[1]);
169 p[2] = v1[2] + ((v2[2] - v1[2]) * uv[0]) + ((v3[2] - v1[2]) * uv[1]);
170}
171
172void interp_v3_v3v3_uchar(uchar target[3], const uchar a[3], const uchar b[3], const float t)
173{
174 const float s = 1.0f - t;
175
176 target[0] = char(floorf(s * a[0] + t * b[0]));
177 target[1] = char(floorf(s * a[1] + t * b[1]));
178 target[2] = char(floorf(s * a[2] + t * b[2]));
179}
180
181void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
182{
183 r[0] = 0.5f * (a[0] + b[0]);
184 r[1] = 0.5f * (a[1] + b[1]);
185 r[2] = 0.5f * (a[2] + b[2]);
186}
187
188void mid_v2_v2v2(float r[2], const float a[2], const float b[2])
189{
190 r[0] = 0.5f * (a[0] + b[0]);
191 r[1] = 0.5f * (a[1] + b[1]);
192}
193
194void mid_v2_v2v2v2(float v[2], const float v1[2], const float v2[2], const float v3[2])
195{
196 v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
197 v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
198}
199
200void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
201{
202 v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
203 v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
204 v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
205}
206
208 float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
209{
210 v[0] = (v1[0] + v2[0] + v3[0] + v4[0]) / 4.0f;
211 v[1] = (v1[1] + v2[1] + v3[1] + v4[1]) / 4.0f;
212 v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f;
213}
214
215void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint vec_arr_num)
216{
217 const float factor = 1.0f / float(vec_arr_num);
218 zero_v3(r);
219
220 for (uint i = 0; i < vec_arr_num; i++) {
221 madd_v3_v3fl(r, vec_arr[i], factor);
222 }
223}
224
225void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3])
226{
227 /* trick, we want the middle of 2 normals as well as the angle between them
228 * avoid multiple calculations by */
229 float angle;
230
231 /* double check they are normalized */
234
235 add_v3_v3v3(r, a, b);
236 angle = (float(M_2_PI) *
237 /* normally we would only multiply by 2,
238 * but instead of an angle make this 0-1 factor */
239 2.0f) *
240 acosf(normalize_v3(r) / 2.0f);
241 mul_v3_fl(r, angle);
242}
243
245
246/* -------------------------------------------------------------------- */
249
250float angle_v3v3v3(const float a[3], const float b[3], const float c[3])
251{
252 float vec1[3], vec2[3];
253
254 sub_v3_v3v3(vec1, b, a);
255 sub_v3_v3v3(vec2, b, c);
256 normalize_v3(vec1);
257 normalize_v3(vec2);
258
259 return angle_normalized_v3v3(vec1, vec2);
260}
261
262float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3])
263{
264 float vec1[3], vec2[3];
265
266 sub_v3_v3v3(vec1, p2, p1);
267 sub_v3_v3v3(vec2, p2, p3);
268 normalize_v3(vec1);
269 normalize_v3(vec2);
270
271 return dot_v3v3(vec1, vec2);
272}
273
274float angle_v3v3(const float a[3], const float b[3])
275{
276 float vec1[3], vec2[3];
277
278 normalize_v3_v3(vec1, a);
279 normalize_v3_v3(vec2, b);
280
281 return angle_normalized_v3v3(vec1, vec2);
282}
283
284float angle_v2v2v2(const float a[2], const float b[2], const float c[2])
285{
286 float vec1[2], vec2[2];
287
288 vec1[0] = b[0] - a[0];
289 vec1[1] = b[1] - a[1];
290
291 vec2[0] = b[0] - c[0];
292 vec2[1] = b[1] - c[1];
293
294 normalize_v2(vec1);
295 normalize_v2(vec2);
296
297 return angle_normalized_v2v2(vec1, vec2);
298}
299
300float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2])
301{
302 float vec1[2], vec2[2];
303
304 sub_v2_v2v2(vec1, p2, p1);
305 sub_v2_v2v2(vec2, p2, p3);
306 normalize_v2(vec1);
307 normalize_v2(vec2);
308
309 return dot_v2v2(vec1, vec2);
310}
311
312float angle_v2v2(const float a[2], const float b[2])
313{
314 float vec1[2], vec2[2];
315
316 vec1[0] = a[0];
317 vec1[1] = a[1];
318
319 vec2[0] = b[0];
320 vec2[1] = b[1];
321
322 normalize_v2(vec1);
323 normalize_v2(vec2);
324
325 return angle_normalized_v2v2(vec1, vec2);
326}
327
328float angle_signed_v2v2(const float v1[2], const float v2[2])
329{
330 const float perp_dot = (v1[1] * v2[0]) - (v1[0] * v2[1]);
331 return atan2f(perp_dot, dot_v2v2(v1, v2));
332}
333
334float angle_normalized_v3v3(const float v1[3], const float v2[3])
335{
336 /* double check they are normalized */
339
340 /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
341 if (dot_v3v3(v1, v2) >= 0.0f) {
342 return 2.0f * safe_asinf(len_v3v3(v1, v2) / 2.0f);
343 }
344
345 float v2_n[3];
346 negate_v3_v3(v2_n, v2);
347 return float(M_PI) - 2.0f * safe_asinf(len_v3v3(v1, v2_n) / 2.0f);
348}
349
350float angle_normalized_v2v2(const float a[2], const float b[2])
351{
352 /* double check they are normalized */
355
356 /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
357 if (dot_v2v2(a, b) >= 0.0f) {
358 return 2.0f * safe_asinf(len_v2v2(a, b) / 2.0f);
359 }
360
361 float v2_n[2];
362 negate_v2_v2(v2_n, b);
363 return float(M_PI) - 2.0f * safe_asinf(len_v2v2(a, v2_n) / 2.0f);
364}
365
366float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
367{
368 float v1_proj[3], v2_proj[3];
369
370 /* project the vectors onto the axis */
371 project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
372 project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
373
374 return angle_v3v3(v1_proj, v2_proj);
375}
376
377float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
378{
379 float v1_proj[3], v2_proj[3], tproj[3];
380 float angle;
381
382 /* project the vectors onto the axis */
383 project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
384 project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
385
386 angle = angle_v3v3(v1_proj, v2_proj);
387
388 /* calculate the sign (reuse 'tproj') */
389 cross_v3_v3v3(tproj, v2_proj, v1_proj);
390 if (dot_v3v3(tproj, axis) < 0.0f) {
391 angle = float(M_PI * 2.0) - angle;
392 }
393
394 return angle;
395}
396
397float angle_on_axis_v3v3v3_v3(const float v1[3],
398 const float v2[3],
399 const float v3[3],
400 const float axis[3])
401{
402 float vec1[3], vec2[3];
403
404 sub_v3_v3v3(vec1, v1, v2);
405 sub_v3_v3v3(vec2, v3, v2);
406
407 return angle_on_axis_v3v3_v3(vec1, vec2, axis);
408}
409
410float angle_signed_on_axis_v3v3v3_v3(const float v1[3],
411 const float v2[3],
412 const float v3[3],
413 const float axis[3])
414{
415 float vec1[3], vec2[3];
416
417 sub_v3_v3v3(vec1, v1, v2);
418 sub_v3_v3v3(vec2, v3, v2);
419
420 return angle_signed_on_axis_v3v3_v3(vec1, vec2, axis);
421}
422
423void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3])
424{
425 float ed1[3], ed2[3], ed3[3];
426
427 sub_v3_v3v3(ed1, v3, v1);
428 sub_v3_v3v3(ed2, v1, v2);
429 sub_v3_v3v3(ed3, v2, v3);
430
431 normalize_v3(ed1);
432 normalize_v3(ed2);
433 normalize_v3(ed3);
434
435 angles[0] = float(M_PI) - angle_normalized_v3v3(ed1, ed2);
436 angles[1] = float(M_PI) - angle_normalized_v3v3(ed2, ed3);
437 // face_angles[2] = M_PI - angle_normalized_v3v3(ed3, ed1);
438 angles[2] = float(M_PI) - (angles[0] + angles[1]);
439}
440
442 float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
443{
444 float ed1[3], ed2[3], ed3[3], ed4[3];
445
446 sub_v3_v3v3(ed1, v4, v1);
447 sub_v3_v3v3(ed2, v1, v2);
448 sub_v3_v3v3(ed3, v2, v3);
449 sub_v3_v3v3(ed4, v3, v4);
450
451 normalize_v3(ed1);
452 normalize_v3(ed2);
453 normalize_v3(ed3);
454 normalize_v3(ed4);
455
456 angles[0] = float(M_PI) - angle_normalized_v3v3(ed1, ed2);
457 angles[1] = float(M_PI) - angle_normalized_v3v3(ed2, ed3);
458 angles[2] = float(M_PI) - angle_normalized_v3v3(ed3, ed4);
459 angles[3] = float(M_PI) - angle_normalized_v3v3(ed4, ed1);
460}
461
462void angle_poly_v3(float *angles, const float *verts[3], int len)
463{
464 int i;
465 float vec[3][3];
466
467 sub_v3_v3v3(vec[2], verts[len - 1], verts[0]);
468 normalize_v3(vec[2]);
469 for (i = 0; i < len; i++) {
470 sub_v3_v3v3(vec[i % 3], verts[i % len], verts[(i + 1) % len]);
471 normalize_v3(vec[i % 3]);
472 angles[i] = float(M_PI) - angle_normalized_v3v3(vec[(i + 2) % 3], vec[i % 3]);
473 }
474}
475
477
478/* -------------------------------------------------------------------- */
481
482void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2])
483{
484 if (UNLIKELY(is_zero_v2(v_proj))) {
485 zero_v2(out);
486 return;
487 }
488
489 const float mul = dot_v2v2(p, v_proj) / dot_v2v2(v_proj, v_proj);
490 mul_v2_v2fl(out, v_proj, mul);
491}
492
493void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
494{
495 if (UNLIKELY(is_zero_v3(v_proj))) {
496 zero_v3(out);
497 return;
498 }
499
500 const float mul = dot_v3v3(p, v_proj) / dot_v3v3(v_proj, v_proj);
501 mul_v3_v3fl(out, v_proj, mul);
502}
503
504void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2])
505{
506 BLI_ASSERT_UNIT_V2(v_proj);
507
508 const float mul = dot_v2v2(p, v_proj);
509 mul_v2_v2fl(out, v_proj, mul);
510}
511
512void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_proj[3])
513{
514 BLI_ASSERT_UNIT_V3(v_proj);
515
516 const float mul = dot_v3v3(p, v_proj);
517 mul_v3_v3fl(out, v_proj, mul);
518}
519
520void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
521{
522 const float mul = dot_v3v3(p, v_plane) / dot_v3v3(v_plane, v_plane);
523 /* out[x] = p[x] - (mul * v_plane[x]) */
524 madd_v3_v3v3fl(out, p, v_plane, -mul);
525}
526
527void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
528{
529 BLI_ASSERT_UNIT_V3(v_plane);
530 const float mul = dot_v3v3(p, v_plane);
531 /* out[x] = p[x] - (mul * v_plane[x]) */
532 madd_v3_v3v3fl(out, p, v_plane, -mul);
533}
534
535void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
536{
537 float vector[3];
538 float mul;
539
540 sub_v3_v3v3(vector, out, plane_co);
541 mul = dot_v3v3(vector, plane_no) / len_squared_v3(plane_no);
542
543 /* out[x] = out[x] - (mul * plane_no[x]) */
544 madd_v3_v3fl(out, plane_no, -mul);
545}
546
547void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
548{
549 float d_12[3], d_23[3];
550 sub_v3_v3v3(d_12, b, a);
551 sub_v3_v3v3(d_23, c, b);
552 normalize_v3(d_12);
553 normalize_v3(d_23);
554 add_v3_v3v3(r, d_12, d_23);
555 normalize_v3(r);
556}
557
558void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3])
559{
560 BLI_ASSERT_UNIT_V3(normal);
561 const float dot2 = 2.0f * dot_v3v3(v, normal);
562 /* out[x] = v[x] - (dot2 * normal[x]) */
563 madd_v3_v3v3fl(out, v, normal, -dot2);
564}
565
566void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
567{
568 const float eps = FLT_EPSILON;
569 const float f = len_squared_v2(n);
570
571 if (f > eps) {
572 const float d = 1.0f / sqrtf(f);
573
574 BLI_assert(isfinite(d));
575
576 r_n1[0] = n[1] * d;
577 r_n1[1] = -n[0] * d;
578 r_n1[2] = 0.0f;
579 r_n2[0] = -n[2] * r_n1[1];
580 r_n2[1] = n[2] * r_n1[0];
581 r_n2[2] = n[0] * r_n1[1] - n[1] * r_n1[0];
582 }
583 else {
584 /* degenerate case */
585 r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
586 r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
587 r_n2[1] = 1.0f;
588 }
589}
590
591void ortho_v3_v3(float out[3], const float v[3])
592{
593 const int axis = axis_dominant_v3_single(v);
594
595 BLI_assert(out != v);
596
597 switch (axis) {
598 case 0:
599 out[0] = -v[1] - v[2];
600 out[1] = v[0];
601 out[2] = v[0];
602 break;
603 case 1:
604 out[0] = v[1];
605 out[1] = -v[0] - v[2];
606 out[2] = v[1];
607 break;
608 case 2:
609 out[0] = v[2];
610 out[1] = v[2];
611 out[2] = -v[0] - v[1];
612 break;
613 }
614}
615
616void ortho_v2_v2(float out[2], const float v[2])
617{
618 BLI_assert(out != v);
619
620 out[0] = -v[1];
621 out[1] = v[0];
622}
623
624void rotate_v2_v2fl(float r[2], const float p[2], const float angle)
625{
626 const float co = cosf(angle);
627 const float si = sinf(angle);
628
629 BLI_assert(r != p);
630
631 r[0] = co * p[0] - si * p[1];
632 r[1] = si * p[0] + co * p[1];
633}
634
636 const float p[3],
637 const float axis[3],
638 const float angle)
639{
640 const float costheta = cosf(angle);
641 const float sintheta = sinf(angle);
642
643 /* double check they are normalized */
644 BLI_ASSERT_UNIT_V3(axis);
645
646 out[0] = ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) +
647 (((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) +
648 (((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]);
649
650 out[1] = (((1 - costheta) * axis[0] * axis[1] + axis[2] * sintheta) * p[0]) +
651 ((costheta + (1 - costheta) * axis[1] * axis[1]) * p[1]) +
652 (((1 - costheta) * axis[1] * axis[2] - axis[0] * sintheta) * p[2]);
653
654 out[2] = (((1 - costheta) * axis[0] * axis[2] - axis[1] * sintheta) * p[0]) +
655 (((1 - costheta) * axis[1] * axis[2] + axis[0] * sintheta) * p[1]) +
656 ((costheta + (1 - costheta) * axis[2] * axis[2]) * p[2]);
657}
658
659void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle)
660{
661 BLI_assert(r != p);
662
663 float axis_n[3];
664
665 normalize_v3_v3(axis_n, axis);
666
667 rotate_normalized_v3_v3v3fl(r, p, axis_n, angle);
668}
669
671
672/* -------------------------------------------------------------------- */
675
676void print_v2(const char *str, const float v[2])
677{
678 printf("%s: %.8f %.8f\n", str, v[0], v[1]);
679}
680
681void print_v3(const char *str, const float v[3])
682{
683 printf("%s: %.8f %.8f %.8f\n", str, v[0], v[1], v[2]);
684}
685
686void print_v4(const char *str, const float v[4])
687{
688 printf("%s: %.8f %.8f %.8f %.8f\n", str, v[0], v[1], v[2], v[3]);
689}
690
691void print_vn(const char *str, const float v[], const int n)
692{
693 int i = 0;
694 printf("%s[%d]:", str, n);
695 while (i < n) {
696 printf(" %.8f", v[i++]);
697 }
698 printf("\n");
699}
700
701void minmax_v4v4_v4(float min[4], float max[4], const float vec[4])
702{
703 min[0] = std::min(min[0], vec[0]);
704 min[1] = std::min(min[1], vec[1]);
705 min[2] = std::min(min[2], vec[2]);
706 min[3] = std::min(min[3], vec[3]);
707
708 max[0] = std::max(max[0], vec[0]);
709 max[1] = std::max(max[1], vec[1]);
710 max[2] = std::max(max[2], vec[2]);
711 max[3] = std::max(max[3], vec[3]);
712}
713
714void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
715{
716 min[0] = std::min(min[0], vec[0]);
717 min[1] = std::min(min[1], vec[1]);
718 min[2] = std::min(min[2], vec[2]);
719
720 max[0] = std::max(max[0], vec[0]);
721 max[1] = std::max(max[1], vec[1]);
722 max[2] = std::max(max[2], vec[2]);
723}
724
725void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
726{
727 min[0] = std::min(min[0], vec[0]);
728 min[1] = std::min(min[1], vec[1]);
729
730 max[0] = std::max(max[0], vec[0]);
731 max[1] = std::max(max[1], vec[1]);
732}
733
734void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist)
735{
736 if (!equals_v3v3(v2, v1)) {
737 float nor[3];
738
739 sub_v3_v3v3(nor, v1, v2);
741 madd_v3_v3v3fl(v1, v2, nor, dist);
742 }
743}
744
745void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist)
746{
747 if (!equals_v2v2(v2, v1)) {
748 float nor[2];
749
750 sub_v2_v2v2(nor, v1, v2);
752 madd_v2_v2v2fl(v1, v2, nor, dist);
753 }
754}
755
756void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
757{
758 float v[3];
759 copy_v3_v3(v, axis_values);
760
761#define SWAP_AXIS(a, b) \
762 { \
763 SWAP(float, v[a], v[b]); \
764 SWAP(int, r_axis_order[a], r_axis_order[b]); \
765 } \
766 (void)0
767
768 if (v[0] < v[1]) {
769 if (v[2] < v[0]) {
770 SWAP_AXIS(0, 2);
771 }
772 }
773 else {
774 if (v[1] < v[2]) {
775 SWAP_AXIS(0, 1);
776 }
777 else {
778 SWAP_AXIS(0, 2);
779 }
780 }
781 if (v[2] < v[1]) {
782 SWAP_AXIS(1, 2);
783 }
784
785#undef SWAP_AXIS
786}
787
789
790/* -------------------------------------------------------------------- */
793
794MINLINE double sqr_db(double f)
795{
796 return f * f;
797}
798
799double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size)
800{
801 double d = 0.0f;
802 const float *array_pt_a = array_src_a + (size - 1);
803 const float *array_pt_b = array_src_b + (size - 1);
804 int i = size;
805 while (i--) {
806 d += double(*(array_pt_a--) * *(array_pt_b--));
807 }
808 return d;
809}
810
811double len_squared_vn(const float *array, const int size)
812{
813 double d = 0.0f;
814 const float *array_pt = array + (size - 1);
815 int i = size;
816 while (i--) {
817 d += sqr_db(double(*(array_pt)--));
818 }
819 return d;
820}
821
822float normalize_vn_vn(float *array_tar, const float *array_src, const int size)
823{
824 const double d = len_squared_vn(array_src, size);
825 float d_sqrt;
826 if (d > 1.0e-35) {
827 d_sqrt = float(sqrt(d));
828 mul_vn_vn_fl(array_tar, array_src, size, 1.0f / d_sqrt);
829 }
830 else {
831 copy_vn_fl(array_tar, size, 0.0f);
832 d_sqrt = 0.0f;
833 }
834 return d_sqrt;
835}
836
837float normalize_vn(float *array_tar, const int size)
838{
839 return normalize_vn_vn(array_tar, array_tar, size);
840}
841
842void range_vn_i(int *array_tar, const int size, const int start)
843{
844 int *array_pt = array_tar + (size - 1);
845 int j = start + (size - 1);
846 int i = size;
847 while (i--) {
848 *(array_pt--) = j--;
849 }
850}
851
852void range_vn_u(uint *array_tar, const int size, const uint start)
853{
854 uint *array_pt = array_tar + (size - 1);
855 uint j = start + uint(size - 1);
856 int i = size;
857 while (i--) {
858 *(array_pt--) = j--;
859 }
860}
861
862void range_vn_fl(float *array_tar, const int size, const float start, const float step)
863{
864 float *array_pt = array_tar + (size - 1);
865 int i = size;
866 while (i--) {
867 *(array_pt--) = start + step * float(i);
868 }
869}
870
871void negate_vn(float *array_tar, const int size)
872{
873 float *array_pt = array_tar + (size - 1);
874 int i = size;
875 while (i--) {
876 *(array_pt--) *= -1.0f;
877 }
878}
879
880void negate_vn_vn(float *array_tar, const float *array_src, const int size)
881{
882 float *tar = array_tar + (size - 1);
883 const float *src = array_src + (size - 1);
884 int i = size;
885 while (i--) {
886 *(tar--) = -*(src--);
887 }
888}
889
890void mul_vn_vn(float *array_tar, const float *array_src, const int size)
891{
892 float *tar = array_tar + (size - 1);
893 const float *src = array_src + (size - 1);
894 int i = size;
895 while (i--) {
896 *(tar--) *= *(src--);
897 }
898}
899
900void mul_vn_vnvn(float *array_tar,
901 const float *array_src_a,
902 const float *array_src_b,
903 const int size)
904{
905 float *tar = array_tar + (size - 1);
906 const float *src_a = array_src_a + (size - 1);
907 const float *src_b = array_src_b + (size - 1);
908 int i = size;
909 while (i--) {
910 *(tar--) = *(src_a--) * *(src_b--);
911 }
912}
913
914void mul_vn_fl(float *array_tar, const int size, const float f)
915{
916 float *array_pt = array_tar + (size - 1);
917 int i = size;
918 while (i--) {
919 *(array_pt--) *= f;
920 }
921}
922
923void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f)
924{
925 float *tar = array_tar + (size - 1);
926 const float *src = array_src + (size - 1);
927 int i = size;
928 while (i--) {
929 *(tar--) = *(src--) * f;
930 }
931}
932
933void add_vn_vn(float *array_tar, const float *array_src, const int size)
934{
935 float *tar = array_tar + (size - 1);
936 const float *src = array_src + (size - 1);
937 int i = size;
938 while (i--) {
939 *(tar--) += *(src--);
940 }
941}
942
943void add_vn_vnvn(float *array_tar,
944 const float *array_src_a,
945 const float *array_src_b,
946 const int size)
947{
948 float *tar = array_tar + (size - 1);
949 const float *src_a = array_src_a + (size - 1);
950 const float *src_b = array_src_b + (size - 1);
951 int i = size;
952 while (i--) {
953 *(tar--) = *(src_a--) + *(src_b--);
954 }
955}
956
957void sub_vn_vn(float *array_tar, const float *array_src, const int size)
958{
959 float *tar = array_tar + (size - 1);
960 const float *src = array_src + (size - 1);
961 int i = size;
962 while (i--) {
963 *(tar--) -= *(src--);
964 }
965}
966
967void sub_vn_vnvn(float *array_tar,
968 const float *array_src_a,
969 const float *array_src_b,
970 const int size)
971{
972 float *tar = array_tar + (size - 1);
973 const float *src_a = array_src_a + (size - 1);
974 const float *src_b = array_src_b + (size - 1);
975 int i = size;
976 while (i--) {
977 *(tar--) = *(src_a--) - *(src_b--);
978 }
979}
980
981void interp_vn_vn(float *array_tar, const float *array_src, const float t, const int size)
982{
983 const float s = 1.0f - t;
984 float *tar = array_tar + (size - 1);
985 const float *src = array_src + (size - 1);
986 int i = size;
987 while (i--) {
988 *(tar) = (s * *(tar)) + (t * *(src));
989 tar--;
990 src--;
991 }
992}
993
994void copy_vn_i(int *array_tar, const int size, const int val)
995{
996 int *tar = array_tar + (size - 1);
997 int i = size;
998 while (i--) {
999 *(tar--) = val;
1000 }
1001}
1002
1003void copy_vn_short(short *array_tar, const int size, const short val)
1004{
1005 short *tar = array_tar + (size - 1);
1006 int i = size;
1007 while (i--) {
1008 *(tar--) = val;
1009 }
1010}
1011
1012void copy_vn_fl(float *array_tar, const int size, const float val)
1013{
1014 float *tar = array_tar + (size - 1);
1015 int i = size;
1016 while (i--) {
1017 *(tar--) = val;
1018 }
1019}
1020
1022
1023/* -------------------------------------------------------------------- */
1026
1027void add_vn_vn_d(double *array_tar, const double *array_src, const int size)
1028{
1029 double *tar = array_tar + (size - 1);
1030 const double *src = array_src + (size - 1);
1031 int i = size;
1032 while (i--) {
1033 *(tar--) += *(src--);
1034 }
1035}
1036
1037void add_vn_vnvn_d(double *array_tar,
1038 const double *array_src_a,
1039 const double *array_src_b,
1040 const int size)
1041{
1042 double *tar = array_tar + (size - 1);
1043 const double *src_a = array_src_a + (size - 1);
1044 const double *src_b = array_src_b + (size - 1);
1045 int i = size;
1046 while (i--) {
1047 *(tar--) = *(src_a--) + *(src_b--);
1048 }
1049}
1050
1051void mul_vn_db(double *array_tar, const int size, const double f)
1052{
1053 double *array_pt = array_tar + (size - 1);
1054 int i = size;
1055 while (i--) {
1056 *(array_pt--) *= f;
1057 }
1058}
1059
1060void interp_v3_v3v3_db(double target[3], const double a[3], const double b[3], const double t)
1061{
1062 const double s = 1.0f - t;
1063
1064 target[0] = s * a[0] + t * b[0];
1065 target[1] = s * a[1] + t * b[1];
1066 target[2] = s * a[2] + t * b[2];
1067}
1068
1069void interp_v2_v2v2_db(double target[2], const double a[2], const double b[2], const double t)
1070{
1071 const double s = 1.0f - t;
1072
1073 target[0] = s * a[0] + t * b[0];
1074 target[1] = s * a[1] + t * b[1];
1075}
1076
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_ASSERT_UNIT_V2(v)
#define BLI_ASSERT_UNIT_V3(v)
MINLINE float safe_asinf(float a)
#define M_PI
MINLINE int axis_dominant_v3_single(const float vec[3])
#define MINLINE
void interp_dot_slerp(float t, float cosom, float r_w[2])
MINLINE float len_squared_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE bool is_zero_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void negate_v2_v2(float r[2], const float a[2])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v2(float r[2])
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v2(float n[2])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void mul_v2_v2fl(float r[2], const float a[2], float f)
MINLINE float normalize_v3(float n[3])
unsigned char uchar
unsigned int uint
#define UNLIKELY(x)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
static void mul(btAlignedObjectArray< T > &items, const Q &value)
nullptr float
#define acosf(x)
#define str(s)
static float verts[][3]
uint nor
#define out
#define printf(...)
#define sqrt
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
void copy_vn_fl(float *array_tar, const int size, const float val)
void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2])
void add_vn_vn_d(double *array_tar, const double *array_src, const int size)
void negate_vn(float *array_tar, const int size)
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t)
void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
void sub_vn_vn(float *array_tar, const float *array_src, const int size)
void mul_vn_db(double *array_tar, const int size, const double f)
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
void rotate_v2_v2fl(float r[2], const float p[2], const float angle)
void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f)
void copy_vn_i(int *array_tar, const int size, const int val)
void print_v3(const char *str, const float v[3])
float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
float normalize_vn(float *array_tar, const int size)
float angle_v3v3v3(const float a[3], const float b[3], const float c[3])
void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3])
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
float angle_normalized_v3v3(const float v1[3], const float v2[3])
void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4])
#define SWAP_AXIS(a, b)
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
void interp_v3_v3v3_db(double target[3], const double a[3], const double b[3], const double t)
double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size)
void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3])
void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
float angle_v3v3(const float a[3], const float b[3])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], const float t)
void mid_v2_v2v2v2(float v[2], const float v1[2], const float v2[2], const float v3[2])
void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3])
void add_vn_vn(float *array_tar, const float *array_src, const int size)
void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_proj[3])
void interp_v2_v2v2v2(float r[2], const float a[2], const float b[2], const float c[2], const float t[3])
void print_v4(const char *str, const float v[4])
bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t)
float normalize_vn_vn(float *array_tar, const float *array_src, const int size)
void negate_vn_vn(float *array_tar, const float *array_src, const int size)
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t)
void copy_vn_short(short *array_tar, const int size, const short val)
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
void interp_v3_v3v3_uchar(uchar target[3], const uchar a[3], const uchar b[3], const float t)
void print_v2(const char *str, const float v[2])
void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3])
void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle)
void ortho_v3_v3(float out[3], const float v[3])
float angle_v2v2(const float a[2], const float b[2])
void interp_v2_v2v2_db(double target[2], const double a[2], const double b[2], const double t)
void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3])
float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2])
void print_vn(const char *str, const float v[], const int n)
void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float w[4])
void minmax_v4v4_v4(float min[4], float max[4], const float vec[4])
void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist)
void mid_v2_v2v2(float r[2], const float a[2], const float b[2])
void range_vn_u(uint *array_tar, const int size, const uint start)
void ortho_v2_v2(float out[2], const float v[2])
void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
void angle_poly_v3(float *angles, const float *verts[3], int len)
void range_vn_fl(float *array_tar, const int size, const float start, const float step)
void interp_vn_vn(float *array_tar, const float *array_src, const float t, const int size)
double len_squared_vn(const float *array, const int size)
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
void mul_vn_vn(float *array_tar, const float *array_src, const int size)
void add_vn_vnvn_d(double *array_tar, const double *array_src_a, const double *array_src_b, const int size)
void mid_v3_v3_array(float r[3], const float(*vec_arr)[3], const uint vec_arr_num)
void range_vn_i(int *array_tar, const int size, const int start)
float angle_v2v2v2(const float a[2], const float b[2], const float c[2])
float angle_normalized_v2v2(const float a[2], const float b[2])
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist)
float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
void mul_vn_fl(float *array_tar, const int size, const float f)
void interp_v3_v3v3v3_uv(float p[3], const float v1[3], const float v2[3], const float v3[3], const float uv[2])
float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], const float angle)
MINLINE double sqr_db(double f)
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
void interp_v2_v2v2v2v2_cubic(float p[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2], const float u)
void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2])
void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
float angle_signed_v2v2(const float v1[2], const float v2[2])
const btScalar eps
Definition poly34.cpp:11
#define floorf
#define sqrtf
#define sinf
#define cosf
#define atan2f
#define min(a, b)
Definition sort.cc:36
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
uint len