littlejsengine 1.19.3 → 1.20.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 (50) hide show
  1. package/FAQ.md +841 -820
  2. package/README.md +29 -25
  3. package/dist/littlejs.d.ts +2455 -935
  4. package/dist/littlejs.esm.js +30344 -21110
  5. package/dist/littlejs.esm.min.js +4 -3
  6. package/dist/littlejs.js +30259 -21052
  7. package/dist/littlejs.min.js +2 -2
  8. package/dist/littlejs.release.js +26567 -20455
  9. package/package.json +10 -5
  10. package/plugins/audioEffects.js +28 -24
  11. package/plugins/box2d.js +2516 -2073
  12. package/plugins/drawUtilities.js +206 -31
  13. package/plugins/gltf.js +740 -0
  14. package/plugins/jsconfig.json +19 -0
  15. package/plugins/lightSystem.js +719 -332
  16. package/plugins/math3d.js +58 -17
  17. package/plugins/medalSystem.js +326 -280
  18. package/plugins/newgrounds.js +400 -199
  19. package/plugins/pathFinder.js +208 -175
  20. package/plugins/pluginExport.js +15 -0
  21. package/plugins/postProcess.js +56 -13
  22. package/plugins/render3d.js +1643 -1577
  23. package/plugins/render3dDebug.js +109 -0
  24. package/plugins/render3dExtras.js +1754 -0
  25. package/plugins/render3dVoxels.js +502 -0
  26. package/plugins/textureSheet.js +496 -458
  27. package/plugins/threejs.js +183 -163
  28. package/plugins/tweakables.js +411 -0
  29. package/plugins/tweenSystem.js +263 -145
  30. package/plugins/uiSystem.js +2024 -1687
  31. package/plugins/zzfxm.js +159 -159
  32. package/src/engine.js +191 -75
  33. package/src/engineAudio.js +229 -125
  34. package/src/engineBuild.mjs +289 -256
  35. package/src/engineDebug.js +912 -742
  36. package/src/engineDraw.js +295 -193
  37. package/src/engineEditor.js +2431 -0
  38. package/src/engineExport.js +12 -0
  39. package/src/engineInput.js +1462 -1293
  40. package/src/engineMath.js +1274 -1252
  41. package/src/engineObject.js +194 -80
  42. package/src/engineParticles.js +583 -532
  43. package/src/engineRelease.js +67 -45
  44. package/src/engineSettings.js +77 -29
  45. package/src/engineTileLayer.js +995 -741
  46. package/src/engineUtilities.js +19 -13
  47. package/src/engineWebGL.js +239 -82
  48. package/src/jsconfig.json +17 -13
  49. package/plugins/box2d.wasm.js +0 -630
  50. package/plugins/box2d.wasm.wasm +0 -0
package/plugins/math3d.js CHANGED
@@ -288,6 +288,7 @@ class Vector3
288
288
 
289
289
  // scratch for multiply, nothing keeps a reference to it
290
290
  const matrix4Scratch = new Float32Array(16);
291
+ const matrix4Identity = new Float32Array([1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]);
291
292
 
292
293
  /**
293
294
  * 4x4 transform matrix for moving, rotating and scaling points in 3D
@@ -330,22 +331,23 @@ class Matrix4
330
331
  return r;
331
332
  }
332
333
 
333
- /** Returns a new rotation matrix, rolled first, then pitched, then yawed
334
+ /** Returns a rotation matrix, rolled first, then pitched, then yawed
334
335
  * @param {Vector3} euler - vec3(pitch, yaw, roll) in radians
336
+ * @param {Matrix4} [matrix] - Written into instead of a new one, for a loop that builds many
335
337
  * @return {Matrix4} */
336
- static rotation(euler)
338
+ static rotation(euler, matrix=new Matrix4)
337
339
  {
338
340
  ASSERT_VECTOR3_VALID(euler);
339
341
  const cx = cos(euler.x), sx = sin(euler.x);
340
342
  const cy = cos(euler.y), sy = sin(euler.y);
341
343
  const cz = cos(euler.z), sz = sin(euler.z);
342
- const r = new Matrix4;
343
- const m = r.m;
344
- // R = Ry * Rx * Rz written out, column major
345
- m[0] = cy*cz + sy*sx*sz; m[1] = cx*sz; m[2] = -sy*cz + cy*sx*sz;
346
- m[4] = -cy*sz + sy*sx*cz; m[5] = cx*cz; m[6] = sy*sz + cy*sx*cz;
347
- m[8] = sy*cx; m[9] = -sx; m[10] = cy*cx;
348
- return r;
344
+ const m = matrix.m;
345
+ // R = Ry * Rx * Rz written out, column major, every element set so a reused matrix comes out clean
346
+ m[0] = cy*cz + sy*sx*sz; m[1] = cx*sz; m[2] = -sy*cz + cy*sx*sz; m[3] = 0;
347
+ m[4] = -cy*sz + sy*sx*cz; m[5] = cx*cz; m[6] = sy*sz + cy*sx*cz; m[7] = 0;
348
+ m[8] = sy*cx; m[9] = -sx; m[10] = cy*cx; m[11] = 0;
349
+ m[12] = m[13] = m[14] = 0; m[15] = 1;
350
+ return matrix;
349
351
  }
350
352
 
