PageRenderTime 15ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmath/v3dmath.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 475 lines | 363 code | 75 blank | 37 comment | 14 complexity | a6aca3aa65a7fbecc52ee38666322dc4 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file v3dmath.h
  3. * @brief High precision 3 dimensional vector.
  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_V3DMATH_H
  27. #define LL_V3DMATH_H
  28. #include "llerror.h"
  29. #include "v3math.h"
  30. class LLVector3d
  31. {
  32. public:
  33. F64 mdV[3];
  34. const static LLVector3d zero;
  35. const static LLVector3d x_axis;
  36. const static LLVector3d y_axis;
  37. const static LLVector3d z_axis;
  38. const static LLVector3d x_axis_neg;
  39. const static LLVector3d y_axis_neg;
  40. const static LLVector3d z_axis_neg;
  41. inline LLVector3d(); // Initializes LLVector3d to (0, 0, 0)
  42. inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z)
  43. inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2])
  44. inline explicit LLVector3d(const LLVector3 &vec);
  45. explicit LLVector3d(const LLSD& sd)
  46. {
  47. setValue(sd);
  48. }
  49. void setValue(const LLSD& sd)
  50. {
  51. mdV[0] = sd[0].asReal();
  52. mdV[1] = sd[1].asReal();
  53. mdV[2] = sd[2].asReal();
  54. }
  55. LLSD getValue() const
  56. {
  57. LLSD ret;
  58. ret[0] = mdV[0];
  59. ret[1] = mdV[1];
  60. ret[2] = mdV[2];
  61. return ret;
  62. }
  63. inline BOOL isFinite() const; // checks to see if all values of LLVector3d are finite
  64. BOOL clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns TRUE if data changed
  65. BOOL abs(); // sets all values to absolute value of original value (first octant), returns TRUE if changed
  66. inline const LLVector3d& clearVec(); // Clears LLVector3d to (0, 0, 0, 1)
  67. inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0)
  68. inline const LLVector3d& zeroVec(); // deprecated
  69. inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1)
  70. inline const LLVector3d& setVec(const LLVector3d &vec); // Sets LLVector3d to vec
  71. inline const LLVector3d& setVec(const F64 *vec); // Sets LLVector3d to vec
  72. inline const LLVector3d& setVec(const LLVector3 &vec);
  73. F64 magVec() const; // Returns magnitude of LLVector3d
  74. F64 magVecSquared() const; // Returns magnitude squared of LLVector3d
  75. inline F64 normVec(); // Normalizes and returns the magnitude of LLVector3d
  76. F64 length() const; // Returns magnitude of LLVector3d
  77. F64 lengthSquared() const; // Returns magnitude squared of LLVector3d
  78. inline F64 normalize(); // Normalizes and returns the magnitude of LLVector3d
  79. const LLVector3d& rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians
  80. const LLVector3d& rotVec(const F64 angle, const F64 x, const F64 y, const F64 z); // Rotates about x,y,z by angle radians
  81. const LLVector3d& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
  82. const LLVector3d& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
  83. BOOL isNull() const; // Returns TRUE if vector has a _very_small_ length
  84. BOOL isExactlyZero() const { return !mdV[VX] && !mdV[VY] && !mdV[VZ]; }
  85. const LLVector3d& operator=(const LLVector4 &a);
  86. F64 operator[](int idx) const { return mdV[idx]; }
  87. F64 &operator[](int idx) { return mdV[idx]; }
  88. friend LLVector3d operator+(const LLVector3d &a, const LLVector3d &b); // Return vector a + b
  89. friend LLVector3d operator-(const LLVector3d &a, const LLVector3d &b); // Return vector a minus b
  90. friend F64 operator*(const LLVector3d &a, const LLVector3d &b); // Return a dot b
  91. friend LLVector3d operator%(const LLVector3d &a, const LLVector3d &b); // Return a cross b
  92. friend LLVector3d operator*(const LLVector3d &a, const F64 k); // Return a times scaler k
  93. friend LLVector3d operator/(const LLVector3d &a, const F64 k); // Return a divided by scaler k
  94. friend LLVector3d operator*(const F64 k, const LLVector3d &a); // Return a times scaler k
  95. friend bool operator==(const LLVector3d &a, const LLVector3d &b); // Return a == b
  96. friend bool operator!=(const LLVector3d &a, const LLVector3d &b); // Return a != b
  97. friend const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b); // Return vector a + b
  98. friend const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b); // Return vector a minus b
  99. friend const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b); // Return a cross b
  100. friend const LLVector3d& operator*=(LLVector3d &a, const F64 k); // Return a times scaler k
  101. friend const LLVector3d& operator/=(LLVector3d &a, const F64 k); // Return a divided by scaler k
  102. friend LLVector3d operator-(const LLVector3d &a); // Return vector -a
  103. friend std::ostream& operator<<(std::ostream& s, const LLVector3d &a); // Stream a
  104. static BOOL parseVector3d(const std::string& buf, LLVector3d* value);
  105. };
  106. typedef LLVector3d LLGlobalVec;
  107. const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)
  108. {
  109. mdV[0] = vec.mV[0];
  110. mdV[1] = vec.mV[1];
  111. mdV[2] = vec.mV[2];
  112. return *this;
  113. }
  114. inline LLVector3d::LLVector3d(void)
  115. {
  116. mdV[0] = 0.f;
  117. mdV[1] = 0.f;
  118. mdV[2] = 0.f;
  119. }
  120. inline LLVector3d::LLVector3d(const F64 x, const F64 y, const F64 z)
  121. {
  122. mdV[VX] = x;
  123. mdV[VY] = y;
  124. mdV[VZ] = z;
  125. }
  126. inline LLVector3d::LLVector3d(const F64 *vec)
  127. {
  128. mdV[VX] = vec[VX];
  129. mdV[VY] = vec[VY];
  130. mdV[VZ] = vec[VZ];
  131. }
  132. inline LLVector3d::LLVector3d(const LLVector3 &vec)
  133. {
  134. mdV[VX] = vec.mV[VX];
  135. mdV[VY] = vec.mV[VY];
  136. mdV[VZ] = vec.mV[VZ];
  137. }
  138. /*
  139. inline LLVector3d::LLVector3d(const LLVector3d &copy)
  140. {
  141. mdV[VX] = copy.mdV[VX];
  142. mdV[VY] = copy.mdV[VY];
  143. mdV[VZ] = copy.mdV[VZ];
  144. }
  145. */
  146. // Destructors
  147. // checker
  148. inline BOOL LLVector3d::isFinite() const
  149. {
  150. return (llfinite(mdV[VX]) && llfinite(mdV[VY]) && llfinite(mdV[VZ]));
  151. }
  152. // Clear and Assignment Functions
  153. inline const LLVector3d& LLVector3d::clearVec(void)
  154. {
  155. mdV[0] = 0.f;
  156. mdV[1] = 0.f;
  157. mdV[2]= 0.f;
  158. return (*this);
  159. }
  160. inline const LLVector3d& LLVector3d::setZero(void)
  161. {
  162. mdV[0] = 0.f;
  163. mdV[1] = 0.f;
  164. mdV[2] = 0.f;
  165. return (*this);
  166. }
  167. inline const LLVector3d& LLVector3d::zeroVec(void)
  168. {
  169. mdV[0] = 0.f;
  170. mdV[1] = 0.f;
  171. mdV[2] = 0.f;
  172. return (*this);
  173. }
  174. inline const LLVector3d& LLVector3d::setVec(const F64 x, const F64 y, const F64 z)
  175. {
  176. mdV[VX] = x;
  177. mdV[VY] = y;
  178. mdV[VZ] = z;
  179. return (*this);
  180. }
  181. inline const LLVector3d& LLVector3d::setVec(const LLVector3d &vec)
  182. {
  183. mdV[0] = vec.mdV[0];
  184. mdV[1] = vec.mdV[1];
  185. mdV[2] = vec.mdV[2];
  186. return (*this);
  187. }
  188. inline const LLVector3d& LLVector3d::setVec(const F64 *vec)
  189. {
  190. mdV[0] = vec[0];
  191. mdV[1] = vec[1];
  192. mdV[2] = vec[2];
  193. return (*this);
  194. }
  195. inline F64 LLVector3d::normVec(void)
  196. {
  197. F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  198. F64 oomag;
  199. if (mag > FP_MAG_THRESHOLD)
  200. {
  201. oomag = 1.f/mag;
  202. mdV[0] *= oomag;
  203. mdV[1] *= oomag;
  204. mdV[2] *= oomag;
  205. }
  206. else
  207. {
  208. mdV[0] = 0.f;
  209. mdV[1] = 0.f;
  210. mdV[2] = 0.f;
  211. mag = 0;
  212. }
  213. return (mag);
  214. }
  215. inline F64 LLVector3d::normalize(void)
  216. {
  217. F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  218. F64 oomag;
  219. if (mag > FP_MAG_THRESHOLD)
  220. {
  221. oomag = 1.f/mag;
  222. mdV[0] *= oomag;
  223. mdV[1] *= oomag;
  224. mdV[2] *= oomag;
  225. }
  226. else
  227. {
  228. mdV[0] = 0.f;
  229. mdV[1] = 0.f;
  230. mdV[2] = 0.f;
  231. mag = 0;
  232. }
  233. return (mag);
  234. }
  235. // LLVector3d Magnitude and Normalization Functions
  236. inline F64 LLVector3d::magVec(void) const
  237. {
  238. return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  239. }
  240. inline F64 LLVector3d::magVecSquared(void) const
  241. {
  242. return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
  243. }
  244. inline F64 LLVector3d::length(void) const
  245. {
  246. return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  247. }
  248. inline F64 LLVector3d::lengthSquared(void) const
  249. {
  250. return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
  251. }
  252. inline LLVector3d operator+(const LLVector3d &a, const LLVector3d &b)
  253. {
  254. LLVector3d c(a);
  255. return c += b;
  256. }
  257. inline LLVector3d operator-(const LLVector3d &a, const LLVector3d &b)
  258. {
  259. LLVector3d c(a);
  260. return c -= b;
  261. }
  262. inline F64 operator*(const LLVector3d &a, const LLVector3d &b)
  263. {
  264. return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]);
  265. }
  266. inline LLVector3d operator%(const LLVector3d &a, const LLVector3d &b)
  267. {
  268. return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] );
  269. }
  270. inline LLVector3d operator/(const LLVector3d &a, const F64 k)
  271. {
  272. F64 t = 1.f / k;
  273. return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t );
  274. }
  275. inline LLVector3d operator*(const LLVector3d &a, const F64 k)
  276. {
  277. return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
  278. }
  279. inline LLVector3d operator*(F64 k, const LLVector3d &a)
  280. {
  281. return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
  282. }
  283. inline bool operator==(const LLVector3d &a, const LLVector3d &b)
  284. {
  285. return ( (a.mdV[0] == b.mdV[0])
  286. &&(a.mdV[1] == b.mdV[1])
  287. &&(a.mdV[2] == b.mdV[2]));
  288. }
  289. inline bool operator!=(const LLVector3d &a, const LLVector3d &b)
  290. {
  291. return ( (a.mdV[0] != b.mdV[0])
  292. ||(a.mdV[1] != b.mdV[1])
  293. ||(a.mdV[2] != b.mdV[2]));
  294. }
  295. inline const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b)
  296. {
  297. a.mdV[0] += b.mdV[0];
  298. a.mdV[1] += b.mdV[1];
  299. a.mdV[2] += b.mdV[2];
  300. return a;
  301. }
  302. inline const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b)
  303. {
  304. a.mdV[0] -= b.mdV[0];
  305. a.mdV[1] -= b.mdV[1];
  306. a.mdV[2] -= b.mdV[2];
  307. return a;
  308. }
  309. inline const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b)
  310. {
  311. LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]);
  312. a = ret;
  313. return a;
  314. }
  315. inline const LLVector3d& operator*=(LLVector3d &a, const F64 k)
  316. {
  317. a.mdV[0] *= k;
  318. a.mdV[1] *= k;
  319. a.mdV[2] *= k;
  320. return a;
  321. }
  322. inline const LLVector3d& operator/=(LLVector3d &a, const F64 k)
  323. {
  324. F64 t = 1.f / k;
  325. a.mdV[0] *= t;
  326. a.mdV[1] *= t;
  327. a.mdV[2] *= t;
  328. return a;
  329. }
  330. inline LLVector3d operator-(const LLVector3d &a)
  331. {
  332. return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] );
  333. }
  334. inline F64 dist_vec(const LLVector3d &a, const LLVector3d &b)
  335. {
  336. F64 x = a.mdV[0] - b.mdV[0];
  337. F64 y = a.mdV[1] - b.mdV[1];
  338. F64 z = a.mdV[2] - b.mdV[2];
  339. return (F32) sqrt( x*x + y*y + z*z );
  340. }
  341. inline F64 dist_vec_squared(const LLVector3d &a, const LLVector3d &b)
  342. {
  343. F64 x = a.mdV[0] - b.mdV[0];
  344. F64 y = a.mdV[1] - b.mdV[1];
  345. F64 z = a.mdV[2] - b.mdV[2];
  346. return x*x + y*y + z*z;
  347. }
  348. inline F64 dist_vec_squared2D(const LLVector3d &a, const LLVector3d &b)
  349. {
  350. F64 x = a.mdV[0] - b.mdV[0];
  351. F64 y = a.mdV[1] - b.mdV[1];
  352. return x*x + y*y;
  353. }
  354. inline LLVector3d lerp(const LLVector3d &a, const LLVector3d &b, const F64 u)
  355. {
  356. return LLVector3d(
  357. a.mdV[VX] + (b.mdV[VX] - a.mdV[VX]) * u,
  358. a.mdV[VY] + (b.mdV[VY] - a.mdV[VY]) * u,
  359. a.mdV[VZ] + (b.mdV[VZ] - a.mdV[VZ]) * u);
  360. }
  361. inline BOOL LLVector3d::isNull() const
  362. {
  363. if ( F_APPROXIMATELY_ZERO > mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ] )
  364. {
  365. return TRUE;
  366. }
  367. return FALSE;
  368. }
  369. inline F64 angle_between(const LLVector3d& a, const LLVector3d& b)
  370. {
  371. LLVector3d an = a;
  372. LLVector3d bn = b;
  373. an.normalize();
  374. bn.normalize();
  375. F64 cosine = an * bn;
  376. F64 angle = (cosine >= 1.0f) ? 0.0f :
  377. (cosine <= -1.0f) ? F_PI :
  378. acos(cosine);
  379. return angle;
  380. }
  381. inline BOOL are_parallel(const LLVector3d &a, const LLVector3d &b, const F64 epsilon)
  382. {
  383. LLVector3d an = a;
  384. LLVector3d bn = b;
  385. an.normalize();
  386. bn.normalize();
  387. F64 dot = an * bn;
  388. if ( (1.0f - fabs(dot)) < epsilon)
  389. {
  390. return TRUE;
  391. }
  392. return FALSE;
  393. }
  394. inline LLVector3d projected_vec(const LLVector3d &a, const LLVector3d &b)
  395. {
  396. LLVector3d project_axis = b;
  397. project_axis.normalize();
  398. return project_axis * (a * project_axis);
  399. }
  400. #endif // LL_V3DMATH_H