PageRenderTime 93ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmath/v3math.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 590 lines | 453 code | 93 blank | 44 comment | 29 complexity | 0da4c56b6ef5bb60c1eeb070a849949b MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file v3math.h
  3. * @brief LLVector3 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_V3MATH_H
  27. #define LL_V3MATH_H
  28. #include "llerror.h"
  29. #include "llmath.h"
  30. #include "llsd.h"
  31. class LLVector2;
  32. class LLVector4;
  33. class LLMatrix3;
  34. class LLMatrix4;
  35. class LLVector3d;
  36. class LLQuaternion;
  37. // LLvector3 = |x y z w|
  38. static const U32 LENGTHOFVECTOR3 = 3;
  39. class LLVector3
  40. {
  41. public:
  42. F32 mV[LENGTHOFVECTOR3];
  43. static const LLVector3 zero;
  44. static const LLVector3 x_axis;
  45. static const LLVector3 y_axis;
  46. static const LLVector3 z_axis;
  47. static const LLVector3 x_axis_neg;
  48. static const LLVector3 y_axis_neg;
  49. static const LLVector3 z_axis_neg;
  50. static const LLVector3 all_one;
  51. inline LLVector3(); // Initializes LLVector3 to (0, 0, 0)
  52. inline LLVector3(const F32 x, const F32 y, const F32 z); // Initializes LLVector3 to (x. y, z)
  53. inline explicit LLVector3(const F32 *vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
  54. explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0)
  55. explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
  56. explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2])
  57. explicit LLVector3(const LLSD& sd);
  58. LLSD getValue() const;
  59. void setValue(const LLSD& sd);
  60. inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
  61. BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed
  62. BOOL clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector
  63. BOOL clampLength( F32 length_limit ); // Scales vector to limit length to a value
  64. void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization
  65. void quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization
  66. void snap(S32 sig_digits); // snaps x,y,z to sig_digits decimal places
  67. BOOL abs(); // sets all values to absolute value of original value (first octant), returns TRUE if changed
  68. inline void clear(); // Clears LLVector3 to (0, 0, 0)
  69. inline void setZero(); // Clears LLVector3 to (0, 0, 0)
  70. inline void clearVec(); // deprecated
  71. inline void zeroVec(); // deprecated
  72. inline void set(F32 x, F32 y, F32 z); // Sets LLVector3 to (x, y, z, 1)
  73. inline void set(const LLVector3 &vec); // Sets LLVector3 to vec
  74. inline void set(const F32 *vec); // Sets LLVector3 to vec
  75. const LLVector3& set(const LLVector4 &vec);
  76. const LLVector3& set(const LLVector3d &vec);// Sets LLVector3 to vec
  77. inline void setVec(F32 x, F32 y, F32 z); // deprecated
  78. inline void setVec(const LLVector3 &vec); // deprecated
  79. inline void setVec(const F32 *vec); // deprecated
  80. const LLVector3& setVec(const LLVector4 &vec); // deprecated
  81. const LLVector3& setVec(const LLVector3d &vec); // deprecated
  82. F32 length() const; // Returns magnitude of LLVector3
  83. F32 lengthSquared() const; // Returns magnitude squared of LLVector3
  84. F32 magVec() const; // deprecated
  85. F32 magVecSquared() const; // deprecated
  86. inline F32 normalize(); // Normalizes and returns the magnitude of LLVector3
  87. inline F32 normVec(); // deprecated
  88. inline BOOL inRange( F32 min, F32 max ) const; // Returns true if all values of the vector are between min and max
  89. const LLVector3& rotVec(F32 angle, const LLVector3 &vec); // Rotates about vec by angle radians
  90. const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians
  91. const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
  92. const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
  93. const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v)
  94. const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec
  95. LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec
  96. BOOL isNull() const; // Returns TRUE if vector has a _very_small_ length
  97. BOOL isExactlyZero() const { return !mV[VX] && !mV[VY] && !mV[VZ]; }
  98. F32 operator[](int idx) const { return mV[idx]; }
  99. F32 &operator[](int idx) { return mV[idx]; }
  100. friend LLVector3 operator+(const LLVector3 &a, const LLVector3 &b); // Return vector a + b
  101. friend LLVector3 operator-(const LLVector3 &a, const LLVector3 &b); // Return vector a minus b
  102. friend F32 operator*(const LLVector3 &a, const LLVector3 &b); // Return a dot b
  103. friend LLVector3 operator%(const LLVector3 &a, const LLVector3 &b); // Return a cross b
  104. friend LLVector3 operator*(const LLVector3 &a, F32 k); // Return a times scaler k
  105. friend LLVector3 operator/(const LLVector3 &a, F32 k); // Return a divided by scaler k
  106. friend LLVector3 operator*(F32 k, const LLVector3 &a); // Return a times scaler k
  107. friend bool operator==(const LLVector3 &a, const LLVector3 &b); // Return a == b
  108. friend bool operator!=(const LLVector3 &a, const LLVector3 &b); // Return a != b
  109. // less than operator useful for using vectors as std::map keys
  110. friend bool operator<(const LLVector3 &a, const LLVector3 &b); // Return a < b
  111. friend const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b); // Return vector a + b
  112. friend const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b); // Return vector a minus b
  113. friend const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b); // Return a cross b
  114. friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b); // Returns a * b;
  115. friend const LLVector3& operator*=(LLVector3 &a, F32 k); // Return a times scaler k
  116. friend const LLVector3& operator/=(LLVector3 &a, F32 k); // Return a divided by scaler k
  117. friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b); // Returns a * b;
  118. friend LLVector3 operator-(const LLVector3 &a); // Return vector -a
  119. friend std::ostream& operator<<(std::ostream& s, const LLVector3 &a); // Stream a
  120. static BOOL parseVector3(const std::string& buf, LLVector3* value);
  121. };
  122. typedef LLVector3 LLSimLocalVec;
  123. // Non-member functions
  124. F32 angle_between(const LLVector3 &a, const LLVector3 &b); // Returns angle (radians) between a and b
  125. 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
  126. F32 dist_vec(const LLVector3 &a, const LLVector3 &b); // Returns distance between a and b
  127. F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b
  128. F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component
  129. LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b
  130. LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec)
  131. LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec)
  132. LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
  133. inline LLVector3::LLVector3(void)
  134. {
  135. mV[0] = 0.f;
  136. mV[1] = 0.f;
  137. mV[2] = 0.f;
  138. }
  139. inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z)
  140. {
  141. mV[VX] = x;
  142. mV[VY] = y;
  143. mV[VZ] = z;
  144. }
  145. inline LLVector3::LLVector3(const F32 *vec)
  146. {
  147. mV[VX] = vec[VX];
  148. mV[VY] = vec[VY];
  149. mV[VZ] = vec[VZ];
  150. }
  151. /*
  152. inline LLVector3::LLVector3(const LLVector3 &copy)
  153. {
  154. mV[VX] = copy.mV[VX];
  155. mV[VY] = copy.mV[VY];
  156. mV[VZ] = copy.mV[VZ];
  157. }
  158. */
  159. // Destructors
  160. // checker
  161. inline BOOL LLVector3::isFinite() const
  162. {
  163. return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]));
  164. }
  165. // Clear and Assignment Functions
  166. inline void LLVector3::clear(void)
  167. {
  168. mV[0] = 0.f;
  169. mV[1] = 0.f;
  170. mV[2] = 0.f;
  171. }
  172. inline void LLVector3::setZero(void)
  173. {
  174. mV[0] = 0.f;
  175. mV[1] = 0.f;
  176. mV[2] = 0.f;
  177. }
  178. inline void LLVector3::clearVec(void)
  179. {
  180. mV[0] = 0.f;
  181. mV[1] = 0.f;
  182. mV[2] = 0.f;
  183. }
  184. inline void LLVector3::zeroVec(void)
  185. {
  186. mV[0] = 0.f;
  187. mV[1] = 0.f;
  188. mV[2] = 0.f;
  189. }
  190. inline void LLVector3::set(F32 x, F32 y, F32 z)
  191. {
  192. mV[VX] = x;
  193. mV[VY] = y;
  194. mV[VZ] = z;
  195. }
  196. inline void LLVector3::set(const LLVector3 &vec)
  197. {
  198. mV[0] = vec.mV[0];
  199. mV[1] = vec.mV[1];
  200. mV[2] = vec.mV[2];
  201. }
  202. inline void LLVector3::set(const F32 *vec)
  203. {
  204. mV[0] = vec[0];
  205. mV[1] = vec[1];
  206. mV[2] = vec[2];
  207. }
  208. // deprecated
  209. inline void LLVector3::setVec(F32 x, F32 y, F32 z)
  210. {
  211. mV[VX] = x;
  212. mV[VY] = y;
  213. mV[VZ] = z;
  214. }
  215. // deprecated
  216. inline void LLVector3::setVec(const LLVector3 &vec)
  217. {
  218. mV[0] = vec.mV[0];
  219. mV[1] = vec.mV[1];
  220. mV[2] = vec.mV[2];
  221. }
  222. // deprecated
  223. inline void LLVector3::setVec(const F32 *vec)
  224. {
  225. mV[0] = vec[0];
  226. mV[1] = vec[1];
  227. mV[2] = vec[2];
  228. }
  229. inline F32 LLVector3::normalize(void)
  230. {
  231. F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
  232. F32 oomag;
  233. if (mag > FP_MAG_THRESHOLD)
  234. {
  235. oomag = 1.f/mag;
  236. mV[0] *= oomag;
  237. mV[1] *= oomag;
  238. mV[2] *= oomag;
  239. }
  240. else
  241. {
  242. mV[0] = 0.f;
  243. mV[1] = 0.f;
  244. mV[2] = 0.f;
  245. mag = 0;
  246. }
  247. return (mag);
  248. }
  249. // deprecated
  250. inline F32 LLVector3::normVec(void)
  251. {
  252. F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
  253. F32 oomag;
  254. if (mag > FP_MAG_THRESHOLD)
  255. {
  256. oomag = 1.f/mag;
  257. mV[0] *= oomag;
  258. mV[1] *= oomag;
  259. mV[2] *= oomag;
  260. }
  261. else
  262. {
  263. mV[0] = 0.f;
  264. mV[1] = 0.f;
  265. mV[2] = 0.f;
  266. mag = 0;
  267. }
  268. return (mag);
  269. }
  270. // LLVector3 Magnitude and Normalization Functions
  271. inline F32 LLVector3::length(void) const
  272. {
  273. return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
  274. }
  275. inline F32 LLVector3::lengthSquared(void) const
  276. {
  277. return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
  278. }
  279. inline F32 LLVector3::magVec(void) const
  280. {
  281. return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
  282. }
  283. inline F32 LLVector3::magVecSquared(void) const
  284. {
  285. return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
  286. }
  287. inline BOOL LLVector3::inRange( F32 min, F32 max ) const
  288. {
  289. return mV[0] >= min && mV[0] <= max &&
  290. mV[1] >= min && mV[1] <= max &&
  291. mV[2] >= min && mV[2] <= max;
  292. }
  293. inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b)
  294. {
  295. LLVector3 c(a);
  296. return c += b;
  297. }
  298. inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b)
  299. {
  300. LLVector3 c(a);
  301. return c -= b;
  302. }
  303. inline F32 operator*(const LLVector3 &a, const LLVector3 &b)
  304. {
  305. return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]);
  306. }
  307. inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b)
  308. {
  309. 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] );
  310. }
  311. inline LLVector3 operator/(const LLVector3 &a, F32 k)
  312. {
  313. F32 t = 1.f / k;
  314. return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t );
  315. }
  316. inline LLVector3 operator*(const LLVector3 &a, F32 k)
  317. {
  318. return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
  319. }
  320. inline LLVector3 operator*(F32 k, const LLVector3 &a)
  321. {
  322. return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
  323. }
  324. inline bool operator==(const LLVector3 &a, const LLVector3 &b)
  325. {
  326. return ( (a.mV[0] == b.mV[0])
  327. &&(a.mV[1] == b.mV[1])
  328. &&(a.mV[2] == b.mV[2]));
  329. }
  330. inline bool operator!=(const LLVector3 &a, const LLVector3 &b)
  331. {
  332. return ( (a.mV[0] != b.mV[0])
  333. ||(a.mV[1] != b.mV[1])
  334. ||(a.mV[2] != b.mV[2]));
  335. }
  336. inline bool operator<(const LLVector3 &a, const LLVector3 &b)
  337. {
  338. return (a.mV[0] < b.mV[0]
  339. || (a.mV[0] == b.mV[0]
  340. && (a.mV[1] < b.mV[1]
  341. || ((a.mV[1] == b.mV[1])
  342. && a.mV[2] < b.mV[2]))));
  343. }
  344. inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b)
  345. {
  346. a.mV[0] += b.mV[0];
  347. a.mV[1] += b.mV[1];
  348. a.mV[2] += b.mV[2];
  349. return a;
  350. }
  351. inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b)
  352. {
  353. a.mV[0] -= b.mV[0];
  354. a.mV[1] -= b.mV[1];
  355. a.mV[2] -= b.mV[2];
  356. return a;
  357. }
  358. inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b)
  359. {
  360. 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]);
  361. a = ret;
  362. return a;
  363. }
  364. inline const LLVector3& operator*=(LLVector3 &a, F32 k)
  365. {
  366. a.mV[0] *= k;
  367. a.mV[1] *= k;
  368. a.mV[2] *= k;
  369. return a;
  370. }
  371. inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b)
  372. {
  373. a.mV[0] *= b.mV[0];
  374. a.mV[1] *= b.mV[1];
  375. a.mV[2] *= b.mV[2];
  376. return a;
  377. }
  378. inline const LLVector3& operator/=(LLVector3 &a, F32 k)
  379. {
  380. F32 t = 1.f / k;
  381. a.mV[0] *= t;
  382. a.mV[1] *= t;
  383. a.mV[2] *= t;
  384. return a;
  385. }
  386. inline LLVector3 operator-(const LLVector3 &a)
  387. {
  388. return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );
  389. }
  390. inline F32 dist_vec(const LLVector3 &a, const LLVector3 &b)
  391. {
  392. F32 x = a.mV[0] - b.mV[0];
  393. F32 y = a.mV[1] - b.mV[1];
  394. F32 z = a.mV[2] - b.mV[2];
  395. return (F32) sqrt( x*x + y*y + z*z );
  396. }
  397. inline F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b)
  398. {
  399. F32 x = a.mV[0] - b.mV[0];
  400. F32 y = a.mV[1] - b.mV[1];
  401. F32 z = a.mV[2] - b.mV[2];
  402. return x*x + y*y + z*z;
  403. }
  404. inline F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b)
  405. {
  406. F32 x = a.mV[0] - b.mV[0];
  407. F32 y = a.mV[1] - b.mV[1];
  408. return x*x + y*y;
  409. }
  410. inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
  411. {
  412. LLVector3 project_axis = b;
  413. project_axis.normalize();
  414. return project_axis * (a * project_axis);
  415. }
  416. inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
  417. {
  418. return projected_vec(a, b);
  419. }
  420. inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b)
  421. {
  422. return a - projected_vec(a, b);
  423. }
  424. inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
  425. {
  426. return LLVector3(
  427. a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
  428. a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
  429. a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
  430. }
  431. inline BOOL LLVector3::isNull() const
  432. {
  433. if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] )
  434. {
  435. return TRUE;
  436. }
  437. return FALSE;
  438. }
  439. inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
  440. {
  441. for (U32 i = 0; i < 3; i++)
  442. {
  443. if (min.mV[i] > pos.mV[i])
  444. {
  445. min.mV[i] = pos.mV[i];
  446. }
  447. if (max.mV[i] < pos.mV[i])
  448. {
  449. max.mV[i] = pos.mV[i];
  450. }
  451. }
  452. }
  453. inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos)
  454. {
  455. for (U32 i = 0; i < 3; i++)
  456. {
  457. if (min.mV[i] > pos[i])
  458. {
  459. min.mV[i] = pos[i];
  460. }
  461. if (max.mV[i] < pos[i])
  462. {
  463. max.mV[i] = pos[i];
  464. }
  465. }
  466. }
  467. inline F32 angle_between(const LLVector3& a, const LLVector3& b)
  468. {
  469. LLVector3 an = a;
  470. LLVector3 bn = b;
  471. an.normalize();
  472. bn.normalize();
  473. F32 cosine = an * bn;
  474. F32 angle = (cosine >= 1.0f) ? 0.0f :
  475. (cosine <= -1.0f) ? F_PI :
  476. (F32)acos(cosine);
  477. return angle;
  478. }
  479. inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon)
  480. {
  481. LLVector3 an = a;
  482. LLVector3 bn = b;
  483. an.normalize();
  484. bn.normalize();
  485. F32 dot = an * bn;
  486. if ( (1.0f - fabs(dot)) < epsilon)
  487. {
  488. return TRUE;
  489. }
  490. return FALSE;
  491. }
  492. inline std::ostream& operator<<(std::ostream& s, const LLVector3 &a)
  493. {
  494. s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }";
  495. return s;
  496. }
  497. #endif