351
353
  /** Returns a new scale matrix
@@ -416,8 +418,10 @@ class Matrix4
416
418
  if (!z.lengthSquared())
417
419
  z = vec3(0, 0, 1); // eye is on the target, face -Z
418
420
  let x = up.cross(z).normalize();
419
- if (!x.lengthSquared()) // up is along the view direction, pick another
420
- x = (abs(z.y) > .99 ? vec3(0, 0, 1) : vec3(0, 1, 0)).cross(z).normalize();
421
+ // up is along the view direction, pick another; looking straight down or up keeps +X as the right axis,
422
+ // as three.js does and as a view tilting there from the +Z side ends up
423
+ if (!x.lengthSquared())
424
+ x = (abs(z.y) > .99 ? vec3(0, 0, z.y > 0 ? -1 : 1) : vec3(0, 1, 0)).cross(z).normalize();
421
425
  const y = z.cross(x);
422
426
  return new Matrix4([x.x, x.y, x.z, 0, y.x, y.y, y.z, 0, z.x, z.y, z.z, 0, eye.x, eye.y, eye.z, 1]);
423
427
  }
@@ -530,6 +534,41 @@ class Matrix4
530
534
  * @return {Vector3} */
531
535
  getTranslation() { return new Vector3(this.m[12], this.m[13], this.m[14]); }
532
536
 
537
+ /** Returns the determinant of the rotation and scale part: negative when the matrix mirrors, 0 when it flattens a
538
+ * shape and has no inverse
539
+ * @return {number} */
540
+ determinant()
541
+ {
542
+ const m = this.m;
543
+ return m[0]*(m[5]*m[10] - m[6]*m[9]) - m[4]*(m[1]*m[10] - m[2]*m[9]) + m[8]*(m[1]*m[6] - m[2]*m[5]);
544
+ }
545
+
546
+ /** Returns the scale part of this matrix, the length of each axis; a mirroring matrix shows as a negative x
547
+ * @return {Vector3} */
548
+ getScale()
549
+ {
550
+ const m = this.m;
551
+ const x = hypot(m[0], m[1], m[2]), y = hypot(m[4], m[5], m[6]), z = hypot(m[8], m[9], m[10]);
552
+ return new Vector3(this.determinant() < 0 ? -x : x, y, z);
553
+ }
554
+
555
+ /** Returns the rotation part of this matrix as vec3(pitch, yaw, roll), the angles Matrix4.rotation builds it from
556
+ * - The scale is divided out first, so it works on a full transform
557
+ * - A matrix with shear, from a scaled parent with a turned child, has no exact answer and gets the nearest
558
+ * @return {Vector3} */
559
+ getRotation()
560
+ {
561
+ // the axes at unit length, see Matrix4.rotation for which element is which
562
+ const m = this.m, s = this.getScale();
563
+ const sx = s.x || 1, sy = s.y || 1, sz = s.z || 1;
564
+ const m1 = m[1] / sx, m5 = m[5] / sy, m8 = m[8] / sz, m9 = m[9] / sz, m10 = m[10] / sz;
565
+ const pitch = Math.asin(clamp(-m9, -1, 1));
566
+ if (abs(m9) < 1 - 1e-6)
567
+ return new Vector3(pitch, atan2(m8, m10), atan2(m1, m5));
568
+ // straight up or down: yaw and roll turn about the same axis, so the roll is zero and yaw takes it all
569
+ return new Vector3(pitch, atan2(m[4] / sy * -m9, m[0] / sx), 0);
570
+ }
571
+
533
572
  /** Returns a string representation of this matrix for debugging
534
573
  * @return {string} */
535
574
  toString()
@@ -550,18 +589,20 @@ class Matrix4
550
589
  * @param {Vector3} [pos]
551
590
  * @param {Vector3} [rotation] - vec3(pitch, yaw, roll) in radians
552
591
  * @param {Vector3} [scale]
592
+ * @param {Matrix4} [matrix] - Written into instead of a new one, for a loop that builds many
553
593
  * @return {Matrix4}
554
594
  * @memberof Math3D
555
595
  */
556
- function buildMatrix(pos, rotation, scale)
596
+ function buildMatrix(pos, rotation, scale, matrix=new Matrix4)
557
597
  {
558
598
  ASSERT(!pos || isVector3(pos), 'pos must be a Vector3', pos);
559
599
  ASSERT(!scale || isVector3(scale), 'scale must be a Vector3', scale);
600
+ ASSERT(matrix instanceof Matrix4, 'the matrix to write into must be a Matrix4');
560
601
  // scale the rotation columns and drop the position in, instead of multiplying three matrices
561
602
  // an object that is not turned at all is most of a big scene, and identity is what the six
562
603
  // trig calls would have worked out to anyway
563
- const turned = rotation && (rotation.x || rotation.y || rotation.z);
564
- const matrix = turned ? Matrix4.rotation(rotation) : new Matrix4, m = matrix.m;
604
+ const turned = rotation && (rotation.x || rotation.y || rotation.z), m = matrix.m;
605
+ turned ? Matrix4.rotation(rotation, matrix) : m.set(matrix4Identity);
565
606
  if (scale)
566
607
  {
567
608
  m[0] *= scale.x; m[1] *= scale.x; m[2] *= scale.x;
@@ -798,12 +839,12 @@ function raycastSphere(ray, pos, radius)
798
839
  {
799
840
  const {origin, direction} = ray;
800
841
  const oc = origin.subtract(pos);
842
+ const c = oc.dot(oc) - radius*radius;
843
+ if (c < 0)
844
+ return 0; // origin is inside the sphere, even for a ray of no length, as raycastBox gives
801
845
  const a = direction.dot(direction);
802
846
  if (!a)
803
847
  return undefined;
804
- const c = oc.dot(oc) - radius*radius;
805
- if (c < 0)
806
- return 0; // origin is inside the sphere
807
848
  const b = 2*oc.dot(direction);
808
849
  const discriminant = b*b - 4*a*c;
809
850
  if (discriminant < 0)