1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 *
19 * The Original Code is: some of this file.
20 *
21 * */
22
23 /** \file
24 * \ingroup bli
25 */
26
27 #ifndef __MATH_VECTOR_INLINE_C__
28 #define __MATH_VECTOR_INLINE_C__
29
30 #include "BLI_math.h"
31
32 /********************************** Init *************************************/
33
zero_v2(float r[2])34 MINLINE void zero_v2(float r[2])
35 {
36 r[0] = 0.0f;
37 r[1] = 0.0f;
38 }
39
zero_v3(float r[3])40 MINLINE void zero_v3(float r[3])
41 {
42 r[0] = 0.0f;
43 r[1] = 0.0f;
44 r[2] = 0.0f;
45 }
46
zero_v4(float r[4])47 MINLINE void zero_v4(float r[4])
48 {
49 r[0] = 0.0f;
50 r[1] = 0.0f;
51 r[2] = 0.0f;
52 r[3] = 0.0f;
53 }
54
copy_v2_v2(float r[2],const float a[2])55 MINLINE void copy_v2_v2(float r[2], const float a[2])
56 {
57 r[0] = a[0];
58 r[1] = a[1];
59 }
60
copy_v3_v3(float r[3],const float a[3])61 MINLINE void copy_v3_v3(float r[3], const float a[3])
62 {
63 r[0] = a[0];
64 r[1] = a[1];
65 r[2] = a[2];
66 }
67
copy_v3fl_v3s(float r[3],const short a[3])68 MINLINE void copy_v3fl_v3s(float r[3], const short a[3])
69 {
70 r[0] = (float)a[0];
71 r[1] = (float)a[1];
72 r[2] = (float)a[2];
73 }
74
copy_v4_v4(float r[4],const float a[4])75 MINLINE void copy_v4_v4(float r[4], const float a[4])
76 {
77 r[0] = a[0];
78 r[1] = a[1];
79 r[2] = a[2];
80 r[3] = a[3];
81 }
82
copy_v2_fl(float r[2],float f)83 MINLINE void copy_v2_fl(float r[2], float f)
84 {
85 r[0] = f;
86 r[1] = f;
87 }
88
copy_v3_fl(float r[3],float f)89 MINLINE void copy_v3_fl(float r[3], float f)
90 {
91 r[0] = f;
92 r[1] = f;
93 r[2] = f;
94 }
95
copy_v4_fl(float r[4],float f)96 MINLINE void copy_v4_fl(float r[4], float f)
97 {
98 r[0] = f;
99 r[1] = f;
100 r[2] = f;
101 r[3] = f;
102 }
103
104 /* unsigned char */
copy_v2_v2_uchar(unsigned char r[2],const unsigned char a[2])105 MINLINE void copy_v2_v2_uchar(unsigned char r[2], const unsigned char a[2])
106 {
107 r[0] = a[0];
108 r[1] = a[1];
109 }
110
copy_v3_v3_uchar(unsigned char r[3],const unsigned char a[3])111 MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3])
112 {
113 r[0] = a[0];
114 r[1] = a[1];
115 r[2] = a[2];
116 }
117
copy_v4_v4_uchar(unsigned char r[4],const unsigned char a[4])118 MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
119 {
120 r[0] = a[0];
121 r[1] = a[1];
122 r[2] = a[2];
123 r[3] = a[3];
124 }
125
copy_v2_uchar(unsigned char r[2],const unsigned char a)126 MINLINE void copy_v2_uchar(unsigned char r[2], const unsigned char a)
127 {
128 r[0] = a;
129 r[1] = a;
130 }
131
copy_v3_uchar(unsigned char r[3],const unsigned char a)132 MINLINE void copy_v3_uchar(unsigned char r[3], const unsigned char a)
133 {
134 r[0] = a;
135 r[1] = a;
136 r[2] = a;
137 }
138
copy_v4_uchar(unsigned char r[4],const unsigned char a)139 MINLINE void copy_v4_uchar(unsigned char r[4], const unsigned char a)
140 {
141 r[0] = a;
142 r[1] = a;
143 r[2] = a;
144 r[3] = a;
145 }
146
147 /* char */
copy_v2_v2_char(char r[2],const char a[2])148 MINLINE void copy_v2_v2_char(char r[2], const char a[2])
149 {
150 r[0] = a[0];
151 r[1] = a[1];
152 }
153
copy_v3_v3_char(char r[3],const char a[3])154 MINLINE void copy_v3_v3_char(char r[3], const char a[3])
155 {
156 r[0] = a[0];
157 r[1] = a[1];
158 r[2] = a[2];
159 }
160
copy_v4_v4_char(char r[4],const char a[4])161 MINLINE void copy_v4_v4_char(char r[4], const char a[4])
162 {
163 r[0] = a[0];
164 r[1] = a[1];
165 r[2] = a[2];
166 r[3] = a[3];
167 }
168
169 /* short */
170
copy_v2_v2_short(short r[2],const short a[2])171 MINLINE void copy_v2_v2_short(short r[2], const short a[2])
172 {
173 r[0] = a[0];
174 r[1] = a[1];
175 }
176
copy_v3_v3_short(short r[3],const short a[3])177 MINLINE void copy_v3_v3_short(short r[3], const short a[3])
178 {
179 r[0] = a[0];
180 r[1] = a[1];
181 r[2] = a[2];
182 }
183
copy_v4_v4_short(short r[4],const short a[4])184 MINLINE void copy_v4_v4_short(short r[4], const short a[4])
185 {
186 r[0] = a[0];
187 r[1] = a[1];
188 r[2] = a[2];
189 r[3] = a[3];
190 }
191
192 /* int */
zero_v2_int(int r[2])193 MINLINE void zero_v2_int(int r[2])
194 {
195 r[0] = 0;
196 r[1] = 0;
197 }
198
zero_v3_int(int r[3])199 MINLINE void zero_v3_int(int r[3])
200 {
201 r[0] = 0;
202 r[1] = 0;
203 r[2] = 0;
204 }
205
copy_v2_v2_int(int r[2],const int a[2])206 MINLINE void copy_v2_v2_int(int r[2], const int a[2])
207 {
208 r[0] = a[0];
209 r[1] = a[1];
210 }
211
copy_v3_v3_int(int r[3],const int a[3])212 MINLINE void copy_v3_v3_int(int r[3], const int a[3])
213 {
214 r[0] = a[0];
215 r[1] = a[1];
216 r[2] = a[2];
217 }
218
copy_v4_v4_int(int r[4],const int a[4])219 MINLINE void copy_v4_v4_int(int r[4], const int a[4])
220 {
221 r[0] = a[0];
222 r[1] = a[1];
223 r[2] = a[2];
224 r[3] = a[3];
225 }
226
227 /* double */
zero_v3_db(double r[3])228 MINLINE void zero_v3_db(double r[3])
229 {
230 r[0] = 0.0;
231 r[1] = 0.0;
232 r[2] = 0.0;
233 }
234
copy_v2_v2_db(double r[2],const double a[2])235 MINLINE void copy_v2_v2_db(double r[2], const double a[2])
236 {
237 r[0] = a[0];
238 r[1] = a[1];
239 }
240
copy_v3_v3_db(double r[3],const double a[3])241 MINLINE void copy_v3_v3_db(double r[3], const double a[3])
242 {
243 r[0] = a[0];
244 r[1] = a[1];
245 r[2] = a[2];
246 }
247
copy_v4_v4_db(double r[4],const double a[4])248 MINLINE void copy_v4_v4_db(double r[4], const double a[4])
249 {
250 r[0] = a[0];
251 r[1] = a[1];
252 r[2] = a[2];
253 r[3] = a[3];
254 }
255
256 /* int <-> float */
round_v2i_v2fl(int r[2],const float a[2])257 MINLINE void round_v2i_v2fl(int r[2], const float a[2])
258 {
259 r[0] = (int)roundf(a[0]);
260 r[1] = (int)roundf(a[1]);
261 }
262
copy_v2fl_v2i(float r[2],const int a[2])263 MINLINE void copy_v2fl_v2i(float r[2], const int a[2])
264 {
265 r[0] = (float)a[0];
266 r[1] = (float)a[1];
267 }
268
269 /* double -> float */
copy_v2fl_v2db(float r[2],const double a[2])270 MINLINE void copy_v2fl_v2db(float r[2], const double a[2])
271 {
272 r[0] = (float)a[0];
273 r[1] = (float)a[1];
274 }
275
copy_v3fl_v3db(float r[3],const double a[3])276 MINLINE void copy_v3fl_v3db(float r[3], const double a[3])
277 {
278 r[0] = (float)a[0];
279 r[1] = (float)a[1];
280 r[2] = (float)a[2];
281 }
282
copy_v4fl_v4db(float r[4],const double a[4])283 MINLINE void copy_v4fl_v4db(float r[4], const double a[4])
284 {
285 r[0] = (float)a[0];
286 r[1] = (float)a[1];
287 r[2] = (float)a[2];
288 r[3] = (float)a[3];
289 }
290
291 /* float -> double */
copy_v2db_v2fl(double r[2],const float a[2])292 MINLINE void copy_v2db_v2fl(double r[2], const float a[2])
293 {
294 r[0] = (double)a[0];
295 r[1] = (double)a[1];
296 }
297
copy_v3db_v3fl(double r[3],const float a[3])298 MINLINE void copy_v3db_v3fl(double r[3], const float a[3])
299 {
300 r[0] = (double)a[0];
301 r[1] = (double)a[1];
302 r[2] = (double)a[2];
303 }
304
copy_v4db_v4fl(double r[4],const float a[4])305 MINLINE void copy_v4db_v4fl(double r[4], const float a[4])
306 {
307 r[0] = (double)a[0];
308 r[1] = (double)a[1];
309 r[2] = (double)a[2];
310 r[3] = (double)a[3];
311 }
312
swap_v2_v2(float a[2],float b[2])313 MINLINE void swap_v2_v2(float a[2], float b[2])
314 {
315 SWAP(float, a[0], b[0]);
316 SWAP(float, a[1], b[1]);
317 }
318
swap_v3_v3(float a[3],float b[3])319 MINLINE void swap_v3_v3(float a[3], float b[3])
320 {
321 SWAP(float, a[0], b[0]);
322 SWAP(float, a[1], b[1]);
323 SWAP(float, a[2], b[2]);
324 }
325
swap_v4_v4(float a[4],float b[4])326 MINLINE void swap_v4_v4(float a[4], float b[4])
327 {
328 SWAP(float, a[0], b[0]);
329 SWAP(float, a[1], b[1]);
330 SWAP(float, a[2], b[2]);
331 SWAP(float, a[3], b[3]);
332 }
333
334 /* float args -> vec */
copy_v2_fl2(float v[2],float x,float y)335 MINLINE void copy_v2_fl2(float v[2], float x, float y)
336 {
337 v[0] = x;
338 v[1] = y;
339 }
340
copy_v3_fl3(float v[3],float x,float y,float z)341 MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
342 {
343 v[0] = x;
344 v[1] = y;
345 v[2] = z;
346 }
347
copy_v4_fl4(float v[4],float x,float y,float z,float w)348 MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
349 {
350 v[0] = x;
351 v[1] = y;
352 v[2] = z;
353 v[3] = w;
354 }
355
356 /********************************* Arithmetic ********************************/
357
add_v2_fl(float r[2],float f)358 MINLINE void add_v2_fl(float r[2], float f)
359 {
360 r[0] += f;
361 r[1] += f;
362 }
363
add_v3_fl(float r[3],float f)364 MINLINE void add_v3_fl(float r[3], float f)
365 {
366 r[0] += f;
367 r[1] += f;
368 r[2] += f;
369 }
370
add_v4_fl(float r[4],float f)371 MINLINE void add_v4_fl(float r[4], float f)
372 {
373 r[0] += f;
374 r[1] += f;
375 r[2] += f;
376 r[3] += f;
377 }
378
add_v2_v2(float r[2],const float a[2])379 MINLINE void add_v2_v2(float r[2], const float a[2])
380 {
381 r[0] += a[0];
382 r[1] += a[1];
383 }
384
add_v2_v2_db(double r[2],const double a[2])385 MINLINE void add_v2_v2_db(double r[2], const double a[2])
386 {
387 r[0] += a[0];
388 r[1] += a[1];
389 }
390
add_v2_v2v2(float r[2],const float a[2],const float b[2])391 MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
392 {
393 r[0] = a[0] + b[0];
394 r[1] = a[1] + b[1];
395 }
396
add_v2_v2_int(int r[2],const int a[2])397 MINLINE void add_v2_v2_int(int r[2], const int a[2])
398 {
399 r[0] = r[0] + a[0];
400 r[1] = r[1] + a[1];
401 }
402
add_v2_v2v2_int(int r[2],const int a[2],const int b[2])403 MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2])
404 {
405 r[0] = a[0] + b[0];
406 r[1] = a[1] + b[1];
407 }
408
add_v3_v3(float r[3],const float a[3])409 MINLINE void add_v3_v3(float r[3], const float a[3])
410 {
411 r[0] += a[0];
412 r[1] += a[1];
413 r[2] += a[2];
414 }
415
add_v3_v3_db(double r[3],const double a[3])416 MINLINE void add_v3_v3_db(double r[3], const double a[3])
417 {
418 r[0] += a[0];
419 r[1] += a[1];
420 r[2] += a[2];
421 }
422
add_v3_v3v3(float r[3],const float a[3],const float b[3])423 MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
424 {
425 r[0] = a[0] + b[0];
426 r[1] = a[1] + b[1];
427 r[2] = a[2] + b[2];
428 }
429
add_v3fl_v3fl_v3i(float r[3],const float a[3],const int b[3])430 MINLINE void add_v3fl_v3fl_v3i(float r[3], const float a[3], const int b[3])
431 {
432 r[0] = a[0] + (float)b[0];
433 r[1] = a[1] + (float)b[1];
434 r[2] = a[2] + (float)b[2];
435 }
436
add_v3fl_v3fl_v3s(float r[3],const float a[3],const short b[3])437 MINLINE void add_v3fl_v3fl_v3s(float r[3], const float a[3], const short b[3])
438 {
439 r[0] = a[0] + (float)b[0];
440 r[1] = a[1] + (float)b[1];
441 r[2] = a[2] + (float)b[2];
442 }
443
add_v4_v4(float r[4],const float a[4])444 MINLINE void add_v4_v4(float r[4], const float a[4])
445 {
446 r[0] += a[0];
447 r[1] += a[1];
448 r[2] += a[2];
449 r[3] += a[3];
450 }
451
add_v4_v4v4(float r[4],const float a[4],const float b[4])452 MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4])
453 {
454 r[0] = a[0] + b[0];
455 r[1] = a[1] + b[1];
456 r[2] = a[2] + b[2];
457 r[3] = a[3] + b[3];
458 }
459
sub_v2_v2(float r[2],const float a[2])460 MINLINE void sub_v2_v2(float r[2], const float a[2])
461 {
462 r[0] -= a[0];
463 r[1] -= a[1];
464 }
465
sub_v2_v2v2(float r[2],const float a[2],const float b[2])466 MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
467 {
468 r[0] = a[0] - b[0];
469 r[1] = a[1] - b[1];
470 }
471
sub_v2_v2v2_db(double r[2],const double a[2],const double b[2])472 MINLINE void sub_v2_v2v2_db(double r[2], const double a[2], const double b[2])
473 {
474 r[0] = a[0] - b[0];
475 r[1] = a[1] - b[1];
476 }
477
sub_v2_v2v2_int(int r[2],const int a[2],const int b[2])478 MINLINE void sub_v2_v2v2_int(int r[2], const int a[2], const int b[2])
479 {
480 r[0] = a[0] - b[0];
481 r[1] = a[1] - b[1];
482 }
483
sub_v3_v3(float r[3],const float a[3])484 MINLINE void sub_v3_v3(float r[3], const float a[3])
485 {
486 r[0] -= a[0];
487 r[1] -= a[1];
488 r[2] -= a[2];
489 }
490
sub_v3_v3v3(float r[3],const float a[3],const float b[3])491 MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
492 {
493 r[0] = a[0] - b[0];
494 r[1] = a[1] - b[1];
495 r[2] = a[2] - b[2];
496 }
497
sub_v3_v3v3_int(int r[3],const int a[3],const int b[3])498 MINLINE void sub_v3_v3v3_int(int r[3], const int a[3], const int b[3])
499 {
500 r[0] = a[0] - b[0];
501 r[1] = a[1] - b[1];
502 r[2] = a[2] - b[2];
503 }
504
sub_v3_v3v3_db(double r[3],const double a[3],const double b[3])505 MINLINE void sub_v3_v3v3_db(double r[3], const double a[3], const double b[3])
506 {
507 r[0] = a[0] - b[0];
508 r[1] = a[1] - b[1];
509 r[2] = a[2] - b[2];
510 }
511
sub_v2db_v2fl_v2fl(double r[2],const float a[2],const float b[2])512 MINLINE void sub_v2db_v2fl_v2fl(double r[2], const float a[2], const float b[2])
513 {
514 r[0] = (double)a[0] - (double)b[0];
515 r[1] = (double)a[1] - (double)b[1];
516 }
517
sub_v3db_v3fl_v3fl(double r[3],const float a[3],const float b[3])518 MINLINE void sub_v3db_v3fl_v3fl(double r[3], const float a[3], const float b[3])
519 {
520 r[0] = (double)a[0] - (double)b[0];
521 r[1] = (double)a[1] - (double)b[1];
522 r[2] = (double)a[2] - (double)b[2];
523 }
524
sub_v4_v4(float r[4],const float a[4])525 MINLINE void sub_v4_v4(float r[4], const float a[4])
526 {
527 r[0] -= a[0];
528 r[1] -= a[1];
529 r[2] -= a[2];
530 r[3] -= a[3];
531 }
532
sub_v4_v4v4(float r[4],const float a[4],const float b[4])533 MINLINE void sub_v4_v4v4(float r[4], const float a[4], const float b[4])
534 {
535 r[0] = a[0] - b[0];
536 r[1] = a[1] - b[1];
537 r[2] = a[2] - b[2];
538 r[3] = a[3] - b[3];
539 }
540
mul_v2_fl(float r[2],float f)541 MINLINE void mul_v2_fl(float r[2], float f)
542 {
543 r[0] *= f;
544 r[1] *= f;
545 }
546
mul_v2_v2fl(float r[2],const float a[2],float f)547 MINLINE void mul_v2_v2fl(float r[2], const float a[2], float f)
548 {
549 r[0] = a[0] * f;
550 r[1] = a[1] * f;
551 }
552
mul_v3_fl(float r[3],float f)553 MINLINE void mul_v3_fl(float r[3], float f)
554 {
555 r[0] *= f;
556 r[1] *= f;
557 r[2] *= f;
558 }
559
mul_v3db_db(double r[3],double f)560 MINLINE void mul_v3db_db(double r[3], double f)
561 {
562 r[0] *= f;
563 r[1] *= f;
564 r[2] *= f;
565 }
566
mul_v3_v3fl(float r[3],const float a[3],float f)567 MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
568 {
569 r[0] = a[0] * f;
570 r[1] = a[1] * f;
571 r[2] = a[2] * f;
572 }
573
mul_v3_v3db_db(double r[3],const double a[3],double f)574 MINLINE void mul_v3_v3db_db(double r[3], const double a[3], double f)
575 {
576 r[0] = a[0] * f;
577 r[1] = a[1] * f;
578 r[2] = a[2] * f;
579 }
580
mul_v2_v2(float r[2],const float a[2])581 MINLINE void mul_v2_v2(float r[2], const float a[2])
582 {
583 r[0] *= a[0];
584 r[1] *= a[1];
585 }
586
mul_v3_v3(float r[3],const float a[3])587 MINLINE void mul_v3_v3(float r[3], const float a[3])
588 {
589 r[0] *= a[0];
590 r[1] *= a[1];
591 r[2] *= a[2];
592 }
593
mul_v4_fl(float r[4],float f)594 MINLINE void mul_v4_fl(float r[4], float f)
595 {
596 r[0] *= f;
597 r[1] *= f;
598 r[2] *= f;
599 r[3] *= f;
600 }
601
mul_v4_v4(float r[4],const float a[4])602 MINLINE void mul_v4_v4(float r[4], const float a[4])
603 {
604 r[0] *= a[0];
605 r[1] *= a[1];
606 r[2] *= a[2];
607 r[3] *= a[3];
608 }
609
mul_v4_v4fl(float r[4],const float a[4],float f)610 MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
611 {
612 r[0] = a[0] * f;
613 r[1] = a[1] * f;
614 r[2] = a[2] * f;
615 r[3] = a[3] * f;
616 }
617
618 /**
619 * Avoid doing:
620 *
621 * angle = atan2f(dvec[0], dvec[1]);
622 * angle_to_mat2(mat, angle);
623 *
624 * instead use a vector as a matrix.
625 */
626
mul_v2_v2_cw(float r[2],const float mat[2],const float vec[2])627 MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2])
628 {
629 BLI_assert(r != vec);
630
631 r[0] = mat[0] * vec[0] + (+mat[1]) * vec[1];
632 r[1] = mat[1] * vec[0] + (-mat[0]) * vec[1];
633 }
634
mul_v2_v2_ccw(float r[2],const float mat[2],const float vec[2])635 MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2])
636 {
637 BLI_assert(r != vec);
638
639 r[0] = mat[0] * vec[0] + (-mat[1]) * vec[1];
640 r[1] = mat[1] * vec[0] + (+mat[0]) * vec[1];
641 }
642
643 /**
644 * Convenience function to get the projected depth of a position.
645 * This avoids creating a temporary 4D vector and multiplying it - only for the 4th component.
646 *
647 * Matches logic for:
648 *
649 * \code{.c}
650 * float co_4d[4] = {co[0], co[1], co[2], 1.0};
651 * mul_m4_v4(mat, co_4d);
652 * return co_4d[3];
653 * \endcode
654 */
mul_project_m4_v3_zfac(const float mat[4][4],const float co[3])655 MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3])
656 {
657 return (mat[0][3] * co[0]) + (mat[1][3] * co[1]) + (mat[2][3] * co[2]) + mat[3][3];
658 }
659
660 /**
661 * Has the effect of #mul_m3_v3(), on a single axis.
662 */
dot_m3_v3_row_x(const float M[3][3],const float a[3])663 MINLINE float dot_m3_v3_row_x(const float M[3][3], const float a[3])
664 {
665 return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
666 }
dot_m3_v3_row_y(const float M[3][3],const float a[3])667 MINLINE float dot_m3_v3_row_y(const float M[3][3], const float a[3])
668 {
669 return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
670 }
dot_m3_v3_row_z(const float M[3][3],const float a[3])671 MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3])
672 {
673 return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
674 }
675
676 /**
677 * Has the effect of #mul_mat3_m4_v3(), on a single axis.
678 * (no adding translation)
679 */
dot_m4_v3_row_x(const float M[4][4],const float a[3])680 MINLINE float dot_m4_v3_row_x(const float M[4][4], const float a[3])
681 {
682 return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
683 }
dot_m4_v3_row_y(const float M[4][4],const float a[3])684 MINLINE float dot_m4_v3_row_y(const float M[4][4], const float a[3])
685 {
686 return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
687 }
dot_m4_v3_row_z(const float M[4][4],const float a[3])688 MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3])
689 {
690 return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
691 }
692
madd_v2_v2fl(float r[2],const float a[2],float f)693 MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
694 {
695 r[0] += a[0] * f;
696 r[1] += a[1] * f;
697 }
698
madd_v3_v3fl(float r[3],const float a[3],float f)699 MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
700 {
701 r[0] += a[0] * f;
702 r[1] += a[1] * f;
703 r[2] += a[2] * f;
704 }
705
madd_v3_v3v3(float r[3],const float a[3],const float b[3])706 MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3])
707 {
708 r[0] += a[0] * b[0];
709 r[1] += a[1] * b[1];
710 r[2] += a[2] * b[2];
711 }
712
madd_v2_v2v2fl(float r[2],const float a[2],const float b[2],float f)713 MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
714 {
715 r[0] = a[0] + b[0] * f;
716 r[1] = a[1] + b[1] * f;
717 }
718
madd_v3_v3v3fl(float r[3],const float a[3],const float b[3],float f)719 MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
720 {
721 r[0] = a[0] + b[0] * f;
722 r[1] = a[1] + b[1] * f;
723 r[2] = a[2] + b[2] * f;
724 }
725
madd_v3_v3v3v3(float r[3],const float a[3],const float b[3],const float c[3])726 MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
727 {
728 r[0] = a[0] + b[0] * c[0];
729 r[1] = a[1] + b[1] * c[1];
730 r[2] = a[2] + b[2] * c[2];
731 }
732
madd_v3fl_v3fl_v3fl_v3i(float r[3],const float a[3],const float b[3],const int c[3])733 MINLINE void madd_v3fl_v3fl_v3fl_v3i(float r[3],
734 const float a[3],
735 const float b[3],
736 const int c[3])
737 {
738 r[0] = a[0] + b[0] * (float)c[0];
739 r[1] = a[1] + b[1] * (float)c[1];
740 r[2] = a[2] + b[2] * (float)c[2];
741 }
742
madd_v4_v4fl(float r[4],const float a[4],float f)743 MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
744 {
745 r[0] += a[0] * f;
746 r[1] += a[1] * f;
747 r[2] += a[2] * f;
748 r[3] += a[3] * f;
749 }
750
madd_v4_v4v4(float r[4],const float a[4],const float b[4])751 MINLINE void madd_v4_v4v4(float r[4], const float a[4], const float b[4])
752 {
753 r[0] += a[0] * b[0];
754 r[1] += a[1] * b[1];
755 r[2] += a[2] * b[2];
756 r[3] += a[3] * b[3];
757 }
758
mul_v3_v3v3(float r[3],const float v1[3],const float v2[3])759 MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
760 {
761 r[0] = v1[0] * v2[0];
762 r[1] = v1[1] * v2[1];
763 r[2] = v1[2] * v2[2];
764 }
765
mul_v2_v2v2(float r[2],const float a[2],const float b[2])766 MINLINE void mul_v2_v2v2(float r[2], const float a[2], const float b[2])
767 {
768 r[0] = a[0] * b[0];
769 r[1] = a[1] * b[1];
770 }
771
negate_v2(float r[2])772 MINLINE void negate_v2(float r[2])
773 {
774 r[0] = -r[0];
775 r[1] = -r[1];
776 }
777
negate_v2_v2(float r[2],const float a[2])778 MINLINE void negate_v2_v2(float r[2], const float a[2])
779 {
780 r[0] = -a[0];
781 r[1] = -a[1];
782 }
783
negate_v3(float r[3])784 MINLINE void negate_v3(float r[3])
785 {
786 r[0] = -r[0];
787 r[1] = -r[1];
788 r[2] = -r[2];
789 }
790
negate_v3_v3(float r[3],const float a[3])791 MINLINE void negate_v3_v3(float r[3], const float a[3])
792 {
793 r[0] = -a[0];
794 r[1] = -a[1];
795 r[2] = -a[2];
796 }
797
negate_v4(float r[4])798 MINLINE void negate_v4(float r[4])
799 {
800 r[0] = -r[0];
801 r[1] = -r[1];
802 r[2] = -r[2];
803 r[3] = -r[3];
804 }
805
negate_v4_v4(float r[4],const float a[4])806 MINLINE void negate_v4_v4(float r[4], const float a[4])
807 {
808 r[0] = -a[0];
809 r[1] = -a[1];
810 r[2] = -a[2];
811 r[3] = -a[3];
812 }
813
814 /* could add more... */
negate_v3_short(short r[3])815 MINLINE void negate_v3_short(short r[3])
816 {
817 r[0] = (short)-r[0];
818 r[1] = (short)-r[1];
819 r[2] = (short)-r[2];
820 }
821
negate_v3_db(double r[3])822 MINLINE void negate_v3_db(double r[3])
823 {
824 r[0] = -r[0];
825 r[1] = -r[1];
826 r[2] = -r[2];
827 }
828
invert_v2(float r[2])829 MINLINE void invert_v2(float r[2])
830 {
831 BLI_assert(!ELEM(0.0f, r[0], r[1]));
832 r[0] = 1.0f / r[0];
833 r[1] = 1.0f / r[1];
834 }
835
invert_v3(float r[3])836 MINLINE void invert_v3(float r[3])
837 {
838 BLI_assert(!ELEM(0.0f, r[0], r[1], r[2]));
839 r[0] = 1.0f / r[0];
840 r[1] = 1.0f / r[1];
841 r[2] = 1.0f / r[2];
842 }
843
abs_v2(float r[2])844 MINLINE void abs_v2(float r[2])
845 {
846 r[0] = fabsf(r[0]);
847 r[1] = fabsf(r[1]);
848 }
849
abs_v2_v2(float r[2],const float a[2])850 MINLINE void abs_v2_v2(float r[2], const float a[2])
851 {
852 r[0] = fabsf(a[0]);
853 r[1] = fabsf(a[1]);
854 }
855
abs_v3(float r[3])856 MINLINE void abs_v3(float r[3])
857 {
858 r[0] = fabsf(r[0]);
859 r[1] = fabsf(r[1]);
860 r[2] = fabsf(r[2]);
861 }
862
abs_v3_v3(float r[3],const float a[3])863 MINLINE void abs_v3_v3(float r[3], const float a[3])
864 {
865 r[0] = fabsf(a[0]);
866 r[1] = fabsf(a[1]);
867 r[2] = fabsf(a[2]);
868 }
869
abs_v4(float r[4])870 MINLINE void abs_v4(float r[4])
871 {
872 r[0] = fabsf(r[0]);
873 r[1] = fabsf(r[1]);
874 r[2] = fabsf(r[2]);
875 r[3] = fabsf(r[3]);
876 }
877
abs_v4_v4(float r[4],const float a[4])878 MINLINE void abs_v4_v4(float r[4], const float a[4])
879 {
880 r[0] = fabsf(a[0]);
881 r[1] = fabsf(a[1]);
882 r[2] = fabsf(a[2]);
883 r[3] = fabsf(a[3]);
884 }
885
dot_v2v2(const float a[2],const float b[2])886 MINLINE float dot_v2v2(const float a[2], const float b[2])
887 {
888 return a[0] * b[0] + a[1] * b[1];
889 }
890
dot_v2v2_db(const double a[2],const double b[2])891 MINLINE double dot_v2v2_db(const double a[2], const double b[2])
892 {
893 return a[0] * b[0] + a[1] * b[1];
894 }
895
dot_v3v3(const float a[3],const float b[3])896 MINLINE float dot_v3v3(const float a[3], const float b[3])
897 {
898 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
899 }
900
dot_v3v3v3(const float p[3],const float a[3],const float b[3])901 MINLINE float dot_v3v3v3(const float p[3], const float a[3], const float b[3])
902 {
903 float vec1[3], vec2[3];
904
905 sub_v3_v3v3(vec1, a, p);
906 sub_v3_v3v3(vec2, b, p);
907 if (is_zero_v3(vec1) || is_zero_v3(vec2)) {
908 return 0.0f;
909 }
910 return dot_v3v3(vec1, vec2);
911 }
912
dot_v4v4(const float a[4],const float b[4])913 MINLINE float dot_v4v4(const float a[4], const float b[4])
914 {
915 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
916 }
917
dot_v3db_v3fl(const double a[3],const float b[3])918 MINLINE double dot_v3db_v3fl(const double a[3], const float b[3])
919 {
920 return a[0] * (double)b[0] + a[1] * (double)b[1] + a[2] * (double)b[2];
921 }
922
dot_v3v3_db(const double a[3],const double b[3])923 MINLINE double dot_v3v3_db(const double a[3], const double b[3])
924 {
925 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
926 }
927
cross_v2v2(const float a[2],const float b[2])928 MINLINE float cross_v2v2(const float a[2], const float b[2])
929 {
930 return a[0] * b[1] - a[1] * b[0];
931 }
932
cross_v2v2_db(const double a[2],const double b[2])933 MINLINE double cross_v2v2_db(const double a[2], const double b[2])
934 {
935 return a[0] * b[1] - a[1] * b[0];
936 }
937
cross_v3_v3v3(float r[3],const float a[3],const float b[3])938 MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
939 {
940 BLI_assert(r != a && r != b);
941 r[0] = a[1] * b[2] - a[2] * b[1];
942 r[1] = a[2] * b[0] - a[0] * b[2];
943 r[2] = a[0] * b[1] - a[1] * b[0];
944 }
945
946 /* cross product suffers from severe precision loss when vectors are
947 * nearly parallel or opposite; doing the computation in double helps a lot */
cross_v3_v3v3_hi_prec(float r[3],const float a[3],const float b[3])948 MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3])
949 {
950 BLI_assert(r != a && r != b);
951 r[0] = (float)((double)a[1] * (double)b[2] - (double)a[2] * (double)b[1]);
952 r[1] = (float)((double)a[2] * (double)b[0] - (double)a[0] * (double)b[2]);
953 r[2] = (float)((double)a[0] * (double)b[1] - (double)a[1] * (double)b[0]);
954 }
955
cross_v3_v3v3_db(double r[3],const double a[3],const double b[3])956 MINLINE void cross_v3_v3v3_db(double r[3], const double a[3], const double b[3])
957 {
958 BLI_assert(r != a && r != b);
959 r[0] = a[1] * b[2] - a[2] * b[1];
960 r[1] = a[2] * b[0] - a[0] * b[2];
961 r[2] = a[0] * b[1] - a[1] * b[0];
962 }
963
964 /* Newell's Method */
965 /* excuse this fairly specific function,
966 * its used for polygon normals all over the place
967 * could use a better name */
add_newell_cross_v3_v3v3(float n[3],const float v_prev[3],const float v_curr[3])968 MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
969 {
970 n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]);
971 n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]);
972 n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
973 }
974
star_m3_v3(float rmat[3][3],float a[3])975 MINLINE void star_m3_v3(float rmat[3][3], float a[3])
976 {
977 rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0;
978 rmat[0][1] = -a[2];
979 rmat[0][2] = a[1];
980 rmat[1][0] = a[2];
981 rmat[1][2] = -a[0];
982 rmat[2][0] = -a[1];
983 rmat[2][1] = a[0];
984 }
985
986 /*********************************** Length **********************************/
987
len_squared_v2(const float v[2])988 MINLINE float len_squared_v2(const float v[2])
989 {
990 return v[0] * v[0] + v[1] * v[1];
991 }
992
len_squared_v3(const float v[3])993 MINLINE float len_squared_v3(const float v[3])
994 {
995 return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
996 }
997
len_squared_v3_db(const double v[3])998 MINLINE double len_squared_v3_db(const double v[3])
999 {
1000 return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
1001 }
1002
len_manhattan_v2(const float v[2])1003 MINLINE float len_manhattan_v2(const float v[2])
1004 {
1005 return fabsf(v[0]) + fabsf(v[1]);
1006 }
1007
len_manhattan_v2_int(const int v[2])1008 MINLINE int len_manhattan_v2_int(const int v[2])
1009 {
1010 return abs(v[0]) + abs(v[1]);
1011 }
1012
len_manhattan_v3(const float v[3])1013 MINLINE float len_manhattan_v3(const float v[3])
1014 {
1015 return fabsf(v[0]) + fabsf(v[1]) + fabsf(v[2]);
1016 }
1017
len_v2(const float v[2])1018 MINLINE float len_v2(const float v[2])
1019 {
1020 return sqrtf(v[0] * v[0] + v[1] * v[1]);
1021 }
1022
len_v2_db(const double v[2])1023 MINLINE double len_v2_db(const double v[2])
1024 {
1025 return sqrt(v[0] * v[0] + v[1] * v[1]);
1026 }
1027
len_v2v2(const float v1[2],const float v2[2])1028 MINLINE float len_v2v2(const float v1[2], const float v2[2])
1029 {
1030 float x, y;
1031
1032 x = v1[0] - v2[0];
1033 y = v1[1] - v2[1];
1034 return sqrtf(x * x + y * y);
1035 }
1036
len_v2v2_db(const double v1[2],const double v2[2])1037 MINLINE double len_v2v2_db(const double v1[2], const double v2[2])
1038 {
1039 double x, y;
1040
1041 x = v1[0] - v2[0];
1042 y = v1[1] - v2[1];
1043 return sqrt(x * x + y * y);
1044 }
1045
len_v2v2_int(const int v1[2],const int v2[2])1046 MINLINE float len_v2v2_int(const int v1[2], const int v2[2])
1047 {
1048 float x, y;
1049
1050 x = (float)(v1[0] - v2[0]);
1051 y = (float)(v1[1] - v2[1]);
1052 return sqrtf(x * x + y * y);
1053 }
1054
len_v3(const float a[3])1055 MINLINE float len_v3(const float a[3])
1056 {
1057 return sqrtf(dot_v3v3(a, a));
1058 }
1059
len_v3_db(const double a[3])1060 MINLINE double len_v3_db(const double a[3])
1061 {
1062 return sqrt(dot_v3v3_db(a, a));
1063 }
1064
len_squared_v2v2(const float a[2],const float b[2])1065 MINLINE float len_squared_v2v2(const float a[2], const float b[2])
1066 {
1067 float d[2];
1068
1069 sub_v2_v2v2(d, b, a);
1070 return dot_v2v2(d, d);
1071 }
1072
len_squared_v2v2_db(const double a[2],const double b[2])1073 MINLINE double len_squared_v2v2_db(const double a[2], const double b[2])
1074 {
1075 double d[2];
1076
1077 sub_v2_v2v2_db(d, b, a);
1078 return dot_v2v2_db(d, d);
1079 }
1080
len_squared_v3v3(const float a[3],const float b[3])1081 MINLINE float len_squared_v3v3(const float a[3], const float b[3])
1082 {
1083 float d[3];
1084
1085 sub_v3_v3v3(d, b, a);
1086 return dot_v3v3(d, d);
1087 }
1088
len_squared_v4v4(const float a[4],const float b[4])1089 MINLINE float len_squared_v4v4(const float a[4], const float b[4])
1090 {
1091 float d[4];
1092
1093 sub_v4_v4v4(d, b, a);
1094 return dot_v4v4(d, d);
1095 }
1096
len_manhattan_v2v2(const float a[2],const float b[2])1097 MINLINE float len_manhattan_v2v2(const float a[2], const float b[2])
1098 {
1099 float d[2];
1100
1101 sub_v2_v2v2(d, b, a);
1102 return len_manhattan_v2(d);
1103 }
1104
len_manhattan_v2v2_int(const int a[2],const int b[2])1105 MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2])
1106 {
1107 int d[2];
1108
1109 sub_v2_v2v2_int(d, b, a);
1110 return len_manhattan_v2_int(d);
1111 }
1112
len_manhattan_v3v3(const float a[3],const float b[3])1113 MINLINE float len_manhattan_v3v3(const float a[3], const float b[3])
1114 {
1115 float d[3];
1116
1117 sub_v3_v3v3(d, b, a);
1118 return len_manhattan_v3(d);
1119 }
1120
len_v3v3(const float a[3],const float b[3])1121 MINLINE float len_v3v3(const float a[3], const float b[3])
1122 {
1123 float d[3];
1124
1125 sub_v3_v3v3(d, b, a);
1126 return len_v3(d);
1127 }
1128
normalize_v2_v2_length(float r[2],const float a[2],const float unit_length)1129 MINLINE float normalize_v2_v2_length(float r[2], const float a[2], const float unit_length)
1130 {
1131 float d = dot_v2v2(a, a);
1132
1133 if (d > 1.0e-35f) {
1134 d = sqrtf(d);
1135 mul_v2_v2fl(r, a, unit_length / d);
1136 }
1137 else {
1138 zero_v2(r);
1139 d = 0.0f;
1140 }
1141
1142 return d;
1143 }
normalize_v2_v2(float r[2],const float a[2])1144 MINLINE float normalize_v2_v2(float r[2], const float a[2])
1145 {
1146 return normalize_v2_v2_length(r, a, 1.0f);
1147 }
1148
normalize_v2(float n[2])1149 MINLINE float normalize_v2(float n[2])
1150 {
1151 return normalize_v2_v2(n, n);
1152 }
1153
normalize_v2_length(float n[2],const float unit_length)1154 MINLINE float normalize_v2_length(float n[2], const float unit_length)
1155 {
1156 return normalize_v2_v2_length(n, n, unit_length);
1157 }
1158
normalize_v3_v3_length(float r[3],const float a[3],const float unit_length)1159 MINLINE float normalize_v3_v3_length(float r[3], const float a[3], const float unit_length)
1160 {
1161 float d = dot_v3v3(a, a);
1162
1163 /* a larger value causes normalize errors in a
1164 * scaled down models with camera extreme close */
1165 if (d > 1.0e-35f) {
1166 d = sqrtf(d);
1167 mul_v3_v3fl(r, a, unit_length / d);
1168 }
1169 else {
1170 zero_v3(r);
1171 d = 0.0f;
1172 }
1173
1174 return d;
1175 }
normalize_v3_v3(float r[3],const float a[3])1176 MINLINE float normalize_v3_v3(float r[3], const float a[3])
1177 {
1178 return normalize_v3_v3_length(r, a, 1.0f);
1179 }
1180
normalize_v3_v3_length_db(double r[3],const double a[3],double const unit_length)1181 MINLINE double normalize_v3_v3_length_db(double r[3], const double a[3], double const unit_length)
1182 {
1183 double d = dot_v3v3_db(a, a);
1184
1185 /* a larger value causes normalize errors in a
1186 * scaled down models with camera extreme close */
1187 if (d > 1.0e-70) {
1188 d = sqrt(d);
1189 mul_v3_v3db_db(r, a, unit_length / d);
1190 }
1191 else {
1192 zero_v3_db(r);
1193 d = 0.0;
1194 }
1195
1196 return d;
1197 }
normalize_v3_v3_db(double r[3],const double a[3])1198 MINLINE double normalize_v3_v3_db(double r[3], const double a[3])
1199 {
1200 return normalize_v3_v3_length_db(r, a, 1.0);
1201 }
1202
normalize_v3_length_db(double n[3],const double unit_length)1203 MINLINE double normalize_v3_length_db(double n[3], const double unit_length)
1204 {
1205 double d = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
1206
1207 /* a larger value causes normalize errors in a
1208 * scaled down models with camera extreme close */
1209 if (d > 1.0e-35) {
1210 double mul;
1211
1212 d = sqrt(d);
1213 mul = unit_length / d;
1214
1215 n[0] *= mul;
1216 n[1] *= mul;
1217 n[2] *= mul;
1218 }
1219 else {
1220 n[0] = n[1] = n[2] = 0;
1221 d = 0.0;
1222 }
1223
1224 return d;
1225 }
normalize_v3_db(double n[3])1226 MINLINE double normalize_v3_db(double n[3])
1227 {
1228 return normalize_v3_length_db(n, 1.0);
1229 }
1230
normalize_v3_length(float n[3],const float unit_length)1231 MINLINE float normalize_v3_length(float n[3], const float unit_length)
1232 {
1233 return normalize_v3_v3_length(n, n, unit_length);
1234 }
1235
normalize_v3(float n[3])1236 MINLINE float normalize_v3(float n[3])
1237 {
1238 return normalize_v3_v3(n, n);
1239 }
1240
normal_float_to_short_v2(short out[2],const float in[2])1241 MINLINE void normal_float_to_short_v2(short out[2], const float in[2])
1242 {
1243 out[0] = (short)(in[0] * 32767.0f);
1244 out[1] = (short)(in[1] * 32767.0f);
1245 }
1246
normal_short_to_float_v3(float out[3],const short in[3])1247 MINLINE void normal_short_to_float_v3(float out[3], const short in[3])
1248 {
1249 out[0] = in[0] * (1.0f / 32767.0f);
1250 out[1] = in[1] * (1.0f / 32767.0f);
1251 out[2] = in[2] * (1.0f / 32767.0f);
1252 }
1253
normal_float_to_short_v3(short out[3],const float in[3])1254 MINLINE void normal_float_to_short_v3(short out[3], const float in[3])
1255 {
1256 out[0] = (short)(in[0] * 32767.0f);
1257 out[1] = (short)(in[1] * 32767.0f);
1258 out[2] = (short)(in[2] * 32767.0f);
1259 }
1260
normal_float_to_short_v4(short out[4],const float in[4])1261 MINLINE void normal_float_to_short_v4(short out[4], const float in[4])
1262 {
1263 out[0] = (short)(in[0] * 32767.0f);
1264 out[1] = (short)(in[1] * 32767.0f);
1265 out[2] = (short)(in[2] * 32767.0f);
1266 out[3] = (short)(in[3] * 32767.0f);
1267 }
1268
1269 /********************************* Comparison ********************************/
1270
is_zero_v2(const float v[2])1271 MINLINE bool is_zero_v2(const float v[2])
1272 {
1273 return (v[0] == 0.0f && v[1] == 0.0f);
1274 }
1275
is_zero_v3(const float v[3])1276 MINLINE bool is_zero_v3(const float v[3])
1277 {
1278 return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f);
1279 }
1280
is_zero_v4(const float v[4])1281 MINLINE bool is_zero_v4(const float v[4])
1282 {
1283 return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f && v[3] == 0.0f);
1284 }
1285
is_one_v3(const float v[3])1286 MINLINE bool is_one_v3(const float v[3])
1287 {
1288 return (v[0] == 1.0f && v[1] == 1.0f && v[2] == 1.0f);
1289 }
1290
1291 /** \name Vector Comparison
1292 *
1293 * \note use ``value <= limit``, so a limit of zero doesn't fail on an exact match.
1294 * \{ */
1295
equals_v2v2(const float v1[2],const float v2[2])1296 MINLINE bool equals_v2v2(const float v1[2], const float v2[2])
1297 {
1298 return ((v1[0] == v2[0]) && (v1[1] == v2[1]));
1299 }
1300
equals_v3v3(const float v1[3],const float v2[3])1301 MINLINE bool equals_v3v3(const float v1[3], const float v2[3])
1302 {
1303 return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]));
1304 }
1305
equals_v4v4(const float v1[4],const float v2[4])1306 MINLINE bool equals_v4v4(const float v1[4], const float v2[4])
1307 {
1308 return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]) && (v1[3] == v2[3]));
1309 }
1310
equals_v2v2_int(const int v1[2],const int v2[2])1311 MINLINE bool equals_v2v2_int(const int v1[2], const int v2[2])
1312 {
1313 return ((v1[0] == v2[0]) && (v1[1] == v2[1]));
1314 }
1315
equals_v3v3_int(const int v1[3],const int v2[3])1316 MINLINE bool equals_v3v3_int(const int v1[3], const int v2[3])
1317 {
1318 return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]));
1319 }
1320
equals_v4v4_int(const int v1[4],const int v2[4])1321 MINLINE bool equals_v4v4_int(const int v1[4], const int v2[4])
1322 {
1323 return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]) && (v1[3] == v2[3]));
1324 }
1325
compare_v2v2(const float v1[2],const float v2[2],const float limit)1326 MINLINE bool compare_v2v2(const float v1[2], const float v2[2], const float limit)
1327 {
1328 return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit));
1329 }
1330
compare_v3v3(const float v1[3],const float v2[3],const float limit)1331 MINLINE bool compare_v3v3(const float v1[3], const float v2[3], const float limit)
1332 {
1333 return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit) &&
1334 compare_ff(v1[2], v2[2], limit));
1335 }
1336
compare_v4v4(const float v1[4],const float v2[4],const float limit)1337 MINLINE bool compare_v4v4(const float v1[4], const float v2[4], const float limit)
1338 {
1339 return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit) &&
1340 compare_ff(v1[2], v2[2], limit) && compare_ff(v1[3], v2[3], limit));
1341 }
1342
compare_v2v2_relative(const float v1[2],const float v2[2],const float limit,const int max_ulps)1343 MINLINE bool compare_v2v2_relative(const float v1[2],
1344 const float v2[2],
1345 const float limit,
1346 const int max_ulps)
1347 {
1348 return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
1349 compare_ff_relative(v1[1], v2[1], limit, max_ulps));
1350 }
1351
compare_v3v3_relative(const float v1[3],const float v2[3],const float limit,const int max_ulps)1352 MINLINE bool compare_v3v3_relative(const float v1[3],
1353 const float v2[3],
1354 const float limit,
1355 const int max_ulps)
1356 {
1357 return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
1358 compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
1359 compare_ff_relative(v1[2], v2[2], limit, max_ulps));
1360 }
1361
compare_v4v4_relative(const float v1[4],const float v2[4],const float limit,const int max_ulps)1362 MINLINE bool compare_v4v4_relative(const float v1[4],
1363 const float v2[4],
1364 const float limit,
1365 const int max_ulps)
1366 {
1367 return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
1368 compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
1369 compare_ff_relative(v1[2], v2[2], limit, max_ulps) &&
1370 compare_ff_relative(v1[3], v2[3], limit, max_ulps));
1371 }
1372
compare_len_v3v3(const float v1[3],const float v2[3],const float limit)1373 MINLINE bool compare_len_v3v3(const float v1[3], const float v2[3], const float limit)
1374 {
1375 float d[3];
1376 sub_v3_v3v3(d, v1, v2);
1377 return (dot_v3v3(d, d) <= (limit * limit));
1378 }
1379
compare_size_v3v3(const float v1[3],const float v2[3],const float limit)1380 MINLINE bool compare_size_v3v3(const float v1[3], const float v2[3], const float limit)
1381 {
1382 for (int i = 0; i < 3; i++) {
1383 if (v2[i] == 0.0f) {
1384 /* Catch division by zero. */
1385 if (v1[i] != v2[i]) {
1386 return false;
1387 }
1388 }
1389 else {
1390 if (fabsf(v1[i] / v2[i] - 1.0f) > limit) {
1391 return false;
1392 }
1393 }
1394 }
1395 return true;
1396 }
1397
1398 /** \name Vector Clamping
1399 * \{ */
1400
clamp_v2(float vec[2],const float min,const float max)1401 MINLINE void clamp_v2(float vec[2], const float min, const float max)
1402 {
1403 CLAMP(vec[0], min, max);
1404 CLAMP(vec[1], min, max);
1405 }
1406
clamp_v3(float vec[3],const float min,const float max)1407 MINLINE void clamp_v3(float vec[3], const float min, const float max)
1408 {
1409 CLAMP(vec[0], min, max);
1410 CLAMP(vec[1], min, max);
1411 CLAMP(vec[2], min, max);
1412 }
1413
clamp_v4(float vec[4],const float min,const float max)1414 MINLINE void clamp_v4(float vec[4], const float min, const float max)
1415 {
1416 CLAMP(vec[0], min, max);
1417 CLAMP(vec[1], min, max);
1418 CLAMP(vec[2], min, max);
1419 CLAMP(vec[3], min, max);
1420 }
1421
clamp_v2_v2v2(float vec[2],const float min[2],const float max[2])1422 MINLINE void clamp_v2_v2v2(float vec[2], const float min[2], const float max[2])
1423 {
1424 CLAMP(vec[0], min[0], max[0]);
1425 CLAMP(vec[1], min[1], max[1]);
1426 }
1427
clamp_v3_v3v3(float vec[3],const float min[3],const float max[3])1428 MINLINE void clamp_v3_v3v3(float vec[3], const float min[3], const float max[3])
1429 {
1430 CLAMP(vec[0], min[0], max[0]);
1431 CLAMP(vec[1], min[1], max[1]);
1432 CLAMP(vec[2], min[2], max[2]);
1433 }
1434
clamp_v4_v4v4(float vec[4],const float min[4],const float max[4])1435 MINLINE void clamp_v4_v4v4(float vec[4], const float min[4], const float max[4])
1436 {
1437 CLAMP(vec[0], min[0], max[0]);
1438 CLAMP(vec[1], min[1], max[1]);
1439 CLAMP(vec[2], min[2], max[2]);
1440 CLAMP(vec[3], min[3], max[3]);
1441 }
1442
1443 /** \} */
1444
1445 /**
1446 * <pre>
1447 * + l1
1448 * |
1449 * neg <- | -> pos
1450 * |
1451 * + l2
1452 * </pre>
1453 *
1454 * \return Positive value when 'pt' is left-of-line
1455 * (looking from 'l1' -> 'l2').
1456 */
line_point_side_v2(const float l1[2],const float l2[2],const float pt[2])1457 MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2])
1458 {
1459 return (((l1[0] - pt[0]) * (l2[1] - pt[1])) - ((l2[0] - pt[0]) * (l1[1] - pt[1])));
1460 }
1461
1462 /** \} */
1463
1464 #endif /* __MATH_VECTOR_INLINE_C__ */
1465