llquaternion.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. /**
  2. * @file llquaternion.cpp
  3. * @brief LLQuaternion class implementation.
  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. #include "linden_common.h"
  33. #include "llmath.h" // For F_PI and GIMBAL_THRESHOLD
  34. #include "llquaternion.h"
  35. #include "llquantize.h"
  36. #include "llmatrix3.h"
  37. #include "llmatrix4.h"
  38. #include "llvector3d.h"
  39. #include "llvector3.h"
  40. #include "llvector4.h"
  41. // WARNING: Do not use this for global const definitions ! Using this at the
  42. // top of a *.cpp file might not give you what you think.
  43. const LLQuaternion LLQuaternion::DEFAULT;
  44. // Constructors
  45. LLQuaternion::LLQuaternion(const LLMatrix4& mat) noexcept
  46. {
  47. *this = mat.quaternion();
  48. normalize();
  49. }
  50. LLQuaternion::LLQuaternion(const LLMatrix3& mat) noexcept
  51. {
  52. *this = mat.quaternion();
  53. normalize();
  54. }
  55. LLQuaternion::LLQuaternion(F32 angle, const LLVector4& vec) noexcept
  56. {
  57. F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] +
  58. vec.mV[VY] * vec.mV[VY] +
  59. vec.mV[VZ] * vec.mV[VZ]);
  60. if (mag > FP_MAG_THRESHOLD)
  61. {
  62. angle *= 0.5;
  63. F32 c = cosf(angle);
  64. F32 s = sinf(angle) / mag;
  65. mQ[VX] = vec.mV[VX] * s;
  66. mQ[VY] = vec.mV[VY] * s;
  67. mQ[VZ] = vec.mV[VZ] * s;
  68. mQ[VW] = c;
  69. }
  70. else
  71. {
  72. loadIdentity();
  73. }
  74. }
  75. LLQuaternion::LLQuaternion(F32 angle, const LLVector3& vec) noexcept
  76. {
  77. F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] +
  78. vec.mV[VY] * vec.mV[VY] +
  79. vec.mV[VZ] * vec.mV[VZ]);
  80. if (mag > FP_MAG_THRESHOLD)
  81. {
  82. angle *= 0.5;
  83. F32 c = cosf(angle);
  84. F32 s = sinf(angle) / mag;
  85. mQ[VX] = vec.mV[VX] * s;
  86. mQ[VY] = vec.mV[VY] * s;
  87. mQ[VZ] = vec.mV[VZ] * s;
  88. mQ[VW] = c;
  89. }
  90. else
  91. {
  92. loadIdentity();
  93. }
  94. }
  95. LLQuaternion::LLQuaternion(const LLVector3& x_axis, const LLVector3& y_axis,
  96. const LLVector3& z_axis) noexcept
  97. {
  98. LLMatrix3 mat;
  99. mat.setRows(x_axis, y_axis, z_axis);
  100. *this = mat.quaternion();
  101. normalize();
  102. }
  103. LLQuaternion::LLQuaternion(const LLSD& sd)
  104. {
  105. setValue(sd);
  106. }
  107. // Quatizations
  108. void LLQuaternion::quantize16(F32 lower, F32 upper)
  109. {
  110. F32 x = mQ[VX];
  111. F32 y = mQ[VY];
  112. F32 z = mQ[VZ];
  113. F32 s = mQ[VS];
  114. x = U16_to_F32(F32_to_U16_ROUND(x, lower, upper), lower, upper);
  115. y = U16_to_F32(F32_to_U16_ROUND(y, lower, upper), lower, upper);
  116. z = U16_to_F32(F32_to_U16_ROUND(z, lower, upper), lower, upper);
  117. s = U16_to_F32(F32_to_U16_ROUND(s, lower, upper), lower, upper);
  118. mQ[VX] = x;
  119. mQ[VY] = y;
  120. mQ[VZ] = z;
  121. mQ[VS] = s;
  122. normalize();
  123. }
  124. void LLQuaternion::quantize8(F32 lower, F32 upper)
  125. {
  126. mQ[VX] = U8_to_F32(F32_to_U8_ROUND(mQ[VX], lower, upper), lower, upper);
  127. mQ[VY] = U8_to_F32(F32_to_U8_ROUND(mQ[VY], lower, upper), lower, upper);
  128. mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper);
  129. mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper);
  130. normalize();
  131. }
  132. // LLVector3 Magnitude and Normalization Functions
  133. // Set LLQuaternion routines
  134. const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, F32 x, F32 y, F32 z)
  135. {
  136. F32 mag = sqrtf(x * x + y * y + z * z);
  137. if (mag > FP_MAG_THRESHOLD)
  138. {
  139. angle *= 0.5;
  140. F32 c = cosf(angle);
  141. F32 s = sinf(angle) / mag;
  142. mQ[VX] = x * s;
  143. mQ[VY] = y * s;
  144. mQ[VZ] = z * s;
  145. mQ[VW] = c;
  146. }
  147. else
  148. {
  149. loadIdentity();
  150. }
  151. return *this;
  152. }
  153. const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector3& vec)
  154. {
  155. F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] +
  156. vec.mV[VY] * vec.mV[VY] +
  157. vec.mV[VZ] * vec.mV[VZ]);
  158. if (mag > FP_MAG_THRESHOLD)
  159. {
  160. angle *= 0.5;
  161. F32 c = cosf(angle);
  162. F32 s = sinf(angle) / mag;
  163. mQ[VX] = vec.mV[VX] * s;
  164. mQ[VY] = vec.mV[VY] * s;
  165. mQ[VZ] = vec.mV[VZ] * s;
  166. mQ[VW] = c;
  167. }
  168. else
  169. {
  170. loadIdentity();
  171. }
  172. return *this;
  173. }
  174. const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector4& vec)
  175. {
  176. F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] +
  177. vec.mV[VY] * vec.mV[VY] +
  178. vec.mV[VZ] * vec.mV[VZ]);
  179. if (mag > FP_MAG_THRESHOLD)
  180. {
  181. angle *= 0.5;
  182. F32 c = cosf(angle);
  183. F32 s = sinf(angle) / mag;
  184. mQ[VX] = vec.mV[VX] * s;
  185. mQ[VY] = vec.mV[VY] * s;
  186. mQ[VZ] = vec.mV[VZ] * s;
  187. mQ[VW] = c;
  188. }
  189. else
  190. {
  191. loadIdentity();
  192. }
  193. return *this;
  194. }
  195. const LLQuaternion& LLQuaternion::setEulerAngles(F32 roll, F32 pitch, F32 yaw)
  196. {
  197. LLMatrix3 rot_mat(roll, pitch, yaw);
  198. rot_mat.orthogonalize();
  199. *this = rot_mat.quaternion();
  200. normalize();
  201. return *this;
  202. }
  203. const LLQuaternion& LLQuaternion::set(const LLMatrix3& mat)
  204. {
  205. *this = mat.quaternion();
  206. normalize();
  207. return *this;
  208. }
  209. const LLQuaternion& LLQuaternion::set(const LLMatrix4& mat)
  210. {
  211. *this = mat.quaternion();
  212. normalize();
  213. return *this;
  214. }
  215. // SJB: This code is correct for a logically stored (non-transposed) matrix;
  216. // Our matrices are stored transposed, OpenGL style, so this generates the
  217. // INVERSE matrix, or the CORRECT matrix form an INVERSE quaternion.
  218. // Because we use similar logic in LLMatrix3::quaternion(), we are internally
  219. // consistant so everything works OK :)
  220. LLMatrix3 LLQuaternion::getMatrix3() const
  221. {
  222. F32 xx = mQ[VX] * mQ[VX];
  223. F32 xy = mQ[VX] * mQ[VY];
  224. F32 xz = mQ[VX] * mQ[VZ];
  225. F32 xw = mQ[VX] * mQ[VW];
  226. F32 yy = mQ[VY] * mQ[VY];
  227. F32 yz = mQ[VY] * mQ[VZ];
  228. F32 yw = mQ[VY] * mQ[VW];
  229. F32 zz = mQ[VZ] * mQ[VZ];
  230. F32 zw = mQ[VZ] * mQ[VW];
  231. LLMatrix3 mat;
  232. mat.mMatrix[0][0] = 1.f - 2.f * (yy + zz);
  233. mat.mMatrix[0][1] = 2.f * (xy + zw);
  234. mat.mMatrix[0][2] = 2.f * (xz - yw);
  235. mat.mMatrix[1][0] = 2.f * (xy - zw);
  236. mat.mMatrix[1][1] = 1.f - 2.f * (xx + zz);
  237. mat.mMatrix[1][2] = 2.f * (yz + xw);
  238. mat.mMatrix[2][0] = 2.f * (xz + yw);
  239. mat.mMatrix[2][1] = 2.f * (yz - xw);
  240. mat.mMatrix[2][2] = 1.f - 2.f * (xx + yy);
  241. return mat;
  242. }
  243. LLMatrix4 LLQuaternion::getMatrix4() const
  244. {
  245. F32 xx = mQ[VX] * mQ[VX];
  246. F32 xy = mQ[VX] * mQ[VY];
  247. F32 xz = mQ[VX] * mQ[VZ];
  248. F32 xw = mQ[VX] * mQ[VW];
  249. F32 yy = mQ[VY] * mQ[VY];
  250. F32 yz = mQ[VY] * mQ[VZ];
  251. F32 yw = mQ[VY] * mQ[VW];
  252. F32 zz = mQ[VZ] * mQ[VZ];
  253. F32 zw = mQ[VZ] * mQ[VW];
  254. LLMatrix4 mat;
  255. mat.mMatrix[0][0] = 1.f - 2.f * (yy + zz);
  256. mat.mMatrix[0][1] = 2.f * (xy + zw);
  257. mat.mMatrix[0][2] = 2.f * (xz - yw);
  258. mat.mMatrix[1][0] = 2.f * (xy - zw);
  259. mat.mMatrix[1][1] = 1.f - 2.f * (xx + zz);
  260. mat.mMatrix[1][2] = 2.f * (yz + xw);
  261. mat.mMatrix[2][0] = 2.f * (xz + yw);
  262. mat.mMatrix[2][1] = 2.f * (yz - xw);
  263. mat.mMatrix[2][2] = 1.f - 2.f * (xx + yy);
  264. // *TODO: should we set the translation portion to zero ?
  265. return mat;
  266. }
  267. // Other useful methods
  268. // calculate the shortest rotation from a to b
  269. void LLQuaternion::shortestArc(const LLVector3& a, const LLVector3& b)
  270. {
  271. F32 ab = a * b; // dotproduct
  272. LLVector3 c = a % b; // crossproduct
  273. F32 cc = c * c; // squared length of the crossproduct
  274. if (ab * ab + cc) // test if the arguments have sufficient magnitude
  275. {
  276. // Test if the arguments are (anti)parallel
  277. if (cc > 0.f)
  278. {
  279. // Note: do not try to optimize this line
  280. F32 s = sqrtf(ab * ab + cc) + ab;
  281. // The inverted magnitude of the quaternion
  282. F32 m = 1.f / sqrtf(cc + s * s);
  283. mQ[VX] = c.mV[VX] * m;
  284. mQ[VY] = c.mV[VY] * m;
  285. mQ[VZ] = c.mV[VZ] * m;
  286. mQ[VW] = s * m;
  287. return;
  288. }
  289. // Test if the angle is bigger than PI/2 (anti parallel)
  290. if (ab < 0.f)
  291. {
  292. // The arguments are anti-parallel, we have to choose an axis
  293. c = a - b;
  294. // The length projected on the XY-plane
  295. F32 m = sqrtf(c.mV[VX] * c.mV[VX] + c.mV[VY] * c.mV[VY]);
  296. if (m > FP_MAG_THRESHOLD)
  297. {
  298. // Return the quaternion with the axis in the XY-plane
  299. mQ[VX] = -c.mV[VY] / m;
  300. mQ[VY] = c.mV[VX] / m;
  301. mQ[VZ] = mQ[VW] = 0.f;
  302. return;
  303. }
  304. else // the vectors are parallel to the Z-axis
  305. {
  306. mQ[VX] = 1.f; // rotate around the X-axis
  307. mQ[VY] = mQ[VZ] = mQ[VW] = 0.f;
  308. return;
  309. }
  310. }
  311. }
  312. loadIdentity();
  313. }
  314. // constrains rotation to a cone angle specified in radians
  315. const LLQuaternion& LLQuaternion::constrain(F32 radians)
  316. {
  317. const F32 cos_angle_lim = cosf(radians / 2); // mQ[VW] limit
  318. const F32 sin_angle_lim = sinf(radians / 2); // rotation axis length limit
  319. if (mQ[VW] < 0.f)
  320. {
  321. mQ[VX] *= -1.f;
  322. mQ[VY] *= -1.f;
  323. mQ[VZ] *= -1.f;
  324. mQ[VW] *= -1.f;
  325. }
  326. // if rotation angle is greater than limit (cos is less than limit)
  327. if (mQ[VW] < cos_angle_lim)
  328. {
  329. mQ[VW] = cos_angle_lim;
  330. F32 axis_len = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] +
  331. mQ[VZ] * mQ[VZ]); // sinf(theta/2)
  332. F32 axis_mult_fact = sin_angle_lim / axis_len;
  333. mQ[VX] *= axis_mult_fact;
  334. mQ[VY] *= axis_mult_fact;
  335. mQ[VZ] *= axis_mult_fact;
  336. }
  337. return *this;
  338. }
  339. // Operators
  340. std::ostream& operator<<(std::ostream& s, const LLQuaternion& a)
  341. {
  342. s << "{ "
  343. << a.mQ[VX] << ", " << a.mQ[VY] << ", " << a.mQ[VZ] << ", " << a.mQ[VW]
  344. << " }";
  345. return s;
  346. }
  347. // Does NOT renormalize the result
  348. LLQuaternion operator*(const LLQuaternion& a, const LLQuaternion& b)
  349. {
  350. LLQuaternion q(b.mQ[3] * a.mQ[0] + b.mQ[0] * a.mQ[3] +
  351. b.mQ[1] * a.mQ[2] - b.mQ[2] * a.mQ[1],
  352. b.mQ[3] * a.mQ[1] + b.mQ[1] * a.mQ[3] +
  353. b.mQ[2] * a.mQ[0] - b.mQ[0] * a.mQ[2],
  354. b.mQ[3] * a.mQ[2] + b.mQ[2] * a.mQ[3] +
  355. b.mQ[0] * a.mQ[1] - b.mQ[1] * a.mQ[0],
  356. b.mQ[3] * a.mQ[3] - b.mQ[0] * a.mQ[0] -
  357. b.mQ[1] * a.mQ[1] - b.mQ[2] * a.mQ[2]);
  358. return q;
  359. }
  360. #if 0
  361. LLMatrix4 operator*(const LLMatrix4& m, const LLQuaternion& q)
  362. {
  363. LLMatrix4 qmat(q);
  364. return (m*qmat);
  365. }
  366. #endif
  367. LLVector4 operator*(const LLVector4& a, const LLQuaternion& rot)
  368. {
  369. F32 rw = -rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] -
  370. rot.mQ[VZ] * a.mV[VZ];
  371. F32 rx = rot.mQ[VW] * a.mV[VX] + rot.mQ[VY] * a.mV[VZ] -
  372. rot.mQ[VZ] * a.mV[VY];
  373. F32 ry = rot.mQ[VW] * a.mV[VY] + rot.mQ[VZ] * a.mV[VX] -
  374. rot.mQ[VX] * a.mV[VZ];
  375. F32 rz = rot.mQ[VW] * a.mV[VZ] + rot.mQ[VX] * a.mV[VY] -
  376. rot.mQ[VY] * a.mV[VX];
  377. F32 nx = -rw * rot.mQ[VX] + rx * rot.mQ[VW] - ry * rot.mQ[VZ] +
  378. rz * rot.mQ[VY];
  379. F32 ny = -rw * rot.mQ[VY] + ry * rot.mQ[VW] - rz * rot.mQ[VX] +
  380. rx * rot.mQ[VZ];
  381. F32 nz = -rw * rot.mQ[VZ] + rz * rot.mQ[VW] - rx * rot.mQ[VY] +
  382. ry * rot.mQ[VX];
  383. return LLVector4(nx, ny, nz, a.mV[VW]);
  384. }
  385. LLVector3 operator*(const LLVector3& a, const LLQuaternion& rot)
  386. {
  387. F32 rw = -rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] -
  388. rot.mQ[VZ] * a.mV[VZ];
  389. F32 rx = rot.mQ[VW] * a.mV[VX] + rot.mQ[VY] * a.mV[VZ] -
  390. rot.mQ[VZ] * a.mV[VY];
  391. F32 ry = rot.mQ[VW] * a.mV[VY] + rot.mQ[VZ] * a.mV[VX] -
  392. rot.mQ[VX] * a.mV[VZ];
  393. F32 rz = rot.mQ[VW] * a.mV[VZ] + rot.mQ[VX] * a.mV[VY] -
  394. rot.mQ[VY] * a.mV[VX];
  395. F32 nx = -rw * rot.mQ[VX] + rx * rot.mQ[VW] - ry * rot.mQ[VZ] +
  396. rz * rot.mQ[VY];
  397. F32 ny = -rw * rot.mQ[VY] + ry * rot.mQ[VW] - rz * rot.mQ[VX] +
  398. rx * rot.mQ[VZ];
  399. F32 nz = -rw * rot.mQ[VZ] + rz * rot.mQ[VW] - rx * rot.mQ[VY] +
  400. ry * rot.mQ[VX];
  401. return LLVector3(nx, ny, nz);
  402. }
  403. LLVector3d operator*(const LLVector3d& a, const LLQuaternion& rot)
  404. {
  405. F64 rw = -rot.mQ[VX] * a.mdV[VX] - rot.mQ[VY] * a.mdV[VY] -
  406. rot.mQ[VZ] * a.mdV[VZ];
  407. F64 rx = rot.mQ[VW] * a.mdV[VX] + rot.mQ[VY] * a.mdV[VZ] -
  408. rot.mQ[VZ] * a.mdV[VY];
  409. F64 ry = rot.mQ[VW] * a.mdV[VY] + rot.mQ[VZ] * a.mdV[VX] -
  410. rot.mQ[VX] * a.mdV[VZ];
  411. F64 rz = rot.mQ[VW] * a.mdV[VZ] + rot.mQ[VX] * a.mdV[VY] -
  412. rot.mQ[VY] * a.mdV[VX];
  413. F64 nx = -rw * rot.mQ[VX] + rx * rot.mQ[VW] - ry * rot.mQ[VZ] +
  414. rz * rot.mQ[VY];
  415. F64 ny = -rw * rot.mQ[VY] + ry * rot.mQ[VW] - rz * rot.mQ[VX] +
  416. rx * rot.mQ[VZ];
  417. F64 nz = -rw * rot.mQ[VZ] + rz * rot.mQ[VW] - rx * rot.mQ[VY] +
  418. ry * rot.mQ[VX];
  419. return LLVector3d(nx, ny, nz);
  420. }
  421. F32 dot(const LLQuaternion& a, const LLQuaternion& b)
  422. {
  423. return a.mQ[VX] * b.mQ[VX] + a.mQ[VY] * b.mQ[VY] + a.mQ[VZ] * b.mQ[VZ] +
  424. a.mQ[VW] * b.mQ[VW];
  425. }
  426. #if 0 // DEMO HACK: This lerp is probably incorrect now due intermediate
  427. // normalization it should look more like the lerp below.
  428. // linear interpolation
  429. LLQuaternion lerp(F32 t, const LLQuaternion& p, const LLQuaternion& q)
  430. {
  431. LLQuaternion r;
  432. r = t * (q - p) + p;
  433. r.normalize();
  434. return r;
  435. }
  436. #endif
  437. // lerp from identity to q
  438. LLQuaternion lerp(F32 t, const LLQuaternion& q)
  439. {
  440. LLQuaternion r;
  441. r.mQ[VX] = t * q.mQ[VX];
  442. r.mQ[VY] = t * q.mQ[VY];
  443. r.mQ[VZ] = t * q.mQ[VZ];
  444. r.mQ[VW] = t * (q.mQ[VZ] - 1.f) + 1.f;
  445. r.normalize();
  446. return r;
  447. }
  448. LLQuaternion lerp(F32 t, const LLQuaternion& p, const LLQuaternion& q)
  449. {
  450. F32 inv_t = 1.f - t;
  451. LLQuaternion r;
  452. r.mQ[VX] = t * q.mQ[VX] + inv_t * p.mQ[VX];
  453. r.mQ[VY] = t * q.mQ[VY] + inv_t * p.mQ[VY];
  454. r.mQ[VZ] = t * q.mQ[VZ] + inv_t * p.mQ[VZ];
  455. r.mQ[VW] = t * q.mQ[VW] + inv_t * p.mQ[VW];
  456. r.normalize();
  457. return r;
  458. }
  459. // spherical linear interpolation
  460. LLQuaternion slerp(F32 u, const LLQuaternion& a, const LLQuaternion& b)
  461. {
  462. // cosine theta = dot product of a and b
  463. F32 cos_t = a.mQ[0] * b.mQ[0] + a.mQ[1] * b.mQ[1] +
  464. a.mQ[2] * b.mQ[2] + a.mQ[3] * b.mQ[3];
  465. // if b is on opposite hemisphere from a, use -a instead
  466. bool bflip = false;
  467. if (cos_t < 0.0f)
  468. {
  469. cos_t = -cos_t;
  470. bflip = true;
  471. }
  472. // If B is (within precision limits) the same as A, just linear interpolate
  473. // between A and B.
  474. F32 alpha; // interpolant
  475. F32 beta; // 1 - interpolant
  476. if (1.f - cos_t < 0.00001f)
  477. {
  478. beta = 1.f - u;
  479. alpha = u;
  480. }
  481. else
  482. {
  483. F32 theta = acosf(cos_t);
  484. F32 sin_t = sinf(theta);
  485. beta = sinf(theta - u * theta) / sin_t;
  486. alpha = sinf(u * theta) / sin_t;
  487. }
  488. if (bflip)
  489. {
  490. beta = -beta;
  491. }
  492. // interpolate
  493. LLQuaternion ret;
  494. ret.mQ[0] = beta * a.mQ[0] + alpha * b.mQ[0];
  495. ret.mQ[1] = beta * a.mQ[1] + alpha * b.mQ[1];
  496. ret.mQ[2] = beta * a.mQ[2] + alpha * b.mQ[2];
  497. ret.mQ[3] = beta * a.mQ[3] + alpha * b.mQ[3];
  498. return ret;
  499. }
  500. // lerp whenever possible
  501. LLQuaternion nlerp(F32 t, const LLQuaternion& a, const LLQuaternion& b)
  502. {
  503. if (dot(a, b) < 0.f)
  504. {
  505. return slerp(t, a, b);
  506. }
  507. else
  508. {
  509. return lerp(t, a, b);
  510. }
  511. }
  512. LLQuaternion nlerp(F32 t, const LLQuaternion& q)
  513. {
  514. if (q.mQ[VW] < 0.f)
  515. {
  516. return slerp(t, q);
  517. }
  518. else
  519. {
  520. return lerp(t, q);
  521. }
  522. }
  523. // slerp from identity quaternion to another quaternion
  524. LLQuaternion slerp(F32 t, const LLQuaternion& q)
  525. {
  526. F32 c = q.mQ[VW];
  527. if (t == 1.f || c == 1.f)
  528. {
  529. // the trivial cases
  530. return q;
  531. }
  532. LLQuaternion r;
  533. F32 angle, stq, stp;
  534. F32 s = sqrtf(1.f - c * c);
  535. if (c < 0.f)
  536. {
  537. // when c < 0.0 then theta > PI/2, since quat and -quat are the same
  538. // rotation we invert one of p or q to reduce unecessary spins. An
  539. // equivalent way to do it is to convert acosf(c) as if it had been
  540. // negative, and to negate stp
  541. F32 angle = acosf(-c);
  542. stp = -sinf(angle * (1.f - t));
  543. stq = sinf(angle * t);
  544. }
  545. else
  546. {
  547. angle = acosf(c);
  548. stp = sinf(angle * (1.f - t));
  549. stq = sinf(angle * t);
  550. }
  551. r.mQ[VX] = (q.mQ[VX] * stq) / s;
  552. r.mQ[VY] = (q.mQ[VY] * stq) / s;
  553. r.mQ[VZ] = (q.mQ[VZ] * stq) / s;
  554. r.mQ[VW] = (stp + q.mQ[VW] * stq) / s;
  555. return r;
  556. }
  557. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order)
  558. {
  559. LLQuaternion xQ(xRot * DEG_TO_RAD, LLVector3(1.f, 0.f, 0.f));
  560. LLQuaternion yQ(yRot * DEG_TO_RAD, LLVector3(0.f, 1.f, 0.f));
  561. LLQuaternion zQ(zRot * DEG_TO_RAD, LLVector3(0.f, 0.f, 1.f));
  562. LLQuaternion ret;
  563. switch (order)
  564. {
  565. case LLQuaternion::XYZ:
  566. ret = xQ * yQ * zQ;
  567. break;
  568. case LLQuaternion::YZX:
  569. ret = yQ * zQ * xQ;
  570. break;
  571. case LLQuaternion::ZXY:
  572. ret = zQ * xQ * yQ;
  573. break;
  574. case LLQuaternion::XZY:
  575. ret = xQ * zQ * yQ;
  576. break;
  577. case LLQuaternion::YXZ:
  578. ret = yQ * xQ * zQ;
  579. break;
  580. case LLQuaternion::ZYX:
  581. ret = zQ * yQ * xQ;
  582. }
  583. return ret;
  584. }
  585. const char* OrderToString(const LLQuaternion::Order order)
  586. {
  587. switch (order)
  588. {
  589. default:
  590. case LLQuaternion::XYZ:
  591. return "XYZ";
  592. case LLQuaternion::YZX:
  593. return "YZX";
  594. case LLQuaternion::ZXY:
  595. return "ZXY";
  596. case LLQuaternion::XZY:
  597. return "XZY";
  598. case LLQuaternion::YXZ:
  599. return "YXZ";
  600. case LLQuaternion::ZYX:
  601. return "ZYX";
  602. }
  603. }
  604. LLQuaternion::Order StringToOrder(const char* str)
  605. {
  606. if (strncmp(str, "XYZ", 3) == 0 || strncmp(str, "xyz", 3) == 0)
  607. return LLQuaternion::XYZ;
  608. if (strncmp(str, "YZX", 3) == 0 || strncmp(str, "yzx", 3) == 0)
  609. return LLQuaternion::YZX;
  610. if (strncmp(str, "ZXY", 3) == 0 || strncmp(str, "zxy", 3) == 0)
  611. return LLQuaternion::ZXY;
  612. if (strncmp(str, "XZY", 3) == 0 || strncmp(str, "xzy", 3) == 0)
  613. return LLQuaternion::XZY;
  614. if (strncmp(str, "YXZ", 3) == 0 || strncmp(str, "yxz", 3) == 0)
  615. return LLQuaternion::YXZ;
  616. if (strncmp(str, "ZYX", 3) == 0 || strncmp(str, "zyx", 3) == 0)
  617. return LLQuaternion::ZYX;
  618. return LLQuaternion::XYZ;
  619. }
  620. void LLQuaternion::getAngleAxis(F32* angle, LLVector3& vec) const
  621. {
  622. // length of the vector-component
  623. F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]);
  624. if (v > FP_MAG_THRESHOLD)
  625. {
  626. F32 oomag = 1.0f / v;
  627. F32 w = mQ[VW];
  628. if (mQ[VW] < 0.0f)
  629. {
  630. w = -w; // make VW positive
  631. oomag = -oomag; // invert the axis
  632. }
  633. vec.mV[VX] = mQ[VX] * oomag; // normalize the axis
  634. vec.mV[VY] = mQ[VY] * oomag;
  635. vec.mV[VZ] = mQ[VZ] * oomag;
  636. *angle = 2.0f * atan2f(v, w); // get the angle
  637. }
  638. else
  639. {
  640. *angle = 0.0f; // no rotation
  641. vec.mV[VX] = 0.0f; // around some dummy axis
  642. vec.mV[VY] = 0.0f;
  643. vec.mV[VZ] = 1.0f;
  644. }
  645. }
  646. const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuth,
  647. F32 altitude)
  648. {
  649. // Euler angle inputs are complements of azimuth/altitude which are
  650. // measured from zenith
  651. F32 pitch = llclamp(F_PI_BY_TWO - altitude, 0.f, F_PI_BY_TWO);
  652. F32 yaw = llclamp(F_PI_BY_TWO - azimuth, 0.f, F_PI_BY_TWO);
  653. setEulerAngles(0.f, pitch, yaw);
  654. return *this;
  655. }
  656. void LLQuaternion::getAzimuthAndAltitude(F32& azimuth, F32& altitude)
  657. {
  658. F32 roll, pitch, yaw;
  659. getEulerAngles(&roll, &pitch, &yaw);
  660. // Make these measured from zenith
  661. altitude = llclamp(F_PI_BY_TWO - pitch, 0.f, F_PI_BY_TWO);
  662. azimuth = llclamp(F_PI_BY_TWO - yaw, 0.f, F_PI_BY_TWO);
  663. }
  664. void LLQuaternion::getAzimuthAndElevation(F32& azimuth, F32& elevation)
  665. {
  666. const LLVector3 vector_zero(1.f, 0.f, 0.f);
  667. LLVector3 point = vector_zero * (*this);
  668. if (!is_approx_zero(point.mV[VX]) || !is_approx_zero(point.mV[VY]))
  669. {
  670. azimuth = atan2f(point.mV[VX], point.mV[VY]) - F_PI_BY_TWO;
  671. if (azimuth < 0.f)
  672. {
  673. azimuth += F_TWO_PI;
  674. }
  675. }
  676. else
  677. {
  678. azimuth = F_TWO_PI - F_PI_BY_TWO;
  679. }
  680. // While vector is normalized, F32 is not sufficiently precise and we can
  681. // get values like 1.0000012 which will result in -PI/2 angle instead of
  682. // PI/2...
  683. elevation = asinf(llclamp(point.mV[VZ], -1.f, 1.f));
  684. }
  685. // Quaternion does not need to be normalized
  686. void LLQuaternion::getEulerAngles(F32* roll, F32* pitch, F32* yaw) const
  687. {
  688. F32 sx = 2 * (mQ[VX] * mQ[VW] - mQ[VY] * mQ[VZ]); // sine of the roll
  689. F32 sy = 2 * (mQ[VY] * mQ[VW] + mQ[VX] * mQ[VZ]); // sine of the pitch
  690. F32 ys = mQ[VW] * mQ[VW] - mQ[VY] * mQ[VY]; // intermediate cosine 1
  691. F32 xz = mQ[VX] * mQ[VX] - mQ[VZ] * mQ[VZ]; // intermediate cosine 2
  692. F32 cx = ys - xz; // cosine of the roll
  693. F32 cy = sqrtf(sx * sx + cx * cx); // cosine of the pitch
  694. if (cy > GIMBAL_THRESHOLD) // no gimbal lock
  695. {
  696. *roll = atan2f(sx, cx);
  697. *pitch = atan2f(sy, cy);
  698. *yaw = atan2f(2 * (mQ[VZ] * mQ[VW] - mQ[VX] * mQ[VY]), ys + xz);
  699. }
  700. else // gimbal lock
  701. {
  702. if (sy > 0)
  703. {
  704. *pitch = F_PI_BY_TWO;
  705. *yaw = 2 * atan2f(mQ[VZ] + mQ[VX], mQ[VW] + mQ[VY]);
  706. }
  707. else
  708. {
  709. *pitch = -F_PI_BY_TWO;
  710. *yaw = 2 * atan2f(mQ[VZ] - mQ[VX], mQ[VW] - mQ[VY]);
  711. }
  712. *roll = 0;
  713. }
  714. }
  715. // Saves space by using the fact that our quaternions are normalized
  716. LLVector3 LLQuaternion::packToVector3() const
  717. {
  718. F32 x = mQ[VX];
  719. F32 y = mQ[VY];
  720. F32 z = mQ[VZ];
  721. F32 w = mQ[VW];
  722. F32 mag = sqrtf(x * x + y * y + z * z + w * w);
  723. if (mag > FP_MAG_THRESHOLD)
  724. {
  725. x /= mag;
  726. y /= mag;
  727. z /= mag;
  728. // no need to normalize w since it is not used
  729. }
  730. if (mQ[VW] >= 0)
  731. {
  732. return LLVector3(x, y , z);
  733. }
  734. else
  735. {
  736. return LLVector3(-x, -y, -z);
  737. }
  738. }
  739. // Saves space by using the fact that our quaternions are normalized
  740. void LLQuaternion::unpackFromVector3(const LLVector3& vec)
  741. {
  742. mQ[VX] = vec.mV[VX];
  743. mQ[VY] = vec.mV[VY];
  744. mQ[VZ] = vec.mV[VZ];
  745. F32 t = 1.f - vec.lengthSquared();
  746. if (t > 0)
  747. {
  748. mQ[VW] = sqrtf(t);
  749. }
  750. else
  751. {
  752. // Need this to avoid trying to find the square root of a negative
  753. // number due to floating point error.
  754. mQ[VW] = 0;
  755. }
  756. }
  757. bool LLQuaternion::parseQuat(const std::string& buf, LLQuaternion* value)
  758. {
  759. if (buf.empty() || value == NULL)
  760. {
  761. return false;
  762. }
  763. LLQuaternion quat;
  764. S32 count = sscanf(buf.c_str(), "%f %f %f %f", quat.mQ + 0, quat.mQ + 1,
  765. quat.mQ + 2, quat.mQ + 3);
  766. if (4 == count)
  767. {
  768. value->set(quat);
  769. return true;
  770. }
  771. return false;
  772. }
  773. //static
  774. bool LLQuaternion::almost_equal(const LLQuaternion& a, const LLQuaternion& b,
  775. F32 tol_angle)
  776. {
  777. // Use the small angle approximation of cos():
  778. // cos(angle) ~= 1.0 - 0.5 * angle^2
  779. return 8.f * fabsf(1.f - fabsf(dot(a, b))) < tol_angle * tol_angle;
  780. }