action-engine-js 1.0.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 (93) hide show
  1. package/LICENSE +45 -0
  2. package/README.md +348 -0
  3. package/actionengine/3rdparty/goblin/goblin.js +9609 -0
  4. package/actionengine/3rdparty/goblin/goblin.min.js +5 -0
  5. package/actionengine/camera/actioncamera.js +90 -0
  6. package/actionengine/camera/cameracollisionhandler.js +69 -0
  7. package/actionengine/character/actioncharacter.js +360 -0
  8. package/actionengine/character/actioncharacter3D.js +61 -0
  9. package/actionengine/core/app.js +430 -0
  10. package/actionengine/debug/basedebugpanel.js +858 -0
  11. package/actionengine/display/canvasmanager.js +75 -0
  12. package/actionengine/display/gl/programmanager.js +570 -0
  13. package/actionengine/display/gl/shaders/lineshader.js +118 -0
  14. package/actionengine/display/gl/shaders/objectshader.js +1756 -0
  15. package/actionengine/display/gl/shaders/particleshader.js +43 -0
  16. package/actionengine/display/gl/shaders/shadowshader.js +319 -0
  17. package/actionengine/display/gl/shaders/spriteshader.js +100 -0
  18. package/actionengine/display/gl/shaders/watershader.js +67 -0
  19. package/actionengine/display/graphics/actionmodel3D.js +191 -0
  20. package/actionengine/display/graphics/actionsprite3D.js +230 -0
  21. package/actionengine/display/graphics/lighting/actiondirectionalshadowlight.js +864 -0
  22. package/actionengine/display/graphics/lighting/actionlight.js +211 -0
  23. package/actionengine/display/graphics/lighting/actionomnidirectionalshadowlight.js +862 -0
  24. package/actionengine/display/graphics/lighting/lightingconstants.js +263 -0
  25. package/actionengine/display/graphics/lighting/lightmanager.js +789 -0
  26. package/actionengine/display/graphics/renderableobject.js +44 -0
  27. package/actionengine/display/graphics/renderers/actionrenderer2D.js +341 -0
  28. package/actionengine/display/graphics/renderers/actionrenderer3D/actionrenderer3D.js +655 -0
  29. package/actionengine/display/graphics/renderers/actionrenderer3D/canvasmanager3D.js +82 -0
  30. package/actionengine/display/graphics/renderers/actionrenderer3D/debugrenderer3D.js +493 -0
  31. package/actionengine/display/graphics/renderers/actionrenderer3D/objectrenderer3D.js +790 -0
  32. package/actionengine/display/graphics/renderers/actionrenderer3D/spriteRenderer3D.js +266 -0
  33. package/actionengine/display/graphics/renderers/actionrenderer3D/sunrenderer3D.js +140 -0
  34. package/actionengine/display/graphics/renderers/actionrenderer3D/waterrenderer3D.js +173 -0
  35. package/actionengine/display/graphics/renderers/actionrenderer3D/weatherrenderer3D.js +87 -0
  36. package/actionengine/display/graphics/texture/proceduraltexture.js +192 -0
  37. package/actionengine/display/graphics/texture/texturemanager.js +242 -0
  38. package/actionengine/display/graphics/texture/textureregistry.js +177 -0
  39. package/actionengine/input/actionscrollablearea.js +1405 -0
  40. package/actionengine/input/inputhandler.js +1647 -0
  41. package/actionengine/math/geometry/geometrybuilder.js +161 -0
  42. package/actionengine/math/geometry/glbexporter.js +364 -0
  43. package/actionengine/math/geometry/glbloader.js +722 -0
  44. package/actionengine/math/geometry/modelcodegenerator.js +97 -0
  45. package/actionengine/math/geometry/triangle.js +33 -0
  46. package/actionengine/math/geometry/triangleutils.js +34 -0
  47. package/actionengine/math/mathutils.js +25 -0
  48. package/actionengine/math/matrix4.js +785 -0
  49. package/actionengine/math/physics/actionphysics.js +108 -0
  50. package/actionengine/math/physics/actionphysicsobject3D.js +164 -0
  51. package/actionengine/math/physics/actionphysicsworld3D.js +238 -0
  52. package/actionengine/math/physics/actionraycast.js +129 -0
  53. package/actionengine/math/physics/shapes/actionphysicsbox3D.js +158 -0
  54. package/actionengine/math/physics/shapes/actionphysicscapsule3D.js +200 -0
  55. package/actionengine/math/physics/shapes/actionphysicscompoundshape3D.js +147 -0
  56. package/actionengine/math/physics/shapes/actionphysicscone3D.js +126 -0
  57. package/actionengine/math/physics/shapes/actionphysicsconvexshape3D.js +72 -0
  58. package/actionengine/math/physics/shapes/actionphysicscylinder3D.js +117 -0
  59. package/actionengine/math/physics/shapes/actionphysicsmesh3D.js +74 -0
  60. package/actionengine/math/physics/shapes/actionphysicsplane3D.js +100 -0
  61. package/actionengine/math/physics/shapes/actionphysicssphere3D.js +95 -0
  62. package/actionengine/math/quaternion.js +61 -0
  63. package/actionengine/math/vector2.js +277 -0
  64. package/actionengine/math/vector3.js +318 -0
  65. package/actionengine/math/viewfrustum.js +136 -0
  66. package/actionengine/network/ACTIONNETREADME.md +810 -0
  67. package/actionengine/network/client/ActionNetManager.js +802 -0
  68. package/actionengine/network/client/ActionNetManagerGUI.js +1709 -0
  69. package/actionengine/network/client/ActionNetManagerP2P.js +1537 -0
  70. package/actionengine/network/client/SyncSystem.js +422 -0
  71. package/actionengine/network/p2p/ActionNetPeer.js +142 -0
  72. package/actionengine/network/p2p/ActionNetTrackerClient.js +623 -0
  73. package/actionengine/network/p2p/DataConnection.js +282 -0
  74. package/actionengine/network/p2p/README.md +510 -0
  75. package/actionengine/network/p2p/example.html +502 -0
  76. package/actionengine/network/server/ActionNetServer.js +577 -0
  77. package/actionengine/network/server/ActionNetServerSSL.js +579 -0
  78. package/actionengine/network/server/ActionNetServerUtils.js +458 -0
  79. package/actionengine/network/server/SERVERREADME.md +314 -0
  80. package/actionengine/network/server/package-lock.json +35 -0
  81. package/actionengine/network/server/package.json +13 -0
  82. package/actionengine/network/server/start.bat +27 -0
  83. package/actionengine/network/server/start.sh +25 -0
  84. package/actionengine/network/server/startwss.bat +27 -0
  85. package/actionengine/sound/audiomanager.js +1589 -0
  86. package/actionengine/sound/soundfont/ACTIONSOUNDFONT_README.md +205 -0
  87. package/actionengine/sound/soundfont/actionparser.js +718 -0
  88. package/actionengine/sound/soundfont/actionreverb.js +252 -0
  89. package/actionengine/sound/soundfont/actionsoundfont.js +543 -0
  90. package/actionengine/sound/soundfont/sf2playerlicence.txt +29 -0
  91. package/actionengine/sound/soundfont/soundfont.js +2 -0
  92. package/dist/action-engine.min.js +328 -0
  93. package/package.json +35 -0
