Blender V2.61 - r43446

util_math.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #ifndef __UTIL_MATH_H__
00020 #define __UTIL_MATH_H__
00021 
00022 /* Math
00023  *
00024  * Basic math functions on scalar and vector types. This header is used by
00025  * both the kernel code when compiled as C++, and other C++ non-kernel code. */
00026 
00027 #ifndef __KERNEL_OPENCL__
00028 
00029 #define _USE_MATH_DEFINES
00030 
00031 #include <float.h>
00032 #include <math.h>
00033 #include <stdio.h>
00034 
00035 #endif
00036 
00037 #include "util_types.h"
00038 
00039 CCL_NAMESPACE_BEGIN
00040 
00041 #ifndef M_PI_F
00042 #define M_PI_F      ((float)3.14159265358979323846264338327950288)
00043 #endif
00044 #ifndef M_PI_2_F
00045 #define M_PI_2_F    ((float)1.57079632679489661923132169163975144)
00046 #endif
00047 #ifndef M_PI_4_F
00048 #define M_PI_4_F    ((float)0.785398163397448309615660845819875721)
00049 #endif
00050 #ifndef M_1_PI_F
00051 #define M_1_PI_F    ((float)0.318309886183790671537767526745028724)
00052 #endif
00053 #ifndef M_2_PI_F
00054 #define M_2_PI_F    ((float)0.636619772367581343075535053490057448)
00055 #endif
00056 
00057 /* Scalar */
00058 
00059 #ifdef _WIN32
00060 
00061 #ifndef __KERNEL_GPU__
00062 
00063 #if(!defined(FREE_WINDOWS))
00064 #define copysignf(x, y) ((float)_copysign(x, y))
00065 #define hypotf(x, y) _hypotf(x, y)
00066 #define isnan(x) _isnan(x)
00067 #endif
00068 
00069 #endif
00070 
00071 __device_inline float fmaxf(float a, float b)
00072 {
00073     return (a > b)? a: b;
00074 }
00075 
00076 __device_inline float fminf(float a, float b)
00077 {
00078     return (a < b)? a: b;
00079 }
00080 
00081 #endif
00082 
00083 #ifndef __KERNEL_GPU__
00084 
00085 __device_inline int max(int a, int b)
00086 {
00087     return (a > b)? a: b;
00088 }
00089 
00090 __device_inline int min(int a, int b)
00091 {
00092     return (a < b)? a: b;
00093 }
00094 
00095 __device_inline float max(float a, float b)
00096 {
00097     return (a > b)? a: b;
00098 }
00099 
00100 __device_inline float min(float a, float b)
00101 {
00102     return (a < b)? a: b;
00103 }
00104 
00105 __device_inline double max(double a, double b)
00106 {
00107     return (a > b)? a: b;
00108 }
00109 
00110 __device_inline double min(double a, double b)
00111 {
00112     return (a < b)? a: b;
00113 }
00114 
00115 #endif
00116 
00117 __device_inline float min4(float a, float b, float c, float d)
00118 {
00119     return min(min(a, b), min(c, d));
00120 }
00121 
00122 __device_inline float max4(float a, float b, float c, float d)
00123 {
00124     return max(max(a, b), max(c, d));
00125 }
00126 
00127 #ifndef __KERNEL_OPENCL__
00128 
00129 __device_inline int clamp(int a, int mn, int mx)
00130 {
00131     return min(max(a, mn), mx);
00132 }
00133 
00134 __device_inline float clamp(float a, float mn, float mx)
00135 {
00136     return min(max(a, mn), mx);
00137 }
00138 
00139 #endif
00140 
00141 __device_inline float signf(float f)
00142 {
00143     return (f < 0.0f)? -1.0f: 1.0f;
00144 }
00145 
00146 __device_inline float nonzerof(float f, float eps)
00147 {
00148     if(fabsf(f) < eps)
00149         return signf(f)*eps;
00150     else
00151         return f;
00152 }
00153 
00154 /* Float2 Vector */
00155 
00156 #ifndef __KERNEL_OPENCL__
00157 
00158 __device_inline bool is_zero(const float2 a)
00159 {
00160     return (a.x == 0.0f && a.y == 0.0f);
00161 }
00162 
00163 #endif
00164 
00165 #ifndef __KERNEL_OPENCL__
00166 
00167 __device_inline float average(const float2 a)
00168 {
00169     return (a.x + a.y)*(1.0f/2.0f);
00170 }
00171 
00172 #endif
00173 
00174 #ifndef __KERNEL_OPENCL__
00175 
00176 __device_inline float2 operator-(const float2 a)
00177 {
00178     float2 r = {-a.x, -a.y};
00179     return r;
00180 }
00181 
00182 __device_inline float2 operator*(const float2 a, const float2 b)
00183 {
00184     float2 r = {a.x*b.x, a.y*b.y};
00185     return r;
00186 }
00187 
00188 __device_inline float2 operator*(const float2 a, float f)
00189 {
00190     float2 r = {a.x*f, a.y*f};
00191     return r;
00192 }
00193 
00194 __device_inline float2 operator*(float f, const float2 a)
00195 {
00196     float2 r = {a.x*f, a.y*f};
00197     return r;
00198 }
00199 
00200 __device_inline float2 operator/(float f, const float2 a)
00201 {
00202     float2 r = {f/a.x, f/a.y};
00203     return r;
00204 }
00205 
00206 __device_inline float2 operator/(const float2 a, float f)
00207 {
00208     float invf = 1.0f/f;
00209     float2 r = {a.x*invf, a.y*invf};
00210     return r;
00211 }
00212 
00213 __device_inline float2 operator/(const float2 a, const float2 b)
00214 {
00215     float2 r = {a.x/b.x, a.y/b.y};
00216     return r;
00217 }
00218 
00219 __device_inline float2 operator+(const float2 a, const float2 b)
00220 {
00221     float2 r = {a.x+b.x, a.y+b.y};
00222     return r;
00223 }
00224 
00225 __device_inline float2 operator-(const float2 a, const float2 b)
00226 {
00227     float2 r = {a.x-b.x, a.y-b.y};
00228     return r;
00229 }
00230 
00231 __device_inline float2 operator+=(float2& a, const float2 b)
00232 {
00233     a.x += b.x;
00234     a.y += b.y;
00235     return a;
00236 }
00237 
00238 __device_inline float2 operator*=(float2& a, const float2 b)
00239 {
00240     a.x *= b.x;
00241     a.y *= b.y;
00242     return a;
00243 }
00244 
00245 __device_inline float2 operator*=(float2& a, float f)
00246 {
00247     a.x *= f;
00248     a.y *= f;
00249     return a;
00250 }
00251 
00252 __device_inline float2 operator/=(float2& a, const float2 b)
00253 {
00254     a.x /= b.x;
00255     a.y /= b.y;
00256     return a;
00257 }
00258 
00259 __device_inline float2 operator/=(float2& a, float f)
00260 {
00261     float invf = 1.0f/f;
00262     a.x *= invf;
00263     a.y *= invf;
00264     return a;
00265 }
00266 
00267 
00268 __device_inline float dot(const float2 a, const float2 b)
00269 {
00270     return a.x*b.x + a.y*b.y;
00271 }
00272 
00273 __device_inline float cross(const float2 a, const float2 b)
00274 {
00275     return (a.x*b.y - a.y*b.x);
00276 }
00277 
00278 #endif
00279 
00280 #ifndef __KERNEL_OPENCL__
00281 
00282 __device_inline float len(const float2 a)
00283 {
00284     return sqrtf(dot(a, a));
00285 }
00286 
00287 __device_inline float2 normalize(const float2 a)
00288 {
00289     return a/len(a);
00290 }
00291 
00292 __device_inline float2 normalize_len(const float2 a, float *t)
00293 {
00294     *t = len(a);
00295     return a/(*t);
00296 }
00297 
00298 __device_inline bool operator==(const float2 a, const float2 b)
00299 {
00300     return (a.x == b.x && a.y == b.y);
00301 }
00302 
00303 __device_inline bool operator!=(const float2 a, const float2 b)
00304 {
00305     return !(a == b);
00306 }
00307 
00308 __device_inline float2 min(float2 a, float2 b)
00309 {
00310     float2 r = {min(a.x, b.x), min(a.y, b.y)};
00311     return r;
00312 }
00313 
00314 __device_inline float2 max(float2 a, float2 b)
00315 {
00316     float2 r = {max(a.x, b.x), max(a.y, b.y)};
00317     return r;
00318 }
00319 
00320 __device_inline float2 clamp(float2 a, float2 mn, float2 mx)
00321 {
00322     return min(max(a, mn), mx);
00323 }
00324 
00325 __device_inline float2 fabs(float2 a)
00326 {
00327     return make_float2(fabsf(a.x), fabsf(a.y));
00328 }
00329 
00330 __device_inline float2 as_float2(const float4 a)
00331 {
00332     return make_float2(a.x, a.y);
00333 }
00334 
00335 #endif
00336 
00337 #ifndef __KERNEL_GPU__
00338 
00339 __device_inline void print_float2(const char *label, const float2& a)
00340 {
00341     printf("%s: %.8f %.8f\n", label, a.x, a.y);
00342 }
00343 
00344 #endif
00345 
00346 #ifndef __KERNEL_OPENCL__
00347 
00348 __device_inline float2 interp(float2 a, float2 b, float t)
00349 {
00350     return a + t*(b - a);
00351 }
00352 
00353 #endif
00354 
00355 /* Float3 Vector */
00356 
00357 __device_inline bool is_zero(const float3 a)
00358 {
00359     return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f);
00360 }
00361 
00362 __device_inline float average(const float3 a)
00363 {
00364     return (a.x + a.y + a.z)*(1.0f/3.0f);
00365 }
00366 
00367 #ifndef __KERNEL_OPENCL__
00368 
00369 __device_inline float3 operator-(const float3 a)
00370 {
00371     float3 r = make_float3(-a.x, -a.y, -a.z);
00372     return r;
00373 }
00374 
00375 __device_inline float3 operator*(const float3 a, const float3 b)
00376 {
00377     float3 r = make_float3(a.x*b.x, a.y*b.y, a.z*b.z);
00378     return r;
00379 }
00380 
00381 __device_inline float3 operator*(const float3 a, float f)
00382 {
00383     float3 r = make_float3(a.x*f, a.y*f, a.z*f);
00384     return r;
00385 }
00386 
00387 __device_inline float3 operator*(float f, const float3 a)
00388 {
00389     float3 r = make_float3(a.x*f, a.y*f, a.z*f);
00390     return r;
00391 }
00392 
00393 __device_inline float3 operator/(float f, const float3 a)
00394 {
00395     float3 r = make_float3(f/a.x, f/a.y, f/a.z);
00396     return r;
00397 }
00398 
00399 __device_inline float3 operator/(const float3 a, float f)
00400 {
00401     float invf = 1.0f/f;
00402     float3 r = make_float3(a.x*invf, a.y*invf, a.z*invf);
00403     return r;
00404 }
00405 
00406 __device_inline float3 operator/(const float3 a, const float3 b)
00407 {
00408     float3 r = make_float3(a.x/b.x, a.y/b.y, a.z/b.z);
00409     return r;
00410 }
00411 
00412 __device_inline float3 operator+(const float3 a, const float3 b)
00413 {
00414     float3 r = make_float3(a.x+b.x, a.y+b.y, a.z+b.z);
00415     return r;
00416 }
00417 
00418 __device_inline float3 operator-(const float3 a, const float3 b)
00419 {
00420     float3 r = make_float3(a.x-b.x, a.y-b.y, a.z-b.z);
00421     return r;
00422 }
00423 
00424 __device_inline float3 operator+=(float3& a, const float3 b)
00425 {
00426     a.x += b.x;
00427     a.y += b.y;
00428     a.z += b.z;
00429     return a;
00430 }
00431 
00432 __device_inline float3 operator*=(float3& a, const float3 b)
00433 {
00434     a.x *= b.x;
00435     a.y *= b.y;
00436     a.z *= b.z;
00437     return a;
00438 }
00439 
00440 __device_inline float3 operator*=(float3& a, float f)
00441 {
00442     a.x *= f;
00443     a.y *= f;
00444     a.z *= f;
00445     return a;
00446 }
00447 
00448 __device_inline float3 operator/=(float3& a, const float3 b)
00449 {
00450     a.x /= b.x;
00451     a.y /= b.y;
00452     a.z /= b.z;
00453     return a;
00454 }
00455 
00456 __device_inline float3 operator/=(float3& a, float f)
00457 {
00458     float invf = 1.0f/f;
00459     a.x *= invf;
00460     a.y *= invf;
00461     a.z *= invf;
00462     return a;
00463 }
00464 
00465 __device_inline float dot(const float3 a, const float3 b)
00466 {
00467     return a.x*b.x + a.y*b.y + a.z*b.z;
00468 }
00469 
00470 __device_inline float3 cross(const float3 a, const float3 b)
00471 {
00472     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);
00473     return r;
00474 }
00475 
00476 #endif
00477 
00478 __device_inline float len(const float3 a)
00479 {
00480     return sqrtf(dot(a, a));
00481 }
00482 
00483 #ifndef __KERNEL_OPENCL__
00484 
00485 __device_inline float3 normalize(const float3 a)
00486 {
00487     return a/len(a);
00488 }
00489 
00490 #endif
00491 
00492 __device_inline float3 normalize_len(const float3 a, float *t)
00493 {
00494     *t = len(a);
00495     return a/(*t);
00496 }
00497 
00498 #ifndef __KERNEL_OPENCL__
00499 
00500 __device_inline bool operator==(const float3 a, const float3 b)
00501 {
00502     return (a.x == b.x && a.y == b.y && a.z == b.z);
00503 }
00504 
00505 __device_inline bool operator!=(const float3 a, const float3 b)
00506 {
00507     return !(a == b);
00508 }
00509 
00510 __device_inline float3 min(float3 a, float3 b)
00511 {
00512     float3 r = make_float3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
00513     return r;
00514 }
00515 
00516 __device_inline float3 max(float3 a, float3 b)
00517 {
00518     float3 r = make_float3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
00519     return r;
00520 }
00521 
00522 __device_inline float3 clamp(float3 a, float3 mn, float3 mx)
00523 {
00524     return min(max(a, mn), mx);
00525 }
00526 
00527 __device_inline float3 fabs(float3 a)
00528 {
00529     return make_float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
00530 }
00531 
00532 #endif
00533 
00534 __device_inline float3 float4_to_float3(const float4 a)
00535 {
00536     return make_float3(a.x, a.y, a.z);
00537 }
00538 
00539 __device_inline float4 float3_to_float4(const float3 a)
00540 {
00541     return make_float4(a.x, a.y, a.z, 1.0f);
00542 }
00543 
00544 #ifndef __KERNEL_GPU__
00545 
00546 __device_inline void print_float3(const char *label, const float3& a)
00547 {
00548     printf("%s: %.8f %.8f %.8f\n", label, a.x, a.y, a.z);
00549 }
00550 
00551 #endif
00552 
00553 __device_inline float3 interp(float3 a, float3 b, float t)
00554 {
00555     return a + t*(b - a);
00556 }
00557 
00558 /* Float4 Vector */
00559 
00560 #ifndef __KERNEL_OPENCL__
00561 
00562 __device_inline bool is_zero(const float4& a)
00563 {
00564     return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
00565 }
00566 
00567 __device_inline float average(const float4& a)
00568 {
00569     return (a.x + a.y + a.z + a.w)*(1.0f/4.0f);
00570 }
00571 
00572 __device_inline float4 operator-(const float4& a)
00573 {
00574     float4 r = {-a.x, -a.y, -a.z, -a.w};
00575     return r;
00576 }
00577 
00578 __device_inline float4 operator*(const float4& a, const float4& b)
00579 {
00580     float4 r = {a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w};
00581     return r;
00582 }
00583 
00584 __device_inline float4 operator*(const float4& a, float f)
00585 {
00586     float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
00587     return r;
00588 }
00589 
00590 __device_inline float4 operator*(float f, const float4& a)
00591 {
00592     float4 r = {a.x*f, a.y*f, a.z*f, a.w*f};
00593     return r;
00594 }
00595 
00596 __device_inline float4 operator/(const float4& a, float f)
00597 {
00598     float invf = 1.0f/f;
00599     float4 r = {a.x*invf, a.y*invf, a.z*invf, a.w*invf};
00600     return r;
00601 }
00602 
00603 __device_inline float4 operator/(const float4& a, const float4& b)
00604 {
00605     float4 r = {a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w};
00606     return r;
00607 }
00608 
00609 __device_inline float4 operator+(const float4& a, const float4& b)
00610 {
00611     float4 r = {a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w};
00612     return r;
00613 }
00614 
00615 __device_inline float4 operator-(const float4& a, const float4& b)
00616 {
00617     float4 r = {a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w};
00618     return r;
00619 }
00620 
00621 __device_inline float4 operator+=(float4& a, const float4& b)
00622 {
00623     a.x += b.x;
00624     a.y += b.y;
00625     a.z += b.z;
00626     a.w += b.w;
00627     return a;
00628 }
00629 
00630 __device_inline float4 operator*=(float4& a, const float4& b)
00631 {
00632     a.x *= b.x;
00633     a.y *= b.y;
00634     a.z *= b.z;
00635     a.w *= b.w;
00636     return a;
00637 }
00638 
00639 __device_inline float4 operator/=(float4& a, float f)
00640 {
00641     float invf = 1.0f/f;
00642     a.x *= invf;
00643     a.y *= invf;
00644     a.z *= invf;
00645     a.w *= invf;
00646     return a;
00647 }
00648 
00649 __device_inline float dot(const float4& a, const float4& b)
00650 {
00651     return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
00652 }
00653 
00654 __device_inline float4 cross(const float4& a, const float4& b)
00655 {
00656     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};
00657     return r;
00658 }
00659 
00660 __device_inline float4 min(float4 a, float4 b)
00661 {
00662     return make_float4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
00663 }
00664 
00665 __device_inline float4 max(float4 a, float4 b)
00666 {
00667     return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
00668 }
00669 
00670 #endif
00671 
00672 #ifndef __KERNEL_GPU__
00673 
00674 __device_inline void print_float4(const char *label, const float4& a)
00675 {
00676     printf("%s: %.8f %.8f %.8f %.8f\n", label, a.x, a.y, a.z, a.w);
00677 }
00678 
00679 #endif
00680 
00681 /* Int3 */
00682 
00683 #ifndef __KERNEL_OPENCL__
00684 
00685 __device_inline int3 max(int3 a, int3 b)
00686 {
00687     int3 r = {max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)};
00688     return r;
00689 }
00690 
00691 __device_inline int3 clamp(const int3& a, int mn, int mx)
00692 {
00693     int3 r = {clamp(a.x, mn, mx), clamp(a.y, mn, mx), clamp(a.z, mn, mx)};
00694     return r;
00695 }
00696 
00697 __device_inline int3 clamp(const int3& a, int3& mn, int mx)
00698 {
00699     int3 r = {clamp(a.x, mn.x, mx), clamp(a.y, mn.y, mx), clamp(a.z, mn.z, mx)};
00700     return r;
00701 }
00702 
00703 #endif
00704 
00705 #ifndef __KERNEL_GPU__
00706 
00707 __device_inline void print_int3(const char *label, const int3& a)
00708 {
00709     printf("%s: %d %d %d\n", label, a.x, a.y, a.z);
00710 }
00711 
00712 #endif
00713 
00714 /* Int4 */
00715 
00716 #ifndef __KERNEL_OPENCL__
00717 
00718 __device_inline int4 operator>=(float4 a, float4 b)
00719 {
00720     return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
00721 }
00722 
00723 #endif
00724 
00725 #ifndef __KERNEL_GPU__
00726 
00727 __device_inline void print_int4(const char *label, const int4& a)
00728 {
00729     printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w);
00730 }
00731 
00732 #endif
00733 
00734 /* Int/Float conversion */
00735 
00736 #ifndef __KERNEL_OPENCL__
00737 
00738 __device_inline unsigned int as_uint(float f)
00739 {
00740     union { unsigned int i; float f; } u;
00741     u.f = f;
00742     return u.i;
00743 }
00744 
00745 __device_inline int __float_as_int(float f)
00746 {
00747     union { int i; float f; } u;
00748     u.f = f;
00749     return u.i;
00750 }
00751 
00752 __device_inline float __int_as_float(int i)
00753 {
00754     union { int i; float f; } u;
00755     u.i = i;
00756     return u.f;
00757 }
00758 
00759 __device_inline uint __float_as_uint(float f)
00760 {
00761     union { uint i; float f; } u;
00762     u.f = f;
00763     return u.i;
00764 }
00765 
00766 __device_inline float __uint_as_float(uint i)
00767 {
00768     union { uint i; float f; } u;
00769     u.i = i;
00770     return u.f;
00771 }
00772 
00773 /* Interpolation */
00774 
00775 template<class A, class B> A lerp(const A& a, const A& b, const B& t)
00776 {
00777     return (A)(a * ((B)1 - t) + b * t);
00778 }
00779 
00780 /* Triangle */
00781 
00782 __device_inline float triangle_area(const float3 v1, const float3 v2, const float3 v3)
00783 {
00784     return len(cross(v3 - v2, v1 - v2))*0.5f;
00785 }
00786 
00787 #endif
00788 
00789 /* Orthonormal vectors */
00790 
00791 __device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b)
00792 {
00793     if(N.x != N.y || N.x != N.z)
00794         *a = make_float3(N.z-N.y, N.x-N.z, N.y-N.x);  //(1,1,1)x N
00795     else
00796         *a = make_float3(N.z-N.y, N.x+N.z, -N.y-N.x);  //(-1,1,1)x N
00797 
00798     *a = normalize(*a);
00799     *b = cross(N, *a);
00800 }
00801 
00802 CCL_NAMESPACE_END
00803 
00804 #endif /* __UTIL_MATH_H__ */
00805