Cycles: svn merge -r39870:r40266 https://svn.blender.org/svnroot/bf-blender/trunk...
[blender-staging.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 #ifndef M_PI_F
42 #define M_PI_F          ((float)3.14159265358979323846264338327950288)
43 #endif
44 #ifndef M_PI_2_F
45 #define M_PI_2_F        ((float)1.57079632679489661923132169163975144)
46 #endif
47 #ifndef M_PI_4_F
48 #define M_PI_4_F        ((float)0.785398163397448309615660845819875721)
49 #endif
50 #ifndef M_1_PI_F
51 #define M_1_PI_F        ((float)0.318309886183790671537767526745028724)
52 #endif
53 #ifndef M_2_PI_F
54 #define M_2_PI_F        ((float)0.636619772367581343075535053490057448)
55 #endif
56
57 /* Scalar */
58
59 #ifdef _WIN32
60
61 #ifndef __KERNEL_GPU__
62
63 #if(!defined(FREE_WINDOWS))
64 #define copysignf(x, y) ((float)_copysign(x, y))
65 #define hypotf(x, y) _hypotf(x, y)
66 #endif
67
68 #endif
69
70 __device_inline float fmaxf(float a, float b)
71 {
72         return (a > b)? a: b;
73 }
74
75 __device_inline float fminf(float a, float b)
76 {
77         return (a < b)? a: b;
78 }
79
80 #endif
81
82 #ifndef __KERNEL_GPU__
83
84 __device_inline int max(int a, int b)
85 {
86         return (a > b)? a: b;
87 }
88
89 __device_inline int min(int a, int b)
90 {
91         return (a < b)? a: b;
92 }
93
94 __device_inline float max(float a, float b)
95 {
96         return (a > b)? a: b;
97 }
98
99 __device_inline float min(float a, float b)
100 {
101         return (a < b)? a: b;
102 }
103
104 __device_inline double max(double a, double b)
105 {
106         return (a > b)? a: b;
107 }
108
109 __device_inline double min(double a, double b)
110 {
111         return (a < b)? a: b;
112 }
113
114 #endif
115
116 __device_inline float min4(float a, float b, float c, float d)
117 {
118         return min(min(min(a, b), c), d);
119 }
120
121 __device_inline float max4(float a, float b, float c, float d)
122 {
123         return max(max(max(a, b), c), d);
124 }
125
126 #ifndef __KERNEL_OPENCL__
127
128 __device_inline int clamp(int a, int mn, int mx)
129 {
130         return min(max(a, mn), mx);
131 }
132
133 __device_inline float clamp(float a, float mn, float mx)
134 {
135         return min(max(a, mn), mx);
136 }
137
138 #endif
139
140 __device_inline float signf(float f)
141 {
142         return (f < 0.0f)? -1.0f: 1.0f;
143 }
144
145 __device_inline float nonzerof(float f, float eps)
146 {
147         if(fabsf(f) < eps)
148                 return signf(f)*eps;
149         else
150                 return f;
151 }
152
153 /* Float2 Vector */
154
155 #ifndef __KERNEL_OPENCL__
156
157 __device_inline bool is_zero(const float2 a)
158 {
159         return (a.x == 0.0f && a.y == 0.0f);
160 }
161
162 #endif
163
164 #ifndef __KERNEL_OPENCL__
165
166 __device_inline float average(const float2 a)
167 {
168         return (a.x + a.y)*(1.0f/2.0f);
169 }
170
171 #endif
172
173 #ifndef __KERNEL_OPENCL__
174
175 __device_inline float2 operator-(const float2 a)
176 {
177         float2 r = {-a.x, -a.y};
178         return r;
179 }
180
181 __device_inline float2 operator*(const float2 a, const float2 b)
182 {
183         float2 r = {a.x*b.x, a.y*b.y};
184         return r;
185 }
186
187 __device_inline float2 operator*(const float2 a, float f)
188 {
189         float2 r = {a.x*f, a.y*f};
190         return r;
191 }
192
193 __device_inline float2 operator*(float f, const float2 a)
194 {
195         float2 r = {a.x*f, a.y*f};
196         return r;
197 }
198
199 __device_inline float2 operator/(float f, const float2 a)
200 {
201         float2 r = {f/a.x, f/a.y};
202         return r;
203 }
204
205 __device_inline float2 operator/(const float2 a, float f)
206 {
207         float invf = 1.0f/f;
208         float2 r = {a.x*invf, a.y*invf};
209         return r;
210 }
211
212 __device_inline float2 operator/(const float2 a, const float2 b)
213 {
214         float2 r = {a.x/b.x, a.y/b.y};
215         return r;
216 }
217
218 __device_inline float2 operator+(const float2 a, const float2 b)
219 {
220         float2 r = {a.x+b.x, a.y+b.y};
221         return r;
222 }
223
224 __device_inline float2 operator-(const float2 a, const float2 b)
225 {
226         float2 r = {a.x-b.x, a.y-b.y};
227         return r;
228 }
229
230 __device_inline float2 operator+=(float2& a, const float2 b)
231 {
232         a.x += b.x;
233         a.y += b.y;
234         return a;
235 }
236
237 __device_inline float2 operator*=(float2& a, const float2 b)
238 {
239         a.x *= b.x;
240         a.y *= b.y;
241         return a;
242 }
243
244 __device_inline float2 operator*=(float2& a, float f)
245 {
246         a.x *= f;
247         a.y *= f;
248         return a;
249 }
250
251 __device_inline float2 operator/=(float2& a, const float2 b)
252 {
253         a.x /= b.x;
254         a.y /= b.y;
255         return a;
256 }
257
258 __device_inline float2 operator/=(float2& a, float f)
259 {
260         float invf = 1.0f/f;
261         a.x *= invf;
262         a.y *= invf;
263         return a;
264 }
265
266
267 __device_inline float dot(const float2 a, const float2 b)
268 {
269         return a.x*b.x + a.y*b.y;
270 }
271
272 __device_inline float cross(const float2 a, const float2 b)
273 {
274         return (a.x*b.y - a.y*b.x);
275 }
276
277 #endif
278
279 #ifndef __KERNEL_OPENCL__
280
281 __device_inline float len(const float2 a)
282 {
283         return sqrtf(dot(a, a));
284 }
285
286 __device_inline float2 normalize(const float2 a)
287 {
288         return a/len(a);
289 }
290
291 __device_inline float2 normalize_len(const float2 a, float *t)
292 {
293         *t = len(a);
294         return a/(*t);
295 }
296
297 __device_inline bool operator==(const float2 a, const float2 b)
298 {
299         return (a.x == b.x && a.y == b.y);
300 }
301
302 __device_inline bool operator!=(const float2 a, const float2 b)
303 {
304         return !(a == b);
305 }
306
307 __device_inline float2 min(float2 a, float2 b)
308 {
309         float2 r = {min(a.x, b.x), min(a.y, b.y)};
310         return r;
311 }
312
313 __device_inline float2 max(float2 a, float2 b)
314 {
315         float2 r = {max(a.x, b.x), max(a.y, b.y)};
316         return r;
317 }
318
319 __device_inline float2 clamp(float2 a, float2 mn, float2 mx)
320 {
321         return min(max(a, mn), mx);
322 }
323
324 __device_inline float2 fabs(float2 a)
325 {
326         return make_float2(fabsf(a.x), fabsf(a.y));
327 }
328
329 __device_inline float2 as_float2(const float4 a)
330 {
331         return make_float2(a.x, a.y);
332 }
333
334 #endif
335
336 #ifndef __KERNEL_GPU__
337
338 __device_inline void print_float2(const char *label, const float2& a)
339 {
340         printf("%s: %.8f %.8f\n", label, a.x, a.y);
341 }
342
343 #endif
344
345 #ifndef __KERNEL_OPENCL__
346
347 __device_inline float2 interp(float2 a, float2 b, float t)
348 {
349         return a + t*(b - a);
350 }
351
352 #endif
353
354 /* Float3 Vector */
355
356 __device_inline bool is_zero(const float3 a)
357 {
358         return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f);
359 }
360
361 __device_inline float average(const float3 a)
362 {
363         return (a.x + a.y + a.z)*(1.0f/3.0f);
364 }
365
366 #ifndef __KERNEL_OPENCL__
367
368 __device_inline float3 operator-(const float3 a)
369 {
370         float3 r = make_float3(-a.x, -a.y, -a.z);
371         return r;
372 }
373
374 __device_inline float3 operator*(const float3 a, const float3 b)
375 {
376         float3 r = make_float3(a.x*b.x, a.y*b.y, a.z*b.z);
377         return r;
378 }
379
380 __device_inline float3 operator*(const float3 a, float f)
381 {
382         float3 r = make_float3(a.x*f, a.y*f, a.z*f);
383         return r;
384 }
385
386 __device_inline float3 operator*(float f, const float3 a)
387 {
388         float3 r = make_float3(a.x*f, a.y*f, a.z*f);
389         return r;
390 }
391
392 __device_inline float3 operator/(float f, const float3 a)
393 {
394         float3 r = make_float3(f/a.x, f/a.y, f/a.z);
395         return r;
396 }
397
398 __device_inline float3 operator/(const float3 a, float f)
399 {
400         float invf = 1.0f/f;
401         float3 r = make_float3(a.x*invf, a.y*invf, a.z*invf);
402         return r;
403 }
404
405 __device_inline float3 operator/(const float3 a, const float3 b)
406 {
407         float3 r = make_float3(a.x/b.x, a.y/b.y, a.z/b.z);
408         return r;
409 }
410
411 __device_inline float3 operator+(const float3 a, const float3 b)
412 {
413         float3 r = make_float3(a.x+b.x, a.y+b.y, a.z+b.z);
414         return r;
415 }
416
417 __device_inline float3 operator-(const float3 a, const float3 b)
418 {
419         float3 r = make_float3(a.x-b.x, a.y-b.y, a.z-b.z);
420         return r;
421 }
422
423 __device_inline float3 operator+=(float3& a, const float3 b)
424 {
425         a.x += b.x;
426         a.y += b.y;
427         a.z += b.z;
428         return a;
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, float f)
440 {
441         a.x *= f;
442         a.y *= f;
443         a.z *= f;
444         return a;
445 }
446
447 __device_inline float3 operator/=(float3& a, const float3 b)
448 {
449         a.x /= b.x;
450         a.y /= b.y;
451         a.z /= b.z;
452         return a;
453 }
454
455 __device_inline float3 operator/=(float3& a, float f)
456 {
457         float invf = 1.0f/f;
458         a.x *= invf;
459         a.y *= invf;
460         a.z *= invf;
461         return a;
462 }
463
464 __device_inline float dot(const float3 a, const float3 b)
465 {
466         return a.x*b.x + a.y*b.y + a.z*b.z;
467 }
468
469 __device_inline float3 cross(const float3 a, const float3 b)
470 {
471         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);
472         return r;
473 }
474
475 #endif
476
477 __device_inline float len(const float3 a)
478 {
479         return sqrtf(dot(a, a));
480 }
481
482 #ifndef __KERNEL_OPENCL__
483
484 __device_inline float3 normalize(const float3 a)
485 {
486         return a/len(a);
487 }
488
489 #endif
490
491 __device_inline float3 normalize_len(const float3 a, float *t)
492 {
493         *t = len(a);
494         return a/(*t);
495 }
496
497 #ifndef __KERNEL_OPENCL__
498
499 __device_inline bool operator==(const float3 a, const float3 b)
500 {
501         return (a.x == b.x && a.y == b.y && a.z == b.z);
502 }
503
504 __device_inline bool operator!=(const float3 a, const float3 b)
505 {
506         return !(a == b);
507 }
508
509 __device_inline float3 min(float3 a, float3 b)
510 {
511         float3 r = make_float3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
512         return r;
513 }
514
515 __device_inline float3 max(float3 a, float3 b)
516 {
517         float3 r = make_float3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
518         return r;
519 }
520
521 __device_inline float3 clamp(float3 a, float3 mn, float3 mx)
522 {
523         return min(max(a, mn), mx);
524 }
525
526 __device_inline float3 fabs(float3 a)
527 {
528         return make_float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
529 }
530
531 #endif
532
533 __device_inline float3 float4_to_float3(const float4 a)
534 {
535         return make_float3(a.x, a.y, a.z);
536 }
537
538 #ifndef __KERNEL_GPU__
539
540 __device_inline void print_float3(const char *label, const float3& a)
541 {
542         printf("%s: %.8f %.8f %.8f\n", label, a.x, a.y, a.z);
543 }
544
545 #endif
546
547 __device_inline float3 interp(float3 a, float3 b, float t)
548 {
549         return a + t*(b - a);
550 }
551
552 /* Float4 Vector */
553
554 #ifndef __KERNEL_OPENCL__
555
556 __device_inline bool is_zero(const float4& a)
557 {
558         return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
559 }
560
561 __device_inline float average(const float4& a)
562 {
563         return (a.x + a.y + a.z + a.w)*(1.0f/4.0f);
564 }
565
566 __device_inline float4 operator-(const float4& a)
567 {
568         float4 r = {-a.x, -a.y, -a.z, -a.w};
569         return r;
570 }
571
572 __device_inline float4 operator*(const float4& a, const float4& b)
573 {
574         float4 r = {a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w};
575         return r;
576 }
577
578 __device_inline float4 operator*(const float4& a, float f)
579 {
580         float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
581         return r;
582 }
583
584 __device_inline float4 operator*(float f, const float4& a)
585 {
586         float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
587         return r;
588 }
589
590 __device_inline float4 operator/(const float4& a, float f)
591 {
592         float invf = 1.0f/f;
593         float4 r = {a.x*invf, a.y*invf, a.z*invf, a.w*invf};
594         return r;
595 }
596
597 __device_inline float4 operator/(const float4& a, const float4& b)
598 {
599         float4 r = {a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w};
600         return r;
601 }
602
603 __device_inline float4 operator+(const float4& a, const float4& b)
604 {
605         float4 r = {a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w};
606         return r;
607 }
608
609 __device_inline float4 operator-(const float4& a, const float4& b)
610 {
611         float4 r = {a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w};
612         return r;
613 }
614
615 __device_inline float4 operator+=(float4& a, const float4& b)
616 {
617         a.x += b.x;
618         a.y += b.y;
619         a.z += b.z;
620         a.w += b.w;
621         return a;
622 }
623
624 __device_inline float4 operator*=(float4& a, const float4& b)
625 {
626         a.x *= b.x;
627         a.y *= b.y;
628         a.z *= b.z;
629         a.w *= b.w;
630         return a;
631 }
632
633 __device_inline float4 operator/=(float4& a, float f)
634 {
635         float invf = 1.0f/f;
636         a.x *= invf;
637         a.y *= invf;
638         a.z *= invf;
639         a.w *= invf;
640         return a;
641 }
642
643 __device_inline float dot(const float4& a, const float4& b)
644 {
645         return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
646 }
647
648 __device_inline float4 cross(const float4& a, const float4& b)
649 {
650         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};
651         return r;
652 }
653
654 __device_inline float4 min(float4 a, float4 b)
655 {
656         return make_float4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
657 }
658
659 __device_inline float4 max(float4 a, float4 b)
660 {
661         return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
662 }
663
664 #endif
665
666 #ifndef __KERNEL_GPU__
667
668 __device_inline void print_float4(const char *label, const float4& a)
669 {
670         printf("%s: %.8f %.8f %.8f %.8f\n", label, a.x, a.y, a.z, a.w);
671 }
672
673 #endif
674
675 /* Int3 */
676
677 #ifndef __KERNEL_OPENCL__
678
679 __device_inline int3 max(int3 a, int3 b)
680 {
681         int3 r = {max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)};
682         return r;
683 }
684
685 __device_inline int3 clamp(const int3& a, int mn, int mx)
686 {
687         int3 r = {clamp(a.x, mn, mx), clamp(a.y, mn, mx), clamp(a.z, mn, mx)};
688         return r;
689 }
690
691 __device_inline int3 clamp(const int3& a, int3& mn, int mx)
692 {
693         int3 r = {clamp(a.x, mn.x, mx), clamp(a.y, mn.y, mx), clamp(a.z, mn.z, mx)};
694         return r;
695 }
696
697 #endif
698
699 #ifndef __KERNEL_GPU__
700
701 __device_inline void print_int3(const char *label, const int3& a)
702 {
703         printf("%s: %d %d %d\n", label, a.x, a.y, a.z);
704 }
705
706 #endif
707
708 /* Int4 */
709
710 #ifndef __KERNEL_OPENCL__
711
712 __device_inline int4 operator>=(float4 a, float4 b)
713 {
714         return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
715 }
716
717 #endif
718
719 #ifndef __KERNEL_GPU__
720
721 __device_inline void print_int4(const char *label, const int4& a)
722 {
723         printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w);
724 }
725
726 #endif
727
728 /* Int/Float conversion */
729
730 #ifndef __KERNEL_OPENCL__
731
732 __device_inline unsigned int as_uint(float f)
733 {
734         union { unsigned int i; float f; } u;
735         u.f = f;
736         return u.i;
737 }
738
739 __device_inline int __float_as_int(float f)
740 {
741         union { int i; float f; } u;
742         u.f = f;
743         return u.i;
744 }
745
746 __device_inline float __int_as_float(int i)
747 {
748         union { int i; float f; } u;
749         u.i = i;
750         return u.f;
751 }
752
753 __device_inline uint __float_as_uint(float f)
754 {
755         union { uint i; float f; } u;
756         u.f = f;
757         return u.i;
758 }
759
760 __device_inline float __uint_as_float(uint i)
761 {
762         union { uint i; float f; } u;
763         u.i = i;
764         return u.f;
765 }
766
767 /* Interpolation */
768
769 template<class A, class B> __device_inline A lerp(const A& a, const A& b, const B& t)
770 {
771         return (A)(a * ((B)1 - t) + b * t);
772 }
773
774 /* Triangle */
775
776 __device_inline float triangle_area(const float3 v1, const float3 v2, const float3 v3)
777 {
778         return len(cross(v3 - v2, v1 - v2))*0.5f;
779 }
780
781 #endif
782
783 CCL_NAMESPACE_END
784
785 #endif /* __UTIL_MATH_H__ */
786