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