hostsupport/hostopenvg/src/riMath.h
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 24 a3f46bb01be2
child 69 3f914c77c2e9
equal deleted inserted replaced
52:39e5f73667ba 53:c2ef9095503a
       
     1 #ifndef __RIMATH_H
       
     2 #define __RIMATH_H
       
     3 
       
     4 /*------------------------------------------------------------------------
       
     5  *
       
     6  * OpenVG 1.1 Reference Implementation
       
     7  * -----------------------------------
       
     8  *
       
     9  * Copyright (c) 2007 The Khronos Group Inc.
       
    10  * Portions copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
    11  *
       
    12  * Permission is hereby granted, free of charge, to any person obtaining a
       
    13  * copy of this software and /or associated documentation files
       
    14  * (the "Materials "), to deal in the Materials without restriction,
       
    15  * including without limitation the rights to use, copy, modify, merge,
       
    16  * publish, distribute, sublicense, and/or sell copies of the Materials,
       
    17  * and to permit persons to whom the Materials are furnished to do so,
       
    18  * subject to the following conditions:
       
    19  *
       
    20  * The above copyright notice and this permission notice shall be included
       
    21  * in all copies or substantial portions of the Materials.
       
    22  *
       
    23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       
    26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
       
    27  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
       
    28  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
       
    29  * THE USE OR OTHER DEALINGS IN THE MATERIALS.
       
    30  *
       
    31  *//**
       
    32  * \file
       
    33  * \brief	Math functions, Vector and Matrix classes.
       
    34  * \note
       
    35  *//*-------------------------------------------------------------------*/
       
    36 
       
    37 #ifndef __RIDEFS_H
       
    38 #include "riDefs.h"
       
    39 #endif
       
    40 
       
    41 #include <math.h>
       
    42 
       
    43 namespace OpenVGRI
       
    44 {
       
    45 
       
    46 /*-------------------------------------------------------------------*//*!
       
    47 * \brief
       
    48 * \param
       
    49 * \return
       
    50 * \note
       
    51 *//*-------------------------------------------------------------------*/
       
    52 
       
    53 RI_INLINE int		RI_ISNAN(float a)
       
    54 {
       
    55     RIfloatInt p;
       
    56     p.f = a;
       
    57     unsigned int exponent = (p.i>>23) & 0xff;
       
    58     unsigned int mantissa = p.i & 0x7fffff;
       
    59     if(exponent == 255 && mantissa)
       
    60         return 1;
       
    61     return 0;
       
    62 }
       
    63 
       
    64 #if (RI_MANTISSA_BITS > 23)
       
    65 #error RI_MANTISSA_BITS is greater than 23
       
    66 #elif (RI_EXPONENT_BITS > 8)
       
    67 #error RI_EXPONENT_BITS is greater than 8
       
    68 #elif (RI_MANTISSA_BITS != 23) || (RI_EXPONENT_BITS != 8)
       
    69 
       
    70 class RIfloat
       
    71 {
       
    72 public:
       
    73     RIfloat() : v(0.0f)						{ removeBits(); }
       
    74     RIfloat(float a) : v(a)					{ removeBits(); }
       
    75     RIfloat(double a) : v((float)a)			{ removeBits(); }
       
    76     RIfloat(int a) : v((float)a)			{ removeBits(); }
       
    77     RIfloat(unsigned int a) : v((float)a)	{ removeBits(); }
       
    78     RIfloat&	operator=(const RIfloat &a)	{ v = a.v; removeBits(); return *this; }
       
    79     RIfloat&	operator+=(const RIfloat &a){ v += a.v; removeBits(); return *this; }
       
    80     RIfloat&	operator-=(const RIfloat &a){ v -= a.v; removeBits(); return *this; }
       
    81     RIfloat&	operator*=(const RIfloat &a){ v *= a.v; removeBits(); return *this; }
       
    82     RIfloat&	operator/=(const RIfloat &a){ v /= a.v; removeBits(); return *this; }
       
    83     RIfloat		operator-() const			{ return -v; }
       
    84     operator float() const					{ return v; }
       
    85     operator double() const					{ return (double)v; }
       
    86     operator int() const					{ return (int)v; }
       
    87 
       
    88     friend RIfloat	operator+(const RIfloat &a, const RIfloat &b);
       
    89     friend RIfloat	operator+(float a, const RIfloat &b);
       
    90     friend RIfloat	operator+(const RIfloat &a, float b);
       
    91     friend RIfloat	operator-(const RIfloat &a, const RIfloat &b);
       
    92     friend RIfloat	operator-(float a, const RIfloat &b);
       
    93     friend RIfloat	operator-(const RIfloat &a, float b);
       
    94     friend RIfloat	operator*(const RIfloat &a, const RIfloat &b);
       
    95     friend RIfloat	operator*(float a, const RIfloat &b);
       
    96     friend RIfloat	operator*(const RIfloat &a, float b);
       
    97     friend RIfloat	operator/(const RIfloat &a, const RIfloat &b);
       
    98     friend RIfloat	operator/(float a, const RIfloat &b);
       
    99     friend RIfloat	operator/(const RIfloat &a, float b);
       
   100 
       
   101     friend bool		operator<(const RIfloat &a, const RIfloat &b);
       
   102     friend bool		operator<(float a, const RIfloat &b);
       
   103     friend bool		operator<(const RIfloat &a, float b);
       
   104     friend bool		operator>(const RIfloat &a, const RIfloat &b);
       
   105     friend bool		operator>(float a, const RIfloat &b);
       
   106     friend bool		operator>(const RIfloat &a, float b);
       
   107     friend bool		operator<=(const RIfloat &a, const RIfloat &b);
       
   108     friend bool		operator<=(float a, const RIfloat &b);
       
   109     friend bool		operator<=(const RIfloat &a, float b);
       
   110     friend bool		operator>=(const RIfloat &a, const RIfloat &b);
       
   111     friend bool		operator>=(float a, const RIfloat &b);
       
   112     friend bool		operator>=(const RIfloat &a, float b);
       
   113     friend bool		operator==(const RIfloat &a, const RIfloat &b);
       
   114     friend bool		operator==(float a, const RIfloat &b);
       
   115     friend bool		operator==(const RIfloat &a, float b);
       
   116     friend bool		operator!=(const RIfloat &a, const RIfloat &b);
       
   117     friend bool		operator!=(float a, const RIfloat &b);
       
   118     friend bool		operator!=(const RIfloat &a, float b);
       
   119 private:
       
   120     void	removeBits()
       
   121     {
       
   122         RIfloatInt p;
       
   123         p.f = v;
       
   124         unsigned int exponent = (p.i>>23) & 0xff;
       
   125         if(exponent == 0 || exponent == 255)
       
   126             return;	//zero, denormal, infinite, or NaN
       
   127 
       
   128         p.i &= ~((1<<(23-RI_MANTISSA_BITS))-1);
       
   129 
       
   130 #if (RI_EXPONENT_BITS != 8)
       
   131         if (exponent > 127 + (1 << (RI_EXPONENT_BITS-1)))
       
   132             exponent = 127 + (1 << (RI_EXPONENT_BITS-1));
       
   133 
       
   134         if (exponent < 127 + 1 - (1 << (RI_EXPONENT_BITS-1)))
       
   135             exponent = 127 + 1 - (1 << (RI_EXPONENT_BITS-1));
       
   136 
       
   137         p.i &= ~(0xff<<23);
       
   138         p.i |= exponent<<23;
       
   139 #endif
       
   140         v = p.f;
       
   141     }
       
   142 
       
   143     float		v;
       
   144 };
       
   145 
       
   146 RI_INLINE RIfloat operator+(const RIfloat &a, const RIfloat &b)	{ return RIfloat(a.v+b.v); }
       
   147 RI_INLINE RIfloat operator+(float a, const RIfloat &b)			{ return RIfloat(a+b.v); }
       
   148 RI_INLINE RIfloat operator+(const RIfloat &a, float b)			{ return RIfloat(a.v+b); }
       
   149 RI_INLINE RIfloat operator-(const RIfloat &a, const RIfloat &b)	{ return RIfloat(a.v-b.v); }
       
   150 RI_INLINE RIfloat operator-(float a, const RIfloat &b)			{ return RIfloat(a-b.v); }
       
   151 RI_INLINE RIfloat operator-(const RIfloat &a, float b)			{ return RIfloat(a.v-b); }
       
   152 RI_INLINE RIfloat operator*(const RIfloat &a, const RIfloat &b)	{ return RIfloat(a.v*b.v); }
       
   153 RI_INLINE RIfloat operator*(float a, const RIfloat &b)			{ return RIfloat(a*b.v); }
       
   154 RI_INLINE RIfloat operator*(const RIfloat &a, float b)			{ return RIfloat(a.v*b); }
       
   155 RI_INLINE RIfloat operator/(const RIfloat &a, const RIfloat &b)	{ return RIfloat(a.v/b.v); }
       
   156 RI_INLINE RIfloat operator/(float a, const RIfloat &b)			{ return RIfloat(a/b.v); }
       
   157 RI_INLINE RIfloat operator/(const RIfloat &a, float b)			{ return RIfloat(a.v/b); }
       
   158 
       
   159 RI_INLINE bool operator<(const RIfloat &a, const RIfloat &b)	{ return a.v < b.v ? true : false; }
       
   160 RI_INLINE bool operator<(float a, const RIfloat &b)				{ return a < b.v ? true : false; }
       
   161 RI_INLINE bool operator<(const RIfloat &a, float b)				{ return a.v < b ? true : false; }
       
   162 RI_INLINE bool operator>(const RIfloat &a, const RIfloat &b)	{ return a.v > b.v ? true : false; }
       
   163 RI_INLINE bool operator>(float a, const RIfloat &b)				{ return a > b.v ? true : false; }
       
   164 RI_INLINE bool operator>(const RIfloat &a, float b)				{ return a.v > b ? true : false; }
       
   165 RI_INLINE bool operator<=(const RIfloat &a, const RIfloat &b)	{ return a.v <= b.v ? true : false; }
       
   166 RI_INLINE bool operator<=(float a, const RIfloat &b)			{ return a <= b.v ? true : false; }
       
   167 RI_INLINE bool operator<=(const RIfloat &a, float b)			{ return a.v <= b ? true : false; }
       
   168 RI_INLINE bool operator>=(const RIfloat &a, const RIfloat &b)	{ return a.v >= b.v ? true : false; }
       
   169 RI_INLINE bool operator>=(float a, const RIfloat &b)			{ return a >= b.v ? true : false; }
       
   170 RI_INLINE bool operator>=(const RIfloat &a, float b)			{ return a.v >= b ? true : false; }
       
   171 RI_INLINE bool operator==(const RIfloat &a, const RIfloat &b)	{ return a.v == b.v ? true : false; }
       
   172 RI_INLINE bool operator==(float a, const RIfloat &b)			{ return a == b.v ? true : false; }
       
   173 RI_INLINE bool operator==(const RIfloat &a, float b)			{ return a.v == b ? true : false; }
       
   174 RI_INLINE bool operator!=(const RIfloat &a, const RIfloat &b)	{ return a.v != b.v ? true : false; }
       
   175 RI_INLINE bool operator!=(float a, const RIfloat &b)			{ return a != b.v ? true : false; }
       
   176 RI_INLINE bool operator!=(const RIfloat &a, float b)			{ return a.v != b ? true : false; }
       
   177 
       
   178 #else
       
   179 typedef float RIfloat;
       
   180 #endif
       
   181 
       
   182 #define	RI_PI						3.141592654f
       
   183 
       
   184 RI_INLINE RIfloat   RI_FRAC(RIfloat f)                          { return f - (RIfloat)(int)f; }
       
   185 RI_INLINE int       RI_ROUND_TO_INT(RIfloat v)                  { return (v >= 0.0f) ? (int)(v+0.5f) : (int)(v-0.5f); }
       
   186 RI_INLINE RIfloat	RI_MAX(RIfloat a, RIfloat b)				{ return (a > b) ? a : b; }
       
   187 RI_INLINE int		RI_MAX(int a, int b)						{ return (a > b) ? a : b; }
       
   188 RI_INLINE RIfloat	RI_MIN(RIfloat a, RIfloat b)				{ return (a < b) ? a : b; }
       
   189 RI_INLINE int		RI_MIN(int a, int b)						{ return (a < b) ? a : b; }
       
   190 RI_INLINE RIfloat	RI_CLAMP(RIfloat a, RIfloat l, RIfloat h)	{ if(RI_ISNAN(a)) return l; RI_ASSERT(l <= h); return (a < l) ? l : (a > h) ? h : a; }
       
   191 RI_INLINE int       RI_CEIL(RIfloat a) {return (int)ceilf(a);}
       
   192 RI_INLINE int       RI_FLOOR(RIfloat a) { return (int)floorf(a); }
       
   193 RI_INLINE void		RI_SWAP(RIfloat &a, RIfloat &b)				{ RIfloat tmp = a; a = b; b = tmp; }
       
   194 RI_INLINE RIfloat	RI_ABS(RIfloat a)							{ return (a < 0.0f) ? -a : a; }
       
   195 RI_INLINE RIfloat	RI_SQR(RIfloat a)							{ return a * a; }
       
   196 RI_INLINE RIfloat	RI_DEG_TO_RAD(RIfloat a)					{ return a * RI_PI / 180.0f; }
       
   197 RI_INLINE RIfloat	RI_RAD_TO_DEG(RIfloat a)					{ return a * 180.0f/ RI_PI; }
       
   198 RI_INLINE RIfloat	RI_MOD(RIfloat a, RIfloat b)				{ if(RI_ISNAN(a) || RI_ISNAN(b)) return 0.0f; RI_ASSERT(b >= 0.0f); if(b == 0.0f) return 0.0f; RIfloat f = (RIfloat)fmod(a, b); if(f < 0.0f) f += b; RI_ASSERT(f >= 0.0f && f <= b); return f; }
       
   199 
       
   200 #define RI_ANY_SWAP(type, a, b) {type tmp = a; a = b; b = tmp;}
       
   201 
       
   202 RI_INLINE void      RI_INT16_SWAP(RIint16 &a, RIint16 &b) {RIint16 tmp = a; a = b; b = tmp;}
       
   203 RI_INLINE int       RI_INT_ABS(int a)                   { return (a >= 0) ? a : -a; }
       
   204 RI_INLINE int		RI_INT_MAX(int a, int b)			{ return (a > b) ? a : b; }
       
   205 RI_INLINE int		RI_INT_MIN(int a, int b)			{ return (a < b) ? a : b; }
       
   206 RI_INLINE int       RI_INT_CLAMP(int a, int l, int h)   { return (a < l) ? l : (a > h) ? h : a; }
       
   207 RI_INLINE void		RI_INT_SWAP(int &a, int &b)			{ int tmp = a; a = b; b = tmp; }
       
   208 RI_INLINE int		RI_INT_MOD(int a, int b)			{ RI_ASSERT(b >= 0); if(!b) return 0; int i = a % b; if(i < 0) i += b; RI_ASSERT(i >= 0 && i < b); return i; }
       
   209 RI_INLINE int		RI_INT_ADDSATURATE(int a, int b)	{ RI_ASSERT(b >= 0); int r = a + b; return (r >= a) ? r : RI_INT32_MAX; }
       
   210 
       
   211 RI_INLINE RIfloat validateFloat(RIfloat f)
       
   212 {
       
   213     //this function is used for all floating point input values
       
   214     if(RI_ISNAN(f)) return 0.0f;	//convert NaN to zero
       
   215     return RI_CLAMP(f, -RI_FLOAT_MAX, RI_FLOAT_MAX);	//clamp +-inf to +-RIfloat max
       
   216 }
       
   217 
       
   218 
       
   219 
       
   220 RI_INLINE int       RI_SHL(int a, int sh)
       
   221 {
       
   222     RI_ASSERT(sh >= 0 && sh <= 31);
       
   223     int r = a << sh;
       
   224     RI_ASSERT(a >= 0 ? (r >= 0) : (r < 0));
       
   225     return r;
       
   226 }
       
   227 
       
   228 RI_INLINE int RI_SAT_SHL(RIint32 a, int sh)
       
   229 {
       
   230     RI_ASSERT(sh >= 0 && sh <= 31);
       
   231 
       
   232     RIint64 r = ((RIint64)a) << sh;
       
   233 
       
   234     if (r > 0x7fffffff)
       
   235         return 0x7fffffff;
       
   236     else if (r < (long long)(int)0x80000000)
       
   237         return 0x80000000;
       
   238 
       
   239     return (RIint32)r;
       
   240 }
       
   241 
       
   242 RI_INLINE int RI_SHR(int a, int sh)
       
   243 {
       
   244     RI_ASSERT(sh >= 0 && sh <= 31);
       
   245     int r = a >> sh;
       
   246     return r;
       
   247 }
       
   248 
       
   249 RI_INLINE RIfloat RI_FLOAT_TO_FX(RIfloat f, unsigned int n) { return (RIfloat)RI_ROUND_TO_INT(f * (RIfloat)RI_SHL(1, n)); }
       
   250 
       
   251 class Matrix3x3;
       
   252 class Vector2;
       
   253 class Vector3;
       
   254 
       
   255 //==============================================================================================
       
   256 
       
   257 //MatrixRxC, R = number of rows, C = number of columns
       
   258 //indexing: matrix[row][column]
       
   259 //Matrix3x3 inline functions cannot be inside the class because Vector3 is not defined yet when Matrix3x3 is defined
       
   260 
       
   261 class Matrix3x3
       
   262 {
       
   263 public:
       
   264     RI_INLINE					Matrix3x3		();						//initialized to identity
       
   265     RI_INLINE					Matrix3x3		( const Matrix3x3& m );
       
   266     RI_INLINE					Matrix3x3		( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 );
       
   267     RI_INLINE					~Matrix3x3		();
       
   268     RI_INLINE Matrix3x3&		operator=		( const Matrix3x3& m );
       
   269     RI_INLINE Vector3&			operator[]		( int i );				//returns a row vector
       
   270     RI_INLINE const Vector3&	operator[]		( int i ) const;
       
   271     RI_INLINE void				set				( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 );
       
   272     RI_INLINE const Vector3		getRow			( int i ) const;
       
   273     RI_INLINE const Vector3		getColumn		( int i ) const;
       
   274     RI_INLINE void				setRow			( int i, const Vector3& v );
       
   275     RI_INLINE void				setColumn		( int i, const Vector3& v );
       
   276     RI_INLINE void				operator*=		( const Matrix3x3& m );
       
   277     RI_INLINE void				operator*=		( RIfloat f );
       
   278     RI_INLINE void				operator+=		( const Matrix3x3& m );
       
   279     RI_INLINE void				operator-=		( const Matrix3x3& m );
       
   280     RI_INLINE const Matrix3x3	operator-		() const;
       
   281     RI_INLINE void				identity		();
       
   282     RI_INLINE void				transpose		();
       
   283     bool						invert			();	//if the matrix is singular, returns false and leaves it unmodified
       
   284     RI_INLINE RIfloat				det				() const;
       
   285     RI_INLINE bool				isAffine		() const;
       
   286     RI_INLINE void              assertValid     () const;
       
   287     RI_INLINE void              validate        ();
       
   288 
       
   289 private:
       
   290     RIfloat						matrix[3][3];
       
   291 };
       
   292 
       
   293 //==============================================================================================
       
   294 
       
   295 class Vector2
       
   296 {
       
   297 public:
       
   298     RI_INLINE					Vector2			() : x(0.0f), y(0.0f)					{}
       
   299     RI_INLINE					Vector2			( const Vector2& v ) : x(v.x), y(v.y)	{}
       
   300     RI_INLINE					Vector2			( RIfloat fx, RIfloat fy ) : x(fx), y(fy)	{}
       
   301     RI_INLINE					~Vector2		()								{}
       
   302     RI_INLINE Vector2&			operator=		( const Vector2& v )			{ x = v.x; y = v.y; return *this; }
       
   303     RI_INLINE RIfloat&			operator[]		( int i )						{ RI_ASSERT(i>=0&&i<2); return (&x)[i]; }
       
   304     RI_INLINE const RIfloat&	operator[]		( int i ) const					{ RI_ASSERT(i>=0&&i<2); return (&x)[i]; }
       
   305     RI_INLINE void				set				( RIfloat fx, RIfloat fy )			{ x = fx; y = fy; }
       
   306     RI_INLINE void				operator*=		( RIfloat f )						{ x *= f; y *= f; }
       
   307     RI_INLINE void				operator+=		( const Vector2& v )			{ x += v.x; y += v.y; }
       
   308     RI_INLINE void				operator-=		( const Vector2& v )			{ x -= v.x; y -= v.y; }
       
   309     RI_INLINE const Vector2		operator-		() const						{ return Vector2(-x,-y); }
       
   310     //if the vector is zero, returns false and leaves it unmodified
       
   311     RI_INLINE bool				normalize		()								{ double l = (double)x*(double)x+(double)y*(double)y; if( l == 0.0 ) return false; l = 1.0 / sqrt(l); x = (RIfloat)((double)x * l); y = (RIfloat)((double)y * l); return true; }
       
   312     RI_INLINE RIfloat			length			() const						{ return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y); }
       
   313     RI_INLINE void				scale			( const Vector2& v )			{ x *= v.x; y *= v.y; }	//component-wise scale
       
   314     RI_INLINE void				negate			()								{ x = -x; y = -y; }
       
   315 
       
   316     RIfloat						x,y;
       
   317 };
       
   318 
       
   319 //==============================================================================================
       
   320 
       
   321 class Vector3
       
   322 {
       
   323 public:
       
   324     RI_INLINE					Vector3			() : x(0.0f), y(0.0f), z(0.0f)							{}
       
   325     RI_INLINE					Vector3			( const Vector3& v ) : x(v.x), y(v.y), z(v.z)			{}
       
   326     RI_INLINE					Vector3			( RIfloat fx, RIfloat fy, RIfloat fz ) : x(fx), y(fy), z(fz)	{}
       
   327     RI_INLINE					~Vector3		()								{}
       
   328     RI_INLINE Vector3&			operator=		( const Vector3& v )			{ x = v.x; y = v.y; z = v.z; return *this; }
       
   329     RI_INLINE RIfloat&			operator[]		( int i )						{ RI_ASSERT(i>=0&&i<3); return (&x)[i]; }
       
   330     RI_INLINE const RIfloat&	operator[]		( int i ) const					{ RI_ASSERT(i>=0&&i<3); return (&x)[i]; }
       
   331     RI_INLINE void				set				( RIfloat fx, RIfloat fy, RIfloat fz ){ x = fx; y = fy; z = fz; }
       
   332     RI_INLINE void				operator*=		( RIfloat f )						{ x *= f; y *= f; z *= f; }
       
   333     RI_INLINE void				operator+=		( const Vector3& v )			{ x += v.x; y += v.y; z += v.z; }
       
   334     RI_INLINE void				operator-=		( const Vector3& v )			{ x -= v.x; y -= v.y; z -= v.z; }
       
   335     RI_INLINE const Vector3		operator-		() const						{ return Vector3(-x,-y,-z); }
       
   336     //if the vector is zero, returns false and leaves it unmodified
       
   337     RI_INLINE bool				normalize		()								{ double l = (double)x*(double)x+(double)y*(double)y+(double)z*(double)z; if( l == 0.0 ) return false; l = 1.0 / sqrt(l); x = (RIfloat)((double)x * l); y = (RIfloat)((double)y * l); z = (RIfloat)((double)z * l); return true; }
       
   338     RI_INLINE RIfloat			length			() const						{ return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y+(double)z*(double)z); }
       
   339     RI_INLINE void				scale			( const Vector3& v )			{ x *= v.x; y *= v.y; z *= v.z; }	//component-wise scale
       
   340     RI_INLINE void				negate			()								{ x = -x; y = -y; z = -z; }
       
   341 
       
   342     RIfloat						x,y,z;
       
   343 };
       
   344 
       
   345 //==============================================================================================
       
   346 
       
   347 //Vector2 global functions
       
   348 RI_INLINE bool			operator==	( const Vector2& v1, const Vector2& v2 )	{ return (v1.x == v2.x) && (v1.y == v2.y); }
       
   349 RI_INLINE bool			operator!=	( const Vector2& v1, const Vector2& v2 )	{ return (v1.x != v2.x) || (v1.y != v2.y); }
       
   350 RI_INLINE bool			isEqual		( const Vector2& v1, const Vector2& v2, RIfloat epsilon )	{ return RI_SQR(v2.x-v1.x) + RI_SQR(v2.y-v1.y) <= epsilon*epsilon; }
       
   351 RI_INLINE bool			isZero		( const Vector2& v )						{ return (v.x == 0.0f) && (v.y == 0.0f); }
       
   352 RI_INLINE const Vector2	operator*	( RIfloat f, const Vector2& v )				{ return Vector2(v.x*f,v.y*f); }
       
   353 RI_INLINE const Vector2	operator*	( const Vector2& v, RIfloat f )				{ return Vector2(v.x*f,v.y*f); }
       
   354 RI_INLINE const Vector2	operator+	( const Vector2& v1, const Vector2& v2 )	{ return Vector2(v1.x+v2.x, v1.y+v2.y); }
       
   355 RI_INLINE const Vector2	operator-	( const Vector2& v1, const Vector2& v2 )	{ return Vector2(v1.x-v2.x, v1.y-v2.y); }
       
   356 RI_INLINE RIfloat		dot			( const Vector2& v1, const Vector2& v2 )	{ return v1.x*v2.x+v1.y*v2.y; }
       
   357 //if v is a zero vector, returns a zero vector
       
   358 RI_INLINE const Vector2	normalize	( const Vector2& v )						{ double l = (double)v.x*(double)v.x+(double)v.y*(double)v.y; if( l != 0.0 ) l = 1.0 / sqrt(l); return Vector2((RIfloat)((double)v.x * l), (RIfloat)((double)v.y * l)); }
       
   359 //if onThis is a zero vector, returns a zero vector
       
   360 RI_INLINE const Vector2	project		( const Vector2& v, const Vector2& onThis ) { RIfloat l = dot(onThis,onThis); if( l != 0.0f ) l = dot(v, onThis)/l; return onThis * l; }
       
   361 RI_INLINE const Vector2	lerp		( const Vector2& v1, const Vector2& v2, RIfloat ratio )	{ return v1 + ratio * (v2 - v1); }
       
   362 RI_INLINE const Vector2	scale		( const Vector2& v1, const Vector2& v2 )	{ return Vector2(v1.x*v2.x, v1.y*v2.y); }
       
   363 //matrix * column vector. The input vector2 is implicitly expanded to (x,y,1)
       
   364 RI_INLINE const Vector2 affineTransform( const Matrix3x3& m, const Vector2& v )	{ RI_ASSERT(m.isAffine()); return Vector2(v.x * m[0][0] + v.y * m[0][1] + m[0][2], v.x * m[1][0] + v.y * m[1][1] + m[1][2]); }
       
   365 //matrix * column vector. The input vector2 is implicitly expanded to (x,y,0)
       
   366 RI_INLINE const Vector2 affineTangentTransform(const Matrix3x3& m, const Vector2& v)	{ RI_ASSERT(m.isAffine()); return Vector2(v.x * m[0][0] + v.y * m[0][1], v.x * m[1][0] + v.y * m[1][1]); }
       
   367 RI_INLINE const Vector2 perpendicularCW(const Vector2& v)						{ return Vector2(v.y, -v.x); }
       
   368 RI_INLINE const Vector2 perpendicularCCW(const Vector2& v)						{ return Vector2(-v.y, v.x); }
       
   369 RI_INLINE const Vector2 perpendicular(const Vector2& v, bool cw)				{ if(cw) return Vector2(v.y, -v.x); return Vector2(-v.y, v.x); }
       
   370 
       
   371 //==============================================================================================
       
   372 
       
   373 //Vector3 global functions
       
   374 RI_INLINE bool			operator==	( const Vector3& v1, const Vector3& v2 )	{ return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z); }
       
   375 RI_INLINE bool			operator!=	( const Vector3& v1, const Vector3& v2 )	{ return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z); }
       
   376 RI_INLINE bool			isEqual		( const Vector3& v1, const Vector3& v2, RIfloat epsilon )	{ return RI_SQR(v2.x-v1.x) + RI_SQR(v2.y-v1.y) + RI_SQR(v2.z-v1.z) <= epsilon*epsilon; }
       
   377 RI_INLINE const Vector3	operator*	( RIfloat f, const Vector3& v )				{ return Vector3(v.x*f,v.y*f,v.z*f); }
       
   378 RI_INLINE const Vector3	operator*	( const Vector3& v, RIfloat f )				{ return Vector3(v.x*f,v.y*f,v.z*f); }
       
   379 RI_INLINE const Vector3	operator+	( const Vector3& v1, const Vector3& v2 )	{ return Vector3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); }
       
   380 RI_INLINE const Vector3	operator-	( const Vector3& v1, const Vector3& v2 )	{ return Vector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); }
       
   381 RI_INLINE RIfloat		dot			( const Vector3& v1, const Vector3& v2 )	{ return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z; }
       
   382 RI_INLINE const Vector3	cross		( const Vector3& v1, const Vector3& v2 )	{ return Vector3( v1.y*v2.z-v1.z*v2.y, v1.z*v2.x-v1.x*v2.z, v1.x*v2.y-v1.y*v2.x ); }
       
   383 //if v is a zero vector, returns a zero vector
       
   384 RI_INLINE const Vector3	normalize	( const Vector3& v )						{ double l = (double)v.x*(double)v.x+(double)v.y*(double)v.y+(double)v.z*(double)v.z; if( l != 0.0 ) l = 1.0 / sqrt(l); return Vector3((RIfloat)((double)v.x * l), (RIfloat)((double)v.y * l), (RIfloat)((double)v.z * l)); }
       
   385 RI_INLINE const Vector3	lerp		( const Vector3& v1, const Vector3& v2, RIfloat ratio )	{ return v1 + ratio * (v2 - v1); }
       
   386 RI_INLINE const Vector3	scale		( const Vector3& v1, const Vector3& v2 )	{ return Vector3(v1.x*v2.x, v1.y*v2.y, v1.z*v2.z); }
       
   387 
       
   388 //==============================================================================================
       
   389 
       
   390 //matrix * column vector
       
   391 RI_INLINE const Vector3	operator*	( const Matrix3x3& m, const Vector3& v)		{ return Vector3( v.x*m[0][0]+v.y*m[0][1]+v.z*m[0][2], v.x*m[1][0]+v.y*m[1][1]+v.z*m[1][2], v.x*m[2][0]+v.y*m[2][1]+v.z*m[2][2] ); }
       
   392 
       
   393 //==============================================================================================
       
   394 
       
   395 //Matrix3x3 global functions
       
   396 RI_INLINE bool				operator==	( const Matrix3x3& m1, const Matrix3x3& m2 )	{ for(int i=0;i<3;i++) for(int j=0;j<3;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
       
   397 RI_INLINE bool				operator!=	( const Matrix3x3& m1, const Matrix3x3& m2 )	{ return !(m1 == m2); }
       
   398 RI_INLINE const Matrix3x3	operator*	( const Matrix3x3& m1, const Matrix3x3& m2 )	{ Matrix3x3 t; for(int i=0;i<3;i++) for(int j=0;j<3;j++) t[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j]; return t; }
       
   399 RI_INLINE const Matrix3x3	operator*	( RIfloat f, const Matrix3x3& m )					{ Matrix3x3 t(m); t *= f; return t; }
       
   400 RI_INLINE const Matrix3x3	operator*	( const Matrix3x3& m, RIfloat f )					{ Matrix3x3 t(m); t *= f; return t; }
       
   401 RI_INLINE const Matrix3x3	operator+	( const Matrix3x3& m1, const Matrix3x3& m2 )	{ Matrix3x3 t(m1); t += m2; return t; }
       
   402 RI_INLINE const Matrix3x3	operator-	( const Matrix3x3& m1, const Matrix3x3& m2 )	{ Matrix3x3 t(m1); t -= m2; return t; }
       
   403 RI_INLINE const Matrix3x3	transpose	( const Matrix3x3& m )							{ Matrix3x3 t(m); t.transpose(); return t; }
       
   404 // if the matrix is singular, returns it unmodified
       
   405 RI_INLINE const Matrix3x3	invert		( const Matrix3x3& m )							{ Matrix3x3 t(m); t.invert(); return t; }
       
   406 
       
   407 //==============================================================================================
       
   408 
       
   409 //Matrix3x3 inline functions (cannot be inside the class because Vector3 is not defined yet when Matrix3x3 is defined)
       
   410 RI_INLINE					Matrix3x3::Matrix3x3	()									{ identity(); }
       
   411 RI_INLINE					Matrix3x3::Matrix3x3	( const Matrix3x3& m )				{ *this = m; }
       
   412 RI_INLINE					Matrix3x3::Matrix3x3	( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 )	{ set(m00,m01,m02,m10,m11,m12,m20,m21,m22); }
       
   413 RI_INLINE					Matrix3x3::~Matrix3x3	()									{}
       
   414 RI_INLINE Matrix3x3&		Matrix3x3::operator=	( const Matrix3x3& m )				{ for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
       
   415 RI_INLINE Vector3&			Matrix3x3::operator[]	( int i )							{ RI_ASSERT(i>=0&&i<3); return (Vector3&)matrix[i][0]; }
       
   416 RI_INLINE const Vector3&	Matrix3x3::operator[]	( int i ) const						{ RI_ASSERT(i>=0&&i<3); return (const Vector3&)matrix[i][0]; }
       
   417 RI_INLINE void				Matrix3x3::set			( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 ) { matrix[0][0] = m00; matrix[0][1] = m01; matrix[0][2] = m02; matrix[1][0] = m10; matrix[1][1] = m11; matrix[1][2] = m12; matrix[2][0] = m20; matrix[2][1] = m21; matrix[2][2] = m22; }
       
   418 RI_INLINE const Vector3		Matrix3x3::getRow		( int i ) const						{ RI_ASSERT(i>=0&&i<3); return Vector3(matrix[i][0], matrix[i][1], matrix[i][2]); }
       
   419 RI_INLINE const Vector3		Matrix3x3::getColumn	( int i ) const						{ RI_ASSERT(i>=0&&i<3); return Vector3(matrix[0][i], matrix[1][i], matrix[2][i]); }
       
   420 RI_INLINE void				Matrix3x3::setRow		( int i, const Vector3& v )			{ RI_ASSERT(i>=0&&i<3); matrix[i][0] = v.x; matrix[i][1] = v.y; matrix[i][2] = v.z; }
       
   421 RI_INLINE void				Matrix3x3::setColumn	( int i, const Vector3& v )			{ RI_ASSERT(i>=0&&i<3); matrix[0][i] = v.x; matrix[1][i] = v.y; matrix[2][i] = v.z; }
       
   422 RI_INLINE void				Matrix3x3::operator*=	( const Matrix3x3& m )				{ *this = *this * m; }
       
   423 RI_INLINE void				Matrix3x3::operator*=	( RIfloat f )							{ for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] *= f; }
       
   424 RI_INLINE void				Matrix3x3::operator+=	( const Matrix3x3& m )				{ for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] += m.matrix[i][j]; }
       
   425 RI_INLINE void				Matrix3x3::operator-=	( const Matrix3x3& m )				{ for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] -= m.matrix[i][j]; }
       
   426 RI_INLINE const Matrix3x3	Matrix3x3::operator-	() const							{ return Matrix3x3( -matrix[0][0],-matrix[0][1],-matrix[0][2], -matrix[1][0],-matrix[1][1],-matrix[1][2], -matrix[2][0],-matrix[2][1],-matrix[2][2]); }
       
   427 RI_INLINE void				Matrix3x3::identity		()									{ for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] = (i == j) ? 1.0f : 0.0f; }
       
   428 RI_INLINE void				Matrix3x3::transpose	()									{ RI_SWAP(matrix[1][0], matrix[0][1]); RI_SWAP(matrix[2][0], matrix[0][2]); RI_SWAP(matrix[2][1], matrix[1][2]); }
       
   429 RI_INLINE RIfloat			Matrix3x3::det			() const							{ return matrix[0][0] * (matrix[1][1]*matrix[2][2] - matrix[2][1]*matrix[1][2]) + matrix[0][1] * (matrix[2][0]*matrix[1][2] - matrix[1][0]*matrix[2][2]) + matrix[0][2] * (matrix[1][0]*matrix[2][1] - matrix[2][0]*matrix[1][1]); }
       
   430 RI_INLINE bool				Matrix3x3::isAffine		() const							{ if(matrix[2][0] == 0.0f && matrix[2][1] == 0.0f && matrix[2][2] == 1.0f) return true; return false; }
       
   431 
       
   432 RI_INLINE void Matrix3x3::validate()
       
   433 {
       
   434     for (int i = 0; i < 3; i++)
       
   435         for (int j = 0; j < 3; j++)
       
   436             matrix[i][j] = validateFloat(matrix[i][j]);
       
   437 }
       
   438 
       
   439 RI_INLINE void Matrix3x3::assertValid() const
       
   440 {
       
   441 #if defined(RI_DEBUG)
       
   442     for (int i = 0; i < 3; i++)
       
   443         for (int j = 0; j < 3; j++)
       
   444             RI_ASSERT(!RI_ISNAN(matrix[i][j]));
       
   445 #endif
       
   446 }
       
   447 
       
   448 //==============================================================================================
       
   449 
       
   450 }	//namespace OpenVGRI
       
   451 
       
   452 #endif /* __RIMATH_H */