# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlCore/GLSLmath.hpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    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 GLSL_MATH_INCLUDE_ONCE
    00033 #define GLSL_MATH_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   // --------------- trunc ---------------
    00722
    00723
    00724   template<typename T>
    00725   T trunc(T a) { return a - fract(a); }
    00726
    00727   template<typename T>
    00728   Vector2<T> trunc(const Vector2<T>& a) {
    00729     return Vector2<T>( a.x() - fract(a.x()),
    00730                   a.y() - fract(a.y()) );
    00731   }
    00732
    00733   template<typename T>
    00734   Vector3<T> trunc(const Vector3<T>& a) {
    00735     return Vector3<T>( a.x() - fract(a.x()),
    00736                   a.y() - fract(a.y()),
    00737                   a.z() - fract(a.z()) );
    00738   }
    00739
    00740   template<typename T>
    00741   Vector4<T> trunc(const Vector4<T>& a) {
    00742     return Vector4<T>( a.x() - fract(a.x()),
    00743                   a.y() - fract(a.y()),
    00744                   a.z() - fract(a.z()),
    00745                   a.w() - fract(a.w()) );
    00746   }
    00747
    00748   // --------------- round ---------------
    00749
    00750   template<typename T>
    00751   T round(T x) { return ((x - floor(x)) >= 0.5) ? ceil(x) : floor(x); }
    00752
    00753   template<typename T>
    00754   Vector2<T> round(const Vector2<T>& a) {
    00755     return Vector2<T>( round(a.x()),
    00756                   round(a.y()) );
    00757   }
    00758
    00759   template<typename T>
    00760   Vector3<T> round(const Vector3<T>& a) {
    00761     return Vector3<T>( round(a.x()),
    00762                   round(a.y()),
    00763                   round(a.z()) );
    00764   }
    00765
    00766   template<typename T>
    00767   Vector4<T> round(const Vector4<T>& a) {
    00768     return Vector4<T>( round(a.x()),
    00769                   round(a.y()),
    00770                   round(a.z()),
    00771                   round(a.w()) );
    00772   }
    00773
    00774   // --------------- modf ---------------
    00775
    00776   inline
    00777   float modf(float a, float& intpart) {
    00778     #if defined(_MSC_VER)
    00779       return ::modf(a,&intpart);
    00780     #else
    00781       double dintpart = intpart;
    00782       float r = (float)::modf((double)a,&dintpart);
    00783       intpart = (float)dintpart;
    00784       return r;
    00785     #endif
    00786   }
    00787
    00788   inline
    00789   double modf(double a, double& intpart) { return ::modf(a,&intpart); }
    00790
    00791   template<typename T>
    00792   Vector2<T> modf(const Vector2<T>& a, Vector2<T>& intpart) {
    00793     return Vector2<T>( modf(a.x(), intpart.x()),
    00794                   modf(a.y(), intpart.y()) );
    00795   }
    00796
    00797   template<typename T>
    00798   Vector3<T> modf(const Vector3<T>& a, Vector3<T>& intpart) {
    00799     return Vector3<T>( modf(a.x(), intpart.x()),
    00800                   modf(a.y(), intpart.y()),
    00801                   modf(a.z(), intpart.z()) );
    00802   }
    00803
    00804   template<typename T>
    00805   Vector4<T> modf(const Vector4<T>& a, Vector4<T>& intpart) {
    00806     return Vector4<T>( modf(a.x(), intpart.x()),
    00807                   modf(a.y(), intpart.y()),
    00808                   modf(a.z(), intpart.z()),
    00809                   modf(a.w(), intpart.w()) );
    00810   }
    00811
    00812   // --------------- roundEven ---------------
    00813
    00814   inline
    00815   float roundEven(float a, float epsilon)
    00816   {
    00817     if( a < 0 )
    00818       return -roundEven(-a, epsilon);
    00819     else
    00820     {
    00821       float intpart;
    00822       vl::modf( a, intpart );
    00823
    00824       // 0.5 case
    00825       if ((a -(intpart + 0.5f)) < epsilon)
    00826       {
    00827         // is even
    00828         if (::fmod(intpart, 2) < epsilon)
    00829           return intpart;
    00830         else
    00831         // is odd
    00832           return ceil(intpart + 0.5f);
    00833       }
    00834       else
    00835       // all the other cases
    00836         return round(a);
    00837     }
    00838   }
    00839
    00840   inline
    00841   double roundEven(double a, double epsilon)
    00842   {
    00843     if( a < 0 )
    00844       return -roundEven(-a, epsilon);
    00845     else
    00846     {
    00847       double intpart;
    00848       vl::modf( a, intpart );
    00849
    00850       // 0.5 case
    00851       if ((a -(intpart + 0.5)) < epsilon)
    00852       {
    00853         // is even
    00854         if (::fmod(intpart, 2) < epsilon)
    00855           return intpart;
    00856         else
    00857         // is odd
    00858           return ceil(intpart + 0.5);
    00859       }
    00860       else
    00861       // all the other cases
    00862         return round(a);
    00863     }
    00864   }
    00865
    00866   template<typename T>
    00867   Vector2<T> roundEven(const Vector2<T>& a, T epsilon = 0.00001) {
    00868     return Vector2<T>( roundEven(a.x(), epsilon),
    00869                        roundEven(a.y(), epsilon) );
    00870   }
    00871
    00872   template<typename T>
    00873   Vector3<T> roundEven(const Vector3<T>& a, T epsilon = 0.00001) {
    00874     return Vector3<T>( roundEven(a.x(), epsilon),
    00875                        roundEven(a.y(), epsilon),
    00876                        roundEven(a.z(), epsilon) );
    00877   }
    00878
    00879   template<typename T>
    00880   Vector4<T> roundEven(const Vector4<T>& a, T epsilon = 0.00001) {
    00881     return Vector4<T>( roundEven(a.x(), epsilon),
    00882                        roundEven(a.y(), epsilon),
    00883                        roundEven(a.z(), epsilon),
    00884                        roundEven(a.w(), epsilon) );
    00885   }
    00886
    00887   // --------------- ceil ---------------
    00888
    00889   template<typename T>
    00890   T ceil(T a) { return ::ceil(a); }
    00891
    00892   template<typename T>
    00893   Vector2<T> ceil(const Vector2<T>& a) {
    00894     return Vector2<T>( ::ceil(a.x()),
    00895                        ::ceil(a.y()) );
    00896   }
    00897
    00898   template<typename T>
    00899   Vector3<T> ceil(const Vector3<T>& a) {
    00900     return Vector3<T>( ::ceil(a.x()),
    00901                        ::ceil(a.y()),
    00902                        ::ceil(a.z()) );
    00903   }
    00904
    00905   template<typename T>
    00906   Vector4<T> ceil(const Vector4<T>& a) {
    00907     return Vector4<T>( ::ceil(a.x()),
    00908                        ::ceil(a.y()),
    00909                        ::ceil(a.z()),
    00910                        ::ceil(a.w()) );
    00911   }
    00912
    00913   // --------------- fract ---------------
    00914
    00915   template<typename T>
    00916   T fract(T a) { return a - floor(a); }
    00917
    00918   template<typename T>
    00919   Vector2<T> fract(const Vector2<T>& a) { return a - floor(a); }
    00920
    00921   template<typename T>
    00922   Vector3<T> fract(const Vector3<T>& a) { return a - floor(a); }
    00923
    00924   template<typename T>
    00925   Vector4<T> fract(const Vector4<T>& a) { return a - floor(a); }
    00926
    00927   // --------------- mod ---------------
    00928
    00929   template<typename T>
    00930   T mod(T a, T b) { return a - b * floor(a/b); }
    00931
    00932   template<typename T>
    00933   Vector2<T> mod(const Vector2<T>& a, T b) { return a - b * floor(a/b); }
    00934
    00935   template<typename T>
    00936   Vector3<T> mod(const Vector3<T>& a, T b) { return a - b * floor(a/b); }
    00937
    00938   template<typename T>
    00939   Vector4<T> mod(const Vector4<T>& a, T b) { return a - b * floor(a/b); }
    00940
    00941   template<typename T>
    00942   Vector2<T> mod(const Vector2<T>& a, const Vector2<T>& b) { return a - b * floor(a/b); }
    00943
    00944   template<typename T>
    00945   Vector3<T> mod(const Vector3<T>& a, const Vector3<T>& b) { return a - b * floor(a/b); }
    00946
    00947   template<typename T>
    00948   Vector4<T> mod(const Vector4<T>& a, const Vector4<T>& b) { return a - b * floor(a/b); }
    00949
    00950   // --------------- mix ---------------
    00951
    00952   template<typename T>
    00953   T mix(T a, T b, T t) { return a*(1-t) + b*t; }
    00954
    00955   template<typename T>
    00956   Vector2<T> mix(const Vector2<T>& a, const Vector2<T>& b, T t) { return a*(1-t) + b*t; }
    00957
    00958   template<typename T>
    00959   Vector3<T> mix(const Vector3<T>& a, const Vector3<T>& b, T t) { return a*(1-t) + b*t; }
    00960
    00961   template<typename T>
    00962   Vector4<T> mix(const Vector4<T>& a, const Vector4<T>& b, T t) { return a*(1-t) + b*t; }
    00963
    00964   template<typename T>
    00965   Vector2<T> mix(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& t)
    00966   {
    00967     return Vector2<T>( a.x()*(1-t.x()) + b.x()*t.x(),
    00968                   a.y()*(1-t.y()) + b.y()*t.y() );
    00969   }
    00970
    00971   template<typename T>
    00972   Vector3<T> mix(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& t)
    00973   {
    00974     return Vector3<T>( a.x()*(1-t.x()) + b.x()*t.x(),
    00975                   a.y()*(1-t.y()) + b.y()*t.y(),
    00976                   a.z()*(1-t.z()) + b.z()*t.z() );
    00977   }
    00978
    00979   template<typename T>
    00980   Vector4<T> mix(const Vector4<T>& a, const Vector4<T>& b, const Vector4<T>& t)
    00981   {
    00982     return Vector4<T>( a.x()*(1-t.x()) + b.x()*t.x(),
    00983                   a.y()*(1-t.y()) + b.y()*t.y(),
    00984                   a.z()*(1-t.z()) + b.z()*t.z(),
    00985                   a.w()*(1-t.w()) + b.w()*t.w() );
    00986   }
    00987
    00988   // --------------- step ---------------
    00989
    00990   template<typename T>
    00991   T step( T edge, T a ) { if (a<edge) return 0; else return 1; }
    00992
    00993   template<typename T>
    00994   Vector2<T> step( const Vector2<T>& edge, const Vector2<T>& a )
    00995   {
    00996     return Vector2<T>( a.x()<edge.x() ? 0 : (T)1,
    00997                        a.y()<edge.y() ? 0 : (T)1 );
    00998   }
    00999
    01000   template<typename T>
    01001   Vector3<T> step( const Vector3<T>& edge, const Vector3<T>& a )
    01002   {
    01003     return Vector3<T>( a.x()<edge.x() ? 0 : (T)1,
    01004                        a.y()<edge.y() ? 0 : (T)1,
    01005                        a.z()<edge.z() ? 0 : (T)1 );
    01006   }
    01007
    01008   template<typename T>
    01009   Vector4<T> step( const Vector4<T>& edge, const Vector4<T>& a )
    01010   {
    01011     return Vector4<T>( a.x()<edge.x() ? 0 : (T)1,
    01012                        a.y()<edge.y() ? 0 : (T)1,
    01013                        a.z()<edge.z() ? 0 : (T)1,
    01014                        a.w()<edge.w() ? 0 : (T)1 );
    01015   }
    01016   // --------------- smoothstep ---------------
    01017
    01018   template<typename T>
    01019   T smoothstep(T edge0, T edge1, T a)
    01020   {
    01021     T t = clamp( (a - edge0) / (edge1 - edge0), (T)0, (T)1);
    01022     return t * t * (3 - 2 * t);
    01023   }
    01024
    01025   template<typename T>
    01026   Vector2<T> smoothstep(const Vector2<T>& edge0, const Vector2<T>& edge1, const Vector2<T>& a)
    01027   {
    01028     Vector2<T> v;
    01029     T t;
    01030     t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t);
    01031     t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t);
    01032     return v;
    01033   }
    01034
    01035   template<typename T>
    01036   Vector3<T> smoothstep(const Vector3<T>& edge0, const Vector3<T>& edge1, const Vector3<T>& a)
    01037   {
    01038     Vector3<T> v;
    01039     T t;
    01040     t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t);
    01041     t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t);
    01042     t = clamp( (a.z() - edge0.z()) / (edge1.z() - edge0.z()), (T)0, (T)1); v.z() = t * t * (3 - 2 * t);
    01043     return v;
    01044   }
    01045
    01046   template<typename T>
    01047   Vector4<T> smoothstep(const Vector4<T>& edge0, const Vector4<T>& edge1, const Vector4<T>& a)
    01048   {
    01049     Vector4<T> v;
    01050     T t;
    01051     t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t);
    01052     t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t);
    01053     t = clamp( (a.z() - edge0.z()) / (edge1.z() - edge0.z()), (T)0, (T)1); v.z() = t * t * (3 - 2 * t);
    01054     t = clamp( (a.w() - edge0.w()) / (edge1.w() - edge0.w()), (T)0, (T)1); v.w() = t * t * (3 - 2 * t);
    01055     return v;
    01056   }
    01057
    01058   // --------------- isnan ---------------
    01059
    01060   template<typename T>
    01061   ivec2 isnan(const Vector2<T>& a) { return ivec2( isnan(a.x()), isnan(a.y()) ); }
    01062
    01063   template<typename T>
    01064   ivec3 isnan(const Vector3<T>& a) { return ivec3( isnan(a.x()), isnan(a.y()), isnan(a.z()) ); }
    01065
    01066   template<typename T>
    01067   ivec4 isnan(const Vector4<T>& a) { return ivec4( isnan(a.x()), isnan(a.y()), isnan(a.z()), isnan(a.w()) ); }
    01068
    01069   // --------------- isinf ---------------
    01070
    01071   template<typename T>
    01072   ivec2 isinf(const Vector2<T>& a) { return ivec2( isinf(a.x()), isinf(a.y()) ); }
    01073
    01074   template<typename T>
    01075   ivec3 isinf(const Vector3<T>& a) { return ivec3( isinf(a.x()), isinf(a.y()), isinf(a.z()) ); }
    01076
    01077   template<typename T>
    01078   ivec4 isinf(const Vector4<T>& a) { return ivec4( isinf(a.x()), isinf(a.y()), isinf(a.z()), isinf(a.w()) ); }
    01079
    01080   // --------------- geometric functions ---------------
    01081
    01082   // --------------- length ---------------
    01083
    01084   template<typename T>
    01085   T length(T v) { return v; }
    01086
    01087   template<typename T>
    01088   T length(const Vector2<T>& v) { return v.length(); }
    01089
    01090   template<typename T>
    01091   T length(const Vector3<T>& v) { return v.length(); }
    01092
    01093   template<typename T>
    01094   T length(const Vector4<T>& v) { return v.length(); }
    01095
    01096   // --------------- distance ---------------
    01097
    01098   template<typename T>
    01099   T distance(T p0, T p1) { return length(p0-p1); }
    01100
    01101   template<typename T>
    01102   T distance(const Vector2<T>& p0, const Vector2<T>& p1) { return length(p0-p1); }
    01103
    01104   template<typename T>
    01105   T distance(const Vector3<T>& p0, const Vector3<T>& p1) { return length(p0-p1); }
    01106
    01107   template<typename T>
    01108   T distance(const Vector4<T>& p0, const Vector4<T>& p1) { return length(p0-p1); }
    01109
    01110   // --------------- dot ---------------
    01111
    01112   inline float dot(float a, float b) { return a*b; }
    01113
    01114   // ....................................
    01115
    01116   inline double dot(double a, double b) { return a*b; }
    01117
    01118   // ....................................
    01119
    01120   inline Real dot(int a, int b) { return (Real)a*b; }
    01121
    01122   // ....................................
    01123
    01124   inline Real dot(unsigned int a, unsigned int b) { return (Real)a*b; }
    01125
    01126   // --------------- normalize ---------------
    01127
    01128   template<typename T>
    01129   T normalize(T) { return (T)1; }
    01130
    01131   template<typename T>
    01132   Vector2<T> normalize(const Vector2<T>& v) { Vector2<T> t = v; t.normalize(); return t; }
    01133
    01134   template<typename T>
    01135   Vector3<T> normalize(const Vector3<T>& v) { Vector3<T> t = v; t.normalize(); return t; }
    01136
    01137   template<typename T>
    01138   Vector4<T> normalize(const Vector4<T>& v) { Vector4<T> t = v; t.normalize(); return t; }
    01139
    01140   // --------------- faceforward ---------------
    01141
    01142   template<typename T>
    01143   T faceforward(T N, T I, T Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; }
    01144
    01145   template<typename T>
    01146   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; }
    01147
    01148   template<typename T>
    01149   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; }
    01150
    01151   template<typename T>
    01152   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; }
    01153
    01154   // --------------- reflect ----------------
    01155
    01156   template<typename T>
    01157   T reflect(T I, T N) { return I-2*dot(N,I)*N; }
    01158
    01159   template<typename T>
    01160   Vector2<T> reflect(const Vector2<T>& I, const Vector2<T>& N) { return I-2*dot(N,I)*N; }
    01161
    01162   template<typename T>
    01163   Vector3<T> reflect(const Vector3<T>& I, const Vector3<T>& N) { return I-2*dot(N,I)*N; }
    01164
    01165   template<typename T>
    01166   Vector4<T> reflect(const Vector4<T>& I, const Vector4<T>& N) { return I-2*dot(N,I)*N; }
    01167
    01168   // --------------- refract ---------------
    01169
    01170   template<typename T>
    01171   T refract(T I, T N, T eta)
    01172   {
    01173     T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
    01174     if (k < 0)
    01175       return 0;
    01176     else
    01177       return eta * I - (eta * dot(N, I) + ::sqrt(k)) * N;
    01178   }
    01179
    01180   template<typename T>
    01181   Vector2<T> refract(const Vector2<T>& I, const Vector2<T>& N, T eta)
    01182   {
    01183     T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
    01184     if (k < 0)
    01185       return Vector2<T>(0,0);
    01186     else
    01187       return eta * I - N * (eta * dot(N, I) + ::sqrt(k));
    01188   }
    01189
    01190   template<typename T>
    01191   Vector3<T> refract(const Vector3<T>& I, const Vector3<T>& N, T eta)
    01192   {
    01193     T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
    01194     if (k < 0)
    01195       return Vector3<T>(0,0,0);
    01196     else
    01197       return eta * I - N * (eta * dot(N, I) + ::sqrt(k));
    01198   }
    01199
    01200   template<typename T>
    01201   Vector4<T> refract(const Vector4<T>& I, const Vector4<T>& N, T eta)
    01202   {
    01203     T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
    01204     if (k < 0)
    01205       return Vector4<T>(0,0,0,0);
    01206     else
    01207       return eta * I - N * (eta * dot(N, I) + ::sqrt(k));
    01208   }
    01209
    01210   // --------------- matrix functions ---------------
    01211
    01212   // --------------- matrixCompMult ---------------
    01213
    01214   template<typename T>
    01215   Matrix2<T> matrixCompMult(const Matrix2<T>& a, const Matrix2<T>& b)
    01216   {
    01217     Matrix2<T> t;
    01218     for(int i=0; i<2; ++i)
    01219       for(int j=0; j<2; ++j)
    01220         t.e(j,i) = a.e(j,i) * b.e(j,i);
    01221     return t;
    01222   }
    01223
    01224   template<typename T>
    01225   Matrix3<T> matrixCompMult(const Matrix3<T>& a, const Matrix3<T>& b)
    01226   {
    01227     Matrix3<T> t;
    01228     for(int i=0; i<3; ++i)
    01229       for(int j=0; j<3; ++j)
    01230         t.e(j,i) = a.e(j,i) * b.e(j,i);
    01231     return t;
    01232   }
    01233
    01234   template<typename T>
    01235   Matrix4<T> matrixCompMult(const Matrix4<T>& a, const Matrix4<T>& b)
    01236   {
    01237     Matrix4<T> t;
    01238     for(int i=0; i<4; ++i)
    01239       for(int j=0; j<4; ++j)
    01240         t.e(j,i) = a.e(j,i) * b.e(j,i);
    01241     return t;
    01242   }
    01243
    01244   // --------------- outerProduct ---------------
    01245
    01246   template<typename T>
    01247   Matrix2<T> outerProduct(const Vector2<T>& a, const Vector2<T>& b)
    01248   {
    01249     Matrix2<T> m;
    01250     for(int i=0; i<2; ++i)
    01251       for(int j=0; j<2; ++j)
    01252         m.e(i,j) = a[i] * b[j];
    01253     return m;
    01254   }
    01255
    01256   template<typename T>
    01257   Matrix3<T> outerProduct(const Vector3<T>& a, const Vector3<T>& b)
    01258   {
    01259     Matrix3<T> m;
    01260     for(int i=0; i<3; ++i)
    01261       for(int j=0; j<3; ++j)
    01262         m.e(i,j) = a[i] * b[j];
    01263     return m;
    01264   }
    01265
    01266   template<typename T>
    01267   Matrix4<T> outerProduct(const Vector4<T>& a, const Vector4<T>& b)
    01268   {
    01269     Matrix4<T> m;
    01270     for(int i=0; i<4; ++i)
    01271       for(int j=0; j<4; ++j)
    01272         m.e(i,j) = a[i] * b[j];
    01273     return m;
    01274   }
    01275
    01276   // --------------- transpose ---------------
    01277
    01278   template<typename T>
    01279   Matrix2<T> transpose(const Matrix2<T>& a)
    01280   {
    01281     Matrix2<T> t;
    01282     for(int i=0; i<2; ++i)
    01283       for(int j=0; j<2; ++j)
    01284         t.e(j,i) = a.e(i,j);
    01285     return t;
    01286   }
    01287
    01288   template<typename T>
    01289   Matrix3<T> transpose(const Matrix3<T>& a)
    01290   {
    01291     Matrix3<T> t;
    01292     for(int i=0; i<3; ++i)
    01293       for(int j=0; j<3; ++j)
    01294         t.e(j,i) = a.e(i,j);
    01295     return t;
    01296   }
    01297
    01298   template<typename T>
    01299   Matrix4<T> transpose(const Matrix4<T>& a)
    01300   {
    01301     Matrix4<T> t;
    01302     for(int i=0; i<4; ++i)
    01303       for(int j=0; j<4; ++j)
    01304         t.e(j,i) = a.e(i,j);
    01305     return t;
    01306   }
    01307
    01308   // --------------- vector relational functions ---------------
    01309
    01310   // --------------- lessThan ---------------
    01311
    01312   template<typename T>
    01313   ivec4 lessThan(const Vector4<T>& a, const Vector4<T>& b) {
    01314     return ivec4( a.x() < b.x() ? 1 : 0,
    01315                   a.y() < b.y() ? 1 : 0,
    01316                   a.z() < b.z() ? 1 : 0,
    01317                   a.w() < b.w() ? 1 : 0 );
    01318   }
    01319
    01320   template<typename T>
    01321   ivec3 lessThan(const Vector3<T>& a, const Vector3<T>& b) {
    01322     return ivec3( a.x() < b.x() ? 1 : 0,
    01323                   a.y() < b.y() ? 1 : 0,
    01324                   a.z() < b.z() ? 1 : 0 );
    01325   }
    01326
    01327   template<typename T>
    01328   ivec2 lessThan(const Vector2<T>& a, const Vector2<T>& b) {
    01329     return ivec2( a.x() < b.x() ? 1 : 0,
    01330                   a.y() < b.y() ? 1 : 0 );
    01331   }
    01332
    01333   // --------------- lessThanEqual ---------------
    01334
    01335   template<typename T>
    01336   ivec4 lessThanEqual(const Vector4<T>& a, const Vector4<T>& b) {
    01337     return ivec4( a.x() <= b.x() ? 1 : 0,
    01338                   a.y() <= b.y() ? 1 : 0,
    01339                   a.z() <= b.z() ? 1 : 0,
    01340                   a.w() <= b.w() ? 1 : 0 );
    01341   }
    01342
    01343   template<typename T>
    01344   ivec3 lessThanEqual(const Vector3<T>& a, const Vector3<T>& b) {
    01345     return ivec3( a.x() <= b.x() ? 1 : 0,
    01346                   a.y() <= b.y() ? 1 : 0,
    01347                   a.z() <= b.z() ? 1 : 0 );
    01348   }
    01349
    01350   template<typename T>
    01351   ivec2 lessThanEqual(const Vector2<T>& a, const Vector2<T>& b) {
    01352     return ivec2( a.x() <= b.x() ? 1 : 0,
    01353                   a.y() <= b.y() ? 1 : 0 );
    01354   }
    01355
    01356   // --------------- greaterThan ---------------
    01357
    01358   template<typename T>
    01359   ivec4 greaterThan(const Vector4<T>& a, const Vector4<T>& b) {
    01360     return ivec4( a.x() > b.x() ? 1 : 0,
    01361                   a.y() > b.y() ? 1 : 0,
    01362                   a.z() > b.z() ? 1 : 0,
    01363                   a.w() > b.w() ? 1 : 0 );
    01364   }
    01365
    01366   template<typename T>
    01367   ivec3 greaterThan(const Vector3<T>& a, const Vector3<T>& b) {
    01368     return ivec3( a.x() > b.x() ? 1 : 0,
    01369                   a.y() > b.y() ? 1 : 0,
    01370                   a.z() > b.z() ? 1 : 0 );
    01371   }
    01372
    01373   template<typename T>
    01374   ivec2 greaterThan(const Vector2<T>& a, const Vector2<T>& b) {
    01375     return ivec2( a.x() > b.x() ? 1 : 0,
    01376                   a.y() > b.y() ? 1 : 0 );
    01377   }
    01378
    01379   // --------------- greaterThanEqual ---------------
    01380
    01381   template<typename T>
    01382   ivec4 greaterThanEqual(const Vector4<T>& a, const Vector4<T>& b) {
    01383     return ivec4( a.x() >= b.x() ? 1 : 0,
    01384                   a.y() >= b.y() ? 1 : 0,
    01385                   a.z() >= b.z() ? 1 : 0,
    01386                   a.w() >= b.w() ? 1 : 0 );
    01387   }
    01388
    01389   template<typename T>
    01390   ivec3 greaterThanEqual(const Vector3<T>& a, const Vector3<T>& b) {
    01391     return ivec3( a.x() >= b.x() ? 1 : 0,
    01392                   a.y() >= b.y() ? 1 : 0,
    01393                   a.z() >= b.z() ? 1 : 0 );
    01394   }
    01395
    01396   template<typename T>
    01397   ivec2 greaterThanEqual(const Vector2<T>& a, const Vector2<T>& b) {
    01398     return ivec2( a.x() >= b.x() ? 1 : 0,
    01399                   a.y() >= b.y() ? 1 : 0 );
    01400   }
    01401
    01402   // --------------- equal ---------------
    01403
    01404   template<typename T>
    01405   ivec4 equal(const Vector4<T>& a, const Vector4<T>& b) {
    01406     return ivec4( a.x() == b.x() ? 1 : 0,
    01407                   a.y() == b.y() ? 1 : 0,
    01408                   a.z() == b.z() ? 1 : 0,
    01409                   a.w() == b.w() ? 1 : 0 );
    01410   }
    01411
    01412   template<typename T>
    01413   ivec3 equal(const Vector3<T>& a, const Vector3<T>& b) {
    01414     return ivec3( a.x() == b.x() ? 1 : 0,
    01415                   a.y() == b.y() ? 1 : 0,
    01416                   a.z() == b.z() ? 1 : 0 );
    01417   }
    01418
    01419   template<typename T>
    01420   ivec2 equal(const Vector2<T>& a, const Vector2<T>& b) {
    01421     return ivec2( a.x() == b.x() ? 1 : 0,
    01422                   a.y() == b.y() ? 1 : 0 );
    01423   }
    01424
    01425   // --------------- notEqual ---------------
    01426
    01427   template<typename T>
    01428   ivec4 notEqual(const Vector4<T>& a, const Vector4<T>& b) {
    01429     return ivec4( a.x() != b.x() ? 1 : 0,
    01430                   a.y() != b.y() ? 1 : 0,
    01431                   a.z() != b.z() ? 1 : 0,
    01432                   a.w() != b.w() ? 1 : 0 );
    01433   }
    01434
    01435   template<typename T>
    01436   ivec3 notEqual(const Vector3<T>& a, const Vector3<T>& b) {
    01437     return ivec3( a.x() != b.x() ? 1 : 0,
    01438                   a.y() != b.y() ? 1 : 0,
    01439                   a.z() != b.z() ? 1 : 0 );
    01440   }
    01441
    01442   template<typename T>
    01443   ivec2 notEqual(const Vector2<T>& a, const Vector2<T>& b) {
    01444     return ivec2( a.x() != b.x() ? 1 : 0,
    01445                   a.y() != b.y() ? 1 : 0 );
    01446   }
    01447
    01448   // --------------- any ---------------
    01449
    01450   inline bool any(const ivec2& a) { return a.x() != 0 || a.y() != 0; }
    01451   inline bool any(const ivec3& a) { return a.x() != 0 || a.y() != 0 || a.z() != 0; }
    01452   inline bool any(const ivec4& a) { return a.x() != 0 || a.y() != 0 || a.z() != 0 || a.w() != 0; }
    01453
    01454   // --------------- all ---------------
    01455
    01456   inline bool all(const ivec2& a) { return a.x() != 0 && a.y() != 0; }
    01457   inline bool all(const ivec3& a) { return a.x() != 0 && a.y() != 0 && a.z() != 0; }
    01458   inline bool all(const ivec4& a) { return a.x() != 0 && a.y() != 0 && a.z() != 0 && a.w() != 0; }
    01459
    01460   // --------------- not ---------------
    01461
    01462 #if defined(_MSC_VER)
    01463   inline ivec2 not(const ivec2& a) { return ivec2( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1); }
    01464   inline ivec3 not(const ivec3& a) { return ivec3( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1, a.z() != 0 ? 0 : 1); }
    01465   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 ); }
    01466 #endif
    01467 }
    01468
    01469 #endif

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:20.
Permission is granted to use this page to write and publish articles regarding Visualization Library.