math 0.0.3 → 0.1.0

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