Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #ifndef glslmath_INCLUDE_ONCE 00033 #define glslmath_INCLUDE_ONCE 00034 00087 #include <cmath> 00088 #include <limits> 00089 #include <vlCore/Vector4.hpp> 00090 #include <vlCore/Matrix4.hpp> 00091 00092 #undef min 00093 #undef max 00094 00095 #if defined(__CUDACC__) 00096 #undef isnan 00097 #undef isinf 00098 #endif 00099 00100 namespace vl 00101 { 00102 // hyperbolic functions not implemented in Visual C++ 00103 00104 // taken from http://support.microsoft.com/kb/625449/it 00105 00106 template<typename T> 00107 T asinh(T x) { return log(x+::sqrt(x*x+1)); } 00108 00109 template<typename T> 00110 T acosh(T x) 00111 { 00112 // must be x>=1, if not return Nan (Not a Number) 00113 if(!(x>=1)) return ::sqrt((T)-1); 00114 00115 // return only the positive result (as sqrt does). 00116 return log(x+::sqrt(x*x-1)); 00117 } 00118 00119 template<typename T> 00120 T atanh(T x) 00121 { 00122 // must be x>-1, x<1, if not return Nan (Not a Number) 00123 if(!(x>-1 && x<1)) return ::sqrt((T)-1); 00124 00125 return log((1+x)/(1-x))/2; 00126 } 00127 00128 // isinf, isnan functions not implemented in Visual C++ 00129 00130 template<typename T> bool isnan(T value) { return !(value == value); } 00131 template<typename T> bool isinf(T value) { return value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max(); } 00132 template<typename T> bool isinf_pos(T value) { return value > std::numeric_limits<T>::max(); } 00133 template<typename T> bool isinf_neg(T value) { return value < std::numeric_limits<T>::min(); } 00134 00135 //----------------------------------------------------------------------------- 00136 // GLSL functions 00137 //----------------------------------------------------------------------------- 00138 00139 template<typename T> 00140 T modf(T a, T& intpart); 00141 00142 // --------------- angle and trigonometric functions --------------- 00143 00144 // --------------- radians --------------- 00145 00146 template<typename T> 00147 T radians(T degrees) { return degrees * (T)dDEG_TO_RAD; } 00148 00149 template<typename T> 00150 Vector2<T> radians(const Vector2<T>& degrees) { 00151 return Vector2<T>( degrees.x() * (T)dDEG_TO_RAD, 00152 degrees.y() * (T)dDEG_TO_RAD ); 00153 } 00154 00155 template<typename T> 00156 Vector3<T> radians(const Vector3<T>& degrees) { 00157 return Vector3<T>( degrees.x() * (T)dDEG_TO_RAD, 00158 degrees.y() * (T)dDEG_TO_RAD, 00159 degrees.z() * (T)dDEG_TO_RAD ); 00160 } 00161 00162 template<typename T> 00163 Vector4<T> radians(const Vector4<T>& degrees) { 00164 return Vector4<T>( degrees.x() * (T)dDEG_TO_RAD, 00165 degrees.y() * (T)dDEG_TO_RAD, 00166 degrees.z() * (T)dDEG_TO_RAD, 00167 degrees.w() * (T)dDEG_TO_RAD ); 00168 } 00169 00170 // --------------- degrees --------------- 00171 00172 template<typename T> 00173 T degrees(T radians) { return radians * (T)dRAD_TO_DEG; } 00174 00175 template<typename T> 00176 Vector2<T> degrees(const Vector2<T>& radians) { 00177 return Vector2<T>( radians.x() * (T)dRAD_TO_DEG, 00178 radians.y() * (T)dRAD_TO_DEG ); 00179 } 00180 00181 template<typename T> 00182 Vector3<T> degrees(const Vector3<T>& radians) { 00183 return Vector3<T>( radians.x() * (T)dRAD_TO_DEG, 00184 radians.y() * (T)dRAD_TO_DEG, 00185 radians.z() * (T)dRAD_TO_DEG ); 00186 } 00187 00188 template<typename T> 00189 Vector4<T> degrees(const Vector4<T>& radians) { 00190 return Vector4<T>( radians.x() * (T)dRAD_TO_DEG, 00191 radians.y() * (T)dRAD_TO_DEG, 00192 radians.z() * (T)dRAD_TO_DEG, 00193 radians.w() * (T)dRAD_TO_DEG ); 00194 } 00195 00196 // --------------- sin --------------- 00197 00198 template<typename T> 00199 T sin(T a) { return ::sin(a); } 00200 00201 template<typename T> 00202 Vector2<T> sin(const Vector2<T>& angle) { 00203 return Vector2<T>( ::sin(angle.x()), 00204 ::sin(angle.y()) ); 00205 } 00206 00207 template<typename T> 00208 Vector3<T> sin(const Vector3<T>& angle) { 00209 return Vector3<T>( ::sin(angle.x()), 00210 ::sin(angle.y()), 00211 ::sin(angle.z()) ); 00212 } 00213 00214 template<typename T> 00215 Vector4<T> sin(const Vector4<T>& angle) { 00216 return Vector4<T>( ::sin(angle.x()), 00217 ::sin(angle.y()), 00218 ::sin(angle.z()), 00219 ::sin(angle.w()) ); 00220 } 00221 00222 // --------------- cos --------------- 00223 00224 template<typename T> 00225 T cos(T a) { return ::cos(a); } 00226 00227 template<typename T> 00228 Vector2<T> cos(const Vector2<T>& angle) { 00229 return Vector2<T>( ::cos(angle.x()), 00230 ::cos(angle.y()) ); 00231 } 00232 00233 template<typename T> 00234 Vector3<T> cos(const Vector3<T>& angle) { 00235 return Vector3<T>( ::cos(angle.x()), 00236 ::cos(angle.y()), 00237 ::cos(angle.z()) ); 00238 } 00239 00240 template<typename T> 00241 Vector4<T> cos(const Vector4<T>& angle) { 00242 return Vector4<T>( ::cos(angle.x()), 00243 ::cos(angle.y()), 00244 ::cos(angle.z()), 00245 ::cos(angle.w()) ); 00246 } 00247 00248 // --------------- tan --------------- 00249 00250 template<typename T> 00251 T tan(T a) { return ::tan(a); } 00252 00253 template<typename T> 00254 Vector2<T> tan(const Vector2<T>& angle) { 00255 return Vector2<T>( ::tan(angle.x()), 00256 ::tan(angle.y()) ); 00257 } 00258 00259 template<typename T> 00260 Vector3<T> tan(const Vector3<T>& angle) { 00261 return Vector3<T>( ::tan(angle.x()), 00262 ::tan(angle.y()), 00263 ::tan(angle.z()) ); 00264 } 00265 00266 template<typename T> 00267 Vector4<T> tan(const Vector4<T>& angle) { 00268 return Vector4<T>( ::tan(angle.x()), 00269 ::tan(angle.y()), 00270 ::tan(angle.z()), 00271 ::tan(angle.w()) ); 00272 } 00273 00274 // --------------- atan --------------- 00275 00276 template<typename T> 00277 T atan(T a) { return ::atan(a); } 00278 00279 template<typename T> 00280 Vector2<T> atan(const Vector2<T>& a, const Vector2<T>& b) { 00281 return Vector2<T>( ::atan2(a.x(), b.x()), 00282 ::atan2(a.y(), b.y()) ); 00283 } 00284 00285 template<typename T> 00286 Vector3<T> atan(const Vector3<T>& a, const Vector3<T>& b) { 00287 return Vector3<T>( ::atan2(a.x(), b.x()), 00288 ::atan2(a.y(), b.y()), 00289 ::atan2(a.z(), b.z()) ); 00290 } 00291 00292 template<typename T> 00293 Vector4<T> atan(const Vector4<T>& a, const Vector4<T>& b) { 00294 return Vector4<T>( ::atan2(a.x(), b.x()), 00295 ::atan2(a.y(), b.y()), 00296 ::atan2(a.z(), b.z()), 00297 ::atan2(a.w(), b.w()) ); 00298 } 00299 00300 // --------------- asin --------------- 00301 00302 template<typename T> 00303 T asin(T a) { return ::asin(a); } 00304 00305 template<typename T> 00306 Vector2<T> asin(const Vector2<T>& angle) { 00307 return Vector2<T>( ::asin(angle.x()), 00308 ::asin(angle.y()) ); 00309 } 00310 00311 template<typename T> 00312 Vector3<T> asin(const Vector3<T>& angle) { 00313 return Vector3<T>( ::asin(angle.x()), 00314 ::asin(angle.y()), 00315 ::asin(angle.z()) ); 00316 } 00317 00318 template<typename T> 00319 Vector4<T> asin(const Vector4<T>& angle) { 00320 return Vector4<T>( ::asin(angle.x()), 00321 ::asin(angle.y()), 00322 ::asin(angle.z()), 00323 ::asin(angle.w()) ); 00324 } 00325 00326 // --------------- acos --------------- 00327 00328 template<typename T> 00329 T acos(T a) { return ::acos(a); } 00330 00331 template<typename T> 00332 Vector2<T> acos(const Vector2<T>& angle) { 00333 return Vector2<T>( ::acos(angle.x()), 00334 ::acos(angle.y()) ); 00335 } 00336 00337 template<typename T> 00338 Vector3<T> acos(const Vector3<T>& angle) { 00339 return Vector3<T>( ::acos(angle.x()), 00340 ::acos(angle.y()), 00341 ::acos(angle.z()) ); 00342 } 00343 00344 template<typename T> 00345 Vector4<T> acos(const Vector4<T>& angle) { 00346 return Vector4<T>( ::acos(angle.x()), 00347 ::acos(angle.y()), 00348 ::acos(angle.z()), 00349 ::acos(angle.w()) ); 00350 } 00351 00352 // --------------- hyperbolic functions --------------- 00353 00354 // --------------- sinh --------------- 00355 00356 template<typename T> 00357 T sinh(T a) { return (exp(a) - exp(-a)) / 2; } 00358 00359 template<typename T> 00360 Vector2<T> sinh(const Vector2<T>& a) { return Vector2<T>( sinh(a.x()), sinh(a.y()) ); } 00361 00362 template<typename T> 00363 Vector3<T> sinh(const Vector3<T>& a) { return Vector3<T>( sinh(a.x()), sinh(a.y()), sinh(a.z()) ); } 00364 00365 template<typename T> 00366 Vector4<T> sinh(const Vector4<T>& a) { return Vector4<T>( sinh(a.x()), sinh(a.y()), sinh(a.z()), sinh(a.w()) ); } 00367 00368 // --------------- cosh --------------- 00369 00370 template<typename T> 00371 T cosh(T a) { return (exp(a) + exp(-a)) / 2; } 00372 00373 template<typename T> 00374 Vector2<T> cosh(const Vector2<T>& a) { return Vector2<T>( cosh(a.x()), cosh(a.y()) ); } 00375 00376 template<typename T> 00377 Vector3<T> cosh(const Vector3<T>& a) { return Vector3<T>( cosh(a.x()), cosh(a.y()), cosh(a.z()) ); } 00378 00379 template<typename T> 00380 Vector4<T> cosh(const Vector4<T>& a) { return Vector4<T>( cosh(a.x()), cosh(a.y()), cosh(a.z()), cosh(a.w()) ); } 00381 00382 // --------------- tanh --------------- 00383 00384 template<typename T> 00385 T tanh(T a) { return sinh(a) / cosh(a); } 00386 00387 template<typename T> 00388 Vector2<T> tanh(const Vector2<T>& a) { return Vector2<T>( tanh(a.x()), tanh(a.y()) ); } 00389 00390 template<typename T> 00391 Vector3<T> tanh(const Vector3<T>& a) { return Vector3<T>( tanh(a.x()), tanh(a.y()), tanh(a.z()) ); } 00392 00393 template<typename T> 00394 Vector4<T> tanh(const Vector4<T>& a) { return Vector4<T>( tanh(a.x()), tanh(a.y()), tanh(a.z()), tanh(a.w()) ); } 00395 00396 // --------------- asinh --------------- 00397 00398 template<typename T> 00399 Vector2<T> asinh(const Vector2<T>& a) { return Vector2<T>( asinh(a.x()), asinh(a.y()) ); } 00400 00401 template<typename T> 00402 Vector3<T> asinh(const Vector3<T>& a) { return Vector3<T>( asinh(a.x()), asinh(a.y()), asinh(a.z()) ); } 00403 00404 template<typename T> 00405 Vector4<T> asinh(const Vector4<T>& a) { return Vector4<T>( asinh(a.x()), asinh(a.y()), asinh(a.z()), asinh(a.w()) ); } 00406 00407 // --------------- acosh --------------- 00408 00409 template<typename T> 00410 Vector2<T> acosh(const Vector2<T>& a) { return Vector2<T>( acosh(a.x()), acosh(a.y()) ); } 00411 00412 template<typename T> 00413 Vector3<T> acosh(const Vector3<T>& a) { return Vector3<T>( acosh(a.x()), acosh(a.y()), acosh(a.z()) ); } 00414 00415 template<typename T> 00416 Vector4<T> acosh(const Vector4<T>& a) { return Vector4<T>( acosh(a.x()), acosh(a.y()), acosh(a.z()), acosh(a.w()) ); } 00417 00418 // --------------- atanh --------------- 00419 00420 template<typename T> 00421 Vector2<T> atanh(const Vector2<T>& a) { return Vector2<T>( atanh(a.x()), atanh(a.y()) ); } 00422 00423 template<typename T> 00424 Vector3<T> atanh(const Vector3<T>& a) { return Vector3<T>( atanh(a.x()), atanh(a.y()), atanh(a.z()) ); } 00425 00426 template<typename T> 00427 Vector4<T> atanh(const Vector4<T>& a) { return Vector4<T>( atanh(a.x()), atanh(a.y()), atanh(a.z()), atanh(a.w()) ); } 00428 00429 // --------------- exponential functions --------------- 00430 00431 // --------------- pow --------------- 00432 00433 template<typename T> 00434 T pow(T a, T b) { return ::pow(a, b); } 00435 00436 template<typename T> 00437 Vector2<T> pow(const Vector2<T>& a, const Vector2<T>& b) { 00438 return Vector2<T>( ::pow(a.x(), b.x()), 00439 ::pow(a.y(), b.y()) ); 00440 } 00441 00442 template<typename T> 00443 Vector3<T> pow(const Vector3<T>& a, const Vector3<T>& b) { 00444 return Vector3<T>( ::pow(a.x(), b.x()), 00445 ::pow(a.y(), b.y()), 00446 ::pow(a.z(), b.z()) ); 00447 } 00448 00449 template<typename T> 00450 Vector4<T> pow(const Vector4<T>& a, const Vector4<T>& b) { 00451 return Vector4<T>( ::pow(a.x(), b.x()), 00452 ::pow(a.y(), b.y()), 00453 ::pow(a.z(), b.z()), 00454 ::pow(a.w(), b.w()) ); 00455 } 00456 00457 // --------------- exp --------------- 00458 00459 template<typename T> 00460 T exp(T a) { return ::exp(a); } 00461 00462 template<typename T> 00463 Vector2<T> exp(const Vector2<T>& a) { 00464 return Vector2<T>( ::exp(a.x()), 00465 ::exp(a.y()) ); 00466 } 00467 00468 template<typename T> 00469 Vector3<T> exp(const Vector3<T>& a) { 00470 return Vector3<T>( ::exp(a.x()), 00471 ::exp(a.y()), 00472 ::exp(a.z()) ); 00473 } 00474 00475 template<typename T> 00476 Vector4<T> exp(const Vector4<T>& a) { 00477 return Vector4<T>( ::exp(a.x()), 00478 ::exp(a.y()), 00479 ::exp(a.z()), 00480 ::exp(a.w()) ); 00481 } 00482 00483 // --------------- log --------------- 00484 00485 template<typename T> 00486 T log(T a) { return ::log(a); } 00487 00488 template<typename T> 00489 Vector2<T> log(const Vector2<T>& a) { 00490 return Vector2<T>( ::log(a.x()), 00491 ::log(a.y()) ); 00492 } 00493 00494 template<typename T> 00495 Vector3<T> log(const Vector3<T>& a) { 00496 return Vector3<T>( ::log(a.x()), 00497 ::log(a.y()), 00498 ::log(a.z()) ); 00499 } 00500 00501 template<typename T> 00502 Vector4<T> log(const Vector4<T>& a) { 00503 return Vector4<T>( ::log(a.x()), 00504 ::log(a.y()), 00505 ::log(a.z()), 00506 ::log(a.w()) ); 00507 } 00508 00509 // --------------- exp2 --------------- 00510 00511 template<typename T> 00512 T exp2(T a) { return ::pow(2, a); } 00513 00514 template<typename T> 00515 Vector2<T> exp2(const Vector2<T>& a) { 00516 return Vector2<T>( ::pow(2, a.x()), 00517 ::pow(2, a.y()) ); 00518 } 00519 00520 template<typename T> 00521 Vector3<T> exp2(const Vector3<T>& a) { 00522 return Vector3<T>( ::pow(2, a.x()), 00523 ::pow(2, a.y()), 00524 ::pow(2, a.z()) ); 00525 } 00526 00527 template<typename T> 00528 Vector4<T> exp2(const Vector4<T>& a) { 00529 return Vector4<T>( ::pow(2, a.x()), 00530 ::pow(2, a.y()), 00531 ::pow(2, a.z()), 00532 ::pow(2, a.w()) ); 00533 } 00534 00535 // --------------- log2 --------------- 00536 00537 template<typename T> 00538 T log2(T a) { return log10(a) / log10(2); } 00539 00540 template<typename T> 00541 Vector2<T> log2(const Vector2<T>& a) { 00542 return Vector2<T>( log2(a.x()), 00543 log2(a.y()) ); 00544 } 00545 00546 template<typename T> 00547 Vector3<T> log2(const Vector3<T>& a) { 00548 return Vector3<T>( log2(a.x()), 00549 log2(a.y()), 00550 log2(a.z()) ); 00551 } 00552 00553 template<typename T> 00554 Vector4<T> log2(const Vector4<T>& a) { 00555 return Vector4<T>( log2(a.x()), 00556 log2(a.y()), 00557 log2(a.z()), 00558 log2(a.w()) ); 00559 } 00560 00561 // --------------- log10 --------------- 00562 00563 // this is not present in the GLSL standard 00564 00565 template<typename T> 00566 T log10(T a) { return ::log10(a); } 00567 00568 template<typename T> 00569 Vector2<T> log10(const Vector2<T>& a) { 00570 return Vector2<T>( ::log10(a.x()), 00571 ::log10(a.y()) ); 00572 } 00573 00574 template<typename T> 00575 Vector3<T> log10(const Vector3<T>& a) { 00576 return Vector3<T>( ::log10(a.x()), 00577 ::log10(a.y()), 00578 ::log10(a.z()) ); 00579 } 00580 00581 template<typename T> 00582 Vector4<T> log10(const Vector4<T>& a) { 00583 return Vector4<T>( ::log10(a.x()), 00584 ::log10(a.y()), 00585 ::log10(a.z()), 00586 ::log10(a.w()) ); 00587 } 00588 00589 // --------------- sqrt --------------- 00590 00591 template<typename T> 00592 T sqrt(T a) { return ::sqrt(a); } 00593 00594 template<typename T> 00595 Vector2<T> sqrt(const Vector2<T>& a) { 00596 return Vector2<T>( ::sqrt(a.x()), 00597 ::sqrt(a.y()) ); 00598 } 00599 00600 template<typename T> 00601 Vector3<T> sqrt(const Vector3<T>& a) { 00602 return Vector3<T>( ::sqrt(a.x()), 00603 ::sqrt(a.y()), 00604 ::sqrt(a.z()) ); 00605 } 00606 00607 template<typename T> 00608 Vector4<T> sqrt(const Vector4<T>& a) { 00609 return Vector4<T>( ::sqrt(a.x()), 00610 ::sqrt(a.y()), 00611 ::sqrt(a.z()), 00612 ::sqrt(a.w()) ); 00613 } 00614 00615 // --------------- inversesqrt --------------- 00616 00617 template<typename T> 00618 T inversesqrt(T a) { return ::sqrt(a); } 00619 00620 template<typename T> 00621 Vector2<T> inversesqrt(const Vector2<T>& a) { 00622 return Vector2<T>( T(1) / ::sqrt(a.x()), 00623 T(1) / ::sqrt(a.y()) ); 00624 } 00625 00626 template<typename T> 00627 Vector3<T> inversesqrt(const Vector3<T>& a) { 00628 return Vector3<T>( T(1) / ::sqrt(a.x()), 00629 T(1) / ::sqrt(a.y()), 00630 T(1) / ::sqrt(a.z()) ); 00631 } 00632 00633 template<typename T> 00634 Vector4<T> inversesqrt(const Vector4<T>& a) { 00635 return Vector4<T>( T(1) / ::sqrt(a.x()), 00636 T(1) / ::sqrt(a.y()), 00637 T(1) / ::sqrt(a.z()), 00638 T(1) / ::sqrt(a.w()) ); 00639 } 00640 00641 // --------------- common functions --------------- 00642 00643 // --------------- abs --------------- 00644 00645 template<typename T> 00646 T abs(T a) { return a >= 0 ? a : -a; } 00647 00648 template<typename T> 00649 Vector2<T> abs(const Vector2<T>& a) 00650 { 00651 return Vector2<T>( a.x() >= 0 ? a.x() : -a.x(), a.y() >= 0 ? a.y() : -a.y() ); 00652 } 00653 00654 template<typename T> 00655 Vector3<T> abs(const Vector3<T>& a) 00656 { 00657 return Vector3<T>( a.x() >= 0 ? a.x() : -a.x(), a.y() >= 0 ? a.y() : -a.y(), a.z() >= 0 ? a.z() : -a.z() ); 00658 } 00659 00660 template<typename T> 00661 Vector4<T> abs(const Vector4<T>& a) 00662 { 00663 return Vector4<T>( a.x() >= 0 ? a.x() : -a.x(), a.y() >= 0 ? a.y() : -a.y(), a.z() >= 0 ? a.z() : -a.z(), a.w() >= 0 ? a.w() : -a.w() ); 00664 } 00665 00666 // --------------- sign --------------- 00667 00668 template<typename T> 00669 T sign(T a) { return a > 0 ? 1 : a == 0 ? 0 : (T)-1; } 00670 00671 template<typename T> 00672 Vector2<T> sign(const Vector2<T> & a) 00673 { 00674 return Vector2<T>( a.x() > 0 ? 1 : a.x() == 0 ? 0 : (T)-1, 00675 a.y() > 0 ? 1 : a.y() == 0 ? 0 : (T)-1 ); 00676 } 00677 00678 template<typename T> 00679 Vector3<T> sign(const Vector3<T> & a) 00680 { 00681 return Vector3<T>( a.x() > 0 ? 1 : a.x() == 0 ? 0 : (T)-1, 00682 a.y() > 0 ? 1 : a.y() == 0 ? 0 : (T)-1, 00683 a.z() > 0 ? 1 : a.z() == 0 ? 0 : (T)-1 ); 00684 } 00685 00686 template<typename T> 00687 Vector4<T> sign(const Vector4<T> & a) 00688 { 00689 return Vector4<T>( a.x() > 0 ? 1 : a.x() == 0 ? 0 : (T)-1, 00690 a.y() > 0 ? 1 : a.y() == 0 ? 0 : (T)-1, 00691 a.z() > 0 ? 1 : a.z() == 0 ? 0 : (T)-1, 00692 a.w() > 0 ? 1 : a.w() == 0 ? 0 : (T)-1 ); 00693 } 00694 00695 // --------------- floor --------------- 00696 00697 template<typename T> 00698 T floor(T a) { return ::floor(a); } 00699 00700 template<typename T> 00701 Vector2<T> floor(const Vector2<T>& a) { 00702 return Vector2<T>( ::floor(a.x()), 00703 ::floor(a.y()) ); 00704 } 00705 00706 template<typename T> 00707 Vector3<T> floor(const Vector3<T>& a) { 00708 return Vector3<T>( ::floor(a.x()), 00709 ::floor(a.y()), 00710 ::floor(a.z()) ); 00711 } 00712 00713 template<typename T> 00714 Vector4<T> floor(const Vector4<T>& a) { 00715 return Vector4<T>( ::floor(a.x()), 00716 ::floor(a.y()), 00717 ::floor(a.z()), 00718 ::floor(a.w()) ); 00719 } 00720 00721 // --------------- fract --------------- 00722 00723 template<typename T> 00724 T fract(T a) { return a - floor(a); } 00725 00726 template<typename T> 00727 Vector2<T> fract(const Vector2<T>& a) { return a - floor(a); } 00728 00729 template<typename T> 00730 Vector3<T> fract(const Vector3<T>& a) { return a - floor(a); } 00731 00732 template<typename T> 00733 Vector4<T> fract(const Vector4<T>& a) { return a - floor(a); } 00734 00735 // --------------- trunc --------------- 00736 00737 template<typename T> 00738 T trunc(T a) { return a - fract(a); } 00739 00740 template<typename T> 00741 Vector2<T> trunc(const Vector2<T>& a) { 00742 return Vector2<T>( a.x() - fract(a.x()), 00743 a.y() - fract(a.y()) ); 00744 } 00745 00746 template<typename T> 00747 Vector3<T> trunc(const Vector3<T>& a) { 00748 return Vector3<T>( a.x() - fract(a.x()), 00749 a.y() - fract(a.y()), 00750 a.z() - fract(a.z()) ); 00751 } 00752 00753 template<typename T> 00754 Vector4<T> trunc(const Vector4<T>& a) { 00755 return Vector4<T>( a.x() - fract(a.x()), 00756 a.y() - fract(a.y()), 00757 a.z() - fract(a.z()), 00758 a.w() - fract(a.w()) ); 00759 } 00760 00761 // --------------- round --------------- 00762 00763 template<typename T> 00764 T round(T x) { return ((x - floor(x)) >= 0.5) ? ceil(x) : floor(x); } 00765 00766 template<typename T> 00767 Vector2<T> round(const Vector2<T>& a) { 00768 return Vector2<T>( round(a.x()), 00769 round(a.y()) ); 00770 } 00771 00772 template<typename T> 00773 Vector3<T> round(const Vector3<T>& a) { 00774 return Vector3<T>( round(a.x()), 00775 round(a.y()), 00776 round(a.z()) ); 00777 } 00778 00779 template<typename T> 00780 Vector4<T> round(const Vector4<T>& a) { 00781 return Vector4<T>( round(a.x()), 00782 round(a.y()), 00783 round(a.z()), 00784 round(a.w()) ); 00785 } 00786 00787 // --------------- modf --------------- 00788 00789 inline 00790 float modf(float a, float& intpart) { 00791 #if defined(_MSC_VER) 00792 return ::modf(a,&intpart); 00793 #else 00794 double dintpart = intpart; 00795 float r = (float)::modf((double)a,&dintpart); 00796 intpart = (float)dintpart; 00797 return r; 00798 #endif 00799 } 00800 00801 inline 00802 double modf(double a, double& intpart) { return ::modf(a,&intpart); } 00803 00804 template<typename T> 00805 Vector2<T> modf(const Vector2<T>& a, Vector2<T>& intpart) { 00806 return Vector2<T>( modf(a.x(), intpart.x()), 00807 modf(a.y(), intpart.y()) ); 00808 } 00809 00810 template<typename T> 00811 Vector3<T> modf(const Vector3<T>& a, Vector3<T>& intpart) { 00812 return Vector3<T>( modf(a.x(), intpart.x()), 00813 modf(a.y(), intpart.y()), 00814 modf(a.z(), intpart.z()) ); 00815 } 00816 00817 template<typename T> 00818 Vector4<T> modf(const Vector4<T>& a, Vector4<T>& intpart) { 00819 return Vector4<T>( modf(a.x(), intpart.x()), 00820 modf(a.y(), intpart.y()), 00821 modf(a.z(), intpart.z()), 00822 modf(a.w(), intpart.w()) ); 00823 } 00824 00825 // --------------- roundEven --------------- 00826 00827 inline 00828 float roundEven(float a, float epsilon) 00829 { 00830 if( a < 0 ) 00831 return -roundEven(-a, epsilon); 00832 else 00833 { 00834 float intpart; 00835 vl::modf( a, intpart ); 00836 00837 // 0.5 case 00838 if ((a -(intpart + 0.5f)) < epsilon) 00839 { 00840 // is even 00841 if (::fmod(intpart, 2) < epsilon) 00842 return intpart; 00843 else 00844 // is odd 00845 return ceil(intpart + 0.5f); 00846 } 00847 else 00848 // all the other cases 00849 return round(a); 00850 } 00851 } 00852 00853 inline 00854 double roundEven(double a, double epsilon) 00855 { 00856 if( a < 0 ) 00857 return -roundEven(-a, epsilon); 00858 else 00859 { 00860 double intpart; 00861 vl::modf( a, intpart ); 00862 00863 // 0.5 case 00864 if ((a -(intpart + 0.5)) < epsilon) 00865 { 00866 // is even 00867 if (::fmod(intpart, 2) < epsilon) 00868 return intpart; 00869 else 00870 // is odd 00871 return ceil(intpart + 0.5); 00872 } 00873 else 00874 // all the other cases 00875 return round(a); 00876 } 00877 } 00878 00879 template<typename T> 00880 Vector2<T> roundEven(const Vector2<T>& a, T epsilon = 0.00001) { 00881 return Vector2<T>( roundEven(a.x(), epsilon), 00882 roundEven(a.y(), epsilon) ); 00883 } 00884 00885 template<typename T> 00886 Vector3<T> roundEven(const Vector3<T>& a, T epsilon = 0.00001) { 00887 return Vector3<T>( roundEven(a.x(), epsilon), 00888 roundEven(a.y(), epsilon), 00889 roundEven(a.z(), epsilon) ); 00890 } 00891 00892 template<typename T> 00893 Vector4<T> roundEven(const Vector4<T>& a, T epsilon = 0.00001) { 00894 return Vector4<T>( roundEven(a.x(), epsilon), 00895 roundEven(a.y(), epsilon), 00896 roundEven(a.z(), epsilon), 00897 roundEven(a.w(), epsilon) ); 00898 } 00899 00900 // --------------- ceil --------------- 00901 00902 template<typename T> 00903 T ceil(T a) { return ::ceil(a); } 00904 00905 template<typename T> 00906 Vector2<T> ceil(const Vector2<T>& a) { 00907 return Vector2<T>( ::ceil(a.x()), 00908 ::ceil(a.y()) ); 00909 } 00910 00911 template<typename T> 00912 Vector3<T> ceil(const Vector3<T>& a) { 00913 return Vector3<T>( ::ceil(a.x()), 00914 ::ceil(a.y()), 00915 ::ceil(a.z()) ); 00916 } 00917 00918 template<typename T> 00919 Vector4<T> ceil(const Vector4<T>& a) { 00920 return Vector4<T>( ::ceil(a.x()), 00921 ::ceil(a.y()), 00922 ::ceil(a.z()), 00923 ::ceil(a.w()) ); 00924 } 00925 00926 // --------------- mod --------------- 00927 00928 template<typename T> 00929 T mod(T a, T b) { return a - b * floor(a/b); } 00930 00931 template<typename T> 00932 Vector2<T> mod(const Vector2<T>& a, T b) { return a - b * floor(a/b); } 00933 00934 template<typename T> 00935 Vector3<T> mod(const Vector3<T>& a, T b) { return a - b * floor(a/b); } 00936 00937 template<typename T> 00938 Vector4<T> mod(const Vector4<T>& a, T b) { return a - b * floor(a/b); } 00939 00940 template<typename T> 00941 Vector2<T> mod(const Vector2<T>& a, const Vector2<T>& b) { return a - b * floor(a/b); } 00942 00943 template<typename T> 00944 Vector3<T> mod(const Vector3<T>& a, const Vector3<T>& b) { return a - b * floor(a/b); } 00945 00946 template<typename T> 00947 Vector4<T> mod(const Vector4<T>& a, const Vector4<T>& b) { return a - b * floor(a/b); } 00948 00949 // --------------- mix --------------- 00950 00951 template<typename T> 00952 T mix(T a, T b, T t) { return a*(1-t) + b*t; } 00953 00954 template<typename T> 00955 Vector2<T> mix(const Vector2<T>& a, const Vector2<T>& b, T t) { return a*(1-t) + b*t; } 00956 00957 template<typename T> 00958 Vector3<T> mix(const Vector3<T>& a, const Vector3<T>& b, T t) { return a*(1-t) + b*t; } 00959 00960 template<typename T> 00961 Vector4<T> mix(const Vector4<T>& a, const Vector4<T>& b, T t) { return a*(1-t) + b*t; } 00962 00963 template<typename T> 00964 Vector2<T> mix(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& t) 00965 { 00966 return Vector2<T>( a.x()*(1-t.x()) + b.x()*t.x(), 00967 a.y()*(1-t.y()) + b.y()*t.y() ); 00968 } 00969 00970 template<typename T> 00971 Vector3<T> mix(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& t) 00972 { 00973 return Vector3<T>( a.x()*(1-t.x()) + b.x()*t.x(), 00974 a.y()*(1-t.y()) + b.y()*t.y(), 00975 a.z()*(1-t.z()) + b.z()*t.z() ); 00976 } 00977 00978 template<typename T> 00979 Vector4<T> mix(const Vector4<T>& a, const Vector4<T>& b, const Vector4<T>& t) 00980 { 00981 return Vector4<T>( a.x()*(1-t.x()) + b.x()*t.x(), 00982 a.y()*(1-t.y()) + b.y()*t.y(), 00983 a.z()*(1-t.z()) + b.z()*t.z(), 00984 a.w()*(1-t.w()) + b.w()*t.w() ); 00985 } 00986 00987 // --------------- step --------------- 00988 00989 template<typename T> 00990 T step( T edge, T a ) { if (a<edge) return 0; else return 1; } 00991 00992 template<typename T> 00993 Vector2<T> step( const Vector2<T>& edge, const Vector2<T>& a ) 00994 { 00995 return Vector2<T>( a.x()<edge.x() ? 0 : (T)1, 00996 a.y()<edge.y() ? 0 : (T)1 ); 00997 } 00998 00999 template<typename T> 01000 Vector3<T> step( const Vector3<T>& edge, const Vector3<T>& a ) 01001 { 01002 return Vector3<T>( a.x()<edge.x() ? 0 : (T)1, 01003 a.y()<edge.y() ? 0 : (T)1, 01004 a.z()<edge.z() ? 0 : (T)1 ); 01005 } 01006 01007 template<typename T> 01008 Vector4<T> step( const Vector4<T>& edge, const Vector4<T>& a ) 01009 { 01010 return Vector4<T>( a.x()<edge.x() ? 0 : (T)1, 01011 a.y()<edge.y() ? 0 : (T)1, 01012 a.z()<edge.z() ? 0 : (T)1, 01013 a.w()<edge.w() ? 0 : (T)1 ); 01014 } 01015 // --------------- smoothstep --------------- 01016 01017 template<typename T> 01018 T smoothstep(T edge0, T edge1, T a) 01019 { 01020 T t = clamp( (a - edge0) / (edge1 - edge0), (T)0, (T)1); 01021 return t * t * (3 - 2 * t); 01022 } 01023 01024 template<typename T> 01025 Vector2<T> smoothstep(const Vector2<T>& edge0, const Vector2<T>& edge1, const Vector2<T>& a) 01026 { 01027 Vector2<T> v; 01028 T t; 01029 t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t); 01030 t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t); 01031 return v; 01032 } 01033 01034 template<typename T> 01035 Vector3<T> smoothstep(const Vector3<T>& edge0, const Vector3<T>& edge1, const Vector3<T>& a) 01036 { 01037 Vector3<T> v; 01038 T t; 01039 t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t); 01040 t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t); 01041 t = clamp( (a.z() - edge0.z()) / (edge1.z() - edge0.z()), (T)0, (T)1); v.z() = t * t * (3 - 2 * t); 01042 return v; 01043 } 01044 01045 template<typename T> 01046 Vector4<T> smoothstep(const Vector4<T>& edge0, const Vector4<T>& edge1, const Vector4<T>& a) 01047 { 01048 Vector4<T> v; 01049 T t; 01050 t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t); 01051 t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t); 01052 t = clamp( (a.z() - edge0.z()) / (edge1.z() - edge0.z()), (T)0, (T)1); v.z() = t * t * (3 - 2 * t); 01053 t = clamp( (a.w() - edge0.w()) / (edge1.w() - edge0.w()), (T)0, (T)1); v.w() = t * t * (3 - 2 * t); 01054 return v; 01055 } 01056 01057 // --------------- isnan --------------- 01058 01059 template<typename T> 01060 ivec2 isnan(const Vector2<T>& a) { return ivec2( isnan(a.x()), isnan(a.y()) ); } 01061 01062 template<typename T> 01063 ivec3 isnan(const Vector3<T>& a) { return ivec3( isnan(a.x()), isnan(a.y()), isnan(a.z()) ); } 01064 01065 template<typename T> 01066 ivec4 isnan(const Vector4<T>& a) { return ivec4( isnan(a.x()), isnan(a.y()), isnan(a.z()), isnan(a.w()) ); } 01067 01068 // --------------- isinf --------------- 01069 01070 template<typename T> 01071 ivec2 isinf(const Vector2<T>& a) { return ivec2( isinf(a.x()), isinf(a.y()) ); } 01072 01073 template<typename T> 01074 ivec3 isinf(const Vector3<T>& a) { return ivec3( isinf(a.x()), isinf(a.y()), isinf(a.z()) ); } 01075 01076 template<typename T> 01077 ivec4 isinf(const Vector4<T>& a) { return ivec4( isinf(a.x()), isinf(a.y()), isinf(a.z()), isinf(a.w()) ); } 01078 01079 // --------------- geometric functions --------------- 01080 01081 // --------------- length --------------- 01082 01083 template<typename T> 01084 T length(T v) { return v; } 01085 01086 template<typename T> 01087 T length(const Vector2<T>& v) { return v.length(); } 01088 01089 template<typename T> 01090 T length(const Vector3<T>& v) { return v.length(); } 01091 01092 template<typename T> 01093 T length(const Vector4<T>& v) { return v.length(); } 01094 01095 // --------------- distance --------------- 01096 01097 template<typename T> 01098 T distance(T p0, T p1) { return length(p0-p1); } 01099 01100 template<typename T> 01101 T distance(const Vector2<T>& p0, const Vector2<T>& p1) { return length(p0-p1); } 01102 01103 template<typename T> 01104 T distance(const Vector3<T>& p0, const Vector3<T>& p1) { return length(p0-p1); } 01105 01106 template<typename T> 01107 T distance(const Vector4<T>& p0, const Vector4<T>& p1) { return length(p0-p1); } 01108 01109 // --------------- dot --------------- 01110 01111 inline float dot(float a, float b) { return a*b; } 01112 01113 // .................................... 01114 01115 inline double dot(double a, double b) { return a*b; } 01116 01117 // .................................... 01118 01119 inline real dot(int a, int b) { return (real)a*b; } 01120 01121 // .................................... 01122 01123 inline real dot(unsigned int a, unsigned int b) { return (real)a*b; } 01124 01125 // --------------- normalize --------------- 01126 01127 template<typename T> 01128 T normalize(T) { return (T)1; } 01129 01130 template<typename T> 01131 Vector2<T> normalize(const Vector2<T>& v) { Vector2<T> t = v; t.normalize(); return t; } 01132 01133 template<typename T> 01134 Vector3<T> normalize(const Vector3<T>& v) { Vector3<T> t = v; t.normalize(); return t; } 01135 01136 template<typename T> 01137 Vector4<T> normalize(const Vector4<T>& v) { Vector4<T> t = v; t.normalize(); return t; } 01138 01139 // --------------- faceforward --------------- 01140 01141 template<typename T> 01142 T faceforward(T N, T I, T Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; } 01143 01144 template<typename T> 01145 Vector2<T> faceforward(const Vector2<T>& N, const Vector2<T>& I, const Vector2<T>& Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; } 01146 01147 template<typename T> 01148 Vector3<T> faceforward(const Vector3<T>& N, const Vector3<T>& I, const Vector3<T>& Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; } 01149 01150 template<typename T> 01151 Vector4<T> faceforward(const Vector4<T>& N, const Vector4<T>& I, const Vector4<T>& Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; } 01152 01153 // --------------- reflect ---------------- 01154 01155 template<typename T> 01156 T reflect(T I, T N) { return I-2*dot(N,I)*N; } 01157 01158 template<typename T> 01159 Vector2<T> reflect(const Vector2<T>& I, const Vector2<T>& N) { return I-2*dot(N,I)*N; } 01160 01161 template<typename T> 01162 Vector3<T> reflect(const Vector3<T>& I, const Vector3<T>& N) { return I-2*dot(N,I)*N; } 01163 01164 template<typename T> 01165 Vector4<T> reflect(const Vector4<T>& I, const Vector4<T>& N) { return I-2*dot(N,I)*N; } 01166 01167 // --------------- refract --------------- 01168 01169 template<typename T> 01170 T refract(T I, T N, T eta) 01171 { 01172 T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I)); 01173 if (k < 0) 01174 return 0; 01175 else 01176 return eta * I - (eta * dot(N, I) + ::sqrt(k)) * N; 01177 } 01178 01179 template<typename T> 01180 Vector2<T> refract(const Vector2<T>& I, const Vector2<T>& N, T eta) 01181 { 01182 T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I)); 01183 if (k < 0) 01184 return Vector2<T>(0,0); 01185 else 01186 return eta * I - N * (eta * dot(N, I) + ::sqrt(k)); 01187 } 01188 01189 template<typename T> 01190 Vector3<T> refract(const Vector3<T>& I, const Vector3<T>& N, T eta) 01191 { 01192 T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I)); 01193 if (k < 0) 01194 return Vector3<T>(0,0,0); 01195 else 01196 return eta * I - N * (eta * dot(N, I) + ::sqrt(k)); 01197 } 01198 01199 template<typename T> 01200 Vector4<T> refract(const Vector4<T>& I, const Vector4<T>& N, T eta) 01201 { 01202 T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I)); 01203 if (k < 0) 01204 return Vector4<T>(0,0,0,0); 01205 else 01206 return eta * I - N * (eta * dot(N, I) + ::sqrt(k)); 01207 } 01208 01209 // --------------- matrix functions --------------- 01210 01211 // --------------- matrixCompMult --------------- 01212 01213 template<typename T> 01214 Matrix2<T> matrixCompMult(const Matrix2<T>& a, const Matrix2<T>& b) 01215 { 01216 Matrix2<T> t; 01217 for(int i=0; i<2; ++i) 01218 for(int j=0; j<2; ++j) 01219 t.e(j,i) = a.e(j,i) * b.e(j,i); 01220 return t; 01221 } 01222 01223 template<typename T> 01224 Matrix3<T> matrixCompMult(const Matrix3<T>& a, const Matrix3<T>& b) 01225 { 01226 Matrix3<T> t; 01227 for(int i=0; i<3; ++i) 01228 for(int j=0; j<3; ++j) 01229 t.e(j,i) = a.e(j,i) * b.e(j,i); 01230 return t; 01231 } 01232 01233 template<typename T> 01234 Matrix4<T> matrixCompMult(const Matrix4<T>& a, const Matrix4<T>& b) 01235 { 01236 Matrix4<T> t; 01237 for(int i=0; i<4; ++i) 01238 for(int j=0; j<4; ++j) 01239 t.e(j,i) = a.e(j,i) * b.e(j,i); 01240 return t; 01241 } 01242 01243 // --------------- outerProduct --------------- 01244 01245 template<typename T> 01246 Matrix2<T> outerProduct(const Vector2<T>& a, const Vector2<T>& b) 01247 { 01248 Matrix2<T> m; 01249 for(int i=0; i<2; ++i) 01250 for(int j=0; j<2; ++j) 01251 m.e(i,j) = a[i] * b[j]; 01252 return m; 01253 } 01254 01255 template<typename T> 01256 Matrix3<T> outerProduct(const Vector3<T>& a, const Vector3<T>& b) 01257 { 01258 Matrix3<T> m; 01259 for(int i=0; i<3; ++i) 01260 for(int j=0; j<3; ++j) 01261 m.e(i,j) = a[i] * b[j]; 01262 return m; 01263 } 01264 01265 template<typename T> 01266 Matrix4<T> outerProduct(const Vector4<T>& a, const Vector4<T>& b) 01267 { 01268 Matrix4<T> m; 01269 for(int i=0; i<4; ++i) 01270 for(int j=0; j<4; ++j) 01271 m.e(i,j) = a[i] * b[j]; 01272 return m; 01273 } 01274 01275 // --------------- transpose --------------- 01276 01277 template<typename T> 01278 Matrix2<T> transpose(const Matrix2<T>& a) 01279 { 01280 Matrix2<T> t; 01281 for(int i=0; i<2; ++i) 01282 for(int j=0; j<2; ++j) 01283 t.e(j,i) = a.e(i,j); 01284 return t; 01285 } 01286 01287 template<typename T> 01288 Matrix3<T> transpose(const Matrix3<T>& a) 01289 { 01290 Matrix3<T> t; 01291 for(int i=0; i<3; ++i) 01292 for(int j=0; j<3; ++j) 01293 t.e(j,i) = a.e(i,j); 01294 return t; 01295 } 01296 01297 template<typename T> 01298 Matrix4<T> transpose(const Matrix4<T>& a) 01299 { 01300 Matrix4<T> t; 01301 for(int i=0; i<4; ++i) 01302 for(int j=0; j<4; ++j) 01303 t.e(j,i) = a.e(i,j); 01304 return t; 01305 } 01306 01307 // --------------- vector relational functions --------------- 01308 01309 // --------------- lessThan --------------- 01310 01311 template<typename T> 01312 ivec4 lessThan(const Vector4<T>& a, const Vector4<T>& b) { 01313 return ivec4( a.x() < b.x() ? 1 : 0, 01314 a.y() < b.y() ? 1 : 0, 01315 a.z() < b.z() ? 1 : 0, 01316 a.w() < b.w() ? 1 : 0 ); 01317 } 01318 01319 template<typename T> 01320 ivec3 lessThan(const Vector3<T>& a, const Vector3<T>& b) { 01321 return ivec3( a.x() < b.x() ? 1 : 0, 01322 a.y() < b.y() ? 1 : 0, 01323 a.z() < b.z() ? 1 : 0 ); 01324 } 01325 01326 template<typename T> 01327 ivec2 lessThan(const Vector2<T>& a, const Vector2<T>& b) { 01328 return ivec2( a.x() < b.x() ? 1 : 0, 01329 a.y() < b.y() ? 1 : 0 ); 01330 } 01331 01332 // --------------- lessThanEqual --------------- 01333 01334 template<typename T> 01335 ivec4 lessThanEqual(const Vector4<T>& a, const Vector4<T>& b) { 01336 return ivec4( a.x() <= b.x() ? 1 : 0, 01337 a.y() <= b.y() ? 1 : 0, 01338 a.z() <= b.z() ? 1 : 0, 01339 a.w() <= b.w() ? 1 : 0 ); 01340 } 01341 01342 template<typename T> 01343 ivec3 lessThanEqual(const Vector3<T>& a, const Vector3<T>& b) { 01344 return ivec3( a.x() <= b.x() ? 1 : 0, 01345 a.y() <= b.y() ? 1 : 0, 01346 a.z() <= b.z() ? 1 : 0 ); 01347 } 01348 01349 template<typename T> 01350 ivec2 lessThanEqual(const Vector2<T>& a, const Vector2<T>& b) { 01351 return ivec2( a.x() <= b.x() ? 1 : 0, 01352 a.y() <= b.y() ? 1 : 0 ); 01353 } 01354 01355 // --------------- greaterThan --------------- 01356 01357 template<typename T> 01358 ivec4 greaterThan(const Vector4<T>& a, const Vector4<T>& b) { 01359 return ivec4( a.x() > b.x() ? 1 : 0, 01360 a.y() > b.y() ? 1 : 0, 01361 a.z() > b.z() ? 1 : 0, 01362 a.w() > b.w() ? 1 : 0 ); 01363 } 01364 01365 template<typename T> 01366 ivec3 greaterThan(const Vector3<T>& a, const Vector3<T>& b) { 01367 return ivec3( a.x() > b.x() ? 1 : 0, 01368 a.y() > b.y() ? 1 : 0, 01369 a.z() > b.z() ? 1 : 0 ); 01370 } 01371 01372 template<typename T> 01373 ivec2 greaterThan(const Vector2<T>& a, const Vector2<T>& b) { 01374 return ivec2( a.x() > b.x() ? 1 : 0, 01375 a.y() > b.y() ? 1 : 0 ); 01376 } 01377 01378 // --------------- greaterThanEqual --------------- 01379 01380 template<typename T> 01381 ivec4 greaterThanEqual(const Vector4<T>& a, const Vector4<T>& b) { 01382 return ivec4( a.x() >= b.x() ? 1 : 0, 01383 a.y() >= b.y() ? 1 : 0, 01384 a.z() >= b.z() ? 1 : 0, 01385 a.w() >= b.w() ? 1 : 0 ); 01386 } 01387 01388 template<typename T> 01389 ivec3 greaterThanEqual(const Vector3<T>& a, const Vector3<T>& b) { 01390 return ivec3( a.x() >= b.x() ? 1 : 0, 01391 a.y() >= b.y() ? 1 : 0, 01392 a.z() >= b.z() ? 1 : 0 ); 01393 } 01394 01395 template<typename T> 01396 ivec2 greaterThanEqual(const Vector2<T>& a, const Vector2<T>& b) { 01397 return ivec2( a.x() >= b.x() ? 1 : 0, 01398 a.y() >= b.y() ? 1 : 0 ); 01399 } 01400 01401 // --------------- equal --------------- 01402 01403 template<typename T> 01404 ivec4 equal(const Vector4<T>& a, const Vector4<T>& b) { 01405 return ivec4( a.x() == b.x() ? 1 : 0, 01406 a.y() == b.y() ? 1 : 0, 01407 a.z() == b.z() ? 1 : 0, 01408 a.w() == b.w() ? 1 : 0 ); 01409 } 01410 01411 template<typename T> 01412 ivec3 equal(const Vector3<T>& a, const Vector3<T>& b) { 01413 return ivec3( a.x() == b.x() ? 1 : 0, 01414 a.y() == b.y() ? 1 : 0, 01415 a.z() == b.z() ? 1 : 0 ); 01416 } 01417 01418 template<typename T> 01419 ivec2 equal(const Vector2<T>& a, const Vector2<T>& b) { 01420 return ivec2( a.x() == b.x() ? 1 : 0, 01421 a.y() == b.y() ? 1 : 0 ); 01422 } 01423 01424 // --------------- notEqual --------------- 01425 01426 template<typename T> 01427 ivec4 notEqual(const Vector4<T>& a, const Vector4<T>& b) { 01428 return ivec4( a.x() != b.x() ? 1 : 0, 01429 a.y() != b.y() ? 1 : 0, 01430 a.z() != b.z() ? 1 : 0, 01431 a.w() != b.w() ? 1 : 0 ); 01432 } 01433 01434 template<typename T> 01435 ivec3 notEqual(const Vector3<T>& a, const Vector3<T>& b) { 01436 return ivec3( a.x() != b.x() ? 1 : 0, 01437 a.y() != b.y() ? 1 : 0, 01438 a.z() != b.z() ? 1 : 0 ); 01439 } 01440 01441 template<typename T> 01442 ivec2 notEqual(const Vector2<T>& a, const Vector2<T>& b) { 01443 return ivec2( a.x() != b.x() ? 1 : 0, 01444 a.y() != b.y() ? 1 : 0 ); 01445 } 01446 01447 // --------------- any --------------- 01448 01449 inline bool any(const ivec2& a) { return a.x() != 0 || a.y() != 0; } 01450 inline bool any(const ivec3& a) { return a.x() != 0 || a.y() != 0 || a.z() != 0; } 01451 inline bool any(const ivec4& a) { return a.x() != 0 || a.y() != 0 || a.z() != 0 || a.w() != 0; } 01452 01453 // --------------- all --------------- 01454 01455 inline bool all(const ivec2& a) { return a.x() != 0 && a.y() != 0; } 01456 inline bool all(const ivec3& a) { return a.x() != 0 && a.y() != 0 && a.z() != 0; } 01457 inline bool all(const ivec4& a) { return a.x() != 0 && a.y() != 0 && a.z() != 0 && a.w() != 0; } 01458 01459 // --------------- not --------------- 01460 01461 #if defined(_MSC_VER) 01462 inline ivec2 not(const ivec2& a) { return ivec2( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1); } 01463 inline ivec3 not(const ivec3& a) { return ivec3( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1, a.z() != 0 ? 0 : 1); } 01464 inline ivec4 not(const ivec4& a) { return ivec4( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1, a.z() != 0 ? 0 : 1, a.w() != 0 ? 0 : 1 ); } 01465 #endif 01466 } 01467 01468 #endif