# HG changeset patch # User Faisal Memon # Date 1273849630 -3600 # Node ID 9662a45141efa4f9034be2ed2e1fbeda75f7b267 # Parent ff5b7046e5c4a4d78cee9764c8177d8cd64f857b Merge 2. Update math support to make available integer comparing, clamping and shifting. diff -r ff5b7046e5c4 -r 9662a45141ef openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMath.cpp --- a/openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMath.cpp Fri May 14 15:46:16 2010 +0100 +++ b/openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMath.cpp Fri May 14 16:07:10 2010 +0100 @@ -4,6 +4,7 @@ * ----------------------------------- * * Copyright (c) 2007 The Khronos Group Inc. + * Portions Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and /or associated documentation files @@ -33,6 +34,20 @@ #include "riDefs.h" #include "riMath.h" +#if 0 +#include + +static void printMatrix(const Matrix3x3& m) +{ + // For tracing a bug in matrix inverse in release-builds. + for(int i = 0; i < 3; i++) + { + printf("[%.4f %.4f %.4f]\n", m[i][0], m[i][1], m[i][2]); + } +} + +#endif + namespace OpenVGRI { @@ -45,6 +60,7 @@ bool Matrix3x3::invert() { + // \todo Save computation on affine matrices? bool affine = isAffine(); RIfloat det00 = matrix[1][1]*matrix[2][2] - matrix[2][1]*matrix[1][2]; RIfloat det01 = matrix[2][0]*matrix[1][2] - matrix[1][0]*matrix[2][2]; @@ -55,15 +71,26 @@ d = 1.0f / d; Matrix3x3 t; - t[0][0] = d * det00; - t[1][0] = d * det01; - t[2][0] = d * det02; - t[0][1] = d * (matrix[2][1]*matrix[0][2] - matrix[0][1]*matrix[2][2]); - t[1][1] = d * (matrix[0][0]*matrix[2][2] - matrix[2][0]*matrix[0][2]); - t[2][1] = d * (matrix[2][0]*matrix[0][1] - matrix[0][0]*matrix[2][1]); - t[0][2] = d * (matrix[0][1]*matrix[1][2] - matrix[1][1]*matrix[0][2]); - t[1][2] = d * (matrix[1][0]*matrix[0][2] - matrix[0][0]*matrix[1][2]); - t[2][2] = d * (matrix[0][0]*matrix[1][1] - matrix[1][0]*matrix[0][1]); + + // \note There is some bug (in GCC?) in accessing matrix elements: If data + // is accessed like: t[i][j], then the following will produce incorrect + // resulst on optimized builds. If the data is accessed through t.matrix, + // then the output is correct. Debug build works correctly, and if print + // calls are inserted, the code also works correctly. The context to get + // this bug appear are fill paints (linear and radial gradient test + // functions). + + t.matrix[0][0] = d * det00; + t.matrix[1][0] = d * det01; + t.matrix[2][0] = d * det02; + //printf("t\n"); + //printMatrix(t); + t.matrix[0][1] = d * (matrix[2][1]*matrix[0][2] - matrix[0][1]*matrix[2][2]); + t.matrix[1][1] = d * (matrix[0][0]*matrix[2][2] - matrix[2][0]*matrix[0][2]); + t.matrix[2][1] = d * (matrix[2][0]*matrix[0][1] - matrix[0][0]*matrix[2][1]); + t.matrix[0][2] = d * (matrix[0][1]*matrix[1][2] - matrix[1][1]*matrix[0][2]); + t.matrix[1][2] = d * (matrix[1][0]*matrix[0][2] - matrix[0][0]*matrix[1][2]); + t.matrix[2][2] = d * (matrix[0][0]*matrix[1][1] - matrix[1][0]*matrix[0][1]); if(affine) t[2].set(0,0,1); //affine matrix stays affine *this = t; diff -r ff5b7046e5c4 -r 9662a45141ef openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMath.h --- a/openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMath.h Fri May 14 15:46:16 2010 +0100 +++ b/openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMath.h Fri May 14 16:07:10 2010 +0100 @@ -7,6 +7,7 @@ * ----------------------------------- * * Copyright (c) 2007 The Khronos Group Inc. + * Portions Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and /or associated documentation files @@ -14,10 +15,10 @@ * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Materials, * and to permit persons to whom the Materials are furnished to do so, - * subject to the following conditions: + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Materials. + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF @@ -30,7 +31,7 @@ *//** * \file * \brief Math functions, Vector and Matrix classes. - * \note + * \note *//*-------------------------------------------------------------------*/ #ifndef __RIDEFS_H @@ -43,21 +44,21 @@ { /*-------------------------------------------------------------------*//*! -* \brief -* \param -* \return -* \note +* \brief +* \param +* \return +* \note *//*-------------------------------------------------------------------*/ RI_INLINE int RI_ISNAN(float a) { - RIfloatInt p; - p.f = a; - unsigned int exponent = (p.i>>23) & 0xff; - unsigned int mantissa = p.i & 0x7fffff; - if(exponent == 255 && mantissa) - return 1; - return 0; + RIfloatInt p; + p.f = a; + unsigned int exponent = (p.i>>23) & 0xff; + unsigned int mantissa = p.i & 0x7fffff; + if(exponent == 255 && mantissa) + return 1; + return 0; } #if (RI_MANTISSA_BITS > 23) @@ -69,77 +70,77 @@ class RIfloat { public: - RIfloat() : v(0.0f) { removeBits(); } - RIfloat(float a) : v(a) { removeBits(); } - RIfloat(double a) : v((float)a) { removeBits(); } - RIfloat(int a) : v((float)a) { removeBits(); } - RIfloat(unsigned int a) : v((float)a) { removeBits(); } - RIfloat& operator=(const RIfloat &a) { v = a.v; removeBits(); return *this; } - RIfloat& operator+=(const RIfloat &a){ v += a.v; removeBits(); return *this; } - RIfloat& operator-=(const RIfloat &a){ v -= a.v; removeBits(); return *this; } - RIfloat& operator*=(const RIfloat &a){ v *= a.v; removeBits(); return *this; } - RIfloat& operator/=(const RIfloat &a){ v /= a.v; removeBits(); return *this; } - RIfloat operator-() const { return -v; } - operator float() const { return v; } - operator double() const { return (double)v; } - operator int() const { return (int)v; } + RIfloat() : v(0.0f) { removeBits(); } + RIfloat(float a) : v(a) { removeBits(); } + RIfloat(double a) : v((float)a) { removeBits(); } + RIfloat(int a) : v((float)a) { removeBits(); } + RIfloat(unsigned int a) : v((float)a) { removeBits(); } + RIfloat& operator=(const RIfloat &a) { v = a.v; removeBits(); return *this; } + RIfloat& operator+=(const RIfloat &a){ v += a.v; removeBits(); return *this; } + RIfloat& operator-=(const RIfloat &a){ v -= a.v; removeBits(); return *this; } + RIfloat& operator*=(const RIfloat &a){ v *= a.v; removeBits(); return *this; } + RIfloat& operator/=(const RIfloat &a){ v /= a.v; removeBits(); return *this; } + RIfloat operator-() const { return -v; } + operator float() const { return v; } + operator double() const { return (double)v; } + operator int() const { return (int)v; } - friend RIfloat operator+(const RIfloat &a, const RIfloat &b); - friend RIfloat operator+(float a, const RIfloat &b); - friend RIfloat operator+(const RIfloat &a, float b); - friend RIfloat operator-(const RIfloat &a, const RIfloat &b); - friend RIfloat operator-(float a, const RIfloat &b); - friend RIfloat operator-(const RIfloat &a, float b); - friend RIfloat operator*(const RIfloat &a, const RIfloat &b); - friend RIfloat operator*(float a, const RIfloat &b); - friend RIfloat operator*(const RIfloat &a, float b); - friend RIfloat operator/(const RIfloat &a, const RIfloat &b); - friend RIfloat operator/(float a, const RIfloat &b); - friend RIfloat operator/(const RIfloat &a, float b); + friend RIfloat operator+(const RIfloat &a, const RIfloat &b); + friend RIfloat operator+(float a, const RIfloat &b); + friend RIfloat operator+(const RIfloat &a, float b); + friend RIfloat operator-(const RIfloat &a, const RIfloat &b); + friend RIfloat operator-(float a, const RIfloat &b); + friend RIfloat operator-(const RIfloat &a, float b); + friend RIfloat operator*(const RIfloat &a, const RIfloat &b); + friend RIfloat operator*(float a, const RIfloat &b); + friend RIfloat operator*(const RIfloat &a, float b); + friend RIfloat operator/(const RIfloat &a, const RIfloat &b); + friend RIfloat operator/(float a, const RIfloat &b); + friend RIfloat operator/(const RIfloat &a, float b); - friend bool operator<(const RIfloat &a, const RIfloat &b); - friend bool operator<(float a, const RIfloat &b); - friend bool operator<(const RIfloat &a, float b); - friend bool operator>(const RIfloat &a, const RIfloat &b); - friend bool operator>(float a, const RIfloat &b); - friend bool operator>(const RIfloat &a, float b); - friend bool operator<=(const RIfloat &a, const RIfloat &b); - friend bool operator<=(float a, const RIfloat &b); - friend bool operator<=(const RIfloat &a, float b); - friend bool operator>=(const RIfloat &a, const RIfloat &b); - friend bool operator>=(float a, const RIfloat &b); - friend bool operator>=(const RIfloat &a, float b); - friend bool operator==(const RIfloat &a, const RIfloat &b); - friend bool operator==(float a, const RIfloat &b); - friend bool operator==(const RIfloat &a, float b); - friend bool operator!=(const RIfloat &a, const RIfloat &b); - friend bool operator!=(float a, const RIfloat &b); - friend bool operator!=(const RIfloat &a, float b); + friend bool operator<(const RIfloat &a, const RIfloat &b); + friend bool operator<(float a, const RIfloat &b); + friend bool operator<(const RIfloat &a, float b); + friend bool operator>(const RIfloat &a, const RIfloat &b); + friend bool operator>(float a, const RIfloat &b); + friend bool operator>(const RIfloat &a, float b); + friend bool operator<=(const RIfloat &a, const RIfloat &b); + friend bool operator<=(float a, const RIfloat &b); + friend bool operator<=(const RIfloat &a, float b); + friend bool operator>=(const RIfloat &a, const RIfloat &b); + friend bool operator>=(float a, const RIfloat &b); + friend bool operator>=(const RIfloat &a, float b); + friend bool operator==(const RIfloat &a, const RIfloat &b); + friend bool operator==(float a, const RIfloat &b); + friend bool operator==(const RIfloat &a, float b); + friend bool operator!=(const RIfloat &a, const RIfloat &b); + friend bool operator!=(float a, const RIfloat &b); + friend bool operator!=(const RIfloat &a, float b); private: - void removeBits() - { - RIfloatInt p; - p.f = v; - unsigned int exponent = (p.i>>23) & 0xff; - if(exponent == 0 || exponent == 255) - return; //zero, denormal, infinite, or NaN + void removeBits() + { + RIfloatInt p; + p.f = v; + unsigned int exponent = (p.i>>23) & 0xff; + if(exponent == 0 || exponent == 255) + return; //zero, denormal, infinite, or NaN - p.i &= ~((1<<(23-RI_MANTISSA_BITS))-1); + p.i &= ~((1<<(23-RI_MANTISSA_BITS))-1); #if (RI_EXPONENT_BITS != 8) - if (exponent > 127 + (1 << (RI_EXPONENT_BITS-1))) - exponent = 127 + (1 << (RI_EXPONENT_BITS-1)); + if (exponent > 127 + (1 << (RI_EXPONENT_BITS-1))) + exponent = 127 + (1 << (RI_EXPONENT_BITS-1)); - if (exponent < 127 + 1 - (1 << (RI_EXPONENT_BITS-1))) - exponent = 127 + 1 - (1 << (RI_EXPONENT_BITS-1)); + if (exponent < 127 + 1 - (1 << (RI_EXPONENT_BITS-1))) + exponent = 127 + 1 - (1 << (RI_EXPONENT_BITS-1)); - p.i &= ~(0xff<<23); - p.i |= exponent<<23; + p.i &= ~(0xff<<23); + p.i |= exponent<<23; #endif - v = p.f; - } + v = p.f; + } - float v; + float v; }; RI_INLINE RIfloat operator+(const RIfloat &a, const RIfloat &b) { return RIfloat(a.v+b.v); } @@ -180,8 +181,11 @@ #define PI 3.141592654f +RI_INLINE int RI_ROUND_TO_INT(RIfloat v) { return (v >= 0.0f) ? (int)(v+0.5f) : (int)(v-0.5f); } RI_INLINE RIfloat RI_MAX(RIfloat a, RIfloat b) { return (a > b) ? a : b; } +RI_INLINE int RI_MAX(int a, int b) { return (a > b) ? a : b; } RI_INLINE RIfloat RI_MIN(RIfloat a, RIfloat b) { return (a < b) ? a : b; } +RI_INLINE int RI_MIN(int a, int b) { return (a < b) ? a : b; } 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; } RI_INLINE void RI_SWAP(RIfloat &a, RIfloat &b) { RIfloat tmp = a; a = b; b = tmp; } RI_INLINE RIfloat RI_ABS(RIfloat a) { return (a < 0.0f) ? -a : a; } @@ -190,12 +194,32 @@ RI_INLINE RIfloat RI_RAD_TO_DEG(RIfloat a) { return a * 180.0f/ PI; } 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; } +#define RI_ANY_SWAP(type, a, b) {type tmp = a; a = b; b = tmp;} + +RI_INLINE void RI_INT16_SWAP(RIint16 &a, RIint16 &b) {RIint16 tmp = a; a = b; b = tmp;} +RI_INLINE int RI_INT_ABS(int a) { return (a >= 0) ? a : -a; } RI_INLINE int RI_INT_MAX(int a, int b) { return (a > b) ? a : b; } RI_INLINE int RI_INT_MIN(int a, int b) { return (a < b) ? a : b; } +RI_INLINE int RI_INT_CLAMP(int a, int l, int h) { return (a < l) ? l : (a > h) ? h : a; } RI_INLINE void RI_INT_SWAP(int &a, int &b) { int tmp = a; a = b; b = tmp; } 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; } 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; } +RI_INLINE int RI_SHL(int a, int sh) +{ + RI_ASSERT(sh >= 0 && sh <= 31); + int r = a << sh; + RI_ASSERT(a >= 0 ? (r >= 0) : (r < 0)); + return r; +} + +RI_INLINE int RI_SHR(int a, int sh) +{ + RI_ASSERT(sh >= 0 && sh <= 31); + int r = a >> sh; + return r; +} + class Matrix3x3; class Vector2; class Vector3; @@ -209,31 +233,31 @@ class Matrix3x3 { public: - RI_INLINE Matrix3x3 (); //initialized to identity - RI_INLINE Matrix3x3 ( const Matrix3x3& m ); - RI_INLINE Matrix3x3 ( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 ); - RI_INLINE ~Matrix3x3 (); - RI_INLINE Matrix3x3& operator= ( const Matrix3x3& m ); - RI_INLINE Vector3& operator[] ( int i ); //returns a row vector - RI_INLINE const Vector3& operator[] ( int i ) const; - RI_INLINE void set ( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 ); - RI_INLINE const Vector3 getRow ( int i ) const; - RI_INLINE const Vector3 getColumn ( int i ) const; - RI_INLINE void setRow ( int i, const Vector3& v ); - RI_INLINE void setColumn ( int i, const Vector3& v ); - RI_INLINE void operator*= ( const Matrix3x3& m ); - RI_INLINE void operator*= ( RIfloat f ); - RI_INLINE void operator+= ( const Matrix3x3& m ); - RI_INLINE void operator-= ( const Matrix3x3& m ); - RI_INLINE const Matrix3x3 operator- () const; - RI_INLINE void identity (); - RI_INLINE void transpose (); - bool invert (); //if the matrix is singular, returns false and leaves it unmodified - RI_INLINE RIfloat det () const; - RI_INLINE bool isAffine () const; + RI_INLINE Matrix3x3 (); //initialized to identity + RI_INLINE Matrix3x3 ( const Matrix3x3& m ); + RI_INLINE Matrix3x3 ( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 ); + RI_INLINE ~Matrix3x3 (); + RI_INLINE Matrix3x3& operator= ( const Matrix3x3& m ); + RI_INLINE Vector3& operator[] ( int i ); //returns a row vector + RI_INLINE const Vector3& operator[] ( int i ) const; + RI_INLINE void set ( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 ); + RI_INLINE const Vector3 getRow ( int i ) const; + RI_INLINE const Vector3 getColumn ( int i ) const; + RI_INLINE void setRow ( int i, const Vector3& v ); + RI_INLINE void setColumn ( int i, const Vector3& v ); + RI_INLINE void operator*= ( const Matrix3x3& m ); + RI_INLINE void operator*= ( RIfloat f ); + RI_INLINE void operator+= ( const Matrix3x3& m ); + RI_INLINE void operator-= ( const Matrix3x3& m ); + RI_INLINE const Matrix3x3 operator- () const; + RI_INLINE void identity (); + RI_INLINE void transpose (); + bool invert (); //if the matrix is singular, returns false and leaves it unmodified + RI_INLINE RIfloat det () const; + RI_INLINE bool isAffine () const; private: - RIfloat matrix[3][3]; + RIfloat matrix[3][3]; }; //============================================================================================== @@ -241,25 +265,25 @@ class Vector2 { public: - RI_INLINE Vector2 () : x(0.0f), y(0.0f) {} - RI_INLINE Vector2 ( const Vector2& v ) : x(v.x), y(v.y) {} - RI_INLINE Vector2 ( RIfloat fx, RIfloat fy ) : x(fx), y(fy) {} - RI_INLINE ~Vector2 () {} - RI_INLINE Vector2& operator= ( const Vector2& v ) { x = v.x; y = v.y; return *this; } - RI_INLINE RIfloat& operator[] ( int i ) { RI_ASSERT(i>=0&&i<2); return (&x)[i]; } - RI_INLINE const RIfloat& operator[] ( int i ) const { RI_ASSERT(i>=0&&i<2); return (&x)[i]; } - RI_INLINE void set ( RIfloat fx, RIfloat fy ) { x = fx; y = fy; } - RI_INLINE void operator*= ( RIfloat f ) { x *= f; y *= f; } - RI_INLINE void operator+= ( const Vector2& v ) { x += v.x; y += v.y; } - RI_INLINE void operator-= ( const Vector2& v ) { x -= v.x; y -= v.y; } - RI_INLINE const Vector2 operator- () const { return Vector2(-x,-y); } - //if the vector is zero, returns false and leaves it unmodified - 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; } - RI_INLINE RIfloat length () const { return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y); } - RI_INLINE void scale ( const Vector2& v ) { x *= v.x; y *= v.y; } //component-wise scale - RI_INLINE void negate () { x = -x; y = -y; } + RI_INLINE Vector2 () : x(0.0f), y(0.0f) {} + RI_INLINE Vector2 ( const Vector2& v ) : x(v.x), y(v.y) {} + RI_INLINE Vector2 ( RIfloat fx, RIfloat fy ) : x(fx), y(fy) {} + RI_INLINE ~Vector2 () {} + RI_INLINE Vector2& operator= ( const Vector2& v ) { x = v.x; y = v.y; return *this; } + RI_INLINE RIfloat& operator[] ( int i ) { RI_ASSERT(i>=0&&i<2); return (&x)[i]; } + RI_INLINE const RIfloat& operator[] ( int i ) const { RI_ASSERT(i>=0&&i<2); return (&x)[i]; } + RI_INLINE void set ( RIfloat fx, RIfloat fy ) { x = fx; y = fy; } + RI_INLINE void operator*= ( RIfloat f ) { x *= f; y *= f; } + RI_INLINE void operator+= ( const Vector2& v ) { x += v.x; y += v.y; } + RI_INLINE void operator-= ( const Vector2& v ) { x -= v.x; y -= v.y; } + RI_INLINE const Vector2 operator- () const { return Vector2(-x,-y); } + //if the vector is zero, returns false and leaves it unmodified + 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; } + RI_INLINE RIfloat length () const { return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y); } + RI_INLINE void scale ( const Vector2& v ) { x *= v.x; y *= v.y; } //component-wise scale + RI_INLINE void negate () { x = -x; y = -y; } - RIfloat x,y; + RIfloat x,y; }; //============================================================================================== @@ -267,25 +291,25 @@ class Vector3 { public: - RI_INLINE Vector3 () : x(0.0f), y(0.0f), z(0.0f) {} - RI_INLINE Vector3 ( const Vector3& v ) : x(v.x), y(v.y), z(v.z) {} - RI_INLINE Vector3 ( RIfloat fx, RIfloat fy, RIfloat fz ) : x(fx), y(fy), z(fz) {} - RI_INLINE ~Vector3 () {} - RI_INLINE Vector3& operator= ( const Vector3& v ) { x = v.x; y = v.y; z = v.z; return *this; } - RI_INLINE RIfloat& operator[] ( int i ) { RI_ASSERT(i>=0&&i<3); return (&x)[i]; } - RI_INLINE const RIfloat& operator[] ( int i ) const { RI_ASSERT(i>=0&&i<3); return (&x)[i]; } - RI_INLINE void set ( RIfloat fx, RIfloat fy, RIfloat fz ){ x = fx; y = fy; z = fz; } - RI_INLINE void operator*= ( RIfloat f ) { x *= f; y *= f; z *= f; } - RI_INLINE void operator+= ( const Vector3& v ) { x += v.x; y += v.y; z += v.z; } - RI_INLINE void operator-= ( const Vector3& v ) { x -= v.x; y -= v.y; z -= v.z; } - RI_INLINE const Vector3 operator- () const { return Vector3(-x,-y,-z); } - //if the vector is zero, returns false and leaves it unmodified - 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; } - RI_INLINE RIfloat length () const { return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y+(double)z*(double)z); } - RI_INLINE void scale ( const Vector3& v ) { x *= v.x; y *= v.y; z *= v.z; } //component-wise scale - RI_INLINE void negate () { x = -x; y = -y; z = -z; } + RI_INLINE Vector3 () : x(0.0f), y(0.0f), z(0.0f) {} + RI_INLINE Vector3 ( const Vector3& v ) : x(v.x), y(v.y), z(v.z) {} + RI_INLINE Vector3 ( RIfloat fx, RIfloat fy, RIfloat fz ) : x(fx), y(fy), z(fz) {} + RI_INLINE ~Vector3 () {} + RI_INLINE Vector3& operator= ( const Vector3& v ) { x = v.x; y = v.y; z = v.z; return *this; } + RI_INLINE RIfloat& operator[] ( int i ) { RI_ASSERT(i>=0&&i<3); return (&x)[i]; } + RI_INLINE const RIfloat& operator[] ( int i ) const { RI_ASSERT(i>=0&&i<3); return (&x)[i]; } + RI_INLINE void set ( RIfloat fx, RIfloat fy, RIfloat fz ){ x = fx; y = fy; z = fz; } + RI_INLINE void operator*= ( RIfloat f ) { x *= f; y *= f; z *= f; } + RI_INLINE void operator+= ( const Vector3& v ) { x += v.x; y += v.y; z += v.z; } + RI_INLINE void operator-= ( const Vector3& v ) { x -= v.x; y -= v.y; z -= v.z; } + RI_INLINE const Vector3 operator- () const { return Vector3(-x,-y,-z); } + //if the vector is zero, returns false and leaves it unmodified + 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; } + RI_INLINE RIfloat length () const { return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y+(double)z*(double)z); } + RI_INLINE void scale ( const Vector3& v ) { x *= v.x; y *= v.y; z *= v.z; } //component-wise scale + RI_INLINE void negate () { x = -x; y = -y; z = -z; } - RIfloat x,y,z; + RIfloat x,y,z; }; //==============================================================================================