@@ -0,0 +1,785 @@
1
+ // actionengine/math/matrix4.js
2
+ class Matrix4 {
3
+ static create() {
4
+ return new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
5
+ }
6
+
7
+ static identity(out) {
8
+ out[0] = 1;
9
+ out[1] = 0;
10
+ out[2] = 0;
11
+ out[3] = 0;
12
+ out[4] = 0;
13
+ out[5] = 1;
14
+ out[6] = 0;
15
+ out[7] = 0;
16
+ out[8] = 0;
17
+ out[9] = 0;
18
+ out[10] = 1;
19
+ out[11] = 0;
20
+ out[12] = 0;
21
+ out[13] = 0;
22
+ out[14] = 0;
23
+ out[15] = 1;
24
+ return out;
25
+ }
26
+ /**
27
+ * Multiply a vector by a matrix
28
+ * @param {Array} out - Output vector (will be modified)
29
+ * @param {Array|Float32Array} matrix - 4x4 matrix
30
+ * @param {Array} vec - Input vector [x, y, z, w]
31
+ * @returns {Array} - The output vector
32
+ */
33
+ static multiplyVector(out, matrix, vec) {
34
+ const x = vec[0];
35
+ const y = vec[1];
36
+ const z = vec[2];
37
+ const w = vec[3] || 1.0;
38
+
39
+ out[0] = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12] * w;
40
+ out[1] = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13] * w;
41
+ out[2] = matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14] * w;
42
+ out[3] = matrix[3] * x + matrix[7] * y + matrix[11] * z + matrix[15] * w;
43
+
44
+ return out;
45
+ }
46
+
47
+ static transformVector(vector, viewMatrix, projectionMatrix) {
48
+ // First multiply by view matrix
49
+ const viewResult = [0, 0, 0, 0];
50
+ for (let i = 0; i < 4; i++) {
51
+ viewResult[i] =
52
+ vector[0] * viewMatrix[i] +
53
+ vector[1] * viewMatrix[i + 4] +
54
+ vector[2] * viewMatrix[i + 8] +
55
+ vector[3] * viewMatrix[i + 12];
56
+ }
57
+
58
+ // Then multiply by projection matrix
59
+ const result = [0, 0, 0, 0];
60
+ for (let i = 0; i < 4; i++) {
61
+ result[i] =
62
+ viewResult[0] * projectionMatrix[i] +
63
+ viewResult[1] * projectionMatrix[i + 4] +
64
+ viewResult[2] * projectionMatrix[i + 8] +
65
+ viewResult[3] * projectionMatrix[i + 12];
66
+ }
67
+
68
+ return result;
69
+ }
70
+ static fromQuat(out, q) {
71
+ const x = q.x,
72
+ y = q.y,
73
+ z = q.z,
74
+ w = q.w;
75
+ const x2 = x + x,
76
+ y2 = y + y,
77
+ z2 = z + z;
78
+ const xx = x * x2,
79
+ xy = x * y2,
80
+ xz = x * z2;
81
+ const yy = y * y2,
82
+ yz = y * z2,
83
+ zz = z * z2;
84
+ const wx = w * x2,
85
+ wy = w * y2,
86
+ wz = w * z2;
87
+
88
+ out[0] = 1 - (yy + zz);
89
+ out[1] = xy + wz;
90
+ out[2] = xz - wy;
91
+ out[3] = 0;
92
+
93
+ out[4] = xy - wz;
94
+ out[5] = 1 - (xx + zz);
95
+ out[6] = yz + wx;
96
+ out[7] = 0;
97
+
98
+ out[8] = xz + wy;
99
+ out[9] = yz - wx;
100
+ out[10] = 1 - (xx + yy);
101
+ out[11] = 0;
102
+
103
+ out[12] = 0;
104
+ out[13] = 0;
105
+ out[14] = 0;
106
+ out[15] = 1;
107
+
108
+ return out;
109
+ }
110
+
111
+ static fromLightDirection(out, dir) {
112
+ // Make sure the direction is normalized
113
+ const nx = dir.x;
114
+ const ny = dir.y;
115
+ const nz = dir.z;
116
+
117
+ // Find a perpendicular vector for the "right" direction
118
+ // Using world-up (0,1,0) as a reference
119
+ const right = [
120
+ nz, // Cross product of dir with (0,1,0)
121
+ 0,
122
+ -nx
123
+ ];
124
+
125
+ // Normalize right vector
126
+ const rLength = Math.sqrt(right[0] * right[0] + right[2] * right[2]);
127
+ right[0] /= rLength;
128
+ right[2] /= rLength;
129
+
130
+ // Get up vector by crossing right with direction
131
+ const up = [
132
+ -nx * ny, // Cross product of right with dir
133
+ nx * nx + nz * nz,
134
+ -ny * nz
135
+ ];
136
+
137
+ // Build the view matrix
138
+ out[0] = right[0];
139
+ out[1] = up[0];
140
+ out[2] = nx;
141
+ out[3] = 0;
142
+
143
+ out[4] = right[1];
144
+ out[5] = up[1];
145
+ out[6] = ny;
146
+ out[7] = 0;
147
+
148
+ out[8] = right[2];
149
+ out[9] = up[2];
150
+ out[10] = nz;
151
+ out[11] = 0;
152
+
153
+ out[12] = 0;
154
+ out[13] = 0;
155
+ out[14] = 0;
156
+ out[15] = 1;
157
+
158
+ return out;
159
+ }
160
+ static copy(out, a) {
161
+ out[0] = a[0];
162
+ out[1] = a[1];
163
+ out[2] = a[2];
164
+ out[3] = a[3];
165
+ out[4] = a[4];
166
+ out[5] = a[5];
167
+ out[6] = a[6];
168
+ out[7] = a[7];
169
+ out[8] = a[8];
170
+ out[9] = a[9];
171
+ out[10] = a[10];
172
+ out[11] = a[11];
173
+ out[12] = a[12];
174
+ out[13] = a[13];
175
+ out[14] = a[14];
176
+ out[15] = a[15];
177
+ return out;
178
+ }
179
+
180
+ static multiply(out, a, b) {
181
+ const a00 = a[0],
182
+ a01 = a[1],
183
+ a02 = a[2],
184
+ a03 = a[3];
185
+ const a10 = a[4],
186
+ a11 = a[5],
187
+ a12 = a[6],
188
+ a13 = a[7];
189
+ const a20 = a[8],
190
+ a21 = a[9],
191
+ a22 = a[10],
192
+ a23 = a[11];
193
+ const a30 = a[12],
194
+ a31 = a[13],
195
+ a32 = a[14],
196
+ a33 = a[15];
197
+
198
+ let b0 = b[0],
199
+ b1 = b[1],
200
+ b2 = b[2],
201
+ b3 = b[3];
202
+ out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
203
+ out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
204
+ out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
205
+ out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
206
+
207
+ b0 = b[4];
208
+ b1 = b[5];
209
+ b2 = b[6];
210
+ b3 = b[7];
211
+ out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
212
+ out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
213
+ out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
214
+ out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
215
+
216
+ b0 = b[8];
217
+ b1 = b[9];
218
+ b2 = b[10];
219
+ b3 = b[11];
220
+ out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
221
+ out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
222
+ out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
223
+ out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
224
+
225
+ b0 = b[12];
226
+ b1 = b[13];
227
+ b2 = b[14];
228
+ b3 = b[15];
229
+ out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
230
+ out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
231
+ out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
232
+ out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
233
+ return out;
234
+ }
235
+ static fromRotationTranslation(out, q, v) {
236
+ // Similar to his code but using our Quaternion class
237
+ const x = q.x,
238
+ y = q.y,
239
+ z = q.z,
240
+ w = q.w;
241
+ const x2 = x + x;
242
+ const y2 = y + y;
243
+ const z2 = z + z;
244
+
245
+ const xx = x * x2;
246
+ const xy = x * y2;
247
+ const xz = x * z2;
248
+ const yy = y * y2;
249
+ const yz = y * z2;
250
+ const zz = z * z2;
251
+ const wx = w * x2;
252
+ const wy = w * y2;
253
+ const wz = w * z2;
254
+
255
+ out[0] = 1 - (yy + zz);
256
+ out[1] = xy + wz;
257
+ out[2] = xz - wy;
258
+ out[3] = 0;
259
+ out[4] = xy - wz;
260
+ out[5] = 1 - (xx + zz);
261
+ out[6] = yz + wx;
262
+ out[7] = 0;
263
+ out[8] = xz + wy;
264
+ out[9] = yz - wx;
265
+ out[10] = 1 - (xx + yy);
266
+ out[11] = 0;
267
+ out[12] = v.x;
268
+ out[13] = v.y;
269
+ out[14] = v.z;
270
+ out[15] = 1;
271
+ return out;
272
+ }
273
+
274
+ static transformVertex(vertex, modelMatrix) {
275
+ const v = [vertex.x, vertex.y, vertex.z, 1];
276
+ const result = [0, 0, 0, 0];
277
+
278
+ for (let i = 0; i < 4; i++) {
279
+ result[i] =
280
+ v[0] * modelMatrix[i] +
281
+ v[1] * modelMatrix[i + 4] +
282
+ v[2] * modelMatrix[i + 8] +
283
+ v[3] * modelMatrix[i + 12];
284
+ }
285
+
286
+ return new Vector3(result[0] / result[3], result[1] / result[3], result[2] / result[3]);
287
+ }
288
+
289
+ static transformNormal(normal, modelMatrix) {
290
+ // Calculate inverse transpose of 3x3 portion of model matrix
291
+ const a = modelMatrix[0],
292
+ b = modelMatrix[1],
293
+ c = modelMatrix[2],
294
+ d = modelMatrix[4],
295
+ e = modelMatrix[5],
296
+ f = modelMatrix[6],
297
+ g = modelMatrix[8],
298
+ h = modelMatrix[9],
299
+ i = modelMatrix[10];
300
+
301
+ const det = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
302
+ const invdet = 1.0 / det;
303
+
304
+ const invTranspose = [
305
+ (e * i - f * h) * invdet,
306
+ (c * h - b * i) * invdet,
307
+ (b * f - c * e) * invdet,
308
+ (f * g - d * i) * invdet,
309
+ (a * i - c * g) * invdet,
310
+ (c * d - a * f) * invdet,
311
+ (d * h - e * g) * invdet,
312
+ (b * g - a * h) * invdet,
313
+ (a * e - b * d) * invdet
314
+ ];
315
+
316
+ const x = normal.x * invTranspose[0] + normal.y * invTranspose[1] + normal.z * invTranspose[2];
317
+ const y = normal.x * invTranspose[3] + normal.y * invTranspose[4] + normal.z * invTranspose[5];
318
+ const z = normal.x * invTranspose[6] + normal.y * invTranspose[7] + normal.z * invTranspose[8];
319
+
320
+ return new Vector3(x, y, z).normalize();
321
+ }
322
+ static perspective(out, fovy, aspect, near, far) {
323
+ const f = 1.0 / Math.tan(fovy / 2);
324
+ out[0] = f / aspect;
325
+ out[1] = 0;
326
+ out[2] = 0;
327
+ out[3] = 0;
328
+ out[4] = 0;
329
+ out[5] = f;
330
+ out[6] = 0;
331
+ out[7] = 0;
332
+ out[8] = 0;
333
+ out[9] = 0;
334
+ out[10] = (far + near) / (near - far);
335
+ out[11] = -1;
336
+ out[12] = 0;
337
+ out[13] = 0;
338
+ out[14] = (2 * far * near) / (near - far);
339
+ out[15] = 0;
340
+ return out;
341
+ }
342
+
343
+ static ortho(out, left, right, bottom, top, near, far) {
344
+ const lr = 1 / (left - right);
345
+ const bt = 1 / (bottom - top);
346
+ const nf = 1 / (near - far);
347
+ out[0] = -2 * lr;
348
+ out[1] = 0;
349
+ out[2] = 0;
350
+ out[3] = 0;
351
+ out[4] = 0;
352
+ out[5] = -2 * bt;
353
+ out[6] = 0;
354
+ out[7] = 0;
355
+ out[8] = 0;
356
+ out[9] = 0;
357
+ out[10] = 2 * nf;
358
+ out[11] = 0;
359
+ out[12] = (left + right) * lr;
360
+ out[13] = (top + bottom) * bt;
361
+ out[14] = (far + near) * nf;
362
+ out[15] = 1;
363
+ return out;
364
+ }
365
+
366
+ static translate(out, a, v) {
367
+ const x = v[0],
368
+ y = v[1],
369
+ z = v[2];
370
+
371
+ if (a !== out) {
372
+ out[0] = a[0];
373
+ out[1] = a[1];
374
+ out[2] = a[2];
375
+ out[3] = a[3];
376
+ out[4] = a[4];
377
+ out[5] = a[5];
378
+ out[6] = a[6];
379
+ out[7] = a[7];
380
+ out[8] = a[8];
381
+ out[9] = a[9];
382
+ out[10] = a[10];
383
+ out[11] = a[11];
384
+ }
385
+
386
+ out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
387
+ out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
388
+ out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
389
+ out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
390
+
391
+ return out;
392
+ }
393
+
394
+ static rotate(out, a, rad, axis) {
395
+ let x = axis[0],
396
+ y = axis[1],
397
+ z = axis[2];
398
+
399
+ let len = Math.hypot(x, y, z);
400
+ if (len < 0.000001) {
401
+ return null;
402
+ }
403
+ len = 1 / len;
404
+ x *= len;
405
+ y *= len;
406
+ z *= len;
407
+
408
+ const s = Math.sin(rad);
409
+ const c = Math.cos(rad);
410
+ const t = 1 - c;
411
+
412
+ const a00 = a[0],
413
+ a01 = a[1],
414
+ a02 = a[2],
415
+ a03 = a[3];
416
+ const a10 = a[4],
417
+ a11 = a[5],
418
+ a12 = a[6],
419
+ a13 = a[7];
420
+ const a20 = a[8],
421
+ a21 = a[9],
422
+ a22 = a[10],
423
+ a23 = a[11];
424
+
425
+ const b00 = x * x * t + c;
426
+ const b01 = y * x * t + z * s;
427
+ const b02 = z * x * t - y * s;
428
+ const b10 = x * y * t - z * s;
429
+ const b11 = y * y * t + c;
430
+ const b12 = z * y * t + x * s;
431
+ const b20 = x * z * t + y * s;
432
+ const b21 = y * z * t - x * s;
433
+ const b22 = z * z * t + c;
434
+
435
+ out[0] = a00 * b00 + a10 * b01 + a20 * b02;
436
+ out[1] = a01 * b00 + a11 * b01 + a21 * b02;
437
+ out[2] = a02 * b00 + a12 * b01 + a22 * b02;
438
+ out[3] = a03 * b00 + a13 * b01 + a23 * b02;
439
+ out[4] = a00 * b10 + a10 * b11 + a20 * b12;
440
+ out[5] = a01 * b10 + a11 * b11 + a21 * b12;
441
+ out[6] = a02 * b10 + a12 * b11 + a22 * b12;
442
+ out[7] = a03 * b10 + a13 * b11 + a23 * b12;
443
+ out[8] = a00 * b20 + a10 * b21 + a20 * b22;
444
+ out[9] = a01 * b20 + a11 * b21 + a21 * b22;
445
+ out[10] = a02 * b20 + a12 * b21 + a22 * b22;
446
+ out[11] = a03 * b20 + a13 * b21 + a23 * b22;
447
+
448
+ if (a !== out) {
449
+ out[12] = a[12];
450
+ out[13] = a[13];
451
+ out[14] = a[14];
452
+ out[15] = a[15];
453
+ }
454
+ return out;
455
+ }
456
+
457
+ static scale(out, a, v) {
458
+ const x = v[0],
459
+ y = v[1],
460
+ z = v[2];
461
+ out[0] = a[0] * x;
462
+ out[1] = a[1] * x;
463
+ out[2] = a[2] * x;
464
+ out[3] = a[3] * x;
465
+ out[4] = a[4] * y;
466
+ out[5] = a[5] * y;
467
+ out[6] = a[6] * y;
468
+ out[7] = a[7] * y;
469
+ out[8] = a[8] * z;
470
+ out[9] = a[9] * z;
471
+ out[10] = a[10] * z;
472
+ out[11] = a[11] * z;
473
+ out[12] = a[12];
474
+ out[13] = a[13];
475
+ out[14] = a[14];
476
+ out[15] = a[15];
477
+ return out;
478
+ }
479
+
480
+ static invert(out, a) {
481
+ const a00 = a[0],
482
+ a01 = a[1],
483
+ a02 = a[2],
484
+ a03 = a[3];
485
+ const a10 = a[4],
486
+ a11 = a[5],
487
+ a12 = a[6],
488
+ a13 = a[7];
489
+ const a20 = a[8],
490
+ a21 = a[9],
491
+ a22 = a[10],
492
+ a23 = a[11];
493
+ const a30 = a[12],
494
+ a31 = a[13],
495
+ a32 = a[14],
496
+ a33 = a[15];
497
+
498
+ const b00 = a00 * a11 - a01 * a10;
499
+ const b01 = a00 * a12 - a02 * a10;
500
+ const b02 = a00 * a13 - a03 * a10;
501
+ const b03 = a01 * a12 - a02 * a11;
502
+ const b04 = a01 * a13 - a03 * a11;
503
+ const b05 = a02 * a13 - a03 * a12;
504
+ const b06 = a20 * a31 - a21 * a30;
505
+ const b07 = a20 * a32 - a22 * a30;
506
+ const b08 = a20 * a33 - a23 * a30;
507
+ const b09 = a21 * a32 - a22 * a31;
508
+ const b10 = a21 * a33 - a23 * a31;
509
+ const b11 = a22 * a33 - a23 * a32;
510
+
511
+ let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
512
+ if (!det) {
513
+ return null;
514
+ }
515
+ det = 1.0 / det;
516
+
517
+ out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
518
+ out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
519
+ out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
520
+ out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
521
+ out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
522
+ out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
523
+ out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
524
+ out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
525
+ out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
526
+ out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
527
+ out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
528
+ out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
529
+ out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
530
+ out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
531
+ out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
532
+ out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
533
+
534
+ return out;
535
+ }
536
+
537
+ static lookAt(out, eye, center, up) {
538
+ let x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
539
+ const eyex = eye[0];
540
+ const eyey = eye[1];
541
+ const eyez = eye[2];
542
+ const upx = up[0];
543
+ const upy = up[1];
544
+ const upz = up[2];
545
+ const centerx = center[0];
546
+ const centery = center[1];
547
+ const centerz = center[2];
548
+
549
+ if (
550
+ Math.abs(eyex - centerx) < 0.000001 &&
551
+ Math.abs(eyey - centery) < 0.000001 &&
552
+ Math.abs(eyez - centerz) < 0.000001
553
+ ) {
554
+ return Matrix4.identity(out);
555
+ }
556
+
557
+ z0 = eyex - centerx;
558
+ z1 = eyey - centery;
559
+ z2 = eyez - centerz;
560
+
561
+ len = 1 / Math.hypot(z0, z1, z2);
562
+ z0 *= len;
563
+ z1 *= len;
564
+ z2 *= len;
565
+
566
+ // Cross product of up and z
567
+ x0 = upy * z2 - upz * z1;
568
+ x1 = upz * z0 - upx * z2;
569
+ x2 = upx * z1 - upy * z0;
570
+ len = Math.hypot(x0, x1, x2);
571
+
572
+ // Handle the case where up and z are colinear (or nearly so)
573
+ if (len < 0.000001) {
574
+ // Find a perpendicular vector to z
575
+ // Try cross product with (1,0,0) first
576
+ if (Math.abs(z0) < 0.9) {
577
+ // Cross with X axis
578
+ x0 = 0;
579
+ x1 = z2;
580
+ x2 = -z1;
581
+ } else {
582
+ // Cross with Z axis if Z is near X
583
+ x0 = z1;
584
+ x1 = -z0;
585
+ x2 = 0;
586
+ }
587
+ len = Math.hypot(x0, x1, x2);
588
+ len = 1 / len;
589
+ x0 *= len;
590
+ x1 *= len;
591
+ x2 *= len;
592
+ } else {
593
+ // Normal case - normalize the computed cross product
594
+ len = 1 / len;
595
+ x0 *= len;
596
+ x1 *= len;
597
+ x2 *= len;
598
+ }
599
+
600
+ y0 = z1 * x2 - z2 * x1;
601
+ y1 = z2 * x0 - z0 * x2;
602
+ y2 = z0 * x1 - z1 * x0;
603
+
604
+ len = Math.hypot(y0, y1, y2);
605
+ if (!len) {
606
+ y0 = 0;
607
+ y1 = 0;
608
+ y2 = 0;
609
+ } else {
610
+ len = 1 / len;
611
+ y0 *= len;
612
+ y1 *= len;
613
+ y2 *= len;
614
+ }
615
+
616
+ out[0] = x0;
617
+ out[1] = y0;
618
+ out[2] = z0;
619
+ out[3] = 0;
620
+ out[4] = x1;
621
+ out[5] = y1;
622
+ out[6] = z1;
623
+ out[7] = 0;
624
+ out[8] = x2;
625
+ out[9] = y2;
626
+ out[10] = z2;
627
+ out[11] = 0;
628
+ out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
629
+ out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
630
+ out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
631
+ out[15] = 1;
632
+
633
+ return out;
634
+ }
635
+
636
+ static transpose(out, a) {
637
+ if (out === a) {
638
+ const a01 = a[1],
639
+ a02 = a[2],
640
+ a03 = a[3],
641
+ a12 = a[6],
642
+ a13 = a[7],
643
+ a23 = a[11];
644
+
645
+ out[1] = a[4];
646
+ out[2] = a[8];
647
+ out[3] = a[12];
648
+ out[4] = a01;
649
+ out[6] = a[9];
650
+ out[7] = a[13];
651
+ out[8] = a02;
652
+ out[9] = a12;
653
+ out[11] = a[14];
654
+ out[12] = a03;
655
+ out[13] = a13;
656
+ out[14] = a23;
657
+ } else {
658
+ out[0] = a[0];
659
+ out[1] = a[4];
660
+ out[2] = a[8];
661
+ out[3] = a[12];
662
+ out[4] = a[1];
663
+ out[5] = a[5];
664
+ out[6] = a[9];
665
+ out[7] = a[13];
666
+ out[8] = a[2];
667
+ out[9] = a[6];
668
+ out[10] = a[10];
669
+ out[11] = a[14];
670
+ out[12] = a[3];
671
+ out[13] = a[7];
672
+ out[14] = a[11];
673
+ out[15] = a[15];
674
+ }
675
+
676
+ return out;
677
+ }
678
+
679
+ static rotateX(out, a, rad) {
680
+ const s = Math.sin(rad);
681
+ const c = Math.cos(rad);
682
+ const a10 = a[4];
683
+ const a11 = a[5];
684
+ const a12 = a[6];
685
+ const a13 = a[7];
686
+ const a20 = a[8];
687
+ const a21 = a[9];
688
+ const a22 = a[10];
689
+ const a23 = a[11];
690
+
691
+ out[4] = a10 * c + a20 * s;
692
+ out[5] = a11 * c + a21 * s;
693
+ out[6] = a12 * c + a22 * s;
694
+ out[7] = a13 * c + a23 * s;
695
+ out[8] = a20 * c - a10 * s;
696
+ out[9] = a21 * c - a11 * s;
697
+ out[10] = a22 * c - a12 * s;
698
+ out[11] = a23 * c - a13 * s;
699
+
700
+ // If the source and destination differ, we need to copy the unchanged rows
701
+ if (a !== out) {
702
+ out[0] = a[0];
703
+ out[1] = a[1];
704
+ out[2] = a[2];
705
+ out[3] = a[3];
706
+ out[12] = a[12];
707
+ out[13] = a[13];
708
+ out[14] = a[14];
709
+ out[15] = a[15];
710
+ }
711
+
712
+ return out;
713
+ }
714
+ static rotateZ(out, a, rad) {
715
+ const s = Math.sin(rad);
716
+ const c = Math.cos(rad);
717
+ const a00 = a[0];
718
+ const a01 = a[1];
719
+ const a02 = a[2];
720
+ const a03 = a[3];
721
+ const a10 = a[4];
722
+ const a11 = a[5];
723
+ const a12 = a[6];
724
+ const a13 = a[7];
725
+
726
+ out[0] = a00 * c + a10 * s;
727
+ out[1] = a01 * c + a11 * s;
728
+ out[2] = a02 * c + a12 * s;
729
+ out[3] = a03 * c + a13 * s;
730
+ out[4] = a10 * c - a00 * s;
731
+ out[5] = a11 * c - a01 * s;
732
+ out[6] = a12 * c - a02 * s;
733
+ out[7] = a13 * c - a03 * s;
734
+
735
+ // If the source and destination differ, we need to copy the unchanged rows
736
+ if (a !== out) {
737
+ out[8] = a[8];
738
+ out[9] = a[9];
739
+ out[10] = a[10];
740
+ out[11] = a[11];
741
+ out[12] = a[12];
742
+ out[13] = a[13];
743
+ out[14] = a[14];
744
+ out[15] = a[15];
745
+ }
746
+
747
+ return out;
748
+ }
749
+
750
+ static rotateY(out, a, rad) {
751
+ const s = Math.sin(rad);
752
+ const c = Math.cos(rad);
753
+ const a00 = a[0];
754
+ const a01 = a[1];
755
+ const a02 = a[2];
756
+ const a03 = a[3];
757
+ const a20 = a[8];
758
+ const a21 = a[9];
759
+ const a22 = a[10];
760
+ const a23 = a[11];
761
+
762
+ out[0] = a00 * c - a20 * s;
763
+ out[1] = a01 * c - a21 * s;
764
+ out[2] = a02 * c - a22 * s;
765
+ out[3] = a03 * c - a23 * s;
766
+ out[8] = a00 * s + a20 * c;
767
+ out[9] = a01 * s + a21 * c;
768
+ out[10] = a02 * s + a22 * c;
769
+ out[11] = a03 * s + a23 * c;
770
+
771
+ // If the source and destination differ, we need to copy the unchanged rows
772
+ if (a !== out) {
773
+ out[4] = a[4];
774
+ out[5] = a[5];
775
+ out[6] = a[6];
776
+ out[7] = a[7];
777
+ out[12] = a[12];
778
+ out[13] = a[13];
779
+ out[14] = a[14];
780
+ out[15] = a[15];
781
+ }
782
+
783
+ return out;
784
+ }
785
+ }