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 clearVec();
00072 inline void zeroVec();
00073 inline void setVec(F32 x, F32 y, F32 z);
00074 inline void setVec(F32 x, F32 y, F32 z, F32 w);
00075 inline void setVec(const LLVector4 &vec);
00076 inline void setVec(const LLVector3 &vec, F32 w = 1.f);
00077 inline void setVec(const F32 *vec);
00078
00079 F32 magVec() const;
00080 F32 magVecSquared() const;
00081 F32 normVec();
00082
00083
00084
00085 BOOL abs();
00086
00087 BOOL isExactlyClear() const { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; }
00088 BOOL isExactlyZero() const { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; }
00089
00090 const LLVector4& rotVec(F32 angle, const LLVector4 &vec);
00091 const LLVector4& rotVec(F32 angle, F32 x, F32 y, F32 z);
00092 const LLVector4& rotVec(const LLMatrix4 &mat);
00093 const LLVector4& rotVec(const LLQuaternion &q);
00094
00095 const LLVector4& scaleVec(const LLVector4& vec);
00096
00097 F32 operator[](int idx) const { return mV[idx]; }
00098 F32 &operator[](int idx) { return mV[idx]; }
00099
00100 friend std::ostream& operator<<(std::ostream& s, const LLVector4 &a);
00101 friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b);
00102 friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b);
00103 friend F32 operator*(const LLVector4 &a, const LLVector4 &b);
00104 friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b);
00105 friend LLVector4 operator/(const LLVector4 &a, F32 k);
00106 friend LLVector4 operator*(const LLVector4 &a, F32 k);
00107 friend LLVector4 operator*(F32 k, const LLVector4 &a);
00108 friend bool operator==(const LLVector4 &a, const LLVector4 &b);
00109 friend bool operator!=(const LLVector4 &a, const LLVector4 &b);
00110
00111 friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b);
00112 friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b);
00113 friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b);
00114 friend const LLVector4& operator*=(LLVector4 &a, F32 k);
00115 friend const LLVector4& operator/=(LLVector4 &a, F32 k);
00116
00117 friend LLVector4 operator-(const LLVector4 &a);
00118 };
00119
00120
00121 F32 angle_between(const LLVector4 &a, const LLVector4 &b);
00122 BOOL are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon=F_APPROXIMATELY_ZERO);
00123 F32 dist_vec(const LLVector4 &a, const LLVector4 &b);
00124 F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b);
00125 LLVector3 vec4to3(const LLVector4 &vec);
00126 LLVector4 vec3to4(const LLVector3 &vec);
00127 LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u);
00128
00129
00130
00131 inline LLVector4::LLVector4(void)
00132 {
00133 mV[VX] = 0.f;
00134 mV[VY] = 0.f;
00135 mV[VZ] = 0.f;
00136 mV[VW] = 1.f;
00137 }
00138
00139 inline LLVector4::LLVector4(F32 x, F32 y, F32 z)
00140 {
00141 mV[VX] = x;
00142 mV[VY] = y;
00143 mV[VZ] = z;
00144 mV[VW] = 1.f;
00145 }
00146
00147 inline LLVector4::LLVector4(F32 x, F32 y, F32 z, F32 w)
00148 {
00149 mV[VX] = x;
00150 mV[VY] = y;
00151 mV[VZ] = z;
00152 mV[VW] = w;
00153 }
00154
00155 inline LLVector4::LLVector4(const F32 *vec)
00156 {
00157 mV[VX] = vec[VX];
00158 mV[VY] = vec[VY];
00159 mV[VZ] = vec[VZ];
00160 mV[VW] = vec[VW];
00161 }
00162
00163 inline LLVector4::LLVector4(const F64 *vec)
00164 {
00165 mV[VX] = (F32) vec[VX];
00166 mV[VY] = (F32) vec[VY];
00167 mV[VZ] = (F32) vec[VZ];
00168 mV[VW] = (F32) vec[VW];
00169 }
00170
00171 inline LLVector4::LLVector4(const LLVector3 &vec)
00172 {
00173 mV[VX] = vec.mV[VX];
00174 mV[VY] = vec.mV[VY];
00175 mV[VZ] = vec.mV[VZ];
00176 mV[VW] = 1.f;
00177 }
00178
00179 inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
00180 {
00181 mV[VX] = vec.mV[VX];
00182 mV[VY] = vec.mV[VY];
00183 mV[VZ] = vec.mV[VZ];
00184 mV[VW] = w;
00185 }
00186
00187
00188 inline BOOL LLVector4::isFinite() const
00189 {
00190 return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]));
00191 }
00192
00193
00194
00195 inline void LLVector4::clearVec(void)
00196 {
00197 mV[VX] = 0.f;
00198 mV[VY] = 0.f;
00199 mV[VZ] = 0.f;
00200 mV[VW] = 1.f;
00201 }
00202
00203 inline void LLVector4::zeroVec(void)
00204 {
00205 mV[VX] = 0.f;
00206 mV[VY] = 0.f;
00207 mV[VZ] = 0.f;
00208 mV[VW] = 0.f;
00209 }
00210
00211 inline void LLVector4::setVec(F32 x, F32 y, F32 z)
00212 {
00213 mV[VX] = x;
00214 mV[VY] = y;
00215 mV[VZ] = z;
00216 mV[VW] = 1.f;
00217 }
00218
00219 inline void LLVector4::setVec(F32 x, F32 y, F32 z, F32 w)
00220 {
00221 mV[VX] = x;
00222 mV[VY] = y;
00223 mV[VZ] = z;
00224 mV[VW] = w;
00225 }
00226
00227 inline void LLVector4::setVec(const LLVector4 &vec)
00228 {
00229 mV[VX] = vec.mV[VX];
00230 mV[VY] = vec.mV[VY];
00231 mV[VZ] = vec.mV[VZ];
00232 mV[VW] = vec.mV[VW];
00233 }
00234
00235 inline void LLVector4::setVec(const LLVector3 &vec, F32 w)
00236 {
00237 mV[VX] = vec.mV[VX];
00238 mV[VY] = vec.mV[VY];
00239 mV[VZ] = vec.mV[VZ];
00240 mV[VW] = w;
00241 }
00242
00243 inline void LLVector4::setVec(const F32 *vec)
00244 {
00245 mV[VX] = vec[VX];
00246 mV[VY] = vec[VY];
00247 mV[VZ] = vec[VZ];
00248 mV[VW] = vec[VW];
00249 }
00250
00251
00252
00253 inline F32 LLVector4::magVec(void) const
00254 {
00255 return fsqrtf(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
00256 }
00257
00258 inline F32 LLVector4::magVecSquared(void) const
00259 {
00260 return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
00261 }
00262
00263
00264
00265 inline LLVector4 operator+(const LLVector4 &a, const LLVector4 &b)
00266 {
00267 LLVector4 c(a);
00268 return c += b;
00269 }
00270
00271 inline LLVector4 operator-(const LLVector4 &a, const LLVector4 &b)
00272 {
00273 LLVector4 c(a);
00274 return c -= b;
00275 }
00276
00277 inline F32 operator*(const LLVector4 &a, const LLVector4 &b)
00278 {
00279 return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]);
00280 }
00281
00282 inline LLVector4 operator%(const LLVector4 &a, const LLVector4 &b)
00283 {
00284 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]);
00285 }
00286
00287 inline LLVector4 operator/(const LLVector4 &a, F32 k)
00288 {
00289 F32 t = 1.f / k;
00290 return LLVector4( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t );
00291 }
00292
00293
00294 inline LLVector4 operator*(const LLVector4 &a, F32 k)
00295 {
00296 return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
00297 }
00298
00299 inline LLVector4 operator*(F32 k, const LLVector4 &a)
00300 {
00301 return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
00302 }
00303
00304 inline bool operator==(const LLVector4 &a, const LLVector4 &b)
00305 {
00306 return ( (a.mV[VX] == b.mV[VX])
00307 &&(a.mV[VY] == b.mV[VY])
00308 &&(a.mV[VZ] == b.mV[VZ]));
00309 }
00310
00311 inline bool operator!=(const LLVector4 &a, const LLVector4 &b)
00312 {
00313 return ( (a.mV[VX] != b.mV[VX])
00314 ||(a.mV[VY] != b.mV[VY])
00315 ||(a.mV[VZ] != b.mV[VZ]));
00316 }
00317
00318 inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b)
00319 {
00320 a.mV[VX] += b.mV[VX];
00321 a.mV[VY] += b.mV[VY];
00322 a.mV[VZ] += b.mV[VZ];
00323 return a;
00324 }
00325
00326 inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b)
00327 {
00328 a.mV[VX] -= b.mV[VX];
00329 a.mV[VY] -= b.mV[VY];
00330 a.mV[VZ] -= b.mV[VZ];
00331 return a;
00332 }
00333
00334 inline const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b)
00335 {
00336 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]);
00337 a = ret;
00338 return a;
00339 }
00340
00341 inline const LLVector4& operator*=(LLVector4 &a, F32 k)
00342 {
00343 a.mV[VX] *= k;
00344 a.mV[VY] *= k;
00345 a.mV[VZ] *= k;
00346 return a;
00347 }
00348
00349 inline const LLVector4& operator/=(LLVector4 &a, F32 k)
00350 {
00351 F32 t = 1.f / k;
00352 a.mV[VX] *= t;
00353 a.mV[VY] *= t;
00354 a.mV[VZ] *= t;
00355 return a;
00356 }
00357
00358 inline LLVector4 operator-(const LLVector4 &a)
00359 {
00360 return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );
00361 }
00362
00363 inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b)
00364 {
00365 LLVector4 vec = a - b;
00366 return (vec.magVec());
00367 }
00368
00369 inline F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b)
00370 {
00371 LLVector4 vec = a - b;
00372 return (vec.magVecSquared());
00373 }
00374
00375 inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u)
00376 {
00377 return LLVector4(
00378 a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
00379 a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
00380 a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u,
00381 a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);
00382 }
00383
00384 inline F32 LLVector4::normVec(void)
00385 {
00386 F32 mag = fsqrtf(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
00387 F32 oomag;
00388
00389 if (mag > FP_MAG_THRESHOLD)
00390 {
00391 oomag = 1.f/mag;
00392 mV[VX] *= oomag;
00393 mV[VY] *= oomag;
00394 mV[VZ] *= oomag;
00395 }
00396 else
00397 {
00398 mV[0] = 0.f;
00399 mV[1] = 0.f;
00400 mV[2] = 0.f;
00401 mag = 0;
00402 }
00403 return (mag);
00404 }
00405
00406
00407 #endif
00408