mat4.js.html 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSDoc: Source: mat4.js</title>
  6. <script src="scripts/prettify/prettify.js"> </script>
  7. <script src="scripts/prettify/lang-css.js"> </script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
  13. </head>
  14. <body>
  15. <div id="main">
  16. <h1 class="page-title">Source: mat4.js</h1>
  17. <section>
  18. <article>
  19. <pre class="prettyprint source linenums"><code>import * as glMatrix from "./common.js";
  20. /**
  21. * 4x4 Matrix&lt;br>Format: column-major, when typed out it looks like row-major&lt;br>The matrices are being post multiplied.
  22. * @module mat4
  23. */
  24. /**
  25. * Creates a new identity mat4
  26. *
  27. * @returns {mat4} a new 4x4 matrix
  28. */
  29. export function create() {
  30. let out = new glMatrix.ARRAY_TYPE(16);
  31. if(glMatrix.ARRAY_TYPE != Float32Array) {
  32. out[1] = 0;
  33. out[2] = 0;
  34. out[3] = 0;
  35. out[4] = 0;
  36. out[6] = 0;
  37. out[7] = 0;
  38. out[8] = 0;
  39. out[9] = 0;
  40. out[11] = 0;
  41. out[12] = 0;
  42. out[13] = 0;
  43. out[14] = 0;
  44. }
  45. out[0] = 1;
  46. out[5] = 1;
  47. out[10] = 1;
  48. out[15] = 1;
  49. return out;
  50. }
  51. /**
  52. * Creates a new mat4 initialized with values from an existing matrix
  53. *
  54. * @param {mat4} a matrix to clone
  55. * @returns {mat4} a new 4x4 matrix
  56. */
  57. export function clone(a) {
  58. let out = new glMatrix.ARRAY_TYPE(16);
  59. out[0] = a[0];
  60. out[1] = a[1];
  61. out[2] = a[2];
  62. out[3] = a[3];
  63. out[4] = a[4];
  64. out[5] = a[5];
  65. out[6] = a[6];
  66. out[7] = a[7];
  67. out[8] = a[8];
  68. out[9] = a[9];
  69. out[10] = a[10];
  70. out[11] = a[11];
  71. out[12] = a[12];
  72. out[13] = a[13];
  73. out[14] = a[14];
  74. out[15] = a[15];
  75. return out;
  76. }
  77. /**
  78. * Copy the values from one mat4 to another
  79. *
  80. * @param {mat4} out the receiving matrix
  81. * @param {mat4} a the source matrix
  82. * @returns {mat4} out
  83. */
  84. export function copy(out, a) {
  85. out[0] = a[0];
  86. out[1] = a[1];
  87. out[2] = a[2];
  88. out[3] = a[3];
  89. out[4] = a[4];
  90. out[5] = a[5];
  91. out[6] = a[6];
  92. out[7] = a[7];
  93. out[8] = a[8];
  94. out[9] = a[9];
  95. out[10] = a[10];
  96. out[11] = a[11];
  97. out[12] = a[12];
  98. out[13] = a[13];
  99. out[14] = a[14];
  100. out[15] = a[15];
  101. return out;
  102. }
  103. /**
  104. * Create a new mat4 with the given values
  105. *
  106. * @param {Number} m00 Component in column 0, row 0 position (index 0)
  107. * @param {Number} m01 Component in column 0, row 1 position (index 1)
  108. * @param {Number} m02 Component in column 0, row 2 position (index 2)
  109. * @param {Number} m03 Component in column 0, row 3 position (index 3)
  110. * @param {Number} m10 Component in column 1, row 0 position (index 4)
  111. * @param {Number} m11 Component in column 1, row 1 position (index 5)
  112. * @param {Number} m12 Component in column 1, row 2 position (index 6)
  113. * @param {Number} m13 Component in column 1, row 3 position (index 7)
  114. * @param {Number} m20 Component in column 2, row 0 position (index 8)
  115. * @param {Number} m21 Component in column 2, row 1 position (index 9)
  116. * @param {Number} m22 Component in column 2, row 2 position (index 10)
  117. * @param {Number} m23 Component in column 2, row 3 position (index 11)
  118. * @param {Number} m30 Component in column 3, row 0 position (index 12)
  119. * @param {Number} m31 Component in column 3, row 1 position (index 13)
  120. * @param {Number} m32 Component in column 3, row 2 position (index 14)
  121. * @param {Number} m33 Component in column 3, row 3 position (index 15)
  122. * @returns {mat4} A new mat4
  123. */
  124. export function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
  125. let out = new glMatrix.ARRAY_TYPE(16);
  126. out[0] = m00;
  127. out[1] = m01;
  128. out[2] = m02;
  129. out[3] = m03;
  130. out[4] = m10;
  131. out[5] = m11;
  132. out[6] = m12;
  133. out[7] = m13;
  134. out[8] = m20;
  135. out[9] = m21;
  136. out[10] = m22;
  137. out[11] = m23;
  138. out[12] = m30;
  139. out[13] = m31;
  140. out[14] = m32;
  141. out[15] = m33;
  142. return out;
  143. }
  144. /**
  145. * Set the components of a mat4 to the given values
  146. *
  147. * @param {mat4} out the receiving matrix
  148. * @param {Number} m00 Component in column 0, row 0 position (index 0)
  149. * @param {Number} m01 Component in column 0, row 1 position (index 1)
  150. * @param {Number} m02 Component in column 0, row 2 position (index 2)
  151. * @param {Number} m03 Component in column 0, row 3 position (index 3)
  152. * @param {Number} m10 Component in column 1, row 0 position (index 4)
  153. * @param {Number} m11 Component in column 1, row 1 position (index 5)
  154. * @param {Number} m12 Component in column 1, row 2 position (index 6)
  155. * @param {Number} m13 Component in column 1, row 3 position (index 7)
  156. * @param {Number} m20 Component in column 2, row 0 position (index 8)
  157. * @param {Number} m21 Component in column 2, row 1 position (index 9)
  158. * @param {Number} m22 Component in column 2, row 2 position (index 10)
  159. * @param {Number} m23 Component in column 2, row 3 position (index 11)
  160. * @param {Number} m30 Component in column 3, row 0 position (index 12)
  161. * @param {Number} m31 Component in column 3, row 1 position (index 13)
  162. * @param {Number} m32 Component in column 3, row 2 position (index 14)
  163. * @param {Number} m33 Component in column 3, row 3 position (index 15)
  164. * @returns {mat4} out
  165. */
  166. export function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
  167. out[0] = m00;
  168. out[1] = m01;
  169. out[2] = m02;
  170. out[3] = m03;
  171. out[4] = m10;
  172. out[5] = m11;
  173. out[6] = m12;
  174. out[7] = m13;
  175. out[8] = m20;
  176. out[9] = m21;
  177. out[10] = m22;
  178. out[11] = m23;
  179. out[12] = m30;
  180. out[13] = m31;
  181. out[14] = m32;
  182. out[15] = m33;
  183. return out;
  184. }
  185. /**
  186. * Set a mat4 to the identity matrix
  187. *
  188. * @param {mat4} out the receiving matrix
  189. * @returns {mat4} out
  190. */
  191. export function identity(out) {
  192. out[0] = 1;
  193. out[1] = 0;
  194. out[2] = 0;
  195. out[3] = 0;
  196. out[4] = 0;
  197. out[5] = 1;
  198. out[6] = 0;
  199. out[7] = 0;
  200. out[8] = 0;
  201. out[9] = 0;
  202. out[10] = 1;
  203. out[11] = 0;
  204. out[12] = 0;
  205. out[13] = 0;
  206. out[14] = 0;
  207. out[15] = 1;
  208. return out;
  209. }
  210. /**
  211. * Transpose the values of a mat4
  212. *
  213. * @param {mat4} out the receiving matrix
  214. * @param {mat4} a the source matrix
  215. * @returns {mat4} out
  216. */
  217. export function transpose(out, a) {
  218. // If we are transposing ourselves we can skip a few steps but have to cache some values
  219. if (out === a) {
  220. let a01 = a[1], a02 = a[2], a03 = a[3];
  221. let a12 = a[6], a13 = a[7];
  222. let a23 = a[11];
  223. out[1] = a[4];
  224. out[2] = a[8];
  225. out[3] = a[12];
  226. out[4] = a01;
  227. out[6] = a[9];
  228. out[7] = a[13];
  229. out[8] = a02;
  230. out[9] = a12;
  231. out[11] = a[14];
  232. out[12] = a03;
  233. out[13] = a13;
  234. out[14] = a23;
  235. } else {
  236. out[0] = a[0];
  237. out[1] = a[4];
  238. out[2] = a[8];
  239. out[3] = a[12];
  240. out[4] = a[1];
  241. out[5] = a[5];
  242. out[6] = a[9];
  243. out[7] = a[13];
  244. out[8] = a[2];
  245. out[9] = a[6];
  246. out[10] = a[10];
  247. out[11] = a[14];
  248. out[12] = a[3];
  249. out[13] = a[7];
  250. out[14] = a[11];
  251. out[15] = a[15];
  252. }
  253. return out;
  254. }
  255. /**
  256. * Inverts a mat4
  257. *
  258. * @param {mat4} out the receiving matrix
  259. * @param {mat4} a the source matrix
  260. * @returns {mat4} out
  261. */
  262. export function invert(out, a) {
  263. let a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
  264. let a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
  265. let a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
  266. let a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
  267. let b00 = a00 * a11 - a01 * a10;
  268. let b01 = a00 * a12 - a02 * a10;
  269. let b02 = a00 * a13 - a03 * a10;
  270. let b03 = a01 * a12 - a02 * a11;
  271. let b04 = a01 * a13 - a03 * a11;
  272. let b05 = a02 * a13 - a03 * a12;
  273. let b06 = a20 * a31 - a21 * a30;
  274. let b07 = a20 * a32 - a22 * a30;
  275. let b08 = a20 * a33 - a23 * a30;
  276. let b09 = a21 * a32 - a22 * a31;
  277. let b10 = a21 * a33 - a23 * a31;
  278. let b11 = a22 * a33 - a23 * a32;
  279. // Calculate the determinant
  280. let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  281. if (!det) {
  282. return null;
  283. }
  284. det = 1.0 / det;
  285. out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  286. out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  287. out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  288. out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
  289. out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  290. out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  291. out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  292. out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
  293. out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  294. out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  295. out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  296. out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
  297. out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
  298. out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
  299. out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
  300. out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  301. return out;
  302. }
  303. /**
  304. * Calculates the adjugate of a mat4
  305. *
  306. * @param {mat4} out the receiving matrix
  307. * @param {mat4} a the source matrix
  308. * @returns {mat4} out
  309. */
  310. export function adjoint(out, a) {
  311. let a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
  312. let a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
  313. let a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
  314. let a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
  315. out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
  316. out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
  317. out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
  318. out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
  319. out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
  320. out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
  321. out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
  322. out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
  323. out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
  324. out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
  325. out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
  326. out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
  327. out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
  328. out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
  329. out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
  330. out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
  331. return out;
  332. }
  333. /**
  334. * Calculates the determinant of a mat4
  335. *
  336. * @param {mat4} a the source matrix
  337. * @returns {Number} determinant of a
  338. */
  339. export function determinant(a) {
  340. let a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
  341. let a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
  342. let a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
  343. let a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
  344. let b00 = a00 * a11 - a01 * a10;
  345. let b01 = a00 * a12 - a02 * a10;
  346. let b02 = a00 * a13 - a03 * a10;
  347. let b03 = a01 * a12 - a02 * a11;
  348. let b04 = a01 * a13 - a03 * a11;
  349. let b05 = a02 * a13 - a03 * a12;
  350. let b06 = a20 * a31 - a21 * a30;
  351. let b07 = a20 * a32 - a22 * a30;
  352. let b08 = a20 * a33 - a23 * a30;
  353. let b09 = a21 * a32 - a22 * a31;
  354. let b10 = a21 * a33 - a23 * a31;
  355. let b11 = a22 * a33 - a23 * a32;
  356. // Calculate the determinant
  357. return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  358. }
  359. /**
  360. * Multiplies two mat4s
  361. *
  362. * @param {mat4} out the receiving matrix
  363. * @param {mat4} a the first operand
  364. * @param {mat4} b the second operand
  365. * @returns {mat4} out
  366. */
  367. export function multiply(out, a, b) {
  368. let a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
  369. let a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
  370. let a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
  371. let a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
  372. // Cache only the current line of the second matrix
  373. let b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
  374. out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  375. out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  376. out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  377. out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  378. b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
  379. out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  380. out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  381. out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  382. out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  383. b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
  384. out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  385. out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  386. out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  387. out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  388. b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
  389. out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  390. out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  391. out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  392. out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  393. return out;
  394. }
  395. /**
  396. * Translate a mat4 by the given vector
  397. *
  398. * @param {mat4} out the receiving matrix
  399. * @param {mat4} a the matrix to translate
  400. * @param {vec3} v vector to translate by
  401. * @returns {mat4} out
  402. */
  403. export function translate(out, a, v) {
  404. let x = v[0], y = v[1], z = v[2];
  405. let a00, a01, a02, a03;
  406. let a10, a11, a12, a13;
  407. let a20, a21, a22, a23;
  408. if (a === out) {
  409. out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
  410. out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
  411. out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
  412. out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
  413. } else {
  414. a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
  415. a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
  416. a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
  417. out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
  418. out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
  419. out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
  420. out[12] = a00 * x + a10 * y + a20 * z + a[12];
  421. out[13] = a01 * x + a11 * y + a21 * z + a[13];
  422. out[14] = a02 * x + a12 * y + a22 * z + a[14];
  423. out[15] = a03 * x + a13 * y + a23 * z + a[15];
  424. }
  425. return out;
  426. }
  427. /**
  428. * Scales the mat4 by the dimensions in the given vec3 not using vectorization
  429. *
  430. * @param {mat4} out the receiving matrix
  431. * @param {mat4} a the matrix to scale
  432. * @param {vec3} v the vec3 to scale the matrix by
  433. * @returns {mat4} out
  434. **/
  435. export function scale(out, a, v) {
  436. let x = v[0], y = v[1], z = v[2];
  437. out[0] = a[0] * x;
  438. out[1] = a[1] * x;
  439. out[2] = a[2] * x;
  440. out[3] = a[3] * x;
  441. out[4] = a[4] * y;
  442. out[5] = a[5] * y;
  443. out[6] = a[6] * y;
  444. out[7] = a[7] * y;
  445. out[8] = a[8] * z;
  446. out[9] = a[9] * z;
  447. out[10] = a[10] * z;
  448. out[11] = a[11] * z;
  449. out[12] = a[12];
  450. out[13] = a[13];
  451. out[14] = a[14];
  452. out[15] = a[15];
  453. return out;
  454. }
  455. /**
  456. * Rotates a mat4 by the given angle around the given axis
  457. *
  458. * @param {mat4} out the receiving matrix
  459. * @param {mat4} a the matrix to rotate
  460. * @param {Number} rad the angle to rotate the matrix by
  461. * @param {vec3} axis the axis to rotate around
  462. * @returns {mat4} out
  463. */
  464. export function rotate(out, a, rad, axis) {
  465. let x = axis[0], y = axis[1], z = axis[2];
  466. let len = Math.sqrt(x * x + y * y + z * z);
  467. let s, c, t;
  468. let a00, a01, a02, a03;
  469. let a10, a11, a12, a13;
  470. let a20, a21, a22, a23;
  471. let b00, b01, b02;
  472. let b10, b11, b12;
  473. let b20, b21, b22;
  474. if (len &lt; glMatrix.EPSILON) { return null; }
  475. len = 1 / len;
  476. x *= len;
  477. y *= len;
  478. z *= len;
  479. s = Math.sin(rad);
  480. c = Math.cos(rad);
  481. t = 1 - c;
  482. a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
  483. a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
  484. a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
  485. // Construct the elements of the rotation matrix
  486. b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
  487. b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
  488. b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
  489. // Perform rotation-specific matrix multiplication
  490. out[0] = a00 * b00 + a10 * b01 + a20 * b02;
  491. out[1] = a01 * b00 + a11 * b01 + a21 * b02;
  492. out[2] = a02 * b00 + a12 * b01 + a22 * b02;
  493. out[3] = a03 * b00 + a13 * b01 + a23 * b02;
  494. out[4] = a00 * b10 + a10 * b11 + a20 * b12;
  495. out[5] = a01 * b10 + a11 * b11 + a21 * b12;
  496. out[6] = a02 * b10 + a12 * b11 + a22 * b12;
  497. out[7] = a03 * b10 + a13 * b11 + a23 * b12;
  498. out[8] = a00 * b20 + a10 * b21 + a20 * b22;
  499. out[9] = a01 * b20 + a11 * b21 + a21 * b22;
  500. out[10] = a02 * b20 + a12 * b21 + a22 * b22;
  501. out[11] = a03 * b20 + a13 * b21 + a23 * b22;
  502. if (a !== out) { // If the source and destination differ, copy the unchanged last row
  503. out[12] = a[12];
  504. out[13] = a[13];
  505. out[14] = a[14];
  506. out[15] = a[15];
  507. }
  508. return out;
  509. }
  510. /**
  511. * Rotates a matrix by the given angle around the X axis
  512. *
  513. * @param {mat4} out the receiving matrix
  514. * @param {mat4} a the matrix to rotate
  515. * @param {Number} rad the angle to rotate the matrix by
  516. * @returns {mat4} out
  517. */
  518. export function rotateX(out, a, rad) {
  519. let s = Math.sin(rad);
  520. let c = Math.cos(rad);
  521. let a10 = a[4];
  522. let a11 = a[5];
  523. let a12 = a[6];
  524. let a13 = a[7];
  525. let a20 = a[8];
  526. let a21 = a[9];
  527. let a22 = a[10];
  528. let a23 = a[11];
  529. if (a !== out) { // If the source and destination differ, copy the unchanged rows
  530. out[0] = a[0];
  531. out[1] = a[1];
  532. out[2] = a[2];
  533. out[3] = a[3];
  534. out[12] = a[12];
  535. out[13] = a[13];
  536. out[14] = a[14];
  537. out[15] = a[15];
  538. }
  539. // Perform axis-specific matrix multiplication
  540. out[4] = a10 * c + a20 * s;
  541. out[5] = a11 * c + a21 * s;
  542. out[6] = a12 * c + a22 * s;
  543. out[7] = a13 * c + a23 * s;
  544. out[8] = a20 * c - a10 * s;
  545. out[9] = a21 * c - a11 * s;
  546. out[10] = a22 * c - a12 * s;
  547. out[11] = a23 * c - a13 * s;
  548. return out;
  549. }
  550. /**
  551. * Rotates a matrix by the given angle around the Y axis
  552. *
  553. * @param {mat4} out the receiving matrix
  554. * @param {mat4} a the matrix to rotate
  555. * @param {Number} rad the angle to rotate the matrix by
  556. * @returns {mat4} out
  557. */
  558. export function rotateY(out, a, rad) {
  559. let s = Math.sin(rad);
  560. let c = Math.cos(rad);
  561. let a00 = a[0];
  562. let a01 = a[1];
  563. let a02 = a[2];
  564. let a03 = a[3];
  565. let a20 = a[8];
  566. let a21 = a[9];
  567. let a22 = a[10];
  568. let a23 = a[11];
  569. if (a !== out) { // If the source and destination differ, copy the unchanged rows
  570. out[4] = a[4];
  571. out[5] = a[5];
  572. out[6] = a[6];
  573. out[7] = a[7];
  574. out[12] = a[12];
  575. out[13] = a[13];
  576. out[14] = a[14];
  577. out[15] = a[15];
  578. }
  579. // Perform axis-specific matrix multiplication
  580. out[0] = a00 * c - a20 * s;
  581. out[1] = a01 * c - a21 * s;
  582. out[2] = a02 * c - a22 * s;
  583. out[3] = a03 * c - a23 * s;
  584. out[8] = a00 * s + a20 * c;
  585. out[9] = a01 * s + a21 * c;
  586. out[10] = a02 * s + a22 * c;
  587. out[11] = a03 * s + a23 * c;
  588. return out;
  589. }
  590. /**
  591. * Rotates a matrix by the given angle around the Z axis
  592. *
  593. * @param {mat4} out the receiving matrix
  594. * @param {mat4} a the matrix to rotate
  595. * @param {Number} rad the angle to rotate the matrix by
  596. * @returns {mat4} out
  597. */
  598. export function rotateZ(out, a, rad) {
  599. let s = Math.sin(rad);
  600. let c = Math.cos(rad);
  601. let a00 = a[0];
  602. let a01 = a[1];
  603. let a02 = a[2];
  604. let a03 = a[3];
  605. let a10 = a[4];
  606. let a11 = a[5];
  607. let a12 = a[6];
  608. let a13 = a[7];
  609. if (a !== out) { // If the source and destination differ, copy the unchanged last row
  610. out[8] = a[8];
  611. out[9] = a[9];
  612. out[10] = a[10];
  613. out[11] = a[11];
  614. out[12] = a[12];
  615. out[13] = a[13];
  616. out[14] = a[14];
  617. out[15] = a[15];
  618. }
  619. // Perform axis-specific matrix multiplication
  620. out[0] = a00 * c + a10 * s;
  621. out[1] = a01 * c + a11 * s;
  622. out[2] = a02 * c + a12 * s;
  623. out[3] = a03 * c + a13 * s;
  624. out[4] = a10 * c - a00 * s;
  625. out[5] = a11 * c - a01 * s;
  626. out[6] = a12 * c - a02 * s;
  627. out[7] = a13 * c - a03 * s;
  628. return out;
  629. }
  630. /**
  631. * Creates a matrix from a vector translation
  632. * This is equivalent to (but much faster than):
  633. *
  634. * mat4.identity(dest);
  635. * mat4.translate(dest, dest, vec);
  636. *
  637. * @param {mat4} out mat4 receiving operation result
  638. * @param {vec3} v Translation vector
  639. * @returns {mat4} out
  640. */
  641. export function fromTranslation(out, v) {
  642. out[0] = 1;
  643. out[1] = 0;
  644. out[2] = 0;
  645. out[3] = 0;
  646. out[4] = 0;
  647. out[5] = 1;
  648. out[6] = 0;
  649. out[7] = 0;
  650. out[8] = 0;
  651. out[9] = 0;
  652. out[10] = 1;
  653. out[11] = 0;
  654. out[12] = v[0];
  655. out[13] = v[1];
  656. out[14] = v[2];
  657. out[15] = 1;
  658. return out;
  659. }
  660. /**
  661. * Creates a matrix from a vector scaling
  662. * This is equivalent to (but much faster than):
  663. *
  664. * mat4.identity(dest);
  665. * mat4.scale(dest, dest, vec);
  666. *
  667. * @param {mat4} out mat4 receiving operation result
  668. * @param {vec3} v Scaling vector
  669. * @returns {mat4} out
  670. */
  671. export function fromScaling(out, v) {
  672. out[0] = v[0];
  673. out[1] = 0;
  674. out[2] = 0;
  675. out[3] = 0;
  676. out[4] = 0;
  677. out[5] = v[1];
  678. out[6] = 0;
  679. out[7] = 0;
  680. out[8] = 0;
  681. out[9] = 0;
  682. out[10] = v[2];
  683. out[11] = 0;
  684. out[12] = 0;
  685. out[13] = 0;
  686. out[14] = 0;
  687. out[15] = 1;
  688. return out;
  689. }
  690. /**
  691. * Creates a matrix from a given angle around a given axis
  692. * This is equivalent to (but much faster than):
  693. *
  694. * mat4.identity(dest);
  695. * mat4.rotate(dest, dest, rad, axis);
  696. *
  697. * @param {mat4} out mat4 receiving operation result
  698. * @param {Number} rad the angle to rotate the matrix by
  699. * @param {vec3} axis the axis to rotate around
  700. * @returns {mat4} out
  701. */
  702. export function fromRotation(out, rad, axis) {
  703. let x = axis[0], y = axis[1], z = axis[2];
  704. let len = Math.sqrt(x * x + y * y + z * z);
  705. let s, c, t;
  706. if (len &lt; glMatrix.EPSILON) { return null; }
  707. len = 1 / len;
  708. x *= len;
  709. y *= len;
  710. z *= len;
  711. s = Math.sin(rad);
  712. c = Math.cos(rad);
  713. t = 1 - c;
  714. // Perform rotation-specific matrix multiplication
  715. out[0] = x * x * t + c;
  716. out[1] = y * x * t + z * s;
  717. out[2] = z * x * t - y * s;
  718. out[3] = 0;
  719. out[4] = x * y * t - z * s;
  720. out[5] = y * y * t + c;
  721. out[6] = z * y * t + x * s;
  722. out[7] = 0;
  723. out[8] = x * z * t + y * s;
  724. out[9] = y * z * t - x * s;
  725. out[10] = z * z * t + c;
  726. out[11] = 0;
  727. out[12] = 0;
  728. out[13] = 0;
  729. out[14] = 0;
  730. out[15] = 1;
  731. return out;
  732. }
  733. /**
  734. * Creates a matrix from the given angle around the X axis
  735. * This is equivalent to (but much faster than):
  736. *
  737. * mat4.identity(dest);
  738. * mat4.rotateX(dest, dest, rad);
  739. *
  740. * @param {mat4} out mat4 receiving operation result
  741. * @param {Number} rad the angle to rotate the matrix by
  742. * @returns {mat4} out
  743. */
  744. export function fromXRotation(out, rad) {
  745. let s = Math.sin(rad);
  746. let c = Math.cos(rad);
  747. // Perform axis-specific matrix multiplication
  748. out[0] = 1;
  749. out[1] = 0;
  750. out[2] = 0;
  751. out[3] = 0;
  752. out[4] = 0;
  753. out[5] = c;
  754. out[6] = s;
  755. out[7] = 0;
  756. out[8] = 0;
  757. out[9] = -s;
  758. out[10] = c;
  759. out[11] = 0;
  760. out[12] = 0;
  761. out[13] = 0;
  762. out[14] = 0;
  763. out[15] = 1;
  764. return out;
  765. }
  766. /**
  767. * Creates a matrix from the given angle around the Y axis
  768. * This is equivalent to (but much faster than):
  769. *
  770. * mat4.identity(dest);
  771. * mat4.rotateY(dest, dest, rad);
  772. *
  773. * @param {mat4} out mat4 receiving operation result
  774. * @param {Number} rad the angle to rotate the matrix by
  775. * @returns {mat4} out
  776. */
  777. export function fromYRotation(out, rad) {
  778. let s = Math.sin(rad);
  779. let c = Math.cos(rad);
  780. // Perform axis-specific matrix multiplication
  781. out[0] = c;
  782. out[1] = 0;
  783. out[2] = -s;
  784. out[3] = 0;
  785. out[4] = 0;
  786. out[5] = 1;
  787. out[6] = 0;
  788. out[7] = 0;
  789. out[8] = s;
  790. out[9] = 0;
  791. out[10] = c;
  792. out[11] = 0;
  793. out[12] = 0;
  794. out[13] = 0;
  795. out[14] = 0;
  796. out[15] = 1;
  797. return out;
  798. }
  799. /**
  800. * Creates a matrix from the given angle around the Z axis
  801. * This is equivalent to (but much faster than):
  802. *
  803. * mat4.identity(dest);
  804. * mat4.rotateZ(dest, dest, rad);
  805. *
  806. * @param {mat4} out mat4 receiving operation result
  807. * @param {Number} rad the angle to rotate the matrix by
  808. * @returns {mat4} out
  809. */
  810. export function fromZRotation(out, rad) {
  811. let s = Math.sin(rad);
  812. let c = Math.cos(rad);
  813. // Perform axis-specific matrix multiplication
  814. out[0] = c;
  815. out[1] = s;
  816. out[2] = 0;
  817. out[3] = 0;
  818. out[4] = -s;
  819. out[5] = c;
  820. out[6] = 0;
  821. out[7] = 0;
  822. out[8] = 0;
  823. out[9] = 0;
  824. out[10] = 1;
  825. out[11] = 0;
  826. out[12] = 0;
  827. out[13] = 0;
  828. out[14] = 0;
  829. out[15] = 1;
  830. return out;
  831. }
  832. /**
  833. * Creates a matrix from a quaternion rotation and vector translation
  834. * This is equivalent to (but much faster than):
  835. *
  836. * mat4.identity(dest);
  837. * mat4.translate(dest, vec);
  838. * let quatMat = mat4.create();
  839. * quat4.toMat4(quat, quatMat);
  840. * mat4.multiply(dest, quatMat);
  841. *
  842. * @param {mat4} out mat4 receiving operation result
  843. * @param {quat4} q Rotation quaternion
  844. * @param {vec3} v Translation vector
  845. * @returns {mat4} out
  846. */
  847. export function fromRotationTranslation(out, q, v) {
  848. // Quaternion math
  849. let x = q[0], y = q[1], z = q[2], w = q[3];
  850. let x2 = x + x;
  851. let y2 = y + y;
  852. let z2 = z + z;
  853. let xx = x * x2;
  854. let xy = x * y2;
  855. let xz = x * z2;
  856. let yy = y * y2;
  857. let yz = y * z2;
  858. let zz = z * z2;
  859. let wx = w * x2;
  860. let wy = w * y2;
  861. let wz = w * z2;
  862. out[0] = 1 - (yy + zz);
  863. out[1] = xy + wz;
  864. out[2] = xz - wy;
  865. out[3] = 0;
  866. out[4] = xy - wz;
  867. out[5] = 1 - (xx + zz);
  868. out[6] = yz + wx;
  869. out[7] = 0;
  870. out[8] = xz + wy;
  871. out[9] = yz - wx;
  872. out[10] = 1 - (xx + yy);
  873. out[11] = 0;
  874. out[12] = v[0];
  875. out[13] = v[1];
  876. out[14] = v[2];
  877. out[15] = 1;
  878. return out;
  879. }
  880. /**
  881. * Creates a new mat4 from a dual quat.
  882. *
  883. * @param {mat4} out Matrix
  884. * @param {quat2} a Dual Quaternion
  885. * @returns {mat4} mat4 receiving operation result
  886. */
  887. export function fromQuat2(out, a) {
  888. let translation = new glMatrix.ARRAY_TYPE(3);
  889. let bx = -a[0], by = -a[1], bz = -a[2], bw = a[3],
  890. ax = a[4], ay = a[5], az = a[6], aw = a[7];
  891. let magnitude = bx * bx + by * by + bz * bz + bw * bw;
  892. //Only scale if it makes sense
  893. if (magnitude > 0) {
  894. translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;
  895. translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;
  896. translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude;
  897. } else {
  898. translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
  899. translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
  900. translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
  901. }
  902. fromRotationTranslation(out, a, translation);
  903. return out;
  904. }
  905. /**
  906. * Returns the translation vector component of a transformation
  907. * matrix. If a matrix is built with fromRotationTranslation,
  908. * the returned vector will be the same as the translation vector
  909. * originally supplied.
  910. * @param {vec3} out Vector to receive translation component
  911. * @param {mat4} mat Matrix to be decomposed (input)
  912. * @return {vec3} out
  913. */
  914. export function getTranslation(out, mat) {
  915. out[0] = mat[12];
  916. out[1] = mat[13];
  917. out[2] = mat[14];
  918. return out;
  919. }
  920. /**
  921. * Returns the scaling factor component of a transformation
  922. * matrix. If a matrix is built with fromRotationTranslationScale
  923. * with a normalized Quaternion paramter, the returned vector will be
  924. * the same as the scaling vector
  925. * originally supplied.
  926. * @param {vec3} out Vector to receive scaling factor component
  927. * @param {mat4} mat Matrix to be decomposed (input)
  928. * @return {vec3} out
  929. */
  930. export function getScaling(out, mat) {
  931. let m11 = mat[0];
  932. let m12 = mat[1];
  933. let m13 = mat[2];
  934. let m21 = mat[4];
  935. let m22 = mat[5];
  936. let m23 = mat[6];
  937. let m31 = mat[8];
  938. let m32 = mat[9];
  939. let m33 = mat[10];
  940. out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);
  941. out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);
  942. out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);
  943. return out;
  944. }
  945. /**
  946. * Returns a quaternion representing the rotational component
  947. * of a transformation matrix. If a matrix is built with
  948. * fromRotationTranslation, the returned quaternion will be the
  949. * same as the quaternion originally supplied.
  950. * @param {quat} out Quaternion to receive the rotation component
  951. * @param {mat4} mat Matrix to be decomposed (input)
  952. * @return {quat} out
  953. */
  954. export function getRotation(out, mat) {
  955. // Algorithm taken from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  956. let trace = mat[0] + mat[5] + mat[10];
  957. let S = 0;
  958. if (trace > 0) {
  959. S = Math.sqrt(trace + 1.0) * 2;
  960. out[3] = 0.25 * S;
  961. out[0] = (mat[6] - mat[9]) / S;
  962. out[1] = (mat[8] - mat[2]) / S;
  963. out[2] = (mat[1] - mat[4]) / S;
  964. } else if ((mat[0] > mat[5]) &amp;&amp; (mat[0] > mat[10])) {
  965. S = Math.sqrt(1.0 + mat[0] - mat[5] - mat[10]) * 2;
  966. out[3] = (mat[6] - mat[9]) / S;
  967. out[0] = 0.25 * S;
  968. out[1] = (mat[1] + mat[4]) / S;
  969. out[2] = (mat[8] + mat[2]) / S;
  970. } else if (mat[5] > mat[10]) {
  971. S = Math.sqrt(1.0 + mat[5] - mat[0] - mat[10]) * 2;
  972. out[3] = (mat[8] - mat[2]) / S;
  973. out[0] = (mat[1] + mat[4]) / S;
  974. out[1] = 0.25 * S;
  975. out[2] = (mat[6] + mat[9]) / S;
  976. } else {
  977. S = Math.sqrt(1.0 + mat[10] - mat[0] - mat[5]) * 2;
  978. out[3] = (mat[1] - mat[4]) / S;
  979. out[0] = (mat[8] + mat[2]) / S;
  980. out[1] = (mat[6] + mat[9]) / S;
  981. out[2] = 0.25 * S;
  982. }
  983. return out;
  984. }
  985. /**
  986. * Creates a matrix from a quaternion rotation, vector translation and vector scale
  987. * This is equivalent to (but much faster than):
  988. *
  989. * mat4.identity(dest);
  990. * mat4.translate(dest, vec);
  991. * let quatMat = mat4.create();
  992. * quat4.toMat4(quat, quatMat);
  993. * mat4.multiply(dest, quatMat);
  994. * mat4.scale(dest, scale)
  995. *
  996. * @param {mat4} out mat4 receiving operation result
  997. * @param {quat4} q Rotation quaternion
  998. * @param {vec3} v Translation vector
  999. * @param {vec3} s Scaling vector
  1000. * @returns {mat4} out
  1001. */
  1002. export function fromRotationTranslationScale(out, q, v, s) {
  1003. // Quaternion math
  1004. let x = q[0], y = q[1], z = q[2], w = q[3];
  1005. let x2 = x + x;
  1006. let y2 = y + y;
  1007. let z2 = z + z;
  1008. let xx = x * x2;
  1009. let xy = x * y2;
  1010. let xz = x * z2;
  1011. let yy = y * y2;
  1012. let yz = y * z2;
  1013. let zz = z * z2;
  1014. let wx = w * x2;
  1015. let wy = w * y2;
  1016. let wz = w * z2;
  1017. let sx = s[0];
  1018. let sy = s[1];
  1019. let sz = s[2];
  1020. out[0] = (1 - (yy + zz)) * sx;
  1021. out[1] = (xy + wz) * sx;
  1022. out[2] = (xz - wy) * sx;
  1023. out[3] = 0;
  1024. out[4] = (xy - wz) * sy;
  1025. out[5] = (1 - (xx + zz)) * sy;
  1026. out[6] = (yz + wx) * sy;
  1027. out[7] = 0;
  1028. out[8] = (xz + wy) * sz;
  1029. out[9] = (yz - wx) * sz;
  1030. out[10] = (1 - (xx + yy)) * sz;
  1031. out[11] = 0;
  1032. out[12] = v[0];
  1033. out[13] = v[1];
  1034. out[14] = v[2];
  1035. out[15] = 1;
  1036. return out;
  1037. }
  1038. /**
  1039. * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin
  1040. * This is equivalent to (but much faster than):
  1041. *
  1042. * mat4.identity(dest);
  1043. * mat4.translate(dest, vec);
  1044. * mat4.translate(dest, origin);
  1045. * let quatMat = mat4.create();
  1046. * quat4.toMat4(quat, quatMat);
  1047. * mat4.multiply(dest, quatMat);
  1048. * mat4.scale(dest, scale)
  1049. * mat4.translate(dest, negativeOrigin);
  1050. *
  1051. * @param {mat4} out mat4 receiving operation result
  1052. * @param {quat4} q Rotation quaternion
  1053. * @param {vec3} v Translation vector
  1054. * @param {vec3} s Scaling vector
  1055. * @param {vec3} o The origin vector around which to scale and rotate
  1056. * @returns {mat4} out
  1057. */
  1058. export function fromRotationTranslationScaleOrigin(out, q, v, s, o) {
  1059. // Quaternion math
  1060. let x = q[0], y = q[1], z = q[2], w = q[3];
  1061. let x2 = x + x;
  1062. let y2 = y + y;
  1063. let z2 = z + z;
  1064. let xx = x * x2;
  1065. let xy = x * y2;
  1066. let xz = x * z2;
  1067. let yy = y * y2;
  1068. let yz = y * z2;
  1069. let zz = z * z2;
  1070. let wx = w * x2;
  1071. let wy = w * y2;
  1072. let wz = w * z2;
  1073. let sx = s[0];
  1074. let sy = s[1];
  1075. let sz = s[2];
  1076. let ox = o[0];
  1077. let oy = o[1];
  1078. let oz = o[2];
  1079. let out0 = (1 - (yy + zz)) * sx;
  1080. let out1 = (xy + wz) * sx;
  1081. let out2 = (xz - wy) * sx;
  1082. let out4 = (xy - wz) * sy;
  1083. let out5 = (1 - (xx + zz)) * sy;
  1084. let out6 = (yz + wx) * sy;
  1085. let out8 = (xz + wy) * sz;
  1086. let out9 = (yz - wx) * sz;
  1087. let out10 = (1 - (xx + yy)) * sz;
  1088. out[0] = out0;
  1089. out[1] = out1;
  1090. out[2] = out2;
  1091. out[3] = 0;
  1092. out[4] = out4;
  1093. out[5] = out5;
  1094. out[6] = out6;
  1095. out[7] = 0;
  1096. out[8] = out8;
  1097. out[9] = out9;
  1098. out[10] = out10;
  1099. out[11] = 0;
  1100. out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);
  1101. out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);
  1102. out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);
  1103. out[15] = 1;
  1104. return out;
  1105. }
  1106. /**
  1107. * Calculates a 4x4 matrix from the given quaternion
  1108. *
  1109. * @param {mat4} out mat4 receiving operation result
  1110. * @param {quat} q Quaternion to create matrix from
  1111. *
  1112. * @returns {mat4} out
  1113. */
  1114. export function fromQuat(out, q) {
  1115. let x = q[0], y = q[1], z = q[2], w = q[3];
  1116. let x2 = x + x;
  1117. let y2 = y + y;
  1118. let z2 = z + z;
  1119. let xx = x * x2;
  1120. let yx = y * x2;
  1121. let yy = y * y2;
  1122. let zx = z * x2;
  1123. let zy = z * y2;
  1124. let zz = z * z2;
  1125. let wx = w * x2;
  1126. let wy = w * y2;
  1127. let wz = w * z2;
  1128. out[0] = 1 - yy - zz;
  1129. out[1] = yx + wz;
  1130. out[2] = zx - wy;
  1131. out[3] = 0;
  1132. out[4] = yx - wz;
  1133. out[5] = 1 - xx - zz;
  1134. out[6] = zy + wx;
  1135. out[7] = 0;
  1136. out[8] = zx + wy;
  1137. out[9] = zy - wx;
  1138. out[10] = 1 - xx - yy;
  1139. out[11] = 0;
  1140. out[12] = 0;
  1141. out[13] = 0;
  1142. out[14] = 0;
  1143. out[15] = 1;
  1144. return out;
  1145. }
  1146. /**
  1147. * Generates a frustum matrix with the given bounds
  1148. *
  1149. * @param {mat4} out mat4 frustum matrix will be written into
  1150. * @param {Number} left Left bound of the frustum
  1151. * @param {Number} right Right bound of the frustum
  1152. * @param {Number} bottom Bottom bound of the frustum
  1153. * @param {Number} top Top bound of the frustum
  1154. * @param {Number} near Near bound of the frustum
  1155. * @param {Number} far Far bound of the frustum
  1156. * @returns {mat4} out
  1157. */
  1158. export function frustum(out, left, right, bottom, top, near, far) {
  1159. let rl = 1 / (right - left);
  1160. let tb = 1 / (top - bottom);
  1161. let nf = 1 / (near - far);
  1162. out[0] = (near * 2) * rl;
  1163. out[1] = 0;
  1164. out[2] = 0;
  1165. out[3] = 0;
  1166. out[4] = 0;
  1167. out[5] = (near * 2) * tb;
  1168. out[6] = 0;
  1169. out[7] = 0;
  1170. out[8] = (right + left) * rl;
  1171. out[9] = (top + bottom) * tb;
  1172. out[10] = (far + near) * nf;
  1173. out[11] = -1;
  1174. out[12] = 0;
  1175. out[13] = 0;
  1176. out[14] = (far * near * 2) * nf;
  1177. out[15] = 0;
  1178. return out;
  1179. }
  1180. /**
  1181. * Generates a perspective projection matrix with the given bounds.
  1182. * Passing null/undefined/no value for far will generate infinite projection matrix.
  1183. *
  1184. * @param {mat4} out mat4 frustum matrix will be written into
  1185. * @param {number} fovy Vertical field of view in radians
  1186. * @param {number} aspect Aspect ratio. typically viewport width/height
  1187. * @param {number} near Near bound of the frustum
  1188. * @param {number} far Far bound of the frustum, can be null or Infinity
  1189. * @returns {mat4} out
  1190. */
  1191. export function perspective(out, fovy, aspect, near, far) {
  1192. let f = 1.0 / Math.tan(fovy / 2), nf;
  1193. out[0] = f / aspect;
  1194. out[1] = 0;
  1195. out[2] = 0;
  1196. out[3] = 0;
  1197. out[4] = 0;
  1198. out[5] = f;
  1199. out[6] = 0;
  1200. out[7] = 0;
  1201. out[8] = 0;
  1202. out[9] = 0;
  1203. out[11] = -1;
  1204. out[12] = 0;
  1205. out[13] = 0;
  1206. out[15] = 0;
  1207. if (far != null &amp;&amp; far !== Infinity) {
  1208. nf = 1 / (near - far);
  1209. out[10] = (far + near) * nf;
  1210. out[14] = (2 * far * near) * nf;
  1211. } else {
  1212. out[10] = -1;
  1213. out[14] = -2 * near;
  1214. }
  1215. return out;
  1216. }
  1217. /**
  1218. * Generates a perspective projection matrix with the given field of view.
  1219. * This is primarily useful for generating projection matrices to be used
  1220. * with the still experiemental WebVR API.
  1221. *
  1222. * @param {mat4} out mat4 frustum matrix will be written into
  1223. * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
  1224. * @param {number} near Near bound of the frustum
  1225. * @param {number} far Far bound of the frustum
  1226. * @returns {mat4} out
  1227. */
  1228. export function perspectiveFromFieldOfView(out, fov, near, far) {
  1229. let upTan = Math.tan(fov.upDegrees * Math.PI/180.0);
  1230. let downTan = Math.tan(fov.downDegrees * Math.PI/180.0);
  1231. let leftTan = Math.tan(fov.leftDegrees * Math.PI/180.0);
  1232. let rightTan = Math.tan(fov.rightDegrees * Math.PI/180.0);
  1233. let xScale = 2.0 / (leftTan + rightTan);
  1234. let yScale = 2.0 / (upTan + downTan);
  1235. out[0] = xScale;
  1236. out[1] = 0.0;
  1237. out[2] = 0.0;
  1238. out[3] = 0.0;
  1239. out[4] = 0.0;
  1240. out[5] = yScale;
  1241. out[6] = 0.0;
  1242. out[7] = 0.0;
  1243. out[8] = -((leftTan - rightTan) * xScale * 0.5);
  1244. out[9] = ((upTan - downTan) * yScale * 0.5);
  1245. out[10] = far / (near - far);
  1246. out[11] = -1.0;
  1247. out[12] = 0.0;
  1248. out[13] = 0.0;
  1249. out[14] = (far * near) / (near - far);
  1250. out[15] = 0.0;
  1251. return out;
  1252. }
  1253. /**
  1254. * Generates a orthogonal projection matrix with the given bounds
  1255. *
  1256. * @param {mat4} out mat4 frustum matrix will be written into
  1257. * @param {number} left Left bound of the frustum
  1258. * @param {number} right Right bound of the frustum
  1259. * @param {number} bottom Bottom bound of the frustum
  1260. * @param {number} top Top bound of the frustum
  1261. * @param {number} near Near bound of the frustum
  1262. * @param {number} far Far bound of the frustum
  1263. * @returns {mat4} out
  1264. */
  1265. export function ortho(out, left, right, bottom, top, near, far) {
  1266. let lr = 1 / (left - right);
  1267. let bt = 1 / (bottom - top);
  1268. let nf = 1 / (near - far);
  1269. out[0] = -2 * lr;
  1270. out[1] = 0;
  1271. out[2] = 0;
  1272. out[3] = 0;
  1273. out[4] = 0;
  1274. out[5] = -2 * bt;
  1275. out[6] = 0;
  1276. out[7] = 0;
  1277. out[8] = 0;
  1278. out[9] = 0;
  1279. out[10] = 2 * nf;
  1280. out[11] = 0;
  1281. out[12] = (left + right) * lr;
  1282. out[13] = (top + bottom) * bt;
  1283. out[14] = (far + near) * nf;
  1284. out[15] = 1;
  1285. return out;
  1286. }
  1287. /**
  1288. * Generates a look-at matrix with the given eye position, focal point, and up axis.
  1289. * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.
  1290. *
  1291. * @param {mat4} out mat4 frustum matrix will be written into
  1292. * @param {vec3} eye Position of the viewer
  1293. * @param {vec3} center Point the viewer is looking at
  1294. * @param {vec3} up vec3 pointing up
  1295. * @returns {mat4} out
  1296. */
  1297. export function lookAt(out, eye, center, up) {
  1298. let x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
  1299. let eyex = eye[0];
  1300. let eyey = eye[1];
  1301. let eyez = eye[2];
  1302. let upx = up[0];
  1303. let upy = up[1];
  1304. let upz = up[2];
  1305. let centerx = center[0];
  1306. let centery = center[1];
  1307. let centerz = center[2];
  1308. if (Math.abs(eyex - centerx) &lt; glMatrix.EPSILON &amp;&amp;
  1309. Math.abs(eyey - centery) &lt; glMatrix.EPSILON &amp;&amp;
  1310. Math.abs(eyez - centerz) &lt; glMatrix.EPSILON) {
  1311. return identity(out);
  1312. }
  1313. z0 = eyex - centerx;
  1314. z1 = eyey - centery;
  1315. z2 = eyez - centerz;
  1316. len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
  1317. z0 *= len;
  1318. z1 *= len;
  1319. z2 *= len;
  1320. x0 = upy * z2 - upz * z1;
  1321. x1 = upz * z0 - upx * z2;
  1322. x2 = upx * z1 - upy * z0;
  1323. len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
  1324. if (!len) {
  1325. x0 = 0;
  1326. x1 = 0;
  1327. x2 = 0;
  1328. } else {
  1329. len = 1 / len;
  1330. x0 *= len;
  1331. x1 *= len;
  1332. x2 *= len;
  1333. }
  1334. y0 = z1 * x2 - z2 * x1;
  1335. y1 = z2 * x0 - z0 * x2;
  1336. y2 = z0 * x1 - z1 * x0;
  1337. len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
  1338. if (!len) {
  1339. y0 = 0;
  1340. y1 = 0;
  1341. y2 = 0;
  1342. } else {
  1343. len = 1 / len;
  1344. y0 *= len;
  1345. y1 *= len;
  1346. y2 *= len;
  1347. }
  1348. out[0] = x0;
  1349. out[1] = y0;
  1350. out[2] = z0;
  1351. out[3] = 0;
  1352. out[4] = x1;
  1353. out[5] = y1;
  1354. out[6] = z1;
  1355. out[7] = 0;
  1356. out[8] = x2;
  1357. out[9] = y2;
  1358. out[10] = z2;
  1359. out[11] = 0;
  1360. out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
  1361. out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
  1362. out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
  1363. out[15] = 1;
  1364. return out;
  1365. }
  1366. /**
  1367. * Generates a matrix that makes something look at something else.
  1368. *
  1369. * @param {mat4} out mat4 frustum matrix will be written into
  1370. * @param {vec3} eye Position of the viewer
  1371. * @param {vec3} center Point the viewer is looking at
  1372. * @param {vec3} up vec3 pointing up
  1373. * @returns {mat4} out
  1374. */
  1375. export function targetTo(out, eye, target, up) {
  1376. let eyex = eye[0],
  1377. eyey = eye[1],
  1378. eyez = eye[2],
  1379. upx = up[0],
  1380. upy = up[1],
  1381. upz = up[2];
  1382. let z0 = eyex - target[0],
  1383. z1 = eyey - target[1],
  1384. z2 = eyez - target[2];
  1385. let len = z0*z0 + z1*z1 + z2*z2;
  1386. if (len > 0) {
  1387. len = 1 / Math.sqrt(len);
  1388. z0 *= len;
  1389. z1 *= len;
  1390. z2 *= len;
  1391. }
  1392. let x0 = upy * z2 - upz * z1,
  1393. x1 = upz * z0 - upx * z2,
  1394. x2 = upx * z1 - upy * z0;
  1395. len = x0*x0 + x1*x1 + x2*x2;
  1396. if (len > 0) {
  1397. len = 1 / Math.sqrt(len);
  1398. x0 *= len;
  1399. x1 *= len;
  1400. x2 *= len;
  1401. }
  1402. out[0] = x0;
  1403. out[1] = x1;
  1404. out[2] = x2;
  1405. out[3] = 0;
  1406. out[4] = z1 * x2 - z2 * x1;
  1407. out[5] = z2 * x0 - z0 * x2;
  1408. out[6] = z0 * x1 - z1 * x0;
  1409. out[7] = 0;
  1410. out[8] = z0;
  1411. out[9] = z1;
  1412. out[10] = z2;
  1413. out[11] = 0;
  1414. out[12] = eyex;
  1415. out[13] = eyey;
  1416. out[14] = eyez;
  1417. out[15] = 1;
  1418. return out;
  1419. };
  1420. /**
  1421. * Returns a string representation of a mat4
  1422. *
  1423. * @param {mat4} a matrix to represent as a string
  1424. * @returns {String} string representation of the matrix
  1425. */
  1426. export function str(a) {
  1427. return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' +
  1428. a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' +
  1429. a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' +
  1430. a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
  1431. }
  1432. /**
  1433. * Returns Frobenius norm of a mat4
  1434. *
  1435. * @param {mat4} a the matrix to calculate Frobenius norm of
  1436. * @returns {Number} Frobenius norm
  1437. */
  1438. export function frob(a) {
  1439. return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) ))
  1440. }
  1441. /**
  1442. * Adds two mat4's
  1443. *
  1444. * @param {mat4} out the receiving matrix
  1445. * @param {mat4} a the first operand
  1446. * @param {mat4} b the second operand
  1447. * @returns {mat4} out
  1448. */
  1449. export function add(out, a, b) {
  1450. out[0] = a[0] + b[0];
  1451. out[1] = a[1] + b[1];
  1452. out[2] = a[2] + b[2];
  1453. out[3] = a[3] + b[3];
  1454. out[4] = a[4] + b[4];
  1455. out[5] = a[5] + b[5];
  1456. out[6] = a[6] + b[6];
  1457. out[7] = a[7] + b[7];
  1458. out[8] = a[8] + b[8];
  1459. out[9] = a[9] + b[9];
  1460. out[10] = a[10] + b[10];
  1461. out[11] = a[11] + b[11];
  1462. out[12] = a[12] + b[12];
  1463. out[13] = a[13] + b[13];
  1464. out[14] = a[14] + b[14];
  1465. out[15] = a[15] + b[15];
  1466. return out;
  1467. }
  1468. /**
  1469. * Subtracts matrix b from matrix a
  1470. *
  1471. * @param {mat4} out the receiving matrix
  1472. * @param {mat4} a the first operand
  1473. * @param {mat4} b the second operand
  1474. * @returns {mat4} out
  1475. */
  1476. export function subtract(out, a, b) {
  1477. out[0] = a[0] - b[0];
  1478. out[1] = a[1] - b[1];
  1479. out[2] = a[2] - b[2];
  1480. out[3] = a[3] - b[3];
  1481. out[4] = a[4] - b[4];
  1482. out[5] = a[5] - b[5];
  1483. out[6] = a[6] - b[6];
  1484. out[7] = a[7] - b[7];
  1485. out[8] = a[8] - b[8];
  1486. out[9] = a[9] - b[9];
  1487. out[10] = a[10] - b[10];
  1488. out[11] = a[11] - b[11];
  1489. out[12] = a[12] - b[12];
  1490. out[13] = a[13] - b[13];
  1491. out[14] = a[14] - b[14];
  1492. out[15] = a[15] - b[15];
  1493. return out;
  1494. }
  1495. /**
  1496. * Multiply each element of the matrix by a scalar.
  1497. *
  1498. * @param {mat4} out the receiving matrix
  1499. * @param {mat4} a the matrix to scale
  1500. * @param {Number} b amount to scale the matrix's elements by
  1501. * @returns {mat4} out
  1502. */
  1503. export function multiplyScalar(out, a, b) {
  1504. out[0] = a[0] * b;
  1505. out[1] = a[1] * b;
  1506. out[2] = a[2] * b;
  1507. out[3] = a[3] * b;
  1508. out[4] = a[4] * b;
  1509. out[5] = a[5] * b;
  1510. out[6] = a[6] * b;
  1511. out[7] = a[7] * b;
  1512. out[8] = a[8] * b;
  1513. out[9] = a[9] * b;
  1514. out[10] = a[10] * b;
  1515. out[11] = a[11] * b;
  1516. out[12] = a[12] * b;
  1517. out[13] = a[13] * b;
  1518. out[14] = a[14] * b;
  1519. out[15] = a[15] * b;
  1520. return out;
  1521. }
  1522. /**
  1523. * Adds two mat4's after multiplying each element of the second operand by a scalar value.
  1524. *
  1525. * @param {mat4} out the receiving vector
  1526. * @param {mat4} a the first operand
  1527. * @param {mat4} b the second operand
  1528. * @param {Number} scale the amount to scale b's elements by before adding
  1529. * @returns {mat4} out
  1530. */
  1531. export function multiplyScalarAndAdd(out, a, b, scale) {
  1532. out[0] = a[0] + (b[0] * scale);
  1533. out[1] = a[1] + (b[1] * scale);
  1534. out[2] = a[2] + (b[2] * scale);
  1535. out[3] = a[3] + (b[3] * scale);
  1536. out[4] = a[4] + (b[4] * scale);
  1537. out[5] = a[5] + (b[5] * scale);
  1538. out[6] = a[6] + (b[6] * scale);
  1539. out[7] = a[7] + (b[7] * scale);
  1540. out[8] = a[8] + (b[8] * scale);
  1541. out[9] = a[9] + (b[9] * scale);
  1542. out[10] = a[10] + (b[10] * scale);
  1543. out[11] = a[11] + (b[11] * scale);
  1544. out[12] = a[12] + (b[12] * scale);
  1545. out[13] = a[13] + (b[13] * scale);
  1546. out[14] = a[14] + (b[14] * scale);
  1547. out[15] = a[15] + (b[15] * scale);
  1548. return out;
  1549. }
  1550. /**
  1551. * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
  1552. *
  1553. * @param {mat4} a The first matrix.
  1554. * @param {mat4} b The second matrix.
  1555. * @returns {Boolean} True if the matrices are equal, false otherwise.
  1556. */
  1557. export function exactEquals(a, b) {
  1558. return a[0] === b[0] &amp;&amp; a[1] === b[1] &amp;&amp; a[2] === b[2] &amp;&amp; a[3] === b[3] &amp;&amp;
  1559. a[4] === b[4] &amp;&amp; a[5] === b[5] &amp;&amp; a[6] === b[6] &amp;&amp; a[7] === b[7] &amp;&amp;
  1560. a[8] === b[8] &amp;&amp; a[9] === b[9] &amp;&amp; a[10] === b[10] &amp;&amp; a[11] === b[11] &amp;&amp;
  1561. a[12] === b[12] &amp;&amp; a[13] === b[13] &amp;&amp; a[14] === b[14] &amp;&amp; a[15] === b[15];
  1562. }
  1563. /**
  1564. * Returns whether or not the matrices have approximately the same elements in the same position.
  1565. *
  1566. * @param {mat4} a The first matrix.
  1567. * @param {mat4} b The second matrix.
  1568. * @returns {Boolean} True if the matrices are equal, false otherwise.
  1569. */
  1570. export function equals(a, b) {
  1571. let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
  1572. let a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7];
  1573. let a8 = a[8], a9 = a[9], a10 = a[10], a11 = a[11];
  1574. let a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15];
  1575. let b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
  1576. let b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7];
  1577. let b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11];
  1578. let b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
  1579. return (Math.abs(a0 - b0) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) &amp;&amp;
  1580. Math.abs(a1 - b1) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) &amp;&amp;
  1581. Math.abs(a2 - b2) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) &amp;&amp;
  1582. Math.abs(a3 - b3) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3)) &amp;&amp;
  1583. Math.abs(a4 - b4) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a4), Math.abs(b4)) &amp;&amp;
  1584. Math.abs(a5 - b5) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a5), Math.abs(b5)) &amp;&amp;
  1585. Math.abs(a6 - b6) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a6), Math.abs(b6)) &amp;&amp;
  1586. Math.abs(a7 - b7) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a7), Math.abs(b7)) &amp;&amp;
  1587. Math.abs(a8 - b8) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a8), Math.abs(b8)) &amp;&amp;
  1588. Math.abs(a9 - b9) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a9), Math.abs(b9)) &amp;&amp;
  1589. Math.abs(a10 - b10) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a10), Math.abs(b10)) &amp;&amp;
  1590. Math.abs(a11 - b11) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a11), Math.abs(b11)) &amp;&amp;
  1591. Math.abs(a12 - b12) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a12), Math.abs(b12)) &amp;&amp;
  1592. Math.abs(a13 - b13) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a13), Math.abs(b13)) &amp;&amp;
  1593. Math.abs(a14 - b14) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a14), Math.abs(b14)) &amp;&amp;
  1594. Math.abs(a15 - b15) &lt;= glMatrix.EPSILON*Math.max(1.0, Math.abs(a15), Math.abs(b15)));
  1595. }
  1596. /**
  1597. * Alias for {@link mat4.multiply}
  1598. * @function
  1599. */
  1600. export const mul = multiply;
  1601. /**
  1602. * Alias for {@link mat4.subtract}
  1603. * @function
  1604. */
  1605. export const sub = subtract;
  1606. </code></pre>
  1607. </article>
  1608. </section>
  1609. </div>
  1610. <nav>
  1611. <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-glMatrix.html">glMatrix</a></li><li><a href="module-mat2.html">mat2</a></li><li><a href="module-mat2d.html">mat2d</a></li><li><a href="module-mat3.html">mat3</a></li><li><a href="module-mat4.html">mat4</a></li><li><a href="module-quat.html">quat</a></li><li><a href="module-quat2.html">quat2</a></li><li><a href="module-vec2.html">vec2</a></li><li><a href="module-vec3.html">vec3</a></li><li><a href="module-vec4.html">vec4</a></li></ul>
  1612. </nav>
  1613. <br class="clear">
  1614. <footer>
  1615. Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Jul 13 2018 11:51:33 GMT+0200 (W. Europe Daylight Time)
  1616. </footer>
  1617. <script> prettyPrint(); </script>
  1618. <script src="scripts/linenumber.js"> </script>
  1619. </body>
  1620. </html>