llvector3.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /**
  2. * @file llvector3.h
  3. * @brief LLVector3 class header file.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_V3MATH_H
  33. #define LL_V3MATH_H
  34. #include "llmath.h"
  35. #include "llsd.h"
  36. class LLVector2;
  37. class LLVector4;
  38. class LLMatrix3;
  39. class LLMatrix4;
  40. class LLVector3d;
  41. class LLQuaternion;
  42. // LLvector3 = |x y z w|
  43. constexpr U32 LENGTHOFVECTOR3 = 3;
  44. class LLVector3
  45. {
  46. public:
  47. LL_INLINE LLVector3() noexcept { mV[0] = mV[1] = mV[2] = 0.f; }
  48. LL_INLINE LLVector3(F32 x, F32 y, F32 z) noexcept
  49. {
  50. mV[VX] = x;
  51. mV[VY] = y;
  52. mV[VZ] = z;
  53. }
  54. LL_INLINE explicit LLVector3(const F32* vec) noexcept
  55. {
  56. mV[VX] = vec[VX];
  57. mV[VY] = vec[VY];
  58. mV[VZ] = vec[VZ];
  59. }
  60. #if 0
  61. LL_INLINE LLVector3(const LLVector3& copy) noexcept
  62. {
  63. mV[VX] = copy.mV[VX];
  64. mV[VY] = copy.mV[VY];
  65. mV[VZ] = copy.mV[VZ];
  66. }
  67. #endif
  68. explicit LLVector3(const LLVector2& vec) noexcept;
  69. explicit LLVector3(const LLVector3d& vec) noexcept;
  70. explicit LLVector3(const LLVector4& vec) noexcept;
  71. // Allow the use of the default C++11 move constructor and assignation
  72. LLVector3(LLVector3&& other) noexcept = default;
  73. LLVector3& operator=(LLVector3&& other) noexcept = default;
  74. LLVector3(const LLVector3& other) = default;
  75. LLVector3& operator=(const LLVector3& other) = default;
  76. LL_INLINE explicit LLVector3(const LLSD& sd) { setValue(sd); }
  77. LL_INLINE LLSD getValue() const
  78. {
  79. LLSD ret;
  80. ret[0] = mV[0];
  81. ret[1] = mV[1];
  82. ret[2] = mV[2];
  83. return ret;
  84. }
  85. LL_INLINE void setValue(const LLSD& sd)
  86. {
  87. mV[0] = (F32)sd[0].asReal();
  88. mV[1] = (F32)sd[1].asReal();
  89. mV[2] = (F32)sd[2].asReal();
  90. }
  91. // checks to see if all values of LLVector3 are finite
  92. LL_INLINE bool isFinite() const
  93. {
  94. return llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]);
  95. }
  96. // Clamps all values to (min, max), returns true if data changed
  97. bool clamp(F32 min, F32 max);
  98. // Scales vector by another vector
  99. bool clamp(const LLVector3& min_vec, const LLVector3& max_vec);
  100. // Scales vector to limit length to a value
  101. bool clampLength(F32 length_limit);
  102. // Change the vector to reflect quatization
  103. void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);
  104. void quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);
  105. // Snaps x,y,z to sig_digits decimal places
  106. void snap(S32 sig_digits);
  107. // Sets all values to absolute value of original value (first octant),
  108. // returns true if changed.
  109. bool abs();
  110. // Clear LLVector3 to (0, 0, 0)
  111. LL_INLINE void clear() { mV[0] = mV[1] = mV[2] = 0.f; }
  112. LL_INLINE void setZero() { mV[0] = mV[1] = mV[2] = 0.f; }
  113. LL_INLINE void set(F32 x, F32 y, F32 z)
  114. {
  115. mV[VX] = x;
  116. mV[VY] = y;
  117. mV[VZ] = z;
  118. }
  119. LL_INLINE void set(const LLVector3& vec)
  120. {
  121. mV[0] = vec.mV[0];
  122. mV[1] = vec.mV[1];
  123. mV[2] = vec.mV[2];
  124. }
  125. LL_INLINE void set(const F32* vec)
  126. {
  127. mV[0] = vec[0];
  128. mV[1] = vec[1];
  129. mV[2] = vec[2];
  130. }
  131. const LLVector3& set(const LLVector4& vec);
  132. const LLVector3& set(const LLVector3d& vec);
  133. // Returns magnitude of LLVector3
  134. LL_INLINE F32 length() const
  135. {
  136. return sqrtf(mV[0] * mV[0] + mV[1] * mV[1] + mV[2] * mV[2]);
  137. }
  138. // Returns squared magnitude
  139. LL_INLINE F32 lengthSquared() const
  140. {
  141. return mV[0] * mV[0] + mV[1] * mV[1] + mV[2] * mV[2];
  142. }
  143. // Normalizes and returns the magnitude
  144. LL_INLINE F32 normalize()
  145. {
  146. F32 mag = sqrtf(mV[0] * mV[0] + mV[1] * mV[1] + mV[2] * mV[2]);
  147. if (mag > FP_MAG_THRESHOLD)
  148. {
  149. F32 oomag = 1.f / mag;
  150. mV[0] *= oomag;
  151. mV[1] *= oomag;
  152. mV[2] *= oomag;
  153. }
  154. else
  155. {
  156. mV[0] = mV[1] = mV[2] = mag = 0.f;
  157. }
  158. return mag;
  159. }
  160. // Returns true if all values of the vector are between min and max
  161. LL_INLINE bool inRange(F32 min, F32 max) const
  162. {
  163. return mV[0] >= min && mV[0] <= max && mV[1] >= min && mV[1] <= max &&
  164. mV[2] >= min && mV[2] <= max;
  165. }
  166. // Rotates about vec by angle radians
  167. const LLVector3& rotVec(F32 angle, const LLVector3& vec);
  168. // Rotates about x,y,z by angle radians
  169. const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z);
  170. // Rotates by LLMatrix4 mat
  171. const LLVector3& rotVec(const LLMatrix3& mat);
  172. // Rotates by LLQuaternion q
  173. const LLVector3& rotVec(const LLQuaternion& q);
  174. // Transforms by LLMatrix4 mat (mat * v)
  175. const LLVector3& transVec(const LLMatrix4& mat);
  176. // Scales per component by vec
  177. const LLVector3& scaleVec(const LLVector3& vec);
  178. // Gets a copy of this vector scaled by vec
  179. LLVector3 scaledVec(const LLVector3& vec) const;
  180. // Returns true if vector has a _very_small_ length
  181. LL_INLINE bool isNull() const
  182. {
  183. return F_APPROXIMATELY_ZERO > mV[VX] * mV[VX] +
  184. mV[VY] * mV[VY] +
  185. mV[VZ] * mV[VZ];
  186. }
  187. LL_INLINE bool isExactlyZero() const { return !mV[VX] && !mV[VY] && !mV[VZ]; }
  188. LL_INLINE F32 operator[](int idx) const { return mV[idx]; }
  189. LL_INLINE F32 &operator[](int idx) { return mV[idx]; }
  190. friend LLVector3 operator+(const LLVector3& a, const LLVector3& b); // Returns vector a + b
  191. friend LLVector3 operator-(const LLVector3& a, const LLVector3& b); // Returns vector a minus b
  192. friend F32 operator*(const LLVector3& a, const LLVector3& b); // Returns a dot b
  193. friend LLVector3 operator%(const LLVector3& a, const LLVector3& b); // Returns a cross b
  194. friend LLVector3 operator*(const LLVector3& a, F32 k); // Returns a times scaler k
  195. friend LLVector3 operator/(const LLVector3& a, F32 k); // Returns a divided by scaler k
  196. friend LLVector3 operator*(F32 k, const LLVector3& a); // Returns a times scaler k
  197. friend bool operator==(const LLVector3& a, const LLVector3& b); // Returns a == b
  198. friend bool operator!=(const LLVector3& a, const LLVector3& b); // Returns a != b
  199. // less than operator useful for using vectors as std::map keys
  200. friend bool operator<(const LLVector3& a, const LLVector3& b); // Returns a < b
  201. friend const LLVector3& operator+=(LLVector3& a, const LLVector3& b); // Returns vector a + b
  202. friend const LLVector3& operator-=(LLVector3& a, const LLVector3& b); // Returns vector a minus b
  203. friend const LLVector3& operator%=(LLVector3& a, const LLVector3& b); // Returns a cross b
  204. friend const LLVector3& operator*=(LLVector3& a, const LLVector3& b); // Returns a * b;
  205. friend const LLVector3& operator*=(LLVector3& a, F32 k); // Returns a times scaler k
  206. friend const LLVector3& operator/=(LLVector3& a, F32 k); // Returns a divided by scaler k
  207. friend const LLVector3& operator*=(LLVector3& a, const LLQuaternion& b);// Returns a * b;
  208. friend LLVector3 operator-(const LLVector3& a); // Returns vector -a
  209. friend std::ostream& operator<<(std::ostream& s, const LLVector3& a); // Streams a
  210. static bool parseVector3(const std::string& buf, LLVector3* value);
  211. static LLVector3 pointToBoxOffset(const LLVector3& pos,
  212. const LLVector3* box);
  213. static bool boxValidAndNonZero(const LLVector3* box);
  214. public:
  215. F32 mV[LENGTHOFVECTOR3];
  216. static const LLVector3 zero;
  217. static const LLVector3 x_axis;
  218. static const LLVector3 y_axis;
  219. static const LLVector3 z_axis;
  220. static const LLVector3 x_axis_neg;
  221. static const LLVector3 y_axis_neg;
  222. static const LLVector3 z_axis_neg;
  223. static const LLVector3 all_one;
  224. };
  225. typedef LLVector3 LLSimLocalVec;
  226. // Non-member functions
  227. LL_INLINE LLVector3 operator+(const LLVector3& a, const LLVector3& b)
  228. {
  229. LLVector3 c(a);
  230. return c += b;
  231. }
  232. LL_INLINE LLVector3 operator-(const LLVector3& a, const LLVector3& b)
  233. {
  234. LLVector3 c(a);
  235. return c -= b;
  236. }
  237. LL_INLINE F32 operator*(const LLVector3& a, const LLVector3& b)
  238. {
  239. return (a.mV[0] * b.mV[0] + a.mV[1] * b.mV[1] + a.mV[2] * b.mV[2]);
  240. }
  241. LL_INLINE LLVector3 operator%(const LLVector3& a, const LLVector3& b)
  242. {
  243. return LLVector3(a.mV[1] * b.mV[2] - b.mV[1] * a.mV[2],
  244. a.mV[2] * b.mV[0] - b.mV[2] * a.mV[0],
  245. a.mV[0] * b.mV[1] - b.mV[0] * a.mV[1]);
  246. }
  247. LL_INLINE LLVector3 operator/(const LLVector3& a, F32 k)
  248. {
  249. F32 t = 1.f / k;
  250. return LLVector3(a.mV[0] * t, a.mV[1] * t, a.mV[2] * t);
  251. }
  252. LL_INLINE LLVector3 operator*(const LLVector3& a, F32 k)
  253. {
  254. return LLVector3(a.mV[0] * k, a.mV[1] * k, a.mV[2] * k);
  255. }
  256. LL_INLINE LLVector3 operator*(F32 k, const LLVector3& a)
  257. {
  258. return LLVector3(a.mV[0] * k, a.mV[1] * k, a.mV[2] * k);
  259. }
  260. LL_INLINE bool operator==(const LLVector3& a, const LLVector3& b)
  261. {
  262. return a.mV[0] == b.mV[0] && a.mV[1] == b.mV[1] && a.mV[2] == b.mV[2];
  263. }
  264. LL_INLINE bool operator!=(const LLVector3& a, const LLVector3& b)
  265. {
  266. return a.mV[0] != b.mV[0] || a.mV[1] != b.mV[1] || a.mV[2] != b.mV[2];
  267. }
  268. LL_INLINE bool operator<(const LLVector3& a, const LLVector3& b)
  269. {
  270. return (a.mV[0] < b.mV[0] ||
  271. (a.mV[0] == b.mV[0] &&
  272. (a.mV[1] < b.mV[1] ||
  273. (a.mV[1] == b.mV[1] && a.mV[2] < b.mV[2]))));
  274. }
  275. LL_INLINE const LLVector3& operator+=(LLVector3& a, const LLVector3& b)
  276. {
  277. a.mV[0] += b.mV[0];
  278. a.mV[1] += b.mV[1];
  279. a.mV[2] += b.mV[2];
  280. return a;
  281. }
  282. LL_INLINE const LLVector3& operator-=(LLVector3& a, const LLVector3& b)
  283. {
  284. a.mV[0] -= b.mV[0];
  285. a.mV[1] -= b.mV[1];
  286. a.mV[2] -= b.mV[2];
  287. return a;
  288. }
  289. LL_INLINE const LLVector3& operator%=(LLVector3& a, const LLVector3& b)
  290. {
  291. LLVector3 ret(a.mV[1] * b.mV[2] - b.mV[1] * a.mV[2],
  292. a.mV[2] * b.mV[0] - b.mV[2] * a.mV[0],
  293. a.mV[0] * b.mV[1] - b.mV[0] * a.mV[1]);
  294. a = ret;
  295. return a;
  296. }
  297. LL_INLINE const LLVector3& operator*=(LLVector3& a, F32 k)
  298. {
  299. a.mV[0] *= k;
  300. a.mV[1] *= k;
  301. a.mV[2] *= k;
  302. return a;
  303. }
  304. LL_INLINE const LLVector3& operator*=(LLVector3& a, const LLVector3& b)
  305. {
  306. a.mV[0] *= b.mV[0];
  307. a.mV[1] *= b.mV[1];
  308. a.mV[2] *= b.mV[2];
  309. return a;
  310. }
  311. LL_INLINE const LLVector3& operator/=(LLVector3& a, F32 k)
  312. {
  313. F32 t = 1.f / k;
  314. a.mV[0] *= t;
  315. a.mV[1] *= t;
  316. a.mV[2] *= t;
  317. return a;
  318. }
  319. LL_INLINE LLVector3 operator-(const LLVector3& a)
  320. {
  321. return LLVector3(-a.mV[0], -a.mV[1], -a.mV[2]);
  322. }
  323. // Returns distance between a and b
  324. LL_INLINE F32 dist_vec(const LLVector3& a, const LLVector3& b)
  325. {
  326. F32 x = a.mV[0] - b.mV[0];
  327. F32 y = a.mV[1] - b.mV[1];
  328. F32 z = a.mV[2] - b.mV[2];
  329. return sqrtf(x * x + y * y + z * z);
  330. }
  331. // Returns distance squared between a and b
  332. LL_INLINE F32 dist_vec_squared(const LLVector3& a, const LLVector3& b)
  333. {
  334. F32 x = a.mV[0] - b.mV[0];
  335. F32 y = a.mV[1] - b.mV[1];
  336. F32 z = a.mV[2] - b.mV[2];
  337. return x * x + y * y + z * z;
  338. }
  339. // Returns distance squared between a and b ignoring Z component
  340. LL_INLINE F32 dist_vec_squared2D(const LLVector3& a, const LLVector3& b)
  341. {
  342. F32 x = a.mV[0] - b.mV[0];
  343. F32 y = a.mV[1] - b.mV[1];
  344. return x * x + y * y;
  345. }
  346. // Returns vector a projected on vector b
  347. LL_INLINE LLVector3 projected_vec(const LLVector3& a, const LLVector3& b)
  348. {
  349. F32 bb = b * b;
  350. if (bb > FP_MAG_THRESHOLD * FP_MAG_THRESHOLD)
  351. {
  352. return ((a * b) / bb) * b;
  353. }
  354. else
  355. {
  356. return b.zero;
  357. }
  358. }
  359. // Returns vector a scaled such that:
  360. // projected_vec(inverse_projected_vec(a, b), b) == b;
  361. LL_INLINE LLVector3 inverse_projected_vec(const LLVector3& a,
  362. const LLVector3& b)
  363. {
  364. LLVector3 normalized_a = a;
  365. normalized_a.normalize();
  366. LLVector3 normalized_b = b;
  367. F64 b_length = normalized_b.normalize();
  368. F64 dot_product = normalized_a * normalized_b;
  369. // NB: if a _|_ b, then returns an infinite vector
  370. return normalized_a * (b_length / dot_product);
  371. }
  372. // Returns vector a projected on vector b (same as projected_vec)
  373. LL_INLINE LLVector3 parallel_component(const LLVector3& a, const LLVector3& b)
  374. {
  375. return projected_vec(a, b);
  376. }
  377. // Returns component of vector a not parallel to vector b (same as
  378. // projected_vec)
  379. LL_INLINE LLVector3 orthogonal_component(const LLVector3& a,
  380. const LLVector3& b)
  381. {
  382. return a - projected_vec(a, b);
  383. }
  384. // Returns a vector that is a linear interpolation between a and b
  385. LL_INLINE LLVector3 lerp(const LLVector3& a, const LLVector3& b, F32 u)
  386. {
  387. return LLVector3(a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
  388. a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
  389. a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
  390. }
  391. LL_INLINE void update_min_max(LLVector3& min, LLVector3& max,
  392. const LLVector3& pos)
  393. {
  394. for (U32 i = 0; i < 3; ++i)
  395. {
  396. if (min.mV[i] > pos.mV[i])
  397. {
  398. min.mV[i] = pos.mV[i];
  399. }
  400. if (max.mV[i] < pos.mV[i])
  401. {
  402. max.mV[i] = pos.mV[i];
  403. }
  404. }
  405. }
  406. LL_INLINE void update_min_max(LLVector3& min, LLVector3& max, const F32* pos)
  407. {
  408. for (U32 i = 0; i < 3; ++i)
  409. {
  410. if (min.mV[i] > pos[i])
  411. {
  412. min.mV[i] = pos[i];
  413. }
  414. if (max.mV[i] < pos[i])
  415. {
  416. max.mV[i] = pos[i];
  417. }
  418. }
  419. }
  420. // Returns angle (radians) between a and b
  421. LL_INLINE F32 angle_between(const LLVector3& a, const LLVector3& b)
  422. {
  423. F32 ab = a * b; // dotproduct
  424. if (ab == -0.0f)
  425. {
  426. ab = 0.0f; // get rid of negative zero
  427. }
  428. LLVector3 c = a % b; // crossproduct
  429. return atan2f(sqrtf(c * c), ab); // return the angle
  430. }
  431. // Returns true if a and b are very close to parallel
  432. LL_INLINE bool are_parallel(const LLVector3& a, const LLVector3& b,
  433. F32 epsilon = F_APPROXIMATELY_ZERO)
  434. {
  435. LLVector3 an = a;
  436. LLVector3 bn = b;
  437. an.normalize();
  438. bn.normalize();
  439. F32 dot = an * bn;
  440. return 1.0f - fabs(dot) < epsilon;
  441. }
  442. LL_INLINE std::ostream& operator<<(std::ostream& s, const LLVector3& a)
  443. {
  444. s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }";
  445. return s;
  446. }
  447. #endif // LL_V3MATH_H