Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/glsl_math.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.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

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:28.
Permission is granted to use this page to write and publish articles regarding Visualization Library.