lecodes-cli 0.1.1 → 0.1.2

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