00001
00032 #ifndef LL_V4MATH_H
00033 #define LL_V4MATH_H
00034
00035 #include "llerror.h"
00036 #include "llmath.h"
00037 #include "v3math.h"
00038
00039 class LLMatrix3;
00040 class LLMatrix4;
00041 class LLQuaternion;
00042
00043
00044
00045 static const U32 LENGTHOFVECTOR4 = 4;
00046
00047 class LLVector4
00048 {
00049 public:
00050 F32 mV[LENGTHOFVECTOR4];
00051 LLVector4();
00052 explicit LLVector4(const F32 *vec);
00053 explicit LLVector4(const F64 *vec);
00054 explicit LLVector4(const LLVector3 &vec);
00055 explicit LLVector4(const LLVector3 &vec, F32 w);
00056 LLVector4(F32 x, F32 y, F32 z);
00057 LLVector4(F32 x, F32 y, F32 z, F32 w);
00058
00059 LLSD getValue() const
00060 {
00061 LLSD ret;
00062 ret[0] = mV[0];
00063 ret[1] = mV[1];
00064 ret[2] = mV[2];
00065 ret[3] = mV[3];
00066 return ret;
00067 }
00068
00069 inline BOOL isFinite() const;
00070
00071 inline void clear();
00072 inline void clearVec();
00073 inline void zeroVec();
00074
00075 inline void set(F32 x, F32 y, F32 z);
00076 inline void set(F32 x, F32 y, F32 z, F32 w);
00077 inline void set(const LLVector4 &vec);
00078 inline void set(const LLVector3 &vec, F32 w = 1.f);
00079 inline void set(const F32 *vec);
00080
00081 inline void setVec(F32 x, F32 y, F32 z);
00082 inline void setVec(F32 x, F32 y, F32 z, F32 w);
00083 inline void setVec(const LLVector4 &vec);
00084 inline void setVec(const LLVector3 &vec, F32 w = 1.f);
00085 inline void setVec(const F32 *vec);
00086
00087 F32 length() const;
00088 F32 lengthSquared() const;
00089 F32 normalize();
00090
00091 F32 magVec() const;
00092 F32 magVecSquared() const;
00093 F32 normVec();
00094
00095
00096
00097 BOOL abs();
00098
00099 BOOL isExactlyClear() const { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; }
00100 BOOL isExactlyZero() const { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; }
00101
00102 const LLVector4& rotVec(F32 angle, const LLVector4 &vec);
00103 const LLVector4& rotVec(F32 angle, F32 x, F32 y, F32 z);
00104 const LLVector4& rotVec(const LLMatrix4 &mat);
00105 const LLVector4& rotVec(const LLQuaternion &q);
00106
00107 const LLVector4& scaleVec(const LLVector4& vec);
00108
00109 F32 operator[](int idx) const { return mV[idx]; }
00110 F32 &operator[](int idx) { return mV[idx]; }
00111
00112 friend std::ostream& operator<<(std::ostream& s, const LLVector4 &a);
00113 friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b);
00114 friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b);
00115 friend F32 operator*(const LLVector4 &a, const LLVector4 &b);
00116 friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b);
00117 friend LLVector4 operator/(const LLVector4 &a, F32 k);
00118 friend LLVector4 operator*(const LLVector4 &a, F32 k);
00119 friend LLVector4 operator*(F32 k, const LLVector4 &a);
00120 friend bool operator==(const LLVector4 &a, const LLVector4 &b);
00121 friend bool operator!=(const LLVector4 &a, const LLVector4 &b);
00122
00123 friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b);
00124 friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b);
00125 friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b);
00126 friend const LLVector4& operator*=(LLVector4 &a, F32 k);
00127 friend const LLVector4& operator/=(LLVector4 &a, F32 k);
00128
00129 friend LLVector4 operator-(const LLVector4 &a);
00130 };
00131
00132
00133 F32 angle_between(const LLVector4 &a, const LLVector4 &b);
00134 BOOL are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon=F_APPROXIMATELY_ZERO);
00135 F32 dist_vec(const LLVector4 &a, const LLVector4 &b);
00136 F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b);
00137 LLVector3 vec4to3(const LLVector4 &vec);
00138 LLVector4 vec3to4(const LLVector3 &vec);
00139 LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u);
00140
00141
00142
00143 inline LLVector4::LLVector4(void)
00144 {
00145 mV[VX] = 0.f;
00146 mV[VY] = 0.f;
00147 mV[VZ] = 0.f;
00148 mV[VW] = 1.f;
00149 }
00150
00151 inline LLVector4::LLVector4(F32 x, F32 y, F32 z)
00152 {
00153 mV[VX] = x;
00154 mV[VY] = y;
00155 mV[VZ] = z;
00156 mV[VW] = 1.f;
00157 }
00158
00159 inline LLVector4::LLVector4(F32 x, F32 y, F32 z, F32 w)
00160 {
00161 mV[VX] = x;
00162 mV[VY] = y;
00163 mV[VZ] = z;
00164 mV[VW] = w;
00165 }
00166
00167 inline LLVector4::LLVector4(const F32 *vec)
00168 {
00169 mV[VX] = vec[VX];
00170 mV[VY] = vec[VY];
00171 mV[VZ] = vec[VZ];
00172 mV[VW] = vec[VW];
00173 }
00174
00175 inline LLVector4::LLVector4(const F64 *vec)
00176 {
00177 mV[VX] = (F32) vec[VX];
00178 mV[VY] = (F32) vec[VY];
00179 mV[VZ] = (F32) vec[VZ];
00180 mV[VW] = (F32) vec[VW];
00181 }
00182
00183 inline LLVector4::LLVector4(const LLVector3 &vec)
00184 {
00185 mV[VX] = vec.mV[VX];
00186 mV[VY] = vec.mV[VY];
00187 mV[VZ] = vec.mV[VZ];
00188 mV[VW] = 1.f;
00189 }
00190
00191 inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
00192 {
00193 mV[VX] = vec.mV[VX];
00194 mV[VY] = vec.mV[VY];
00195 mV[VZ] = vec.mV[VZ];
00196 mV[VW] = w;
00197 }
00198
00199
00200 inline BOOL LLVector4::isFinite() const
00201 {
00202 return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]));
00203 }
00204
00205
00206
00207 inline void LLVector4::clear(void)
00208 {
00209 mV[VX] = 0.f;
00210 mV[VY] = 0.f;
00211 mV[VZ] = 0.f;
00212 mV[VW] = 1.f;
00213 }
00214
00215
00216 inline void LLVector4::clearVec(void)
00217 {
00218 mV[VX] = 0.f;
00219 mV[VY] = 0.f;
00220 mV[VZ] = 0.f;
00221 mV[VW] = 1.f;
00222 }
00223
00224
00225 inline void LLVector4::zeroVec(void)
00226 {
00227 mV[VX] = 0.f;
00228 mV[VY] = 0.f;
00229 mV[VZ] = 0.f;
00230 mV[VW] = 0.f;
00231 }
00232
00233 inline void LLVector4::set(F32 x, F32 y, F32 z)
00234 {
00235 mV[VX] = x;
00236 mV[VY] = y;
00237 mV[VZ] = z;
00238 mV[VW] = 1.f;
00239 }
00240
00241 inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w)
00242 {
00243 mV[VX] = x;
00244 mV[VY] = y;
00245 mV[VZ] = z;
00246 mV[VW] = w;
00247 }
00248
00249 inline void LLVector4::set(const LLVector4 &vec)
00250 {
00251 mV[VX] = vec.mV[VX];
00252 mV[VY] = vec.mV[VY];
00253 mV[VZ] = vec.mV[VZ];
00254 mV[VW] = vec.mV[VW];
00255 }
00256
00257 inline void LLVector4::set(const LLVector3 &vec, F32 w)
00258 {
00259 mV[VX] = vec.mV[VX];
00260 mV[VY] = vec.mV[VY];
00261 mV[VZ] = vec.mV[VZ];
00262 mV[VW] = w;
00263 }
00264
00265 inline void LLVector4::set(const F32 *vec)
00266 {
00267 mV[VX] = vec[VX];
00268 mV[VY] = vec[VY];
00269 mV[VZ] = vec[VZ];
00270 mV[VW] = vec[VW];
00271 }
00272
00273
00274
00275 inline void LLVector4::setVec(F32 x, F32 y, F32 z)
00276 {
00277 mV[VX] = x;
00278 mV[VY] = y;
00279 mV[VZ] = z;
00280 mV[VW] = 1.f;
00281 }
00282
00283
00284 inline void LLVector4::setVec(F32 x, F32 y, F32 z, F32 w)
00285 {
00286 mV[VX] = x;
00287 mV[VY] = y;
00288 mV[VZ] = z;
00289 mV[VW] = w;
00290 }
00291
00292
00293 inline void LLVector4::setVec(const LLVector4 &vec)
00294 {
00295 mV[VX] = vec.mV[VX];
00296 mV[VY] = vec.mV[VY];
00297 mV[VZ] = vec.mV[VZ];
00298 mV[VW] = vec.mV[VW];
00299 }
00300
00301
00302 inline void LLVector4::setVec(const LLVector3 &vec, F32 w)
00303 {
00304 mV[VX] = vec.mV[VX];
00305 mV[VY] = vec.mV[VY];
00306 mV[VZ] = vec.mV[VZ];
00307 mV[VW] = w;
00308 }
00309
00310
00311 inline void LLVector4::setVec(const F32 *vec)
00312 {
00313 mV[VX] = vec[VX];
00314 mV[VY] = vec[VY];
00315 mV[VZ] = vec[VZ];
00316 mV[VW] = vec[VW];
00317 }
00318
00319
00320
00321 inline F32 LLVector4::length(void) const
00322 {
00323 return fsqrtf(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
00324 }
00325
00326 inline F32 LLVector4::lengthSquared(void) const
00327 {
00328 return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
00329 }
00330
00331 inline F32 LLVector4::magVec(void) const
00332 {
00333 return fsqrtf(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
00334 }
00335
00336 inline F32 LLVector4::magVecSquared(void) const
00337 {
00338 return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
00339 }
00340
00341
00342
00343 inline LLVector4 operator+(const LLVector4 &a, const LLVector4 &b)
00344 {
00345 LLVector4 c(a);
00346 return c += b;
00347 }
00348
00349 inline LLVector4 operator-(const LLVector4 &a, const LLVector4 &b)
00350 {
00351 LLVector4 c(a);
00352 return c -= b;
00353 }
00354
00355 inline F32 operator*(const LLVector4 &a, const LLVector4 &b)
00356 {
00357 return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]);
00358 }
00359
00360 inline LLVector4 operator%(const LLVector4 &a, const LLVector4 &b)
00361 {
00362 return LLVector4(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]);
00363 }
00364
00365 inline LLVector4 operator/(const LLVector4 &a, F32 k)
00366 {
00367 F32 t = 1.f / k;
00368 return LLVector4( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t );
00369 }
00370
00371
00372 inline LLVector4 operator*(const LLVector4 &a, F32 k)
00373 {
00374 return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
00375 }
00376
00377 inline LLVector4 operator*(F32 k, const LLVector4 &a)
00378 {
00379 return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
00380 }
00381
00382 inline bool operator==(const LLVector4 &a, const LLVector4 &b)
00383 {
00384 return ( (a.mV[VX] == b.mV[VX])
00385 &&(a.mV[VY] == b.mV[VY])
00386 &&(a.mV[VZ] == b.mV[VZ]));
00387 }
00388
00389 inline bool operator!=(const LLVector4 &a, const LLVector4 &b)
00390 {
00391 return ( (a.mV[VX] != b.mV[VX])
00392 ||(a.mV[VY] != b.mV[VY])
00393 ||(a.mV[VZ] != b.mV[VZ])
00394 ||(a.mV[VW] != b.mV[VW]) );
00395 }
00396
00397 inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b)
00398 {
00399 a.mV[VX] += b.mV[VX];
00400 a.mV[VY] += b.mV[VY];
00401 a.mV[VZ] += b.mV[VZ];
00402 return a;
00403 }
00404
00405 inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b)
00406 {
00407 a.mV[VX] -= b.mV[VX];
00408 a.mV[VY] -= b.mV[VY];
00409 a.mV[VZ] -= b.mV[VZ];
00410 return a;
00411 }
00412
00413 inline const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b)
00414 {
00415 LLVector4 ret(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]);
00416 a = ret;
00417 return a;
00418 }
00419
00420 inline const LLVector4& operator*=(LLVector4 &a, F32 k)
00421 {
00422 a.mV[VX] *= k;
00423 a.mV[VY] *= k;
00424 a.mV[VZ] *= k;
00425 return a;
00426 }
00427
00428 inline const LLVector4& operator/=(LLVector4 &a, F32 k)
00429 {
00430 F32 t = 1.f / k;
00431 a.mV[VX] *= t;
00432 a.mV[VY] *= t;
00433 a.mV[VZ] *= t;
00434 return a;
00435 }
00436
00437 inline LLVector4 operator-(const LLVector4 &a)
00438 {
00439 return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );
00440 }
00441
00442 inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b)
00443 {
00444 LLVector4 vec = a - b;
00445 return (vec.length());
00446 }
00447
00448 inline F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b)
00449 {
00450 LLVector4 vec = a - b;
00451 return (vec.lengthSquared());
00452 }
00453
00454 inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u)
00455 {
00456 return LLVector4(
00457 a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
00458 a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
00459 a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u,
00460 a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);
00461 }
00462
00463 inline F32 LLVector4::normalize(void)
00464 {
00465 F32 mag = fsqrtf(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
00466 F32 oomag;
00467
00468 if (mag > FP_MAG_THRESHOLD)
00469 {
00470 oomag = 1.f/mag;
00471 mV[VX] *= oomag;
00472 mV[VY] *= oomag;
00473 mV[VZ] *= oomag;
00474 }
00475 else
00476 {
00477 mV[0] = 0.f;
00478 mV[1] = 0.f;
00479 mV[2] = 0.f;
00480 mag = 0;
00481 }
00482 return (mag);
00483 }
00484
00485
00486 inline F32 LLVector4::normVec(void)
00487 {
00488 F32 mag = fsqrtf(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
00489 F32 oomag;
00490
00491 if (mag > FP_MAG_THRESHOLD)
00492 {
00493 oomag = 1.f/mag;
00494 mV[VX] *= oomag;
00495 mV[VY] *= oomag;
00496 mV[VZ] *= oomag;
00497 }
00498 else
00499 {
00500 mV[0] = 0.f;
00501 mV[1] = 0.f;
00502 mV[2] = 0.f;
00503 mag = 0;
00504 }
00505 return (mag);
00506 }
00507
00508
00509 #endif
00510