Fix T70439: Local view always including new objects
[blender.git] / source / blender / blenlib / intern / math_vector_inline.c
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
34 MINLINE void zero_v2(float r[2])
35 {
36   r[0] = 0.0f;
37   r[1] = 0.0f;
38 }
39
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
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
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
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
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
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
83 MINLINE void copy_v2_fl(float r[2], float f)
84 {
85   r[0] = f;
86   r[1] = f;
87 }
88
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
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 */
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
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
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
126 /* char */
127 MINLINE void copy_v2_v2_char(char r[2], const char a[2])
128 {
129   r[0] = a[0];
130   r[1] = a[1];
131 }
132
133 MINLINE void copy_v3_v3_char(char r[3], const char a[3])
134 {
135   r[0] = a[0];
136   r[1] = a[1];
137   r[2] = a[2];
138 }
139
140 MINLINE void copy_v4_v4_char(char r[4], const char a[4])
141 {
142   r[0] = a[0];
143   r[1] = a[1];
144   r[2] = a[2];
145   r[3] = a[3];
146 }
147
148 /* short */
149
150 MINLINE void copy_v2_v2_short(short r[2], const short a[2])
151 {
152   r[0] = a[0];
153   r[1] = a[1];
154 }
155
156 MINLINE void copy_v3_v3_short(short r[3], const short a[3])
157 {
158   r[0] = a[0];
159   r[1] = a[1];
160   r[2] = a[2];
161 }
162
163 MINLINE void copy_v4_v4_short(short r[4], const short a[4])
164 {
165   r[0] = a[0];
166   r[1] = a[1];
167   r[2] = a[2];
168   r[3] = a[3];
169 }
170
171 /* int */
172 MINLINE void zero_v3_int(int r[3])
173 {
174   r[0] = 0;
175   r[1] = 0;
176   r[2] = 0;
177 }
178
179 MINLINE void copy_v2_v2_int(int r[2], const int a[2])
180 {
181   r[0] = a[0];
182   r[1] = a[1];
183 }
184
185 MINLINE void copy_v3_v3_int(int r[3], const int a[3])
186 {
187   r[0] = a[0];
188   r[1] = a[1];
189   r[2] = a[2];
190 }
191
192 MINLINE void copy_v4_v4_int(int r[4], const int a[4])
193 {
194   r[0] = a[0];
195   r[1] = a[1];
196   r[2] = a[2];
197   r[3] = a[3];
198 }
199
200 /* double */
201 MINLINE void zero_v3_db(double r[3])
202 {
203   r[0] = 0.0;
204   r[1] = 0.0;
205   r[2] = 0.0;
206 }
207
208 MINLINE void copy_v2_v2_db(double r[2], const double a[2])
209 {
210   r[0] = a[0];
211   r[1] = a[1];
212 }
213
214 MINLINE void copy_v3_v3_db(double r[3], const double a[3])
215 {
216   r[0] = a[0];
217   r[1] = a[1];
218   r[2] = a[2];
219 }
220
221 MINLINE void copy_v4_v4_db(double r[4], const double a[4])
222 {
223   r[0] = a[0];
224   r[1] = a[1];
225   r[2] = a[2];
226   r[3] = a[3];
227 }
228
229 /* int <-> float */
230 MINLINE void round_v2i_v2fl(int r[2], const float a[2])
231 {
232   r[0] = (int)roundf(a[0]);
233   r[1] = (int)roundf(a[1]);
234 }
235
236 MINLINE void copy_v2fl_v2i(float r[2], const int a[2])
237 {
238   r[0] = (float)a[0];
239   r[1] = (float)a[1];
240 }
241
242 /* double -> float */
243 MINLINE void copy_v2fl_v2db(float r[2], const double a[2])
244 {
245   r[0] = (float)a[0];
246   r[1] = (float)a[1];
247 }
248
249 MINLINE void copy_v3fl_v3db(float r[3], const double a[3])
250 {
251   r[0] = (float)a[0];
252   r[1] = (float)a[1];
253   r[2] = (float)a[2];
254 }
255
256 MINLINE void copy_v4fl_v4db(float r[4], const double a[4])
257 {
258   r[0] = (float)a[0];
259   r[1] = (float)a[1];
260   r[2] = (float)a[2];
261   r[3] = (float)a[3];
262 }
263
264 /* float -> double */
265 MINLINE void copy_v2db_v2fl(double r[2], const float a[2])
266 {
267   r[0] = (double)a[0];
268   r[1] = (double)a[1];
269 }
270
271 MINLINE void copy_v3db_v3fl(double r[3], const float a[3])
272 {
273   r[0] = (double)a[0];
274   r[1] = (double)a[1];
275   r[2] = (double)a[2];
276 }
277
278 MINLINE void copy_v4db_v4fl(double r[4], const float a[4])
279 {
280   r[0] = (double)a[0];
281   r[1] = (double)a[1];
282   r[2] = (double)a[2];
283   r[3] = (double)a[3];
284 }
285
286 MINLINE void swap_v2_v2(float a[2], float b[2])
287 {
288   SWAP(float, a[0], b[0]);
289   SWAP(float, a[1], b[1]);
290 }
291
292 MINLINE void swap_v3_v3(float a[3], float b[3])
293 {
294   SWAP(float, a[0], b[0]);
295   SWAP(float, a[1], b[1]);
296   SWAP(float, a[2], b[2]);
297 }
298
299 MINLINE void swap_v4_v4(float a[4], float b[4])
300 {
301   SWAP(float, a[0], b[0]);
302   SWAP(float, a[1], b[1]);
303   SWAP(float, a[2], b[2]);
304   SWAP(float, a[3], b[3]);
305 }
306
307 /* float args -> vec */
308 MINLINE void copy_v2_fl2(float v[2], float x, float y)
309 {
310   v[0] = x;
311   v[1] = y;
312 }
313
314 MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
315 {
316   v[0] = x;
317   v[1] = y;
318   v[2] = z;
319 }
320
321 MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
322 {
323   v[0] = x;
324   v[1] = y;
325   v[2] = z;
326   v[3] = w;
327 }
328
329 /********************************* Arithmetic ********************************/
330
331 MINLINE void add_v2_fl(float r[2], float f)
332 {
333   r[0] += f;
334   r[1] += f;
335 }
336
337 MINLINE void add_v3_fl(float r[3], float f)
338 {
339   r[0] += f;
340   r[1] += f;
341   r[2] += f;
342 }
343
344 MINLINE void add_v4_fl(float r[4], float f)
345 {
346   r[0] += f;
347   r[1] += f;
348   r[2] += f;
349   r[3] += f;
350 }
351
352 MINLINE void add_v2_v2(float r[2], const float a[2])
353 {
354   r[0] += a[0];
355   r[1] += a[1];
356 }
357
358 MINLINE void add_v2_v2_db(double r[2], const double a[2])
359 {
360   r[0] += a[0];
361   r[1] += a[1];
362 }
363
364 MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
365 {
366   r[0] = a[0] + b[0];
367   r[1] = a[1] + b[1];
368 }
369
370 MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2])
371 {
372   r[0] = a[0] + b[0];
373   r[1] = a[1] + b[1];
374 }
375
376 MINLINE void add_v3_v3(float r[3], const float a[3])
377 {
378   r[0] += a[0];
379   r[1] += a[1];
380   r[2] += a[2];
381 }
382
383 MINLINE void add_v3_v3_db(double r[3], const double a[3])
384 {
385   r[0] += a[0];
386   r[1] += a[1];
387   r[2] += a[2];
388 }
389
390 MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
391 {
392   r[0] = a[0] + b[0];
393   r[1] = a[1] + b[1];
394   r[2] = a[2] + b[2];
395 }
396
397 MINLINE void add_v3fl_v3fl_v3i(float r[3], const float a[3], const int b[3])
398 {
399   r[0] = a[0] + (float)b[0];
400   r[1] = a[1] + (float)b[1];
401   r[2] = a[2] + (float)b[2];
402 }
403
404 MINLINE void add_v3fl_v3fl_v3s(float r[3], const float a[3], const short b[3])
405 {
406   r[0] = a[0] + (float)b[0];
407   r[1] = a[1] + (float)b[1];
408   r[2] = a[2] + (float)b[2];
409 }
410
411 MINLINE void add_v4_v4(float r[4], const float a[4])
412 {
413   r[0] += a[0];
414   r[1] += a[1];
415   r[2] += a[2];
416   r[3] += a[3];
417 }
418
419 MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4])
420 {
421   r[0] = a[0] + b[0];
422   r[1] = a[1] + b[1];
423   r[2] = a[2] + b[2];
424   r[3] = a[3] + b[3];
425 }
426
427 MINLINE void sub_v2_v2(float r[2], const float a[2])
428 {
429   r[0] -= a[0];
430   r[1] -= a[1];
431 }
432
433 MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
434 {
435   r[0] = a[0] - b[0];
436   r[1] = a[1] - b[1];
437 }
438
439 MINLINE void sub_v2_v2v2_db(double r[2], const double a[2], const double b[2])
440 {
441   r[0] = a[0] - b[0];
442   r[1] = a[1] - b[1];
443 }
444
445 MINLINE void sub_v2_v2v2_int(int r[2], const int a[2], const int b[2])
446 {
447   r[0] = a[0] - b[0];
448   r[1] = a[1] - b[1];
449 }
450
451 MINLINE void sub_v3_v3(float r[3], const float a[3])
452 {
453   r[0] -= a[0];
454   r[1] -= a[1];
455   r[2] -= a[2];
456 }
457
458 MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
459 {
460   r[0] = a[0] - b[0];
461   r[1] = a[1] - b[1];
462   r[2] = a[2] - b[2];
463 }
464
465 MINLINE void sub_v3_v3v3_int(int r[3], const int a[3], const int b[3])
466 {
467   r[0] = a[0] - b[0];
468   r[1] = a[1] - b[1];
469   r[2] = a[2] - b[2];
470 }
471
472 MINLINE void sub_v3_v3v3_db(double r[3], const double a[3], const double b[3])
473 {
474   r[0] = a[0] - b[0];
475   r[1] = a[1] - b[1];
476   r[2] = a[2] - b[2];
477 }
478
479 MINLINE void sub_v3db_v3fl_v3fl(double r[3], const float a[3], const float b[3])
480 {
481   r[0] = (double)a[0] - (double)b[0];
482   r[1] = (double)a[1] - (double)b[1];
483   r[2] = (double)a[2] - (double)b[2];
484 }
485
486 MINLINE void sub_v4_v4(float r[4], const float a[4])
487 {
488   r[0] -= a[0];
489   r[1] -= a[1];
490   r[2] -= a[2];
491   r[3] -= a[3];
492 }
493
494 MINLINE void sub_v4_v4v4(float r[4], const float a[4], const float b[4])
495 {
496   r[0] = a[0] - b[0];
497   r[1] = a[1] - b[1];
498   r[2] = a[2] - b[2];
499   r[3] = a[3] - b[3];
500 }
501
502 MINLINE void mul_v2_fl(float r[2], float f)
503 {
504   r[0] *= f;
505   r[1] *= f;
506 }
507
508 MINLINE void mul_v2_v2fl(float r[2], const float a[2], float f)
509 {
510   r[0] = a[0] * f;
511   r[1] = a[1] * f;
512 }
513
514 MINLINE void mul_v3_fl(float r[3], float f)
515 {
516   r[0] *= f;
517   r[1] *= f;
518   r[2] *= f;
519 }
520
521 MINLINE void mul_v3db_db(double r[3], double f)
522 {
523   r[0] *= f;
524   r[1] *= f;
525   r[2] *= f;
526 }
527
528 MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
529 {
530   r[0] = a[0] * f;
531   r[1] = a[1] * f;
532   r[2] = a[2] * f;
533 }
534
535 MINLINE void mul_v2_v2(float r[2], const float a[2])
536 {
537   r[0] *= a[0];
538   r[1] *= a[1];
539 }
540
541 MINLINE void mul_v3_v3(float r[3], const float a[3])
542 {
543   r[0] *= a[0];
544   r[1] *= a[1];
545   r[2] *= a[2];
546 }
547
548 MINLINE void mul_v4_fl(float r[4], float f)
549 {
550   r[0] *= f;
551   r[1] *= f;
552   r[2] *= f;
553   r[3] *= f;
554 }
555
556 MINLINE void mul_v4_v4(float r[4], const float a[4])
557 {
558   r[0] *= a[0];
559   r[1] *= a[1];
560   r[2] *= a[2];
561   r[3] *= a[3];
562 }
563
564 MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
565 {
566   r[0] = a[0] * f;
567   r[1] = a[1] * f;
568   r[2] = a[2] * f;
569   r[3] = a[3] * f;
570 }
571
572 /**
573  * Avoid doing:
574  *
575  * angle = atan2f(dvec[0], dvec[1]);
576  * angle_to_mat2(mat, angle);
577  *
578  * instead use a vector as a matrix.
579  */
580
581 MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2])
582 {
583   BLI_assert(r != vec);
584
585   r[0] = mat[0] * vec[0] + (+mat[1]) * vec[1];
586   r[1] = mat[1] * vec[0] + (-mat[0]) * vec[1];
587 }
588
589 MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2])
590 {
591   BLI_assert(r != vec);
592
593   r[0] = mat[0] * vec[0] + (-mat[1]) * vec[1];
594   r[1] = mat[1] * vec[0] + (+mat[0]) * vec[1];
595 }
596
597 /**
598  * Convenience function to get the projected depth of a position.
599  * This avoids creating a temporary 4D vector and multiplying it - only for the 4th component.
600  *
601  * Matches logic for:
602  *
603  * \code{.c}
604  * float co_4d[4] = {co[0], co[1], co[2], 1.0};
605  * mul_m4_v4(mat, co_4d);
606  * return co_4d[3];
607  * \endcode
608  */
609 MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3])
610 {
611   return (mat[0][3] * co[0]) + (mat[1][3] * co[1]) + (mat[2][3] * co[2]) + mat[3][3];
612 }
613
614 /**
615  * Has the effect of #mul_m3_v3(), on a single axis.
616  */
617 MINLINE float dot_m3_v3_row_x(const float M[3][3], const float a[3])
618 {
619   return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
620 }
621 MINLINE float dot_m3_v3_row_y(const float M[3][3], const float a[3])
622 {
623   return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
624 }
625 MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3])
626 {
627   return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
628 }
629
630 /**
631  * Has the effect of #mul_mat3_m4_v3(), on a single axis.
632  * (no adding translation)
633  */
634 MINLINE float dot_m4_v3_row_x(const float M[4][4], const float a[3])
635 {
636   return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
637 }
638 MINLINE float dot_m4_v3_row_y(const float M[4][4], const float a[3])
639 {
640   return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
641 }
642 MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3])
643 {
644   return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
645 }
646
647 MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
648 {
649   r[0] += a[0] * f;
650   r[1] += a[1] * f;
651 }
652
653 MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
654 {
655   r[0] += a[0] * f;
656   r[1] += a[1] * f;
657   r[2] += a[2] * f;
658 }
659
660 MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3])
661 {
662   r[0] += a[0] * b[0];
663   r[1] += a[1] * b[1];
664   r[2] += a[2] * b[2];
665 }
666
667 MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
668 {
669   r[0] = a[0] + b[0] * f;
670   r[1] = a[1] + b[1] * f;
671 }
672
673 MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
674 {
675   r[0] = a[0] + b[0] * f;
676   r[1] = a[1] + b[1] * f;
677   r[2] = a[2] + b[2] * f;
678 }
679
680 MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
681 {
682   r[0] = a[0] + b[0] * c[0];
683   r[1] = a[1] + b[1] * c[1];
684   r[2] = a[2] + b[2] * c[2];
685 }
686
687 MINLINE void madd_v3fl_v3fl_v3fl_v3i(float r[3],
688                                      const float a[3],
689                                      const float b[3],
690                                      const int c[3])
691 {
692   r[0] = a[0] + b[0] * (float)c[0];
693   r[1] = a[1] + b[1] * (float)c[1];
694   r[2] = a[2] + b[2] * (float)c[2];
695 }
696
697 MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
698 {
699   r[0] += a[0] * f;
700   r[1] += a[1] * f;
701   r[2] += a[2] * f;
702   r[3] += a[3] * f;
703 }
704
705 MINLINE void madd_v4_v4v4(float r[4], const float a[4], const float b[4])
706 {
707   r[0] += a[0] * b[0];
708   r[1] += a[1] * b[1];
709   r[2] += a[2] * b[2];
710   r[3] += a[3] * b[3];
711 }
712
713 MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
714 {
715   r[0] = v1[0] * v2[0];
716   r[1] = v1[1] * v2[1];
717   r[2] = v1[2] * v2[2];
718 }
719
720 MINLINE void mul_v2_v2v2(float r[2], const float a[2], const float b[2])
721 {
722   r[0] = a[0] * b[0];
723   r[1] = a[1] * b[1];
724 }
725
726 MINLINE void negate_v2(float r[2])
727 {
728   r[0] = -r[0];
729   r[1] = -r[1];
730 }
731
732 MINLINE void negate_v2_v2(float r[2], const float a[2])
733 {
734   r[0] = -a[0];
735   r[1] = -a[1];
736 }
737
738 MINLINE void negate_v3(float r[3])
739 {
740   r[0] = -r[0];
741   r[1] = -r[1];
742   r[2] = -r[2];
743 }
744
745 MINLINE void negate_v3_v3(float r[3], const float a[3])
746 {
747   r[0] = -a[0];
748   r[1] = -a[1];
749   r[2] = -a[2];
750 }
751
752 MINLINE void negate_v4(float r[4])
753 {
754   r[0] = -r[0];
755   r[1] = -r[1];
756   r[2] = -r[2];
757   r[3] = -r[3];
758 }
759
760 MINLINE void negate_v4_v4(float r[4], const float a[4])
761 {
762   r[0] = -a[0];
763   r[1] = -a[1];
764   r[2] = -a[2];
765   r[3] = -a[3];
766 }
767
768 /* could add more... */
769 MINLINE void negate_v3_short(short r[3])
770 {
771   r[0] = (short)-r[0];
772   r[1] = (short)-r[1];
773   r[2] = (short)-r[2];
774 }
775
776 MINLINE void negate_v3_db(double r[3])
777 {
778   r[0] = -r[0];
779   r[1] = -r[1];
780   r[2] = -r[2];
781 }
782
783 MINLINE void invert_v2(float r[2])
784 {
785   BLI_assert(!ELEM(0.0f, r[0], r[1]));
786   r[0] = 1.0f / r[0];
787   r[1] = 1.0f / r[1];
788 }
789
790 MINLINE void invert_v3(float r[3])
791 {
792   BLI_assert(!ELEM(0.0f, r[0], r[1], r[2]));
793   r[0] = 1.0f / r[0];
794   r[1] = 1.0f / r[1];
795   r[2] = 1.0f / r[2];
796 }
797
798 MINLINE void abs_v2(float r[2])
799 {
800   r[0] = fabsf(r[0]);
801   r[1] = fabsf(r[1]);
802 }
803
804 MINLINE void abs_v2_v2(float r[2], const float a[2])
805 {
806   r[0] = fabsf(a[0]);
807   r[1] = fabsf(a[1]);
808 }
809
810 MINLINE void abs_v3(float r[3])
811 {
812   r[0] = fabsf(r[0]);
813   r[1] = fabsf(r[1]);
814   r[2] = fabsf(r[2]);
815 }
816
817 MINLINE void abs_v3_v3(float r[3], const float a[3])
818 {
819   r[0] = fabsf(a[0]);
820   r[1] = fabsf(a[1]);
821   r[2] = fabsf(a[2]);
822 }
823
824 MINLINE void abs_v4(float r[4])
825 {
826   r[0] = fabsf(r[0]);
827   r[1] = fabsf(r[1]);
828   r[2] = fabsf(r[2]);
829   r[3] = fabsf(r[3]);
830 }
831
832 MINLINE void abs_v4_v4(float r[4], const float a[4])
833 {
834   r[0] = fabsf(a[0]);
835   r[1] = fabsf(a[1]);
836   r[2] = fabsf(a[2]);
837   r[3] = fabsf(a[3]);
838 }
839
840 MINLINE float dot_v2v2(const float a[2], const float b[2])
841 {
842   return a[0] * b[0] + a[1] * b[1];
843 }
844
845 MINLINE double dot_v2v2_db(const double a[2], const double b[2])
846 {
847   return a[0] * b[0] + a[1] * b[1];
848 }
849
850 MINLINE float dot_v3v3(const float a[3], const float b[3])
851 {
852   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
853 }
854
855 MINLINE float dot_v3v3v3(const float p[3], const float a[3], const float b[3])
856 {
857   float vec1[3], vec2[3];
858
859   sub_v3_v3v3(vec1, a, p);
860   sub_v3_v3v3(vec2, b, p);
861   if (is_zero_v3(vec1) || is_zero_v3(vec2)) {
862     return 0.0f;
863   }
864   return dot_v3v3(vec1, vec2);
865 }
866
867 MINLINE float dot_v4v4(const float a[4], const float b[4])
868 {
869   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
870 }
871
872 MINLINE double dot_v3db_v3fl(const double a[3], const float b[3])
873 {
874   return a[0] * (double)b[0] + a[1] * (double)b[1] + a[2] * (double)b[2];
875 }
876
877 MINLINE double dot_v3v3_db(const double a[3], const double b[3])
878 {
879   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
880 }
881
882 MINLINE float cross_v2v2(const float a[2], const float b[2])
883 {
884   return a[0] * b[1] - a[1] * b[0];
885 }
886
887 MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
888 {
889   BLI_assert(r != a && r != b);
890   r[0] = a[1] * b[2] - a[2] * b[1];
891   r[1] = a[2] * b[0] - a[0] * b[2];
892   r[2] = a[0] * b[1] - a[1] * b[0];
893 }
894
895 /* cross product suffers from severe precision loss when vectors are
896  * nearly parallel or opposite; doing the computation in double helps a lot */
897 MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3])
898 {
899   BLI_assert(r != a && r != b);
900   r[0] = (float)((double)a[1] * (double)b[2] - (double)a[2] * (double)b[1]);
901   r[1] = (float)((double)a[2] * (double)b[0] - (double)a[0] * (double)b[2]);
902   r[2] = (float)((double)a[0] * (double)b[1] - (double)a[1] * (double)b[0]);
903 }
904
905 MINLINE void cross_v3_v3v3_db(double r[3], const double a[3], const double b[3])
906 {
907   BLI_assert(r != a && r != b);
908   r[0] = a[1] * b[2] - a[2] * b[1];
909   r[1] = a[2] * b[0] - a[0] * b[2];
910   r[2] = a[0] * b[1] - a[1] * b[0];
911 }
912
913 /* Newell's Method */
914 /* excuse this fairly specific function,
915  * its used for polygon normals all over the place
916  * could use a better name */
917 MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
918 {
919   n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]);
920   n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]);
921   n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
922 }
923
924 MINLINE void star_m3_v3(float rmat[3][3], float a[3])
925 {
926   rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0;
927   rmat[0][1] = -a[2];
928   rmat[0][2] = a[1];
929   rmat[1][0] = a[2];
930   rmat[1][2] = -a[0];
931   rmat[2][0] = -a[1];
932   rmat[2][1] = a[0];
933 }
934
935 /*********************************** Length **********************************/
936
937 MINLINE float len_squared_v2(const float v[2])
938 {
939   return v[0] * v[0] + v[1] * v[1];
940 }
941
942 MINLINE float len_squared_v3(const float v[3])
943 {
944   return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
945 }
946
947 MINLINE float len_manhattan_v2(const float v[2])
948 {
949   return fabsf(v[0]) + fabsf(v[1]);
950 }
951
952 MINLINE int len_manhattan_v2_int(const int v[2])
953 {
954   return abs(v[0]) + abs(v[1]);
955 }
956
957 MINLINE float len_manhattan_v3(const float v[3])
958 {
959   return fabsf(v[0]) + fabsf(v[1]) + fabsf(v[2]);
960 }
961
962 MINLINE float len_v2(const float v[2])
963 {
964   return sqrtf(v[0] * v[0] + v[1] * v[1]);
965 }
966
967 MINLINE float len_v2v2(const float v1[2], const float v2[2])
968 {
969   float x, y;
970
971   x = v1[0] - v2[0];
972   y = v1[1] - v2[1];
973   return sqrtf(x * x + y * y);
974 }
975
976 MINLINE double len_v2v2_db(const double v1[2], const double v2[2])
977 {
978   double x, y;
979
980   x = v1[0] - v2[0];
981   y = v1[1] - v2[1];
982   return sqrt(x * x + y * y);
983 }
984
985 MINLINE float len_v2v2_int(const int v1[2], const int v2[2])
986 {
987   float x, y;
988
989   x = (float)(v1[0] - v2[0]);
990   y = (float)(v1[1] - v2[1]);
991   return sqrtf(x * x + y * y);
992 }
993
994 MINLINE float len_v3(const float a[3])
995 {
996   return sqrtf(dot_v3v3(a, a));
997 }
998
999 MINLINE float len_squared_v2v2(const float a[2], const float b[2])
1000 {
1001   float d[2];
1002
1003   sub_v2_v2v2(d, b, a);
1004   return dot_v2v2(d, d);
1005 }
1006
1007 MINLINE double len_squared_v2v2_db(const double a[2], const double b[2])
1008 {
1009   double d[2];
1010
1011   sub_v2_v2v2_db(d, b, a);
1012   return dot_v2v2_db(d, d);
1013 }
1014
1015 MINLINE float len_squared_v3v3(const float a[3], const float b[3])
1016 {
1017   float d[3];
1018
1019   sub_v3_v3v3(d, b, a);
1020   return dot_v3v3(d, d);
1021 }
1022
1023 MINLINE float len_squared_v4v4(const float a[4], const float b[4])
1024 {
1025   float d[4];
1026
1027   sub_v4_v4v4(d, b, a);
1028   return dot_v4v4(d, d);
1029 }
1030
1031 MINLINE float len_manhattan_v2v2(const float a[2], const float b[2])
1032 {
1033   float d[2];
1034
1035   sub_v2_v2v2(d, b, a);
1036   return len_manhattan_v2(d);
1037 }
1038
1039 MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2])
1040 {
1041   int d[2];
1042
1043   sub_v2_v2v2_int(d, b, a);
1044   return len_manhattan_v2_int(d);
1045 }
1046
1047 MINLINE float len_manhattan_v3v3(const float a[3], const float b[3])
1048 {
1049   float d[3];
1050
1051   sub_v3_v3v3(d, b, a);
1052   return len_manhattan_v3(d);
1053 }
1054
1055 MINLINE float len_v3v3(const float a[3], const float b[3])
1056 {
1057   float d[3];
1058
1059   sub_v3_v3v3(d, b, a);
1060   return len_v3(d);
1061 }
1062
1063 MINLINE float normalize_v2_v2_length(float r[2], const float a[2], const float unit_length)
1064 {
1065   float d = dot_v2v2(a, a);
1066
1067   if (d > 1.0e-35f) {
1068     d = sqrtf(d);
1069     mul_v2_v2fl(r, a, unit_length / d);
1070   }
1071   else {
1072     zero_v2(r);
1073     d = 0.0f;
1074   }
1075
1076   return d;
1077 }
1078 MINLINE float normalize_v2_v2(float r[2], const float a[2])
1079 {
1080   return normalize_v2_v2_length(r, a, 1.0f);
1081 }
1082
1083 MINLINE float normalize_v2(float n[2])
1084 {
1085   return normalize_v2_v2(n, n);
1086 }
1087
1088 MINLINE float normalize_v2_length(float n[2], const float unit_length)
1089 {
1090   return normalize_v2_v2_length(n, n, unit_length);
1091 }
1092
1093 MINLINE float normalize_v3_v3_length(float r[3], const float a[3], const float unit_length)
1094 {
1095   float d = dot_v3v3(a, a);
1096
1097   /* a larger value causes normalize errors in a
1098    * scaled down models with camera extreme close */
1099   if (d > 1.0e-35f) {
1100     d = sqrtf(d);
1101     mul_v3_v3fl(r, a, unit_length / d);
1102   }
1103   else {
1104     zero_v3(r);
1105     d = 0.0f;
1106   }
1107
1108   return d;
1109 }
1110 MINLINE float normalize_v3_v3(float r[3], const float a[3])
1111 {
1112   return normalize_v3_v3_length(r, a, 1.0f);
1113 }
1114
1115 MINLINE double normalize_v3_length_d(double n[3], const double unit_length)
1116 {
1117   double d = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
1118
1119   /* a larger value causes normalize errors in a
1120    * scaled down models with camera extreme close */
1121   if (d > 1.0e-35) {
1122     double mul;
1123
1124     d = sqrt(d);
1125     mul = unit_length / d;
1126
1127     n[0] *= mul;
1128     n[1] *= mul;
1129     n[2] *= mul;
1130   }
1131   else {
1132     n[0] = n[1] = n[2] = 0;
1133     d = 0.0;
1134   }
1135
1136   return d;
1137 }
1138 MINLINE double normalize_v3_d(double n[3])
1139 {
1140   return normalize_v3_length_d(n, 1.0);
1141 }
1142
1143 MINLINE float normalize_v3_length(float n[3], const float unit_length)
1144 {
1145   return normalize_v3_v3_length(n, n, unit_length);
1146 }
1147
1148 MINLINE float normalize_v3(float n[3])
1149 {
1150   return normalize_v3_v3(n, n);
1151 }
1152
1153 MINLINE void normal_float_to_short_v2(short out[2], const float in[2])
1154 {
1155   out[0] = (short)(in[0] * 32767.0f);
1156   out[1] = (short)(in[1] * 32767.0f);
1157 }
1158
1159 MINLINE void normal_short_to_float_v3(float out[3], const short in[3])
1160 {
1161   out[0] = in[0] * (1.0f / 32767.0f);
1162   out[1] = in[1] * (1.0f / 32767.0f);
1163   out[2] = in[2] * (1.0f / 32767.0f);
1164 }
1165
1166 MINLINE void normal_float_to_short_v3(short out[3], const float in[3])
1167 {
1168   out[0] = (short)(in[0] * 32767.0f);
1169   out[1] = (short)(in[1] * 32767.0f);
1170   out[2] = (short)(in[2] * 32767.0f);
1171 }
1172
1173 MINLINE void normal_float_to_short_v4(short out[4], const float in[4])
1174 {
1175   out[0] = (short)(in[0] * 32767.0f);
1176   out[1] = (short)(in[1] * 32767.0f);
1177   out[2] = (short)(in[2] * 32767.0f);
1178   out[3] = (short)(in[3] * 32767.0f);
1179 }
1180
1181 /********************************* Comparison ********************************/
1182
1183 MINLINE bool is_zero_v2(const float v[2])
1184 {
1185   return (v[0] == 0.0f && v[1] == 0.0f);
1186 }
1187
1188 MINLINE bool is_zero_v3(const float v[3])
1189 {
1190   return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f);
1191 }
1192
1193 MINLINE bool is_zero_v4(const float v[4])
1194 {
1195   return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f && v[3] == 0.0f);
1196 }
1197
1198 MINLINE bool is_one_v3(const float v[3])
1199 {
1200   return (v[0] == 1.0f && v[1] == 1.0f && v[2] == 1.0f);
1201 }
1202
1203 /** \name Vector Comparison
1204  *
1205  * \note use ``value <= limit``, so a limit of zero doesn't fail on an exact match.
1206  * \{ */
1207
1208 MINLINE bool equals_v2v2(const float v1[2], const float v2[2])
1209 {
1210   return ((v1[0] == v2[0]) && (v1[1] == v2[1]));
1211 }
1212
1213 MINLINE bool equals_v3v3(const float v1[3], const float v2[3])
1214 {
1215   return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]));
1216 }
1217
1218 MINLINE bool equals_v4v4(const float v1[4], const float v2[4])
1219 {
1220   return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]) && (v1[3] == v2[3]));
1221 }
1222
1223 MINLINE bool compare_v2v2(const float v1[2], const float v2[2], const float limit)
1224 {
1225   return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit));
1226 }
1227
1228 MINLINE bool compare_v3v3(const float v1[3], const float v2[3], const float limit)
1229 {
1230   return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit) &&
1231           compare_ff(v1[2], v2[2], limit));
1232 }
1233
1234 MINLINE bool compare_v4v4(const float v1[4], const float v2[4], const float limit)
1235 {
1236   return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit) &&
1237           compare_ff(v1[2], v2[2], limit) && compare_ff(v1[3], v2[3], limit));
1238 }
1239
1240 MINLINE bool compare_v2v2_relative(const float v1[2],
1241                                    const float v2[2],
1242                                    const float limit,
1243                                    const int max_ulps)
1244 {
1245   return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
1246           compare_ff_relative(v1[1], v2[1], limit, max_ulps));
1247 }
1248
1249 MINLINE bool compare_v3v3_relative(const float v1[3],
1250                                    const float v2[3],
1251                                    const float limit,
1252                                    const int max_ulps)
1253 {
1254   return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
1255           compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
1256           compare_ff_relative(v1[2], v2[2], limit, max_ulps));
1257 }
1258
1259 MINLINE bool compare_v4v4_relative(const float v1[4],
1260                                    const float v2[4],
1261                                    const float limit,
1262                                    const int max_ulps)
1263 {
1264   return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
1265           compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
1266           compare_ff_relative(v1[2], v2[2], limit, max_ulps) &&
1267           compare_ff_relative(v1[3], v2[3], limit, max_ulps));
1268 }
1269
1270 MINLINE bool compare_len_v3v3(const float v1[3], const float v2[3], const float limit)
1271 {
1272   float d[3];
1273   sub_v3_v3v3(d, v1, v2);
1274   return (dot_v3v3(d, d) <= (limit * limit));
1275 }
1276
1277 /**
1278  * <pre>
1279  *        + l1
1280  *        |
1281  * neg <- | -> pos
1282  *        |
1283  *        + l2
1284  * </pre>
1285  *
1286  * \return Positive value when 'pt' is left-of-line
1287  * (looking from 'l1' -> 'l2').
1288  */
1289 MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2])
1290 {
1291   return (((l1[0] - pt[0]) * (l2[1] - pt[1])) - ((l2[0] - pt[0]) * (l1[1] - pt[1])));
1292 }
1293
1294 /** \} */
1295
1296 #endif /* __MATH_VECTOR_INLINE_C__ */