019dede07fab0e87435449710e7e719cddf5549b
[blender.git] / intern / cycles / util / util_math.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #ifndef __UTIL_MATH_H__
20 #define __UTIL_MATH_H__
21
22 /* Math
23  *
24  * Basic math functions on scalar and vector types. This header is used by
25  * both the kernel code when compiled as C++, and other C++ non-kernel code. */
26
27 #ifndef __KERNEL_OPENCL__
28
29 #define _USE_MATH_DEFINES
30
31 #include <float.h>
32 #include <math.h>
33 #include <stdio.h>
34
35 #endif
36
37 #include "util_types.h"
38
39 CCL_NAMESPACE_BEGIN
40
41 /* Float Pi variations */
42
43 #ifndef M_PI_F
44 #define M_PI_F          ((float)3.14159265358979323846264338327950288)
45 #endif
46 #ifndef M_PI_2_F
47 #define M_PI_2_F        ((float)1.57079632679489661923132169163975144)
48 #endif
49 #ifndef M_PI_4_F
50 #define M_PI_4_F        ((float)0.785398163397448309615660845819875721)
51 #endif
52 #ifndef M_1_PI_F
53 #define M_1_PI_F        ((float)0.318309886183790671537767526745028724)
54 #endif
55 #ifndef M_2_PI_F
56 #define M_2_PI_F        ((float)0.636619772367581343075535053490057448)
57 #endif
58
59 /* Scalar */
60
61 #ifdef _WIN32
62
63 #ifndef __KERNEL_GPU__
64
65 #if(!defined(FREE_WINDOWS))
66 #define copysignf(x, y) ((float)_copysign(x, y))
67 #define hypotf(x, y) _hypotf(x, y)
68 #define isnan(x) _isnan(x)
69 #define isfinite(x) _finite(x)
70 #endif
71
72 #endif
73
74 #ifndef __KERNEL_OPENCL__
75
76 __device_inline float fmaxf(float a, float b)
77 {
78         return (a > b)? a: b;
79 }
80
81 __device_inline float fminf(float a, float b)
82 {
83         return (a < b)? a: b;
84 }
85
86 #endif
87
88 #endif
89
90 #ifndef __KERNEL_GPU__
91
92 __device_inline int max(int a, int b)
93 {
94         return (a > b)? a: b;
95 }
96
97 __device_inline int min(int a, int b)
98 {
99         return (a < b)? a: b;
100 }
101
102 __device_inline float max(float a, float b)
103 {
104         return (a > b)? a: b;
105 }
106
107 __device_inline float min(float a, float b)
108 {
109         return (a < b)? a: b;
110 }
111
112 __device_inline double max(double a, double b)
113 {
114         return (a > b)? a: b;
115 }
116
117 __device_inline double min(double a, double b)
118 {
119         return (a < b)? a: b;
120 }
121
122 #endif
123
124 __device_inline float min4(float a, float b, float c, float d)
125 {
126         return min(min(a, b), min(c, d));
127 }
128
129 __device_inline float max4(float a, float b, float c, float d)
130 {
131         return max(max(a, b), max(c, d));
132 }
133
134 #ifndef __KERNEL_OPENCL__
135
136 __device_inline int clamp(int a, int mn, int mx)
137 {
138         return min(max(a, mn), mx);
139 }
140
141 __device_inline float clamp(float a, float mn, float mx)
142 {
143         return min(max(a, mn), mx);
144 }
145
146 #endif
147
148 __device_inline float signf(float f)
149 {
150         return (f < 0.0f)? -1.0f: 1.0f;
151 }
152
153 __device_inline float nonzerof(float f, float eps)
154 {
155         if(fabsf(f) < eps)
156                 return signf(f)*eps;
157         else
158                 return f;
159 }
160
161 /* Float2 Vector */
162
163 #ifndef __KERNEL_OPENCL__
164
165 __device_inline bool is_zero(const float2 a)
166 {
167         return (a.x == 0.0f && a.y == 0.0f);
168 }
169
170 #endif
171
172 #ifndef __KERNEL_OPENCL__
173
174 __device_inline float average(const float2 a)
175 {
176         return (a.x + a.y)*(1.0f/2.0f);
177 }
178
179 #endif
180
181 #ifndef __KERNEL_OPENCL__
182
183 __device_inline float2 operator-(const float2 a)
184 {
185         float2 r = {-a.x, -a.y};
186         return r;
187 }
188
189 __device_inline float2 operator*(const float2 a, const float2 b)
190 {
191         float2 r = {a.x*b.x, a.y*b.y};
192         return r;
193 }
194
195 __device_inline float2 operator*(const float2 a, float f)
196 {
197         float2 r = {a.x*f, a.y*f};
198         return r;
199 }
200
201 __device_inline float2 operator*(float f, const float2 a)
202 {
203         float2 r = {a.x*f, a.y*f};
204         return r;
205 }
206
207 __device_inline float2 operator/(float f, const float2 a)
208 {
209         float2 r = {f/a.x, f/a.y};
210         return r;
211 }
212
213 __device_inline float2 operator/(const float2 a, float f)
214 {
215         float invf = 1.0f/f;
216         float2 r = {a.x*invf, a.y*invf};
217         return r;
218 }
219
220 __device_inline float2 operator/(const float2 a, const float2 b)
221 {
222         float2 r = {a.x/b.x, a.y/b.y};
223         return r;
224 }
225
226 __device_inline float2 operator+(const float2 a, const float2 b)
227 {
228         float2 r = {a.x+b.x, a.y+b.y};
229         return r;
230 }
231
232 __device_inline float2 operator-(const float2 a, const float2 b)
233 {
234         float2 r = {a.x-b.x, a.y-b.y};
235         return r;
236 }
237
238 __device_inline float2 operator+=(float2& a, const float2 b)
239 {
240         a.x += b.x;
241         a.y += b.y;
242         return a;
243 }
244
245 __device_inline float2 operator*=(float2& a, const float2 b)
246 {
247         a.x *= b.x;
248         a.y *= b.y;
249         return a;
250 }
251
252 __device_inline float2 operator*=(float2& a, float f)
253 {
254         a.x *= f;
255         a.y *= f;
256         return a;
257 }
258
259 __device_inline float2 operator/=(float2& a, const float2 b)
260 {
261         a.x /= b.x;
262         a.y /= b.y;
263         return a;
264 }
265
266 __device_inline float2 operator/=(float2& a, float f)
267 {
268         float invf = 1.0f/f;
269         a.x *= invf;
270         a.y *= invf;
271         return a;
272 }
273
274
275 __device_inline float dot(const float2 a, const float2 b)
276 {
277         return a.x*b.x + a.y*b.y;
278 }
279
280 __device_inline float cross(const float2 a, const float2 b)
281 {
282         return (a.x*b.y - a.y*b.x);
283 }
284
285 #endif
286
287 #ifndef __KERNEL_OPENCL__
288
289 __device_inline float len(const float2 a)
290 {
291         return sqrtf(dot(a, a));
292 }
293
294 __device_inline float2 normalize(const float2 a)
295 {
296         return a/len(a);
297 }
298
299 __device_inline float2 normalize_len(const float2 a, float *t)
300 {
301         *t = len(a);
302         return a/(*t);
303 }
304
305 __device_inline bool operator==(const float2 a, const float2 b)
306 {
307         return (a.x == b.x && a.y == b.y);
308 }
309
310 __device_inline bool operator!=(const float2 a, const float2 b)
311 {
312         return !(a == b);
313 }
314
315 __device_inline float2 min(float2 a, float2 b)
316 {
317         float2 r = {min(a.x, b.x), min(a.y, b.y)};
318         return r;
319 }
320
321 __device_inline float2 max(float2 a, float2 b)
322 {
323         float2 r = {max(a.x, b.x), max(a.y, b.y)};
324         return r;
325 }
326
327 __device_inline float2 clamp(float2 a, float2 mn, float2 mx)
328 {
329         return min(max(a, mn), mx);
330 }
331
332 __device_inline float2 fabs(float2 a)
333 {
334         return make_float2(fabsf(a.x), fabsf(a.y));
335 }
336
337 __device_inline float2 as_float2(const float4 a)
338 {
339         return make_float2(a.x, a.y);
340 }
341
342 #endif
343
344 #ifndef __KERNEL_GPU__
345
346 __device_inline void print_float2(const char *label, const float2& a)
347 {
348         printf("%s: %.8f %.8f\n", label, a.x, a.y);
349 }
350
351 #endif
352
353 #ifndef __KERNEL_OPENCL__
354
355 __device_inline float2 interp(float2 a, float2 b, float t)
356 {
357         return a + t*(b - a);
358 }
359
360 #endif
361
362 /* Float3 Vector */
363
364 __device_inline bool is_zero(const float3 a)
365 {
366         return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f);
367 }
368
369 __device_inline float average(const float3 a)
370 {
371         return (a.x + a.y + a.z)*(1.0f/3.0f);
372 }
373
374 #ifndef __KERNEL_OPENCL__
375
376 __device_inline float3 operator-(const float3 a)
377 {
378         float3 r = make_float3(-a.x, -a.y, -a.z);
379         return r;
380 }
381
382 __device_inline float3 operator*(const float3 a, const float3 b)
383 {
384         float3 r = make_float3(a.x*b.x, a.y*b.y, a.z*b.z);
385         return r;
386 }
387
388 __device_inline float3 operator*(const float3 a, float f)
389 {
390         float3 r = make_float3(a.x*f, a.y*f, a.z*f);
391         return r;
392 }
393
394 __device_inline float3 operator*(float f, const float3 a)
395 {
396         float3 r = make_float3(a.x*f, a.y*f, a.z*f);
397         return r;
398 }
399
400 __device_inline float3 operator/(float f, const float3 a)
401 {
402         float3 r = make_float3(f/a.x, f/a.y, f/a.z);
403         return r;
404 }
405
406 __device_inline float3 operator/(const float3 a, float f)
407 {
408         float invf = 1.0f/f;
409         float3 r = make_float3(a.x*invf, a.y*invf, a.z*invf);
410         return r;
411 }
412
413 __device_inline float3 operator/(const float3 a, const float3 b)
414 {
415         float3 r = make_float3(a.x/b.x, a.y/b.y, a.z/b.z);
416         return r;
417 }
418
419 __device_inline float3 operator+(const float3 a, const float3 b)
420 {
421         float3 r = make_float3(a.x+b.x, a.y+b.y, a.z+b.z);
422         return r;
423 }
424
425 __device_inline float3 operator-(const float3 a, const float3 b)
426 {
427         float3 r = make_float3(a.x-b.x, a.y-b.y, a.z-b.z);
428         return r;
429 }
430
431 __device_inline float3 operator+=(float3& a, const float3 b)
432 {
433         a.x += b.x;
434         a.y += b.y;
435         a.z += b.z;
436         return a;
437 }
438
439 __device_inline float3 operator*=(float3& a, const float3 b)
440 {
441         a.x *= b.x;
442         a.y *= b.y;
443         a.z *= b.z;
444         return a;
445 }
446
447 __device_inline float3 operator*=(float3& a, float f)
448 {
449         a.x *= f;
450         a.y *= f;
451         a.z *= f;
452         return a;
453 }
454
455 __device_inline float3 operator/=(float3& a, const float3 b)
456 {
457         a.x /= b.x;
458         a.y /= b.y;
459         a.z /= b.z;
460         return a;
461 }
462
463 __device_inline float3 operator/=(float3& a, float f)
464 {
465         float invf = 1.0f/f;
466         a.x *= invf;
467         a.y *= invf;
468         a.z *= invf;
469         return a;
470 }
471
472 __device_inline float dot(const float3 a, const float3 b)
473 {
474         return a.x*b.x + a.y*b.y + a.z*b.z;
475 }
476
477 __device_inline float3 cross(const float3 a, const float3 b)
478 {
479         float3 r = make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
480         return r;
481 }
482
483 #endif
484
485 __device_inline float len(const float3 a)
486 {
487         return sqrtf(dot(a, a));
488 }
489
490 #ifndef __KERNEL_OPENCL__
491
492 __device_inline float3 normalize(const float3 a)
493 {
494         return a/len(a);
495 }
496
497 #endif
498
499 __device_inline float3 normalize_len(const float3 a, float *t)
500 {
501         *t = len(a);
502         return a/(*t);
503 }
504
505 #ifndef __KERNEL_OPENCL__
506
507 __device_inline bool operator==(const float3 a, const float3 b)
508 {
509         return (a.x == b.x && a.y == b.y && a.z == b.z);
510 }
511
512 __device_inline bool operator!=(const float3 a, const float3 b)
513 {
514         return !(a == b);
515 }
516
517 __device_inline float3 min(float3 a, float3 b)
518 {
519         float3 r = make_float3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
520         return r;
521 }
522
523 __device_inline float3 max(float3 a, float3 b)
524 {
525         float3 r = make_float3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
526         return r;
527 }
528
529 __device_inline float3 clamp(float3 a, float3 mn, float3 mx)
530 {
531         return min(max(a, mn), mx);
532 }
533
534 __device_inline float3 fabs(float3 a)
535 {
536         return make_float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
537 }
538
539 #endif
540
541 __device_inline float3 float4_to_float3(const float4 a)
542 {
543         return make_float3(a.x, a.y, a.z);
544 }
545
546 __device_inline float4 float3_to_float4(const float3 a)
547 {
548         return make_float4(a.x, a.y, a.z, 1.0f);
549 }
550
551 #ifndef __KERNEL_GPU__
552
553 __device_inline void print_float3(const char *label, const float3& a)
554 {
555         printf("%s: %.8f %.8f %.8f\n", label, a.x, a.y, a.z);
556 }
557
558 #endif
559
560 __device_inline float3 interp(float3 a, float3 b, float t)
561 {
562         return a + t*(b - a);
563 }
564
565 /* Float4 Vector */
566
567 #ifndef __KERNEL_OPENCL__
568
569 __device_inline bool is_zero(const float4& a)
570 {
571         return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
572 }
573
574 __device_inline float average(const float4& a)
575 {
576         return (a.x + a.y + a.z + a.w)*(1.0f/4.0f);
577 }
578
579 __device_inline float4 operator-(const float4& a)
580 {
581         float4 r = {-a.x, -a.y, -a.z, -a.w};
582         return r;
583 }
584
585 __device_inline float4 operator*(const float4& a, const float4& b)
586 {
587         float4 r = {a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w};
588         return r;
589 }
590
591 __device_inline float4 operator*(const float4& a, float f)
592 {
593         float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
594         return r;
595 }
596
597 __device_inline float4 operator*(float f, const float4& a)
598 {
599         float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
600         return r;
601 }
602
603 __device_inline float4 operator/(const float4& a, float f)
604 {
605         float invf = 1.0f/f;
606         float4 r = {a.x*invf, a.y*invf, a.z*invf, a.w*invf};
607         return r;
608 }
609
610 __device_inline float4 operator/(const float4& a, const float4& b)
611 {
612         float4 r = {a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w};
613         return r;
614 }
615
616 __device_inline float4 operator+(const float4& a, const float4& b)
617 {
618         float4 r = {a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w};
619         return r;
620 }
621
622 __device_inline float4 operator-(const float4& a, const float4& b)
623 {
624         float4 r = {a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w};
625         return r;
626 }
627
628 __device_inline float4 operator+=(float4& a, const float4& b)
629 {
630         a.x += b.x;
631         a.y += b.y;
632         a.z += b.z;
633         a.w += b.w;
634         return a;
635 }
636
637 __device_inline float4 operator*=(float4& a, const float4& b)
638 {
639         a.x *= b.x;
640         a.y *= b.y;
641         a.z *= b.z;
642         a.w *= b.w;
643         return a;
644 }
645
646 __device_inline float4 operator/=(float4& a, float f)
647 {
648         float invf = 1.0f/f;
649         a.x *= invf;
650         a.y *= invf;
651         a.z *= invf;
652         a.w *= invf;
653         return a;
654 }
655
656 __device_inline float dot(const float4& a, const float4& b)
657 {
658         return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
659 }
660
661 __device_inline float4 cross(const float4& a, const float4& b)
662 {
663         float4 r = {a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x, 0.0f};
664         return r;
665 }
666
667 __device_inline float4 min(float4 a, float4 b)
668 {
669         return make_float4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
670 }
671
672 __device_inline float4 max(float4 a, float4 b)
673 {
674         return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
675 }
676
677 #endif
678
679 #ifndef __KERNEL_GPU__
680
681 __device_inline void print_float4(const char *label, const float4& a)
682 {
683         printf("%s: %.8f %.8f %.8f %.8f\n", label, a.x, a.y, a.z, a.w);
684 }
685
686 #endif
687
688 /* Int3 */
689
690 #ifndef __KERNEL_OPENCL__
691
692 __device_inline int3 max(int3 a, int3 b)
693 {
694         int3 r = {max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)};
695         return r;
696 }
697
698 __device_inline int3 clamp(const int3& a, int mn, int mx)
699 {
700         int3 r = {clamp(a.x, mn, mx), clamp(a.y, mn, mx), clamp(a.z, mn, mx)};
701         return r;
702 }
703
704 __device_inline int3 clamp(const int3& a, int3& mn, int mx)
705 {
706         int3 r = {clamp(a.x, mn.x, mx), clamp(a.y, mn.y, mx), clamp(a.z, mn.z, mx)};
707         return r;
708 }
709
710 #endif
711
712 #ifndef __KERNEL_GPU__
713
714 __device_inline void print_int3(const char *label, const int3& a)
715 {
716         printf("%s: %d %d %d\n", label, a.x, a.y, a.z);
717 }
718
719 #endif
720
721 /* Int4 */
722
723 #ifndef __KERNEL_OPENCL__
724
725 __device_inline int4 operator>=(float4 a, float4 b)
726 {
727         return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
728 }
729
730 #endif
731
732 #ifndef __KERNEL_GPU__
733
734 __device_inline void print_int4(const char *label, const int4& a)
735 {
736         printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w);
737 }
738
739 #endif
740
741 /* Int/Float conversion */
742
743 #ifndef __KERNEL_OPENCL__
744
745 __device_inline unsigned int as_uint(float f)
746 {
747         union { unsigned int i; float f; } u;
748         u.f = f;
749         return u.i;
750 }
751
752 __device_inline int __float_as_int(float f)
753 {
754         union { int i; float f; } u;
755         u.f = f;
756         return u.i;
757 }
758
759 __device_inline float __int_as_float(int i)
760 {
761         union { int i; float f; } u;
762         u.i = i;
763         return u.f;
764 }
765
766 __device_inline uint __float_as_uint(float f)
767 {
768         union { uint i; float f; } u;
769         u.f = f;
770         return u.i;
771 }
772
773 __device_inline float __uint_as_float(uint i)
774 {
775         union { uint i; float f; } u;
776         u.i = i;
777         return u.f;
778 }
779
780 /* Interpolation */
781
782 template<class A, class B> A lerp(const A& a, const A& b, const B& t)
783 {
784         return (A)(a * ((B)1 - t) + b * t);
785 }
786
787 /* Triangle */
788
789 __device_inline float triangle_area(const float3 v1, const float3 v2, const float3 v3)
790 {
791         return len(cross(v3 - v2, v1 - v2))*0.5f;
792 }
793
794 #endif
795
796 /* Orthonormal vectors */
797
798 __device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b)
799 {
800         if(N.x != N.y || N.x != N.z)
801                 *a = make_float3(N.z-N.y, N.x-N.z, N.y-N.x);  //(1,1,1)x N
802         else
803                 *a = make_float3(N.z-N.y, N.x+N.z, -N.y-N.x);  //(-1,1,1)x N
804
805         *a = normalize(*a);
806         *b = cross(N, *a);
807 }
808
809 /* Color division */
810
811 __device_inline float3 safe_divide_color(float3 a, float3 b)
812 {
813         float x, y, z;
814
815         x = (b.x != 0.0f)? a.x/b.x: 0.0f;
816         y = (b.y != 0.0f)? a.y/b.y: 0.0f;
817         z = (b.z != 0.0f)? a.z/b.z: 0.0f;
818
819         return make_float3(x, y, z);
820 }
821
822 CCL_NAMESPACE_END
823
824 #endif /* __UTIL_MATH_H__ */
825