v3math.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_V3MATH_H
00033 #define LL_V3MATH_H
00034 
00035 #include "llerror.h"
00036 #include "llmath.h"
00037 
00038 #include "llsd.h"
00039 class LLVector4;
00040 class LLMatrix3;
00041 class LLVector3d;
00042 class LLQuaternion;
00043 
00044 //  LLvector3 = |x y z w|
00045 
00046 static const U32 LENGTHOFVECTOR3 = 3;
00047 
00048 class LLVector3
00049 {
00050         public:
00051                 F32 mV[LENGTHOFVECTOR3];
00052 
00053                 static const LLVector3 zero;
00054                 static const LLVector3 x_axis;
00055                 static const LLVector3 y_axis;
00056                 static const LLVector3 z_axis;
00057                 static const LLVector3 x_axis_neg;
00058                 static const LLVector3 y_axis_neg;
00059                 static const LLVector3 z_axis_neg;
00060                 static const LLVector3 all_one;
00061 
00062                 inline LLVector3();                                                     // Initializes LLVector3 to (0, 0, 0)
00063                 inline LLVector3(const F32 x, const F32 y, const F32 z);                        // Initializes LLVector3 to (x. y, z)
00064                 inline explicit LLVector3(const F32 *vec);                              // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
00065                 explicit LLVector3(const LLVector3d &vec);                              // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
00066                 explicit LLVector3(const LLVector4 &vec);                               // Initializes LLVector4 to (vec[0]. vec[1], vec[2])
00067                 LLVector3(const LLSD& sd);
00068 
00069                 LLSD getValue() const;
00070 
00071                 void setValue(const LLSD& sd);
00072 
00073                 const LLVector3& operator=(const LLSD& sd);
00074 
00075                 inline BOOL isFinite() const;                                                                   // checks to see if all values of LLVector3 are finite
00076                 BOOL            clamp(F32 min, F32 max);                // Clamps all values to (min,max), returns TRUE if data changed
00077 
00078                 void            quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);   // changes the vector to reflect quatization
00079                 void            quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);    // changes the vector to reflect quatization
00080                 void            snap(S32 sig_digits);                                                                                   // snaps x,y,z to sig_digits decimal places
00081 
00082                 BOOL            abs();                                          // sets all values to absolute value of original value (first octant), returns TRUE if changed
00083                 
00084                 inline void     clearVec();                                             // Clears LLVector3 to (0, 0, 0, 1)
00085                 inline void     zeroVec();                                              // Zero LLVector3 to (0, 0, 0, 0)
00086                 inline void     setVec(F32 x, F32 y, F32 z);    // Sets LLVector3 to (x, y, z, 1)
00087                 inline void     setVec(const LLVector3 &vec);   // Sets LLVector3 to vec
00088                 inline void     setVec(const F32 *vec);                 // Sets LLVector3 to vec
00089 
00090                 const LLVector3& setVec(const LLVector4 &vec);
00091                 const LLVector3& setVec(const LLVector3d &vec); // Sets LLVector3 to vec
00092 
00093                 F32             magVec() const;                         // Returns magnitude of LLVector3
00094                 F32             magVecSquared() const;          // Returns magnitude squared of LLVector3
00095                 inline F32              normVec();                                      // Normalizes and returns the magnitude of LLVector3
00096 
00097                 const LLVector3&        rotVec(F32 angle, const LLVector3 &vec);        // Rotates about vec by angle radians
00098                 const LLVector3&        rotVec(F32 angle, F32 x, F32 y, F32 z);         // Rotates about x,y,z by angle radians
00099                 const LLVector3&        rotVec(const LLMatrix3 &mat);                           // Rotates by LLMatrix4 mat
00100                 const LLVector3&        rotVec(const LLQuaternion &q);                          // Rotates by LLQuaternion q
00101 
00102                 const LLVector3&        scaleVec(const LLVector3& vec);                         // scales per component by vec
00103                 LLVector3                       scaledVec(const LLVector3& vec) const;                  // get a copy of this vector scaled by vec
00104 
00105                 BOOL isNull() const;                    // Returns TRUE if vector has a _very_small_ length
00106                 BOOL isExactlyZero() const              { return !mV[VX] && !mV[VY] && !mV[VZ]; }
00107 
00108                 F32 operator[](int idx) const { return mV[idx]; }
00109                 F32 &operator[](int idx) { return mV[idx]; }
00110         
00111                 friend LLVector3 operator+(const LLVector3 &a, const LLVector3 &b);     // Return vector a + b
00112                 friend LLVector3 operator-(const LLVector3 &a, const LLVector3 &b);     // Return vector a minus b
00113                 friend F32 operator*(const LLVector3 &a, const LLVector3 &b);           // Return a dot b
00114                 friend LLVector3 operator%(const LLVector3 &a, const LLVector3 &b);     // Return a cross b
00115                 friend LLVector3 operator*(const LLVector3 &a, F32 k);                          // Return a times scaler k
00116                 friend LLVector3 operator/(const LLVector3 &a, F32 k);                          // Return a divided by scaler k
00117                 friend LLVector3 operator*(F32 k, const LLVector3 &a);                          // Return a times scaler k
00118                 friend bool operator==(const LLVector3 &a, const LLVector3 &b);         // Return a == b
00119                 friend bool operator!=(const LLVector3 &a, const LLVector3 &b);         // Return a != b
00120                 // less than operator useful for using vectors as std::map keys
00121                 friend bool operator<(const LLVector3 &a, const LLVector3 &b);          // Return a < b
00122 
00123                 friend const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b);   // Return vector a + b
00124                 friend const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b);   // Return vector a minus b
00125                 friend const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b);   // Return a cross b
00126                 friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b);   // Returns a * b;
00127                 friend const LLVector3& operator*=(LLVector3 &a, F32 k);                                // Return a times scaler k
00128                 friend const LLVector3& operator/=(LLVector3 &a, F32 k);                                // Return a divided by scaler k
00129                 friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b);        // Returns a * b;
00130 
00131                 friend LLVector3 operator-(const LLVector3 &a);                                 // Return vector -a
00132 
00133                 friend std::ostream&     operator<<(std::ostream& s, const LLVector3 &a);               // Stream a
00134 
00135                 static BOOL parseVector3(const char* buf, LLVector3* value);
00136 };
00137 
00138 typedef LLVector3 LLSimLocalVec;
00139 
00140 // Non-member functions 
00141 
00142 F32     angle_between(const LLVector3 &a, const LLVector3 &b);  // Returns angle (radians) between a and b
00143 BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon=F_APPROXIMATELY_ZERO);    // Returns TRUE if a and b are very close to parallel
00144 F32     dist_vec(const LLVector3 &a, const LLVector3 &b);               // Returns distance between a and b
00145 F32     dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance sqaured between a and b
00146 F32     dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance sqaured between a and b ignoring Z component
00147 LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b
00148 LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
00149 
00150 inline LLVector3::LLVector3(void)
00151 {
00152         mV[0] = 0.f;
00153         mV[1] = 0.f;
00154         mV[2] = 0.f;
00155 }
00156 
00157 inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z)
00158 {
00159         mV[VX] = x;
00160         mV[VY] = y;
00161         mV[VZ] = z;
00162 }
00163 
00164 inline LLVector3::LLVector3(const F32 *vec)
00165 {
00166         mV[VX] = vec[VX];
00167         mV[VY] = vec[VY];
00168         mV[VZ] = vec[VZ];
00169 }
00170 
00171 /*
00172 inline LLVector3::LLVector3(const LLVector3 &copy)
00173 {
00174         mV[VX] = copy.mV[VX];
00175         mV[VY] = copy.mV[VY];
00176         mV[VZ] = copy.mV[VZ];
00177 }
00178 */
00179 
00180 // Destructors
00181 
00182 // checker
00183 inline BOOL LLVector3::isFinite() const
00184 {
00185         return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]));
00186 }
00187 
00188 
00189 // Clear and Assignment Functions
00190 
00191 inline void     LLVector3::clearVec(void)
00192 {
00193         mV[0] = 0.f;
00194         mV[1] = 0.f;
00195         mV[2] = 0.f;
00196 }
00197 
00198 inline void     LLVector3::zeroVec(void)
00199 {
00200         mV[0] = 0.f;
00201         mV[1] = 0.f;
00202         mV[2] = 0.f;
00203 }
00204 
00205 inline void     LLVector3::setVec(F32 x, F32 y, F32 z)
00206 {
00207         mV[VX] = x;
00208         mV[VY] = y;
00209         mV[VZ] = z;
00210 }
00211 
00212 inline void     LLVector3::setVec(const LLVector3 &vec)
00213 {
00214         mV[0] = vec.mV[0];
00215         mV[1] = vec.mV[1];
00216         mV[2] = vec.mV[2];
00217 }
00218 
00219 inline void     LLVector3::setVec(const F32 *vec)
00220 {
00221         mV[0] = vec[0];
00222         mV[1] = vec[1];
00223         mV[2] = vec[2];
00224 }
00225 
00226 inline F32 LLVector3::normVec(void)
00227 {
00228         F32 mag = fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
00229         F32 oomag;
00230 
00231         if (mag > FP_MAG_THRESHOLD)
00232         {
00233                 oomag = 1.f/mag;
00234                 mV[0] *= oomag;
00235                 mV[1] *= oomag;
00236                 mV[2] *= oomag;
00237         }
00238         else
00239         {
00240                 mV[0] = 0.f;
00241                 mV[1] = 0.f;
00242                 mV[2] = 0.f;
00243                 mag = 0;
00244         }
00245         return (mag);
00246 }
00247 
00248 // LLVector3 Magnitude and Normalization Functions
00249 
00250 inline F32      LLVector3::magVec(void) const
00251 {
00252         return fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
00253 }
00254 
00255 inline F32      LLVector3::magVecSquared(void) const
00256 {
00257         return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
00258 }
00259 
00260 inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b)
00261 {
00262         LLVector3 c(a);
00263         return c += b;
00264 }
00265 
00266 inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b)
00267 {
00268         LLVector3 c(a);
00269         return c -= b;
00270 }
00271 
00272 inline F32  operator*(const LLVector3 &a, const LLVector3 &b)
00273 {
00274         return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]);
00275 }
00276 
00277 inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b)
00278 {
00279         return LLVector3( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1] );
00280 }
00281 
00282 inline LLVector3 operator/(const LLVector3 &a, F32 k)
00283 {
00284         F32 t = 1.f / k;
00285         return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t );
00286 }
00287 
00288 inline LLVector3 operator*(const LLVector3 &a, F32 k)
00289 {
00290         return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
00291 }
00292 
00293 inline LLVector3 operator*(F32 k, const LLVector3 &a)
00294 {
00295         return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
00296 }
00297 
00298 inline bool operator==(const LLVector3 &a, const LLVector3 &b)
00299 {
00300         return (  (a.mV[0] == b.mV[0])
00301                         &&(a.mV[1] == b.mV[1])
00302                         &&(a.mV[2] == b.mV[2]));
00303 }
00304 
00305 inline bool operator!=(const LLVector3 &a, const LLVector3 &b)
00306 {
00307         return (  (a.mV[0] != b.mV[0])
00308                         ||(a.mV[1] != b.mV[1])
00309                         ||(a.mV[2] != b.mV[2]));
00310 }
00311 
00312 inline bool operator<(const LLVector3 &a, const LLVector3 &b)
00313 {
00314         return (a.mV[0] < b.mV[0]
00315                         || (a.mV[0] == b.mV[0]
00316                                 && (a.mV[1] < b.mV[1]
00317                                         || (a.mV[1] == b.mV[1])
00318                                                 && a.mV[2] < b.mV[2])));
00319 }
00320 
00321 inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b)
00322 {
00323         a.mV[0] += b.mV[0];
00324         a.mV[1] += b.mV[1];
00325         a.mV[2] += b.mV[2];
00326         return a;
00327 }
00328 
00329 inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b)
00330 {
00331         a.mV[0] -= b.mV[0];
00332         a.mV[1] -= b.mV[1];
00333         a.mV[2] -= b.mV[2];
00334         return a;
00335 }
00336 
00337 inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b)
00338 {
00339         LLVector3 ret( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1]);
00340         a = ret;
00341         return a;
00342 }
00343 
00344 inline const LLVector3& operator*=(LLVector3 &a, F32 k)
00345 {
00346         a.mV[0] *= k;
00347         a.mV[1] *= k;
00348         a.mV[2] *= k;
00349         return a;
00350 }
00351 
00352 inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b)
00353 {
00354         a.mV[0] *= b.mV[0];
00355         a.mV[1] *= b.mV[1];
00356         a.mV[2] *= b.mV[2];
00357         return a;
00358 }
00359 
00360 inline const LLVector3& operator/=(LLVector3 &a, F32 k)
00361 {
00362         F32 t = 1.f / k;
00363         a.mV[0] *= t;
00364         a.mV[1] *= t;
00365         a.mV[2] *= t;
00366         return a;
00367 }
00368 
00369 inline LLVector3 operator-(const LLVector3 &a)
00370 {
00371         return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );
00372 }
00373 
00374 inline F32      dist_vec(const LLVector3 &a, const LLVector3 &b)
00375 {
00376         F32 x = a.mV[0] - b.mV[0];
00377         F32 y = a.mV[1] - b.mV[1];
00378         F32 z = a.mV[2] - b.mV[2];
00379         return fsqrtf( x*x + y*y + z*z );
00380 }
00381 
00382 inline F32      dist_vec_squared(const LLVector3 &a, const LLVector3 &b)
00383 {
00384         F32 x = a.mV[0] - b.mV[0];
00385         F32 y = a.mV[1] - b.mV[1];
00386         F32 z = a.mV[2] - b.mV[2];
00387         return x*x + y*y + z*z;
00388 }
00389 
00390 inline F32      dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b)
00391 {
00392         F32 x = a.mV[0] - b.mV[0];
00393         F32 y = a.mV[1] - b.mV[1];
00394         return x*x + y*y;
00395 }
00396 
00397 inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
00398 {
00399         LLVector3 project_axis = b;
00400         project_axis.normVec();
00401         return project_axis * (a * project_axis);
00402 }
00403 
00404 inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
00405 {
00406         return LLVector3(
00407                 a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
00408                 a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
00409                 a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
00410 }
00411 
00412 
00413 inline BOOL     LLVector3::isNull() const
00414 {
00415         if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] )
00416         {
00417                 return TRUE;
00418         }
00419         return FALSE;
00420 }
00421 
00422 inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
00423 {
00424         for (U32 i = 0; i < 3; i++)
00425         {
00426                 if (min.mV[i] > pos.mV[i])
00427                 {
00428                         min.mV[i] = pos.mV[i];
00429                 }
00430                 if (max.mV[i] < pos.mV[i])
00431                 {
00432                         max.mV[i] = pos.mV[i];
00433                 }
00434         }
00435 }
00436 
00437 inline F32 angle_between(const LLVector3& a, const LLVector3& b)
00438 {
00439         LLVector3 an = a;
00440         LLVector3 bn = b;
00441         an.normVec();
00442         bn.normVec();
00443         F32 cosine = an * bn;
00444         F32 angle = (cosine >= 1.0f) ? 0.0f :
00445                                 (cosine <= -1.0f) ? F_PI :
00446                                 (F32)acos(cosine);
00447         return angle;
00448 }
00449 
00450 inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon)
00451 {
00452         LLVector3 an = a;
00453         LLVector3 bn = b;
00454         an.normVec();
00455         bn.normVec();
00456         F32 dot = an * bn;
00457         if ( (1.0f - fabs(dot)) < epsilon)
00458         {
00459                 return TRUE;
00460         }
00461         return FALSE;
00462 }
00463 
00464 #endif

Generated on Thu Jul 1 06:10:00 2010 for Second Life Viewer by  doxygen 1.4.7