quat2.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. "use strict";
  2. function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.create = create;
  7. exports.clone = clone;
  8. exports.fromValues = fromValues;
  9. exports.fromRotationTranslationValues = fromRotationTranslationValues;
  10. exports.fromRotationTranslation = fromRotationTranslation;
  11. exports.fromTranslation = fromTranslation;
  12. exports.fromRotation = fromRotation;
  13. exports.fromMat4 = fromMat4;
  14. exports.copy = copy;
  15. exports.identity = identity;
  16. exports.set = set;
  17. exports.getDual = getDual;
  18. exports.setDual = setDual;
  19. exports.getTranslation = getTranslation;
  20. exports.translate = translate;
  21. exports.rotateX = rotateX;
  22. exports.rotateY = rotateY;
  23. exports.rotateZ = rotateZ;
  24. exports.rotateByQuatAppend = rotateByQuatAppend;
  25. exports.rotateByQuatPrepend = rotateByQuatPrepend;
  26. exports.rotateAroundAxis = rotateAroundAxis;
  27. exports.add = add;
  28. exports.multiply = multiply;
  29. exports.scale = scale;
  30. exports.lerp = lerp;
  31. exports.invert = invert;
  32. exports.conjugate = conjugate;
  33. exports.normalize = normalize;
  34. exports.str = str;
  35. exports.exactEquals = exactEquals;
  36. exports.equals = equals;
  37. exports.sqrLen = exports.squaredLength = exports.len = exports.length = exports.dot = exports.mul = exports.setReal = exports.getReal = void 0;
  38. var glMatrix = _interopRequireWildcard(require("./common.js"));
  39. var quat = _interopRequireWildcard(require("./quat.js"));
  40. var mat4 = _interopRequireWildcard(require("./mat4.js"));
  41. function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
  42. function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  43. /**
  44. * Dual Quaternion<br>
  45. * Format: [real, dual]<br>
  46. * Quaternion format: XYZW<br>
  47. * Make sure to have normalized dual quaternions, otherwise the functions may not work as intended.<br>
  48. * @module quat2
  49. */
  50. /**
  51. * Creates a new identity dual quat
  52. *
  53. * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation]
  54. */
  55. function create() {
  56. var dq = new glMatrix.ARRAY_TYPE(8);
  57. if (glMatrix.ARRAY_TYPE != Float32Array) {
  58. dq[0] = 0;
  59. dq[1] = 0;
  60. dq[2] = 0;
  61. dq[4] = 0;
  62. dq[5] = 0;
  63. dq[6] = 0;
  64. dq[7] = 0;
  65. }
  66. dq[3] = 1;
  67. return dq;
  68. }
  69. /**
  70. * Creates a new quat initialized with values from an existing quaternion
  71. *
  72. * @param {ReadonlyQuat2} a dual quaternion to clone
  73. * @returns {quat2} new dual quaternion
  74. * @function
  75. */
  76. function clone(a) {
  77. var dq = new glMatrix.ARRAY_TYPE(8);
  78. dq[0] = a[0];
  79. dq[1] = a[1];
  80. dq[2] = a[2];
  81. dq[3] = a[3];
  82. dq[4] = a[4];
  83. dq[5] = a[5];
  84. dq[6] = a[6];
  85. dq[7] = a[7];
  86. return dq;
  87. }
  88. /**
  89. * Creates a new dual quat initialized with the given values
  90. *
  91. * @param {Number} x1 X component
  92. * @param {Number} y1 Y component
  93. * @param {Number} z1 Z component
  94. * @param {Number} w1 W component
  95. * @param {Number} x2 X component
  96. * @param {Number} y2 Y component
  97. * @param {Number} z2 Z component
  98. * @param {Number} w2 W component
  99. * @returns {quat2} new dual quaternion
  100. * @function
  101. */
  102. function fromValues(x1, y1, z1, w1, x2, y2, z2, w2) {
  103. var dq = new glMatrix.ARRAY_TYPE(8);
  104. dq[0] = x1;
  105. dq[1] = y1;
  106. dq[2] = z1;
  107. dq[3] = w1;
  108. dq[4] = x2;
  109. dq[5] = y2;
  110. dq[6] = z2;
  111. dq[7] = w2;
  112. return dq;
  113. }
  114. /**
  115. * Creates a new dual quat from the given values (quat and translation)
  116. *
  117. * @param {Number} x1 X component
  118. * @param {Number} y1 Y component
  119. * @param {Number} z1 Z component
  120. * @param {Number} w1 W component
  121. * @param {Number} x2 X component (translation)
  122. * @param {Number} y2 Y component (translation)
  123. * @param {Number} z2 Z component (translation)
  124. * @returns {quat2} new dual quaternion
  125. * @function
  126. */
  127. function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) {
  128. var dq = new glMatrix.ARRAY_TYPE(8);
  129. dq[0] = x1;
  130. dq[1] = y1;
  131. dq[2] = z1;
  132. dq[3] = w1;
  133. var ax = x2 * 0.5,
  134. ay = y2 * 0.5,
  135. az = z2 * 0.5;
  136. dq[4] = ax * w1 + ay * z1 - az * y1;
  137. dq[5] = ay * w1 + az * x1 - ax * z1;
  138. dq[6] = az * w1 + ax * y1 - ay * x1;
  139. dq[7] = -ax * x1 - ay * y1 - az * z1;
  140. return dq;
  141. }
  142. /**
  143. * Creates a dual quat from a quaternion and a translation
  144. *
  145. * @param {ReadonlyQuat2} dual quaternion receiving operation result
  146. * @param {ReadonlyQuat} q a normalized quaternion
  147. * @param {ReadonlyVec3} t tranlation vector
  148. * @returns {quat2} dual quaternion receiving operation result
  149. * @function
  150. */
  151. function fromRotationTranslation(out, q, t) {
  152. var ax = t[0] * 0.5,
  153. ay = t[1] * 0.5,
  154. az = t[2] * 0.5,
  155. bx = q[0],
  156. by = q[1],
  157. bz = q[2],
  158. bw = q[3];
  159. out[0] = bx;
  160. out[1] = by;
  161. out[2] = bz;
  162. out[3] = bw;
  163. out[4] = ax * bw + ay * bz - az * by;
  164. out[5] = ay * bw + az * bx - ax * bz;
  165. out[6] = az * bw + ax * by - ay * bx;
  166. out[7] = -ax * bx - ay * by - az * bz;
  167. return out;
  168. }
  169. /**
  170. * Creates a dual quat from a translation
  171. *
  172. * @param {ReadonlyQuat2} dual quaternion receiving operation result
  173. * @param {ReadonlyVec3} t translation vector
  174. * @returns {quat2} dual quaternion receiving operation result
  175. * @function
  176. */
  177. function fromTranslation(out, t) {
  178. out[0] = 0;
  179. out[1] = 0;
  180. out[2] = 0;
  181. out[3] = 1;
  182. out[4] = t[0] * 0.5;
  183. out[5] = t[1] * 0.5;
  184. out[6] = t[2] * 0.5;
  185. out[7] = 0;
  186. return out;
  187. }
  188. /**
  189. * Creates a dual quat from a quaternion
  190. *
  191. * @param {ReadonlyQuat2} dual quaternion receiving operation result
  192. * @param {ReadonlyQuat} q the quaternion
  193. * @returns {quat2} dual quaternion receiving operation result
  194. * @function
  195. */
  196. function fromRotation(out, q) {
  197. out[0] = q[0];
  198. out[1] = q[1];
  199. out[2] = q[2];
  200. out[3] = q[3];
  201. out[4] = 0;
  202. out[5] = 0;
  203. out[6] = 0;
  204. out[7] = 0;
  205. return out;
  206. }
  207. /**
  208. * Creates a new dual quat from a matrix (4x4)
  209. *
  210. * @param {quat2} out the dual quaternion
  211. * @param {ReadonlyMat4} a the matrix
  212. * @returns {quat2} dual quat receiving operation result
  213. * @function
  214. */
  215. function fromMat4(out, a) {
  216. //TODO Optimize this
  217. var outer = quat.create();
  218. mat4.getRotation(outer, a);
  219. var t = new glMatrix.ARRAY_TYPE(3);
  220. mat4.getTranslation(t, a);
  221. fromRotationTranslation(out, outer, t);
  222. return out;
  223. }
  224. /**
  225. * Copy the values from one dual quat to another
  226. *
  227. * @param {quat2} out the receiving dual quaternion
  228. * @param {ReadonlyQuat2} a the source dual quaternion
  229. * @returns {quat2} out
  230. * @function
  231. */
  232. function copy(out, a) {
  233. out[0] = a[0];
  234. out[1] = a[1];
  235. out[2] = a[2];
  236. out[3] = a[3];
  237. out[4] = a[4];
  238. out[5] = a[5];
  239. out[6] = a[6];
  240. out[7] = a[7];
  241. return out;
  242. }
  243. /**
  244. * Set a dual quat to the identity dual quaternion
  245. *
  246. * @param {quat2} out the receiving quaternion
  247. * @returns {quat2} out
  248. */
  249. function identity(out) {
  250. out[0] = 0;
  251. out[1] = 0;
  252. out[2] = 0;
  253. out[3] = 1;
  254. out[4] = 0;
  255. out[5] = 0;
  256. out[6] = 0;
  257. out[7] = 0;
  258. return out;
  259. }
  260. /**
  261. * Set the components of a dual quat to the given values
  262. *
  263. * @param {quat2} out the receiving quaternion
  264. * @param {Number} x1 X component
  265. * @param {Number} y1 Y component
  266. * @param {Number} z1 Z component
  267. * @param {Number} w1 W component
  268. * @param {Number} x2 X component
  269. * @param {Number} y2 Y component
  270. * @param {Number} z2 Z component
  271. * @param {Number} w2 W component
  272. * @returns {quat2} out
  273. * @function
  274. */
  275. function set(out, x1, y1, z1, w1, x2, y2, z2, w2) {
  276. out[0] = x1;
  277. out[1] = y1;
  278. out[2] = z1;
  279. out[3] = w1;
  280. out[4] = x2;
  281. out[5] = y2;
  282. out[6] = z2;
  283. out[7] = w2;
  284. return out;
  285. }
  286. /**
  287. * Gets the real part of a dual quat
  288. * @param {quat} out real part
  289. * @param {ReadonlyQuat2} a Dual Quaternion
  290. * @return {quat} real part
  291. */
  292. var getReal = quat.copy;
  293. /**
  294. * Gets the dual part of a dual quat
  295. * @param {quat} out dual part
  296. * @param {ReadonlyQuat2} a Dual Quaternion
  297. * @return {quat} dual part
  298. */
  299. exports.getReal = getReal;
  300. function getDual(out, a) {
  301. out[0] = a[4];
  302. out[1] = a[5];
  303. out[2] = a[6];
  304. out[3] = a[7];
  305. return out;
  306. }
  307. /**
  308. * Set the real component of a dual quat to the given quaternion
  309. *
  310. * @param {quat2} out the receiving quaternion
  311. * @param {ReadonlyQuat} q a quaternion representing the real part
  312. * @returns {quat2} out
  313. * @function
  314. */
  315. var setReal = quat.copy;
  316. /**
  317. * Set the dual component of a dual quat to the given quaternion
  318. *
  319. * @param {quat2} out the receiving quaternion
  320. * @param {ReadonlyQuat} q a quaternion representing the dual part
  321. * @returns {quat2} out
  322. * @function
  323. */
  324. exports.setReal = setReal;
  325. function setDual(out, q) {
  326. out[4] = q[0];
  327. out[5] = q[1];
  328. out[6] = q[2];
  329. out[7] = q[3];
  330. return out;
  331. }
  332. /**
  333. * Gets the translation of a normalized dual quat
  334. * @param {vec3} out translation
  335. * @param {ReadonlyQuat2} a Dual Quaternion to be decomposed
  336. * @return {vec3} translation
  337. */
  338. function getTranslation(out, a) {
  339. var ax = a[4],
  340. ay = a[5],
  341. az = a[6],
  342. aw = a[7],
  343. bx = -a[0],
  344. by = -a[1],
  345. bz = -a[2],
  346. bw = a[3];
  347. out[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
  348. out[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
  349. out[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
  350. return out;
  351. }
  352. /**
  353. * Translates a dual quat by the given vector
  354. *
  355. * @param {quat2} out the receiving dual quaternion
  356. * @param {ReadonlyQuat2} a the dual quaternion to translate
  357. * @param {ReadonlyVec3} v vector to translate by
  358. * @returns {quat2} out
  359. */
  360. function translate(out, a, v) {
  361. var ax1 = a[0],
  362. ay1 = a[1],
  363. az1 = a[2],
  364. aw1 = a[3],
  365. bx1 = v[0] * 0.5,
  366. by1 = v[1] * 0.5,
  367. bz1 = v[2] * 0.5,
  368. ax2 = a[4],
  369. ay2 = a[5],
  370. az2 = a[6],
  371. aw2 = a[7];
  372. out[0] = ax1;
  373. out[1] = ay1;
  374. out[2] = az1;
  375. out[3] = aw1;
  376. out[4] = aw1 * bx1 + ay1 * bz1 - az1 * by1 + ax2;
  377. out[5] = aw1 * by1 + az1 * bx1 - ax1 * bz1 + ay2;
  378. out[6] = aw1 * bz1 + ax1 * by1 - ay1 * bx1 + az2;
  379. out[7] = -ax1 * bx1 - ay1 * by1 - az1 * bz1 + aw2;
  380. return out;
  381. }
  382. /**
  383. * Rotates a dual quat around the X axis
  384. *
  385. * @param {quat2} out the receiving dual quaternion
  386. * @param {ReadonlyQuat2} a the dual quaternion to rotate
  387. * @param {number} rad how far should the rotation be
  388. * @returns {quat2} out
  389. */
  390. function rotateX(out, a, rad) {
  391. var bx = -a[0],
  392. by = -a[1],
  393. bz = -a[2],
  394. bw = a[3],
  395. ax = a[4],
  396. ay = a[5],
  397. az = a[6],
  398. aw = a[7],
  399. ax1 = ax * bw + aw * bx + ay * bz - az * by,
  400. ay1 = ay * bw + aw * by + az * bx - ax * bz,
  401. az1 = az * bw + aw * bz + ax * by - ay * bx,
  402. aw1 = aw * bw - ax * bx - ay * by - az * bz;
  403. quat.rotateX(out, a, rad);
  404. bx = out[0];
  405. by = out[1];
  406. bz = out[2];
  407. bw = out[3];
  408. out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  409. out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  410. out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  411. out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  412. return out;
  413. }
  414. /**
  415. * Rotates a dual quat around the Y axis
  416. *
  417. * @param {quat2} out the receiving dual quaternion
  418. * @param {ReadonlyQuat2} a the dual quaternion to rotate
  419. * @param {number} rad how far should the rotation be
  420. * @returns {quat2} out
  421. */
  422. function rotateY(out, a, rad) {
  423. var bx = -a[0],
  424. by = -a[1],
  425. bz = -a[2],
  426. bw = a[3],
  427. ax = a[4],
  428. ay = a[5],
  429. az = a[6],
  430. aw = a[7],
  431. ax1 = ax * bw + aw * bx + ay * bz - az * by,
  432. ay1 = ay * bw + aw * by + az * bx - ax * bz,
  433. az1 = az * bw + aw * bz + ax * by - ay * bx,
  434. aw1 = aw * bw - ax * bx - ay * by - az * bz;
  435. quat.rotateY(out, a, rad);
  436. bx = out[0];
  437. by = out[1];
  438. bz = out[2];
  439. bw = out[3];
  440. out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  441. out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  442. out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  443. out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  444. return out;
  445. }
  446. /**
  447. * Rotates a dual quat around the Z axis
  448. *
  449. * @param {quat2} out the receiving dual quaternion
  450. * @param {ReadonlyQuat2} a the dual quaternion to rotate
  451. * @param {number} rad how far should the rotation be
  452. * @returns {quat2} out
  453. */
  454. function rotateZ(out, a, rad) {
  455. var bx = -a[0],
  456. by = -a[1],
  457. bz = -a[2],
  458. bw = a[3],
  459. ax = a[4],
  460. ay = a[5],
  461. az = a[6],
  462. aw = a[7],
  463. ax1 = ax * bw + aw * bx + ay * bz - az * by,
  464. ay1 = ay * bw + aw * by + az * bx - ax * bz,
  465. az1 = az * bw + aw * bz + ax * by - ay * bx,
  466. aw1 = aw * bw - ax * bx - ay * by - az * bz;
  467. quat.rotateZ(out, a, rad);
  468. bx = out[0];
  469. by = out[1];
  470. bz = out[2];
  471. bw = out[3];
  472. out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  473. out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  474. out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  475. out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  476. return out;
  477. }
  478. /**
  479. * Rotates a dual quat by a given quaternion (a * q)
  480. *
  481. * @param {quat2} out the receiving dual quaternion
  482. * @param {ReadonlyQuat2} a the dual quaternion to rotate
  483. * @param {ReadonlyQuat} q quaternion to rotate by
  484. * @returns {quat2} out
  485. */
  486. function rotateByQuatAppend(out, a, q) {
  487. var qx = q[0],
  488. qy = q[1],
  489. qz = q[2],
  490. qw = q[3],
  491. ax = a[0],
  492. ay = a[1],
  493. az = a[2],
  494. aw = a[3];
  495. out[0] = ax * qw + aw * qx + ay * qz - az * qy;
  496. out[1] = ay * qw + aw * qy + az * qx - ax * qz;
  497. out[2] = az * qw + aw * qz + ax * qy - ay * qx;
  498. out[3] = aw * qw - ax * qx - ay * qy - az * qz;
  499. ax = a[4];
  500. ay = a[5];
  501. az = a[6];
  502. aw = a[7];
  503. out[4] = ax * qw + aw * qx + ay * qz - az * qy;
  504. out[5] = ay * qw + aw * qy + az * qx - ax * qz;
  505. out[6] = az * qw + aw * qz + ax * qy - ay * qx;
  506. out[7] = aw * qw - ax * qx - ay * qy - az * qz;
  507. return out;
  508. }
  509. /**
  510. * Rotates a dual quat by a given quaternion (q * a)
  511. *
  512. * @param {quat2} out the receiving dual quaternion
  513. * @param {ReadonlyQuat} q quaternion to rotate by
  514. * @param {ReadonlyQuat2} a the dual quaternion to rotate
  515. * @returns {quat2} out
  516. */
  517. function rotateByQuatPrepend(out, q, a) {
  518. var qx = q[0],
  519. qy = q[1],
  520. qz = q[2],
  521. qw = q[3],
  522. bx = a[0],
  523. by = a[1],
  524. bz = a[2],
  525. bw = a[3];
  526. out[0] = qx * bw + qw * bx + qy * bz - qz * by;
  527. out[1] = qy * bw + qw * by + qz * bx - qx * bz;
  528. out[2] = qz * bw + qw * bz + qx * by - qy * bx;
  529. out[3] = qw * bw - qx * bx - qy * by - qz * bz;
  530. bx = a[4];
  531. by = a[5];
  532. bz = a[6];
  533. bw = a[7];
  534. out[4] = qx * bw + qw * bx + qy * bz - qz * by;
  535. out[5] = qy * bw + qw * by + qz * bx - qx * bz;
  536. out[6] = qz * bw + qw * bz + qx * by - qy * bx;
  537. out[7] = qw * bw - qx * bx - qy * by - qz * bz;
  538. return out;
  539. }
  540. /**
  541. * Rotates a dual quat around a given axis. Does the normalisation automatically
  542. *
  543. * @param {quat2} out the receiving dual quaternion
  544. * @param {ReadonlyQuat2} a the dual quaternion to rotate
  545. * @param {ReadonlyVec3} axis the axis to rotate around
  546. * @param {Number} rad how far the rotation should be
  547. * @returns {quat2} out
  548. */
  549. function rotateAroundAxis(out, a, axis, rad) {
  550. //Special case for rad = 0
  551. if (Math.abs(rad) < glMatrix.EPSILON) {
  552. return copy(out, a);
  553. }
  554. var axisLength = Math.hypot(axis[0], axis[1], axis[2]);
  555. rad = rad * 0.5;
  556. var s = Math.sin(rad);
  557. var bx = s * axis[0] / axisLength;
  558. var by = s * axis[1] / axisLength;
  559. var bz = s * axis[2] / axisLength;
  560. var bw = Math.cos(rad);
  561. var ax1 = a[0],
  562. ay1 = a[1],
  563. az1 = a[2],
  564. aw1 = a[3];
  565. out[0] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  566. out[1] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  567. out[2] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  568. out[3] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  569. var ax = a[4],
  570. ay = a[5],
  571. az = a[6],
  572. aw = a[7];
  573. out[4] = ax * bw + aw * bx + ay * bz - az * by;
  574. out[5] = ay * bw + aw * by + az * bx - ax * bz;
  575. out[6] = az * bw + aw * bz + ax * by - ay * bx;
  576. out[7] = aw * bw - ax * bx - ay * by - az * bz;
  577. return out;
  578. }
  579. /**
  580. * Adds two dual quat's
  581. *
  582. * @param {quat2} out the receiving dual quaternion
  583. * @param {ReadonlyQuat2} a the first operand
  584. * @param {ReadonlyQuat2} b the second operand
  585. * @returns {quat2} out
  586. * @function
  587. */
  588. function add(out, a, b) {
  589. out[0] = a[0] + b[0];
  590. out[1] = a[1] + b[1];
  591. out[2] = a[2] + b[2];
  592. out[3] = a[3] + b[3];
  593. out[4] = a[4] + b[4];
  594. out[5] = a[5] + b[5];
  595. out[6] = a[6] + b[6];
  596. out[7] = a[7] + b[7];
  597. return out;
  598. }
  599. /**
  600. * Multiplies two dual quat's
  601. *
  602. * @param {quat2} out the receiving dual quaternion
  603. * @param {ReadonlyQuat2} a the first operand
  604. * @param {ReadonlyQuat2} b the second operand
  605. * @returns {quat2} out
  606. */
  607. function multiply(out, a, b) {
  608. var ax0 = a[0],
  609. ay0 = a[1],
  610. az0 = a[2],
  611. aw0 = a[3],
  612. bx1 = b[4],
  613. by1 = b[5],
  614. bz1 = b[6],
  615. bw1 = b[7],
  616. ax1 = a[4],
  617. ay1 = a[5],
  618. az1 = a[6],
  619. aw1 = a[7],
  620. bx0 = b[0],
  621. by0 = b[1],
  622. bz0 = b[2],
  623. bw0 = b[3];
  624. out[0] = ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0;
  625. out[1] = ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0;
  626. out[2] = az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0;
  627. out[3] = aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0;
  628. out[4] = ax0 * bw1 + aw0 * bx1 + ay0 * bz1 - az0 * by1 + ax1 * bw0 + aw1 * bx0 + ay1 * bz0 - az1 * by0;
  629. out[5] = ay0 * bw1 + aw0 * by1 + az0 * bx1 - ax0 * bz1 + ay1 * bw0 + aw1 * by0 + az1 * bx0 - ax1 * bz0;
  630. out[6] = az0 * bw1 + aw0 * bz1 + ax0 * by1 - ay0 * bx1 + az1 * bw0 + aw1 * bz0 + ax1 * by0 - ay1 * bx0;
  631. out[7] = aw0 * bw1 - ax0 * bx1 - ay0 * by1 - az0 * bz1 + aw1 * bw0 - ax1 * bx0 - ay1 * by0 - az1 * bz0;
  632. return out;
  633. }
  634. /**
  635. * Alias for {@link quat2.multiply}
  636. * @function
  637. */
  638. var mul = multiply;
  639. /**
  640. * Scales a dual quat by a scalar number
  641. *
  642. * @param {quat2} out the receiving dual quat
  643. * @param {ReadonlyQuat2} a the dual quat to scale
  644. * @param {Number} b amount to scale the dual quat by
  645. * @returns {quat2} out
  646. * @function
  647. */
  648. exports.mul = mul;
  649. function scale(out, a, b) {
  650. out[0] = a[0] * b;
  651. out[1] = a[1] * b;
  652. out[2] = a[2] * b;
  653. out[3] = a[3] * b;
  654. out[4] = a[4] * b;
  655. out[5] = a[5] * b;
  656. out[6] = a[6] * b;
  657. out[7] = a[7] * b;
  658. return out;
  659. }
  660. /**
  661. * Calculates the dot product of two dual quat's (The dot product of the real parts)
  662. *
  663. * @param {ReadonlyQuat2} a the first operand
  664. * @param {ReadonlyQuat2} b the second operand
  665. * @returns {Number} dot product of a and b
  666. * @function
  667. */
  668. var dot = quat.dot;
  669. /**
  670. * Performs a linear interpolation between two dual quats's
  671. * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5)
  672. *
  673. * @param {quat2} out the receiving dual quat
  674. * @param {ReadonlyQuat2} a the first operand
  675. * @param {ReadonlyQuat2} b the second operand
  676. * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
  677. * @returns {quat2} out
  678. */
  679. exports.dot = dot;
  680. function lerp(out, a, b, t) {
  681. var mt = 1 - t;
  682. if (dot(a, b) < 0) t = -t;
  683. out[0] = a[0] * mt + b[0] * t;
  684. out[1] = a[1] * mt + b[1] * t;
  685. out[2] = a[2] * mt + b[2] * t;
  686. out[3] = a[3] * mt + b[3] * t;
  687. out[4] = a[4] * mt + b[4] * t;
  688. out[5] = a[5] * mt + b[5] * t;
  689. out[6] = a[6] * mt + b[6] * t;
  690. out[7] = a[7] * mt + b[7] * t;
  691. return out;
  692. }
  693. /**
  694. * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper
  695. *
  696. * @param {quat2} out the receiving dual quaternion
  697. * @param {ReadonlyQuat2} a dual quat to calculate inverse of
  698. * @returns {quat2} out
  699. */
  700. function invert(out, a) {
  701. var sqlen = squaredLength(a);
  702. out[0] = -a[0] / sqlen;
  703. out[1] = -a[1] / sqlen;
  704. out[2] = -a[2] / sqlen;
  705. out[3] = a[3] / sqlen;
  706. out[4] = -a[4] / sqlen;
  707. out[5] = -a[5] / sqlen;
  708. out[6] = -a[6] / sqlen;
  709. out[7] = a[7] / sqlen;
  710. return out;
  711. }
  712. /**
  713. * Calculates the conjugate of a dual quat
  714. * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result.
  715. *
  716. * @param {quat2} out the receiving quaternion
  717. * @param {ReadonlyQuat2} a quat to calculate conjugate of
  718. * @returns {quat2} out
  719. */
  720. function conjugate(out, a) {
  721. out[0] = -a[0];
  722. out[1] = -a[1];
  723. out[2] = -a[2];
  724. out[3] = a[3];
  725. out[4] = -a[4];
  726. out[5] = -a[5];
  727. out[6] = -a[6];
  728. out[7] = a[7];
  729. return out;
  730. }
  731. /**
  732. * Calculates the length of a dual quat
  733. *
  734. * @param {ReadonlyQuat2} a dual quat to calculate length of
  735. * @returns {Number} length of a
  736. * @function
  737. */
  738. var length = quat.length;
  739. /**
  740. * Alias for {@link quat2.length}
  741. * @function
  742. */
  743. exports.length = length;
  744. var len = length;
  745. /**
  746. * Calculates the squared length of a dual quat
  747. *
  748. * @param {ReadonlyQuat2} a dual quat to calculate squared length of
  749. * @returns {Number} squared length of a
  750. * @function
  751. */
  752. exports.len = len;
  753. var squaredLength = quat.squaredLength;
  754. /**
  755. * Alias for {@link quat2.squaredLength}
  756. * @function
  757. */
  758. exports.squaredLength = squaredLength;
  759. var sqrLen = squaredLength;
  760. /**
  761. * Normalize a dual quat
  762. *
  763. * @param {quat2} out the receiving dual quaternion
  764. * @param {ReadonlyQuat2} a dual quaternion to normalize
  765. * @returns {quat2} out
  766. * @function
  767. */
  768. exports.sqrLen = sqrLen;
  769. function normalize(out, a) {
  770. var magnitude = squaredLength(a);
  771. if (magnitude > 0) {
  772. magnitude = Math.sqrt(magnitude);
  773. var a0 = a[0] / magnitude;
  774. var a1 = a[1] / magnitude;
  775. var a2 = a[2] / magnitude;
  776. var a3 = a[3] / magnitude;
  777. var b0 = a[4];
  778. var b1 = a[5];
  779. var b2 = a[6];
  780. var b3 = a[7];
  781. var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3;
  782. out[0] = a0;
  783. out[1] = a1;
  784. out[2] = a2;
  785. out[3] = a3;
  786. out[4] = (b0 - a0 * a_dot_b) / magnitude;
  787. out[5] = (b1 - a1 * a_dot_b) / magnitude;
  788. out[6] = (b2 - a2 * a_dot_b) / magnitude;
  789. out[7] = (b3 - a3 * a_dot_b) / magnitude;
  790. }
  791. return out;
  792. }
  793. /**
  794. * Returns a string representation of a dual quatenion
  795. *
  796. * @param {ReadonlyQuat2} a dual quaternion to represent as a string
  797. * @returns {String} string representation of the dual quat
  798. */
  799. function str(a) {
  800. return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")";
  801. }
  802. /**
  803. * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===)
  804. *
  805. * @param {ReadonlyQuat2} a the first dual quaternion.
  806. * @param {ReadonlyQuat2} b the second dual quaternion.
  807. * @returns {Boolean} true if the dual quaternions are equal, false otherwise.
  808. */
  809. function exactEquals(a, b) {
  810. return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7];
  811. }
  812. /**
  813. * Returns whether or not the dual quaternions have approximately the same elements in the same position.
  814. *
  815. * @param {ReadonlyQuat2} a the first dual quat.
  816. * @param {ReadonlyQuat2} b the second dual quat.
  817. * @returns {Boolean} true if the dual quats are equal, false otherwise.
  818. */
  819. function equals(a, b) {
  820. var a0 = a[0],
  821. a1 = a[1],
  822. a2 = a[2],
  823. a3 = a[3],
  824. a4 = a[4],
  825. a5 = a[5],
  826. a6 = a[6],
  827. a7 = a[7];
  828. var b0 = b[0],
  829. b1 = b[1],
  830. b2 = b[2],
  831. b3 = b[3],
  832. b4 = b[4],
  833. b5 = b[5],
  834. b6 = b[6],
  835. b7 = b[7];
  836. return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7));
  837. }