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
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();
00063 inline LLVector3(const F32 x, const F32 y, const F32 z);
00064 inline explicit LLVector3(const F32 *vec);
00065 explicit LLVector3(const LLVector3d &vec);
00066 explicit LLVector3(const LLVector4 &vec);
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;
00076 BOOL clamp(F32 min, F32 max);
00077
00078 void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);
00079 void quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);
00080 void snap(S32 sig_digits);
00081
00082 BOOL abs();
00083
00084 inline void clear();
00085 inline void setZero();
00086 inline void clearVec();
00087 inline void zeroVec();
00088
00089 inline void set(F32 x, F32 y, F32 z);
00090 inline void set(const LLVector3 &vec);
00091 inline void set(const F32 *vec);
00092 const LLVector3& set(const LLVector4 &vec);
00093 const LLVector3& set(const LLVector3d &vec);
00094
00095 inline void setVec(F32 x, F32 y, F32 z);
00096 inline void setVec(const LLVector3 &vec);
00097 inline void setVec(const F32 *vec);
00098
00099 const LLVector3& setVec(const LLVector4 &vec);
00100 const LLVector3& setVec(const LLVector3d &vec);
00101
00102 F32 length() const;
00103 F32 lengthSquared() const;
00104 F32 magVec() const;
00105 F32 magVecSquared() const;
00106
00107 inline F32 normalize();
00108 inline F32 normVec();
00109
00110 inline BOOL inRange( F32 min, F32 max ) const;
00111
00112 const LLVector3& rotVec(F32 angle, const LLVector3 &vec);
00113 const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z);
00114 const LLVector3& rotVec(const LLMatrix3 &mat);
00115 const LLVector3& rotVec(const LLQuaternion &q);
00116
00117 const LLVector3& scaleVec(const LLVector3& vec);
00118 LLVector3 scaledVec(const LLVector3& vec) const;
00119
00120 BOOL isNull() const;
00121 BOOL isExactlyZero() const { return !mV[VX] && !mV[VY] && !mV[VZ]; }
00122
00123 F32 operator[](int idx) const { return mV[idx]; }
00124 F32 &operator[](int idx) { return mV[idx]; }
00125
00126 friend LLVector3 operator+(const LLVector3 &a, const LLVector3 &b);
00127 friend LLVector3 operator-(const LLVector3 &a, const LLVector3 &b);
00128 friend F32 operator*(const LLVector3 &a, const LLVector3 &b);
00129 friend LLVector3 operator%(const LLVector3 &a, const LLVector3 &b);
00130 friend LLVector3 operator*(const LLVector3 &a, F32 k);
00131 friend LLVector3 operator/(const LLVector3 &a, F32 k);
00132 friend LLVector3 operator*(F32 k, const LLVector3 &a);
00133 friend bool operator==(const LLVector3 &a, const LLVector3 &b);
00134 friend bool operator!=(const LLVector3 &a, const LLVector3 &b);
00135
00136 friend bool operator<(const LLVector3 &a, const LLVector3 &b);
00137
00138 friend const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b);
00139 friend const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b);
00140 friend const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b);
00141 friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b);
00142 friend const LLVector3& operator*=(LLVector3 &a, F32 k);
00143 friend const LLVector3& operator/=(LLVector3 &a, F32 k);
00144 friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b);
00145
00146 friend LLVector3 operator-(const LLVector3 &a);
00147
00148 friend std::ostream& operator<<(std::ostream& s, const LLVector3 &a);
00149
00150 static BOOL parseVector3(const char* buf, LLVector3* value);
00151 };
00152
00153 typedef LLVector3 LLSimLocalVec;
00154
00155
00156
00157 F32 angle_between(const LLVector3 &a, const LLVector3 &b);
00158 BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon=F_APPROXIMATELY_ZERO);
00159 F32 dist_vec(const LLVector3 &a, const LLVector3 &b);
00160 F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);
00161 F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);
00162 LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b);
00163 LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u);
00164
00165 inline LLVector3::LLVector3(void)
00166 {
00167 mV[0] = 0.f;
00168 mV[1] = 0.f;
00169 mV[2] = 0.f;
00170 }
00171
00172 inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z)
00173 {
00174 mV[VX] = x;
00175 mV[VY] = y;
00176 mV[VZ] = z;
00177 }
00178
00179 inline LLVector3::LLVector3(const F32 *vec)
00180 {
00181 mV[VX] = vec[VX];
00182 mV[VY] = vec[VY];
00183 mV[VZ] = vec[VZ];
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 inline BOOL LLVector3::isFinite() const
00199 {
00200 return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]));
00201 }
00202
00203
00204
00205
00206 inline void LLVector3::clear(void)
00207 {
00208 mV[0] = 0.f;
00209 mV[1] = 0.f;
00210 mV[2] = 0.f;
00211 }
00212
00213 inline void LLVector3::setZero(void)
00214 {
00215 mV[0] = 0.f;
00216 mV[1] = 0.f;
00217 mV[2] = 0.f;
00218 }
00219
00220 inline void LLVector3::clearVec(void)
00221 {
00222 mV[0] = 0.f;
00223 mV[1] = 0.f;
00224 mV[2] = 0.f;
00225 }
00226
00227 inline void LLVector3::zeroVec(void)
00228 {
00229 mV[0] = 0.f;
00230 mV[1] = 0.f;
00231 mV[2] = 0.f;
00232 }
00233
00234 inline void LLVector3::set(F32 x, F32 y, F32 z)
00235 {
00236 mV[VX] = x;
00237 mV[VY] = y;
00238 mV[VZ] = z;
00239 }
00240
00241 inline void LLVector3::set(const LLVector3 &vec)
00242 {
00243 mV[0] = vec.mV[0];
00244 mV[1] = vec.mV[1];
00245 mV[2] = vec.mV[2];
00246 }
00247
00248 inline void LLVector3::set(const F32 *vec)
00249 {
00250 mV[0] = vec[0];
00251 mV[1] = vec[1];
00252 mV[2] = vec[2];
00253 }
00254
00255
00256 inline void LLVector3::setVec(F32 x, F32 y, F32 z)
00257 {
00258 mV[VX] = x;
00259 mV[VY] = y;
00260 mV[VZ] = z;
00261 }
00262
00263
00264 inline void LLVector3::setVec(const LLVector3 &vec)
00265 {
00266 mV[0] = vec.mV[0];
00267 mV[1] = vec.mV[1];
00268 mV[2] = vec.mV[2];
00269 }
00270
00271
00272 inline void LLVector3::setVec(const F32 *vec)
00273 {
00274 mV[0] = vec[0];
00275 mV[1] = vec[1];
00276 mV[2] = vec[2];
00277 }
00278
00279 inline F32 LLVector3::normalize(void)
00280 {
00281 F32 mag = fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
00282 F32 oomag;
00283
00284 if (mag > FP_MAG_THRESHOLD)
00285 {
00286 oomag = 1.f/mag;
00287 mV[0] *= oomag;
00288 mV[1] *= oomag;
00289 mV[2] *= oomag;
00290 }
00291 else
00292 {
00293 mV[0] = 0.f;
00294 mV[1] = 0.f;
00295 mV[2] = 0.f;
00296 mag = 0;
00297 }
00298 return (mag);
00299 }
00300
00301
00302 inline F32 LLVector3::normVec(void)
00303 {
00304 F32 mag = fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
00305 F32 oomag;
00306
00307 if (mag > FP_MAG_THRESHOLD)
00308 {
00309 oomag = 1.f/mag;
00310 mV[0] *= oomag;
00311 mV[1] *= oomag;
00312 mV[2] *= oomag;
00313 }
00314 else
00315 {
00316 mV[0] = 0.f;
00317 mV[1] = 0.f;
00318 mV[2] = 0.f;
00319 mag = 0;
00320 }
00321 return (mag);
00322 }
00323
00324
00325
00326 inline F32 LLVector3::length(void) const
00327 {
00328 return fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
00329 }
00330
00331 inline F32 LLVector3::lengthSquared(void) const
00332 {
00333 return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
00334 }
00335
00336 inline F32 LLVector3::magVec(void) const
00337 {
00338 return fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
00339 }
00340
00341 inline F32 LLVector3::magVecSquared(void) const
00342 {
00343 return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
00344 }
00345
00346 inline BOOL LLVector3::inRange( F32 min, F32 max ) const
00347 {
00348 return mV[0] >= min && mV[0] <= max &&
00349 mV[1] >= min && mV[1] <= max &&
00350 mV[2] >= min && mV[2] <= max;
00351 }
00352
00353 inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b)
00354 {
00355 LLVector3 c(a);
00356 return c += b;
00357 }
00358
00359 inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b)
00360 {
00361 LLVector3 c(a);
00362 return c -= b;
00363 }
00364
00365 inline F32 operator*(const LLVector3 &a, const LLVector3 &b)
00366 {
00367 return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]);
00368 }
00369
00370 inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b)
00371 {
00372 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] );
00373 }
00374
00375 inline LLVector3 operator/(const LLVector3 &a, F32 k)
00376 {
00377 F32 t = 1.f / k;
00378 return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t );
00379 }
00380
00381 inline LLVector3 operator*(const LLVector3 &a, F32 k)
00382 {
00383 return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
00384 }
00385
00386 inline LLVector3 operator*(F32 k, const LLVector3 &a)
00387 {
00388 return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
00389 }
00390
00391 inline bool operator==(const LLVector3 &a, const LLVector3 &b)
00392 {
00393 return ( (a.mV[0] == b.mV[0])
00394 &&(a.mV[1] == b.mV[1])
00395 &&(a.mV[2] == b.mV[2]));
00396 }
00397
00398 inline bool operator!=(const LLVector3 &a, const LLVector3 &b)
00399 {
00400 return ( (a.mV[0] != b.mV[0])
00401 ||(a.mV[1] != b.mV[1])
00402 ||(a.mV[2] != b.mV[2]));
00403 }
00404
00405 inline bool operator<(const LLVector3 &a, const LLVector3 &b)
00406 {
00407 return (a.mV[0] < b.mV[0]
00408 || (a.mV[0] == b.mV[0]
00409 && (a.mV[1] < b.mV[1]
00410 || (a.mV[1] == b.mV[1])
00411 && a.mV[2] < b.mV[2])));
00412 }
00413
00414 inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b)
00415 {
00416 a.mV[0] += b.mV[0];
00417 a.mV[1] += b.mV[1];
00418 a.mV[2] += b.mV[2];
00419 return a;
00420 }
00421
00422 inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b)
00423 {
00424 a.mV[0] -= b.mV[0];
00425 a.mV[1] -= b.mV[1];
00426 a.mV[2] -= b.mV[2];
00427 return a;
00428 }
00429
00430 inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b)
00431 {
00432 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]);
00433 a = ret;
00434 return a;
00435 }
00436
00437 inline const LLVector3& operator*=(LLVector3 &a, F32 k)
00438 {
00439 a.mV[0] *= k;
00440 a.mV[1] *= k;
00441 a.mV[2] *= k;
00442 return a;
00443 }
00444
00445 inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b)
00446 {
00447 a.mV[0] *= b.mV[0];
00448 a.mV[1] *= b.mV[1];
00449 a.mV[2] *= b.mV[2];
00450 return a;
00451 }
00452
00453 inline const LLVector3& operator/=(LLVector3 &a, F32 k)
00454 {
00455 F32 t = 1.f / k;
00456 a.mV[0] *= t;
00457 a.mV[1] *= t;
00458 a.mV[2] *= t;
00459 return a;
00460 }
00461
00462 inline LLVector3 operator-(const LLVector3 &a)
00463 {
00464 return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );
00465 }
00466
00467 inline F32 dist_vec(const LLVector3 &a, const LLVector3 &b)
00468 {
00469 F32 x = a.mV[0] - b.mV[0];
00470 F32 y = a.mV[1] - b.mV[1];
00471 F32 z = a.mV[2] - b.mV[2];
00472 return fsqrtf( x*x + y*y + z*z );
00473 }
00474
00475 inline F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b)
00476 {
00477 F32 x = a.mV[0] - b.mV[0];
00478 F32 y = a.mV[1] - b.mV[1];
00479 F32 z = a.mV[2] - b.mV[2];
00480 return x*x + y*y + z*z;
00481 }
00482
00483 inline F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b)
00484 {
00485 F32 x = a.mV[0] - b.mV[0];
00486 F32 y = a.mV[1] - b.mV[1];
00487 return x*x + y*y;
00488 }
00489
00490 inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
00491 {
00492 LLVector3 project_axis = b;
00493 project_axis.normalize();
00494 return project_axis * (a * project_axis);
00495 }
00496
00497 inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
00498 {
00499 return LLVector3(
00500 a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
00501 a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
00502 a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
00503 }
00504
00505
00506 inline BOOL LLVector3::isNull() const
00507 {
00508 if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] )
00509 {
00510 return TRUE;
00511 }
00512 return FALSE;
00513 }
00514
00515 inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
00516 {
00517 for (U32 i = 0; i < 3; i++)
00518 {
00519 if (min.mV[i] > pos.mV[i])
00520 {
00521 min.mV[i] = pos.mV[i];
00522 }
00523 if (max.mV[i] < pos.mV[i])
00524 {
00525 max.mV[i] = pos.mV[i];
00526 }
00527 }
00528 }
00529
00530 inline F32 angle_between(const LLVector3& a, const LLVector3& b)
00531 {
00532 LLVector3 an = a;
00533 LLVector3 bn = b;
00534 an.normalize();
00535 bn.normalize();
00536 F32 cosine = an * bn;
00537 F32 angle = (cosine >= 1.0f) ? 0.0f :
00538 (cosine <= -1.0f) ? F_PI :
00539 (F32)acos(cosine);
00540 return angle;
00541 }
00542
00543 inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon)
00544 {
00545 LLVector3 an = a;
00546 LLVector3 bn = b;
00547 an.normalize();
00548 bn.normalize();
00549 F32 dot = an * bn;
00550 if ( (1.0f - fabs(dot)) < epsilon)
00551 {
00552 return TRUE;
00553 }
00554 return FALSE;
00555 }
00556
00557 #endif