Blender V2.61 - r43446
|
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