PageRenderTime 119ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmath/v4math.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 505 lines | 385 code | 79 blank | 41 comment | 19 complexity | 1a595c50e1197af7dacfb765a0acb7f6 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file v4math.h
  3. * @brief LLVector4 class header file.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_V4MATH_H
  27. #define LL_V4MATH_H
  28. #include "llerror.h"
  29. #include "llmath.h"
  30. #include "v3math.h"
  31. class LLMatrix3;
  32. class LLMatrix4;
  33. class LLQuaternion;
  34. // LLVector4 = |x y z w|
  35. static const U32 LENGTHOFVECTOR4 = 4;
  36. class LLVector4
  37. {
  38. public:
  39. F32 mV[LENGTHOFVECTOR4];
  40. LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1)
  41. explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3])
  42. explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
  43. explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1)
  44. explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w)
  45. LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1)
  46. LLVector4(F32 x, F32 y, F32 z, F32 w);
  47. LLSD getValue() const
  48. {
  49. LLSD ret;
  50. ret[0] = mV[0];
  51. ret[1] = mV[1];
  52. ret[2] = mV[2];
  53. ret[3] = mV[3];
  54. return ret;
  55. }
  56. inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
  57. inline void clear(); // Clears LLVector4 to (0, 0, 0, 1)
  58. inline void clearVec(); // deprecated
  59. inline void zeroVec(); // deprecated
  60. inline void set(F32 x, F32 y, F32 z); // Sets LLVector4 to (x, y, z, 1)
  61. inline void set(F32 x, F32 y, F32 z, F32 w); // Sets LLVector4 to (x, y, z, w)
  62. inline void set(const LLVector4 &vec); // Sets LLVector4 to vec
  63. inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec
  64. inline void set(const F32 *vec); // Sets LLVector4 to vec
  65. inline void setVec(F32 x, F32 y, F32 z); // deprecated
  66. inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated
  67. inline void setVec(const LLVector4 &vec); // deprecated
  68. inline void setVec(const LLVector3 &vec, F32 w = 1.f); // deprecated
  69. inline void setVec(const F32 *vec); // deprecated
  70. F32 length() const; // Returns magnitude of LLVector4
  71. F32 lengthSquared() const; // Returns magnitude squared of LLVector4
  72. F32 normalize(); // Normalizes and returns the magnitude of LLVector4
  73. F32 magVec() const; // deprecated
  74. F32 magVecSquared() const; // deprecated
  75. F32 normVec(); // deprecated
  76. // Sets all values to absolute value of their original values
  77. // Returns TRUE if data changed
  78. BOOL abs();
  79. BOOL isExactlyClear() const { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; }
  80. BOOL isExactlyZero() const { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; }
  81. const LLVector4& rotVec(F32 angle, const LLVector4 &vec); // Rotates about vec by angle radians
  82. const LLVector4& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians
  83. const LLVector4& rotVec(const LLMatrix4 &mat); // Rotates by MAT4 mat
  84. const LLVector4& rotVec(const LLQuaternion &q); // Rotates by QUAT q
  85. const LLVector4& scaleVec(const LLVector4& vec); // Scales component-wise by vec
  86. F32 operator[](int idx) const { return mV[idx]; }
  87. F32 &operator[](int idx) { return mV[idx]; }
  88. friend std::ostream& operator<<(std::ostream& s, const LLVector4 &a); // Print a
  89. friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b); // Return vector a + b
  90. friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b); // Return vector a minus b
  91. friend F32 operator*(const LLVector4 &a, const LLVector4 &b); // Return a dot b
  92. friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b); // Return a cross b
  93. friend LLVector4 operator/(const LLVector4 &a, F32 k); // Return a divided by scaler k
  94. friend LLVector4 operator*(const LLVector4 &a, F32 k); // Return a times scaler k
  95. friend LLVector4 operator*(F32 k, const LLVector4 &a); // Return a times scaler k
  96. friend bool operator==(const LLVector4 &a, const LLVector4 &b); // Return a == b
  97. friend bool operator!=(const LLVector4 &a, const LLVector4 &b); // Return a != b
  98. friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b); // Return vector a + b
  99. friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b); // Return vector a minus b
  100. friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b); // Return a cross b
  101. friend const LLVector4& operator*=(LLVector4 &a, F32 k); // Return a times scaler k
  102. friend const LLVector4& operator/=(LLVector4 &a, F32 k); // Return a divided by scaler k
  103. friend LLVector4 operator-(const LLVector4 &a); // Return vector -a
  104. };
  105. // Non-member functions
  106. F32 angle_between(const LLVector4 &a, const LLVector4 &b); // Returns angle (radians) between a and b
  107. BOOL are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon=F_APPROXIMATELY_ZERO); // Returns TRUE if a and b are very close to parallel
  108. F32 dist_vec(const LLVector4 &a, const LLVector4 &b); // Returns distance between a and b
  109. F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b); // Returns distance squared between a and b
  110. LLVector3 vec4to3(const LLVector4 &vec);
  111. LLVector4 vec3to4(const LLVector3 &vec);
  112. LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
  113. // Constructors
  114. inline LLVector4::LLVector4(void)
  115. {
  116. mV[VX] = 0.f;
  117. mV[VY] = 0.f;
  118. mV[VZ] = 0.f;
  119. mV[VW] = 1.f;
  120. }
  121. inline LLVector4::LLVector4(F32 x, F32 y, F32 z)
  122. {
  123. mV[VX] = x;
  124. mV[VY] = y;
  125. mV[VZ] = z;
  126. mV[VW] = 1.f;
  127. }
  128. inline LLVector4::LLVector4(F32 x, F32 y, F32 z, F32 w)
  129. {
  130. mV[VX] = x;
  131. mV[VY] = y;
  132. mV[VZ] = z;
  133. mV[VW] = w;
  134. }
  135. inline LLVector4::LLVector4(const F32 *vec)
  136. {
  137. mV[VX] = vec[VX];
  138. mV[VY] = vec[VY];
  139. mV[VZ] = vec[VZ];
  140. mV[VW] = vec[VW];
  141. }
  142. inline LLVector4::LLVector4(const F64 *vec)
  143. {
  144. mV[VX] = (F32) vec[VX];
  145. mV[VY] = (F32) vec[VY];
  146. mV[VZ] = (F32) vec[VZ];
  147. mV[VW] = (F32) vec[VW];
  148. }
  149. inline LLVector4::LLVector4(const LLVector3 &vec)
  150. {
  151. mV[VX] = vec.mV[VX];
  152. mV[VY] = vec.mV[VY];
  153. mV[VZ] = vec.mV[VZ];
  154. mV[VW] = 1.f;
  155. }
  156. inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
  157. {
  158. mV[VX] = vec.mV[VX];
  159. mV[VY] = vec.mV[VY];
  160. mV[VZ] = vec.mV[VZ];
  161. mV[VW] = w;
  162. }
  163. inline BOOL LLVector4::isFinite() const
  164. {
  165. return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]));
  166. }
  167. // Clear and Assignment Functions
  168. inline void LLVector4::clear(void)
  169. {
  170. mV[VX] = 0.f;
  171. mV[VY] = 0.f;
  172. mV[VZ] = 0.f;
  173. mV[VW] = 1.f;
  174. }
  175. // deprecated
  176. inline void LLVector4::clearVec(void)
  177. {
  178. mV[VX] = 0.f;
  179. mV[VY] = 0.f;
  180. mV[VZ] = 0.f;
  181. mV[VW] = 1.f;
  182. }
  183. // deprecated
  184. inline void LLVector4::zeroVec(void)
  185. {
  186. mV[VX] = 0.f;
  187. mV[VY] = 0.f;
  188. mV[VZ] = 0.f;
  189. mV[VW] = 0.f;
  190. }
  191. inline void LLVector4::set(F32 x, F32 y, F32 z)
  192. {
  193. mV[VX] = x;
  194. mV[VY] = y;
  195. mV[VZ] = z;
  196. mV[VW] = 1.f;
  197. }
  198. inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w)
  199. {
  200. mV[VX] = x;
  201. mV[VY] = y;
  202. mV[VZ] = z;
  203. mV[VW] = w;
  204. }
  205. inline void LLVector4::set(const LLVector4 &vec)
  206. {
  207. mV[VX] = vec.mV[VX];
  208. mV[VY] = vec.mV[VY];
  209. mV[VZ] = vec.mV[VZ];
  210. mV[VW] = vec.mV[VW];
  211. }
  212. inline void LLVector4::set(const LLVector3 &vec, F32 w)
  213. {
  214. mV[VX] = vec.mV[VX];
  215. mV[VY] = vec.mV[VY];
  216. mV[VZ] = vec.mV[VZ];
  217. mV[VW] = w;
  218. }
  219. inline void LLVector4::set(const F32 *vec)
  220. {
  221. mV[VX] = vec[VX];
  222. mV[VY] = vec[VY];
  223. mV[VZ] = vec[VZ];
  224. mV[VW] = vec[VW];
  225. }
  226. // deprecated
  227. inline void LLVector4::setVec(F32 x, F32 y, F32 z)
  228. {
  229. mV[VX] = x;
  230. mV[VY] = y;
  231. mV[VZ] = z;
  232. mV[VW] = 1.f;
  233. }
  234. // deprecated
  235. inline void LLVector4::setVec(F32 x, F32 y, F32 z, F32 w)
  236. {
  237. mV[VX] = x;
  238. mV[VY] = y;
  239. mV[VZ] = z;
  240. mV[VW] = w;
  241. }
  242. // deprecated
  243. inline void LLVector4::setVec(const LLVector4 &vec)
  244. {
  245. mV[VX] = vec.mV[VX];
  246. mV[VY] = vec.mV[VY];
  247. mV[VZ] = vec.mV[VZ];
  248. mV[VW] = vec.mV[VW];
  249. }
  250. // deprecated
  251. inline void LLVector4::setVec(const LLVector3 &vec, F32 w)
  252. {
  253. mV[VX] = vec.mV[VX];
  254. mV[VY] = vec.mV[VY];
  255. mV[VZ] = vec.mV[VZ];
  256. mV[VW] = w;
  257. }
  258. // deprecated
  259. inline void LLVector4::setVec(const F32 *vec)
  260. {
  261. mV[VX] = vec[VX];
  262. mV[VY] = vec[VY];
  263. mV[VZ] = vec[VZ];
  264. mV[VW] = vec[VW];
  265. }
  266. // LLVector4 Magnitude and Normalization Functions
  267. inline F32 LLVector4::length(void) const
  268. {
  269. return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
  270. }
  271. inline F32 LLVector4::lengthSquared(void) const
  272. {
  273. return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
  274. }
  275. inline F32 LLVector4::magVec(void) const
  276. {
  277. return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
  278. }
  279. inline F32 LLVector4::magVecSquared(void) const
  280. {
  281. return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
  282. }
  283. // LLVector4 Operators
  284. inline LLVector4 operator+(const LLVector4 &a, const LLVector4 &b)
  285. {
  286. LLVector4 c(a);
  287. return c += b;
  288. }
  289. inline LLVector4 operator-(const LLVector4 &a, const LLVector4 &b)
  290. {
  291. LLVector4 c(a);
  292. return c -= b;
  293. }
  294. inline F32 operator*(const LLVector4 &a, const LLVector4 &b)
  295. {
  296. return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]);
  297. }
  298. inline LLVector4 operator%(const LLVector4 &a, const LLVector4 &b)
  299. {
  300. 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]);
  301. }
  302. inline LLVector4 operator/(const LLVector4 &a, F32 k)
  303. {
  304. F32 t = 1.f / k;
  305. return LLVector4( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t );
  306. }
  307. inline LLVector4 operator*(const LLVector4 &a, F32 k)
  308. {
  309. return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
  310. }
  311. inline LLVector4 operator*(F32 k, const LLVector4 &a)
  312. {
  313. return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
  314. }
  315. inline bool operator==(const LLVector4 &a, const LLVector4 &b)
  316. {
  317. return ( (a.mV[VX] == b.mV[VX])
  318. &&(a.mV[VY] == b.mV[VY])
  319. &&(a.mV[VZ] == b.mV[VZ]));
  320. }
  321. inline bool operator!=(const LLVector4 &a, const LLVector4 &b)
  322. {
  323. return ( (a.mV[VX] != b.mV[VX])
  324. ||(a.mV[VY] != b.mV[VY])
  325. ||(a.mV[VZ] != b.mV[VZ])
  326. ||(a.mV[VW] != b.mV[VW]) );
  327. }
  328. inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b)
  329. {
  330. a.mV[VX] += b.mV[VX];
  331. a.mV[VY] += b.mV[VY];
  332. a.mV[VZ] += b.mV[VZ];
  333. return a;
  334. }
  335. inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b)
  336. {
  337. a.mV[VX] -= b.mV[VX];
  338. a.mV[VY] -= b.mV[VY];
  339. a.mV[VZ] -= b.mV[VZ];
  340. return a;
  341. }
  342. inline const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b)
  343. {
  344. 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]);
  345. a = ret;
  346. return a;
  347. }
  348. inline const LLVector4& operator*=(LLVector4 &a, F32 k)
  349. {
  350. a.mV[VX] *= k;
  351. a.mV[VY] *= k;
  352. a.mV[VZ] *= k;
  353. return a;
  354. }
  355. inline const LLVector4& operator/=(LLVector4 &a, F32 k)
  356. {
  357. F32 t = 1.f / k;
  358. a.mV[VX] *= t;
  359. a.mV[VY] *= t;
  360. a.mV[VZ] *= t;
  361. return a;
  362. }
  363. inline LLVector4 operator-(const LLVector4 &a)
  364. {
  365. return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );
  366. }
  367. inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b)
  368. {
  369. LLVector4 vec = a - b;
  370. return (vec.length());
  371. }
  372. inline F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b)
  373. {
  374. LLVector4 vec = a - b;
  375. return (vec.lengthSquared());
  376. }
  377. inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u)
  378. {
  379. return LLVector4(
  380. a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
  381. a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
  382. a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u,
  383. a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);
  384. }
  385. inline F32 LLVector4::normalize(void)
  386. {
  387. F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
  388. F32 oomag;
  389. if (mag > FP_MAG_THRESHOLD)
  390. {
  391. oomag = 1.f/mag;
  392. mV[VX] *= oomag;
  393. mV[VY] *= oomag;
  394. mV[VZ] *= oomag;
  395. }
  396. else
  397. {
  398. mV[0] = 0.f;
  399. mV[1] = 0.f;
  400. mV[2] = 0.f;
  401. mag = 0;
  402. }
  403. return (mag);
  404. }
  405. // deprecated
  406. inline F32 LLVector4::normVec(void)
  407. {
  408. F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
  409. F32 oomag;
  410. if (mag > FP_MAG_THRESHOLD)
  411. {
  412. oomag = 1.f/mag;
  413. mV[VX] *= oomag;
  414. mV[VY] *= oomag;
  415. mV[VZ] *= oomag;
  416. }
  417. else
  418. {
  419. mV[0] = 0.f;
  420. mV[1] = 0.f;
  421. mV[2] = 0.f;
  422. mag = 0;
  423. }
  424. return (mag);
  425. }
  426. #endif