@inglorious/engine 0.1.1 → 0.2.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 (201) hide show
  1. package/README.md +39 -36
  2. package/package.json +10 -22
  3. package/src/engine/ai/movement/dynamic/align.js +63 -63
  4. package/src/engine/ai/movement/dynamic/arrive.js +42 -43
  5. package/src/engine/ai/movement/dynamic/evade.js +38 -38
  6. package/src/engine/ai/movement/dynamic/face.js +19 -20
  7. package/src/engine/ai/movement/dynamic/flee.js +45 -45
  8. package/src/engine/ai/movement/dynamic/look-where-youre-going.js +16 -17
  9. package/src/engine/ai/movement/dynamic/match-velocity.js +51 -50
  10. package/src/engine/ai/movement/dynamic/pursue.js +38 -38
  11. package/src/engine/ai/movement/dynamic/seek.js +44 -44
  12. package/src/engine/ai/movement/dynamic/wander.js +31 -32
  13. package/src/engine/ai/movement/kinematic/align.js +37 -37
  14. package/src/engine/ai/movement/kinematic/arrive.js +42 -42
  15. package/src/engine/ai/movement/kinematic/face.js +19 -20
  16. package/src/engine/ai/movement/kinematic/flee.js +26 -26
  17. package/src/engine/ai/movement/kinematic/seek.js +26 -26
  18. package/src/engine/ai/movement/kinematic/seek.test.js +42 -42
  19. package/src/engine/ai/movement/kinematic/wander-as-seek.js +31 -31
  20. package/src/engine/ai/movement/kinematic/wander.js +27 -27
  21. package/src/engine/animation/sprite.js +101 -0
  22. package/src/engine/animation/ticker.js +38 -0
  23. package/src/engine/behaviors/camera.js +68 -0
  24. package/src/engine/behaviors/controls/dynamic/modern.js +76 -0
  25. package/src/engine/behaviors/controls/dynamic/shooter.js +84 -0
  26. package/src/engine/behaviors/controls/dynamic/tank.js +69 -0
  27. package/src/engine/behaviors/controls/event-handlers.js +17 -0
  28. package/src/engine/behaviors/controls/kinematic/modern.js +76 -0
  29. package/src/engine/behaviors/controls/kinematic/shooter.js +82 -0
  30. package/src/engine/behaviors/controls/kinematic/tank.js +67 -0
  31. package/src/engine/behaviors/debug/collision.js +35 -0
  32. package/src/engine/behaviors/fps.js +29 -0
  33. package/src/engine/behaviors/fsm.js +33 -0
  34. package/src/{game/decorators → engine/behaviors}/fsm.test.js +49 -56
  35. package/src/engine/behaviors/game.js +15 -0
  36. package/src/engine/behaviors/input/controls.js +37 -0
  37. package/src/engine/behaviors/input/gamepad.js +114 -0
  38. package/src/engine/behaviors/input/input.js +48 -0
  39. package/src/engine/behaviors/input/keyboard.js +64 -0
  40. package/src/engine/behaviors/input/mouse.js +91 -0
  41. package/src/engine/behaviors/physics/bouncy.js +25 -0
  42. package/src/engine/behaviors/physics/clamped.js +36 -0
  43. package/src/{game/decorators/collisions.js → engine/behaviors/physics/collidable.js} +20 -24
  44. package/src/engine/behaviors/physics/jumpable.js +145 -0
  45. package/src/engine/behaviors/ui/button.js +17 -0
  46. package/src/engine/collision/detection.js +110 -115
  47. package/src/engine/core/api.js +34 -0
  48. package/src/engine/core/dev-tools.js +135 -0
  49. package/src/engine/core/engine.js +119 -0
  50. package/src/engine/core/loop.js +15 -0
  51. package/src/engine/{loop → core/loops}/animation-frame.js +25 -26
  52. package/src/engine/{loop → core/loops}/elapsed.js +22 -23
  53. package/src/engine/{loop → core/loops}/fixed.js +27 -28
  54. package/src/engine/{loop → core/loops}/flash.js +13 -14
  55. package/src/engine/{loop → core/loops}/lag.js +26 -27
  56. package/src/engine/core/select.js +26 -0
  57. package/src/engine/core/store.js +178 -0
  58. package/src/engine/core/store.test.js +110 -0
  59. package/src/engine/movement/dynamic/modern.js +21 -24
  60. package/src/engine/movement/dynamic/tank.js +43 -43
  61. package/src/engine/movement/kinematic/modern.js +16 -16
  62. package/src/engine/movement/kinematic/modern.test.js +27 -27
  63. package/src/engine/movement/kinematic/tank.js +27 -27
  64. package/src/engine/physics/bounds.js +138 -0
  65. package/src/engine/physics/position.js +43 -0
  66. package/src/engine/physics/position.test.js +80 -0
  67. package/src/engine/systems/sprite-animation.js +27 -0
  68. package/src/main.js +10 -5
  69. package/src/renderers/canvas/absolute-position.js +18 -0
  70. package/src/renderers/canvas/camera.js +13 -0
  71. package/src/renderers/canvas/canvas-renderer.js +68 -0
  72. package/src/{ui → renderers}/canvas/character.js +38 -35
  73. package/src/{ui → renderers}/canvas/form/button.js +25 -25
  74. package/src/{ui → renderers}/canvas/fps.js +18 -18
  75. package/src/renderers/canvas/image/hitmask.js +51 -0
  76. package/src/{ui → renderers}/canvas/image/image.js +34 -37
  77. package/src/{ui → renderers}/canvas/image/sprite.js +49 -49
  78. package/src/{ui → renderers}/canvas/image/tilemap.js +66 -64
  79. package/src/{ui → renderers}/canvas/mouse.js +37 -37
  80. package/src/renderers/canvas/rendering-system.js +79 -0
  81. package/src/{ui → renderers}/canvas/shapes/circle.js +29 -31
  82. package/src/{ui → renderers}/canvas/shapes/rectangle.js +27 -31
  83. package/src/renderers/react/game/character/index.jsx +20 -0
  84. package/src/{ui → renderers}/react/game/cursor/index.jsx +20 -20
  85. package/src/{ui → renderers}/react/game/form/fields/field/index.jsx +56 -56
  86. package/src/{ui → renderers}/react/game/form/fields/index.jsx +12 -12
  87. package/src/{ui → renderers}/react/game/form/index.jsx +22 -22
  88. package/src/{ui → renderers}/react/game/fps/index.jsx +16 -16
  89. package/src/{ui → renderers}/react/game/game.jsx +72 -71
  90. package/src/{ui → renderers}/react/game/index.jsx +29 -29
  91. package/src/{ui → renderers}/react/game/platform/index.jsx +30 -30
  92. package/src/{ui → renderers}/react/game/scene/index.jsx +27 -25
  93. package/src/{ui → renderers}/react/game/sprite/index.jsx +60 -58
  94. package/src/{ui → renderers}/react/game/stats/index.jsx +22 -22
  95. package/src/{ui → renderers}/react/hocs/with-absolute-position/index.jsx +20 -20
  96. package/src/{ui → renderers}/react/index.jsx +9 -9
  97. package/src/utils/algorithms/decision-tree.js +24 -24
  98. package/src/utils/algorithms/decision-tree.test.js +153 -102
  99. package/src/utils/algorithms/path-finding.js +155 -155
  100. package/src/utils/algorithms/path-finding.test.js +151 -151
  101. package/src/utils/data-structures/array.js +83 -83
  102. package/src/utils/data-structures/array.test.js +173 -173
  103. package/src/utils/data-structures/board.js +159 -159
  104. package/src/utils/data-structures/board.test.js +242 -242
  105. package/src/utils/data-structures/boolean.js +9 -9
  106. package/src/utils/data-structures/heap.js +164 -164
  107. package/src/utils/data-structures/heap.test.js +103 -103
  108. package/src/utils/data-structures/object.js +138 -102
  109. package/src/utils/data-structures/object.test.js +218 -121
  110. package/src/utils/data-structures/objects.js +66 -48
  111. package/src/utils/data-structures/objects.test.js +99 -99
  112. package/src/utils/data-structures/tree.js +36 -36
  113. package/src/utils/data-structures/tree.test.js +33 -33
  114. package/src/utils/functions/functions.js +19 -19
  115. package/src/utils/functions/functions.test.js +23 -23
  116. package/src/utils/math/geometry/circle.js +70 -117
  117. package/src/utils/math/geometry/circle.test.js +97 -97
  118. package/src/utils/math/geometry/hitmask.js +70 -39
  119. package/src/utils/math/geometry/hitmask.test.js +155 -84
  120. package/src/utils/math/geometry/line.js +35 -35
  121. package/src/utils/math/geometry/line.test.js +49 -49
  122. package/src/utils/math/geometry/point.js +78 -71
  123. package/src/utils/math/geometry/point.test.js +81 -81
  124. package/src/utils/math/geometry/rectangle.js +76 -45
  125. package/src/utils/math/geometry/rectangle.test.js +42 -42
  126. package/src/utils/math/geometry/segment.js +80 -80
  127. package/src/utils/math/geometry/segment.test.js +183 -183
  128. package/src/utils/math/geometry/triangle.js +15 -15
  129. package/src/utils/math/geometry/triangle.test.js +11 -11
  130. package/src/utils/math/linear-algebra/2d.js +28 -28
  131. package/src/utils/math/linear-algebra/2d.test.js +17 -17
  132. package/src/utils/math/linear-algebra/quaternion.js +22 -22
  133. package/src/utils/math/linear-algebra/quaternion.test.js +25 -25
  134. package/src/utils/math/linear-algebra/quaternions.js +20 -20
  135. package/src/utils/math/linear-algebra/quaternions.test.js +29 -29
  136. package/src/utils/math/linear-algebra/vector.js +327 -302
  137. package/src/utils/math/linear-algebra/vector.test.js +265 -257
  138. package/src/utils/math/linear-algebra/vectors.js +122 -122
  139. package/src/utils/math/linear-algebra/vectors.test.js +65 -65
  140. package/src/utils/math/linear-interpolation.js +9 -0
  141. package/src/utils/math/numbers.js +90 -90
  142. package/src/utils/math/numbers.test.js +137 -137
  143. package/src/utils/math/rng.js +44 -44
  144. package/src/utils/math/rng.test.js +39 -39
  145. package/src/utils/math/statistics.js +43 -43
  146. package/src/utils/math/statistics.test.js +47 -47
  147. package/src/utils/math/trigonometry.js +89 -89
  148. package/src/utils/math/trigonometry.test.js +52 -52
  149. package/src/utils/physics/acceleration.js +61 -63
  150. package/src/utils/physics/friction.js +28 -30
  151. package/src/utils/physics/friction.test.js +42 -44
  152. package/src/utils/physics/gravity.js +69 -71
  153. package/src/utils/physics/gravity.test.js +77 -80
  154. package/src/utils/physics/jump.js +31 -41
  155. package/src/utils/physics/velocity.js +36 -38
  156. package/src/engine/loop.js +0 -15
  157. package/src/engine/store.js +0 -174
  158. package/src/engine/store.test.js +0 -256
  159. package/src/engine.js +0 -74
  160. package/src/game/animation.js +0 -26
  161. package/src/game/bounds.js +0 -66
  162. package/src/game/decorators/character.js +0 -5
  163. package/src/game/decorators/clamp-to-bounds.js +0 -15
  164. package/src/game/decorators/controls/dynamic/modern.js +0 -48
  165. package/src/game/decorators/controls/dynamic/shooter.js +0 -47
  166. package/src/game/decorators/controls/dynamic/tank.js +0 -55
  167. package/src/game/decorators/controls/kinematic/modern.js +0 -49
  168. package/src/game/decorators/controls/kinematic/shooter.js +0 -45
  169. package/src/game/decorators/controls/kinematic/tank.js +0 -52
  170. package/src/game/decorators/debug/collisions.js +0 -32
  171. package/src/game/decorators/double-jump.js +0 -70
  172. package/src/game/decorators/fps.js +0 -30
  173. package/src/game/decorators/fsm.js +0 -27
  174. package/src/game/decorators/game.js +0 -11
  175. package/src/game/decorators/image/image.js +0 -5
  176. package/src/game/decorators/image/sprite.js +0 -5
  177. package/src/game/decorators/image/tilemap.js +0 -5
  178. package/src/game/decorators/input/controls.js +0 -27
  179. package/src/game/decorators/input/gamepad.js +0 -74
  180. package/src/game/decorators/input/input.js +0 -41
  181. package/src/game/decorators/input/keyboard.js +0 -49
  182. package/src/game/decorators/input/mouse.js +0 -65
  183. package/src/game/decorators/jump.js +0 -72
  184. package/src/game/decorators/platform.js +0 -5
  185. package/src/game/decorators/ui/button.js +0 -21
  186. package/src/game/sprite.js +0 -119
  187. package/src/ui/canvas/absolute-position.js +0 -17
  188. package/src/ui/canvas/image/hitmask.js +0 -37
  189. package/src/ui/canvas.js +0 -81
  190. package/src/ui/react/game/character/index.jsx +0 -30
  191. package/src/utils/math/geometry/platform.js +0 -42
  192. package/src/utils/math/geometry/platform.test.js +0 -133
  193. /package/src/{ui → renderers}/react/game/character/character.module.scss +0 -0
  194. /package/src/{ui → renderers}/react/game/cursor/cursor.module.scss +0 -0
  195. /package/src/{ui → renderers}/react/game/form/fields/field/field.module.scss +0 -0
  196. /package/src/{ui → renderers}/react/game/form/fields/fields.module.scss +0 -0
  197. /package/src/{ui → renderers}/react/game/form/form.module.scss +0 -0
  198. /package/src/{ui → renderers}/react/game/platform/platform.module.scss +0 -0
  199. /package/src/{ui → renderers}/react/game/scene/scene.module.scss +0 -0
  200. /package/src/{ui → renderers}/react/game/sprite/sprite.module.css +0 -0
  201. /package/src/{ui → renderers}/react/hocs/with-absolute-position/with-absolute-position.module.scss +0 -0
@@ -1,89 +1,89 @@
1
- import { mod } from "./numbers.js"
2
-
3
- const HALF_CIRCLE_IN_DEGRESS = 180 // Half-circle in degrees (180°)
4
- const FULL_CIRCLE = 2 // Full circle multiplier for radians (2π)
5
-
6
- /**
7
- * Calculates the arctangent of the quotient of its arguments.
8
- * @param {number} y - The y-coordinate.
9
- * @param {number} x - The x-coordinate.
10
- * @returns {number} The angle in radians.
11
- */
12
- export function atan2(y, x) {
13
- return Math.atan2(y, x)
14
- }
15
-
16
- /**
17
- * Calculates the cosine of an angle.
18
- * @param {number} angle - The angle in radians.
19
- * @returns {number} The cosine of the angle.
20
- */
21
- export function cos(angle) {
22
- return Math.cos(angle)
23
- }
24
-
25
- /**
26
- * Alias for the `cos` function.
27
- * @type {typeof cos}.
28
- */
29
- export const cosine = cos
30
-
31
- /**
32
- * Returns the value of π (pi).
33
- * @returns {number} The value of π.
34
- */
35
- export function pi() {
36
- return Math.PI
37
- }
38
-
39
- /**
40
- * Calculates the sine of an angle.
41
- * @param {number} angle - The angle in radians.
42
- * @returns {number} The sine of the angle.
43
- */
44
- export function sin(angle) {
45
- return Math.sin(angle)
46
- }
47
-
48
- /**
49
- * Alias for the `sin` function.
50
- * @type {typeof sin}.
51
- */
52
- export const sine = sin
53
-
54
- /**
55
- * Converts an angle from radians to degrees.
56
- * @param {number} radians - The angle in radians.
57
- * @returns {number} The angle in degrees.
58
- */
59
- export function toDegrees(radians) {
60
- return (radians * HALF_CIRCLE_IN_DEGRESS) / pi()
61
- }
62
-
63
- /**
64
- * Converts an angle from degrees to radians.
65
- * @param {number} degrees - The angle in degrees.
66
- * @returns {number} The angle in radians.
67
- */
68
- export function toRadians(degrees) {
69
- return (degrees * pi()) / HALF_CIRCLE_IN_DEGRESS
70
- }
71
-
72
- /**
73
- * Normalizes an angle to the range [-π, π].
74
- * @param {number} angle - The angle in radians.
75
- * @returns {number} The normalized angle in radians.
76
- */
77
- export function toRange(angle) {
78
- if (angle > -pi() && angle < pi()) {
79
- return angle
80
- }
81
-
82
- angle = mod(angle, FULL_CIRCLE * pi())
83
-
84
- if (angle > pi()) {
85
- angle -= FULL_CIRCLE * pi()
86
- }
87
-
88
- return angle
89
- }
1
+ import { mod } from "./numbers.js"
2
+
3
+ const HALF_CIRCLE_IN_DEGRESS = 180 // Half-circle in degrees (180°)
4
+ const FULL_CIRCLE = 2 // Full circle multiplier for radians (2π)
5
+
6
+ /**
7
+ * Calculates the arctangent of the quotient of its arguments.
8
+ * @param {number} y - The y-coordinate.
9
+ * @param {number} x - The x-coordinate.
10
+ * @returns {number} The angle in radians.
11
+ */
12
+ export function atan2(y, x) {
13
+ return Math.atan2(y, x)
14
+ }
15
+
16
+ /**
17
+ * Calculates the cosine of an angle.
18
+ * @param {number} angle - The angle in radians.
19
+ * @returns {number} The cosine of the angle.
20
+ */
21
+ export function cos(angle) {
22
+ return Math.cos(angle)
23
+ }
24
+
25
+ /**
26
+ * Alias for the `cos` function.
27
+ * @type {typeof cos}.
28
+ */
29
+ export const cosine = cos
30
+
31
+ /**
32
+ * Returns the value of π (pi).
33
+ * @returns {number} The value of π.
34
+ */
35
+ export function pi() {
36
+ return Math.PI
37
+ }
38
+
39
+ /**
40
+ * Calculates the sine of an angle.
41
+ * @param {number} angle - The angle in radians.
42
+ * @returns {number} The sine of the angle.
43
+ */
44
+ export function sin(angle) {
45
+ return Math.sin(angle)
46
+ }
47
+
48
+ /**
49
+ * Alias for the `sin` function.
50
+ * @type {typeof sin}.
51
+ */
52
+ export const sine = sin
53
+
54
+ /**
55
+ * Converts an angle from radians to degrees.
56
+ * @param {number} radians - The angle in radians.
57
+ * @returns {number} The angle in degrees.
58
+ */
59
+ export function toDegrees(radians) {
60
+ return (radians * HALF_CIRCLE_IN_DEGRESS) / pi()
61
+ }
62
+
63
+ /**
64
+ * Converts an angle from degrees to radians.
65
+ * @param {number} degrees - The angle in degrees.
66
+ * @returns {number} The angle in radians.
67
+ */
68
+ export function toRadians(degrees) {
69
+ return (degrees * pi()) / HALF_CIRCLE_IN_DEGRESS
70
+ }
71
+
72
+ /**
73
+ * Normalizes an angle to the range [-π, π].
74
+ * @param {number} angle - The angle in radians.
75
+ * @returns {number} The normalized angle in radians.
76
+ */
77
+ export function toRange(angle) {
78
+ if (angle > -pi() && angle < pi()) {
79
+ return angle
80
+ }
81
+
82
+ angle = mod(angle, FULL_CIRCLE * pi())
83
+
84
+ if (angle > pi()) {
85
+ angle -= FULL_CIRCLE * pi()
86
+ }
87
+
88
+ return angle
89
+ }
@@ -1,52 +1,52 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { pi, toDegrees, toRadians, toRange } from "./trigonometry.js"
4
-
5
- test("it should convert radians to degrees", () => {
6
- const radians = pi() / 4
7
- const expectedResult = 45
8
-
9
- expect(toDegrees(radians)).toBeCloseTo(expectedResult)
10
- })
11
-
12
- test("it should convert radians to degrees", () => {
13
- const degrees = 45
14
- const expectedResult = pi() / 4
15
-
16
- expect(toRadians(degrees)).toBeCloseTo(expectedResult)
17
- })
18
-
19
- test("it should convert an angle greater than pi to a range between -pi and pi", () => {
20
- const angle = (5 / 4) * pi()
21
- const expectedResult = (-3 / 4) * pi()
22
-
23
- expect(toRange(angle)).toBeCloseTo(expectedResult)
24
- })
25
-
26
- test("it should convert an angle greater than 2pi to a range between -pi and pi", () => {
27
- const angle = (13 / 4) * pi()
28
- const expectedResult = (-3 / 4) * pi()
29
-
30
- expect(toRange(angle)).toBeCloseTo(expectedResult)
31
- })
32
-
33
- test("it should convert an angle less than pi to a range between -pi and pi", () => {
34
- const angle = (-5 / 4) * pi()
35
- const expectedResult = (3 / 4) * pi()
36
-
37
- expect(toRange(angle)).toBeCloseTo(expectedResult)
38
- })
39
-
40
- test("it should convert an angle less than 2pi to a range between -pi and pi", () => {
41
- const angle = (-13 / 4) * pi()
42
- const expectedResult = (3 / 4) * pi()
43
-
44
- expect(toRange(angle)).toBeCloseTo(expectedResult)
45
- })
46
-
47
- test("it should not convert an angle already in the range [-pi, pi]", () => {
48
- const angle = (3 / 4) * pi()
49
- const expectedResult = (3 / 4) * pi()
50
-
51
- expect(toRange(angle)).toBe(expectedResult)
52
- })
1
+ import { expect, test } from "vitest"
2
+
3
+ import { pi, toDegrees, toRadians, toRange } from "./trigonometry.js"
4
+
5
+ test("it should convert radians to degrees", () => {
6
+ const radians = pi() / 4
7
+ const expectedResult = 45
8
+
9
+ expect(toDegrees(radians)).toBeCloseTo(expectedResult)
10
+ })
11
+
12
+ test("it should convert radians to degrees", () => {
13
+ const degrees = 45
14
+ const expectedResult = pi() / 4
15
+
16
+ expect(toRadians(degrees)).toBeCloseTo(expectedResult)
17
+ })
18
+
19
+ test("it should convert an angle greater than pi to a range between -pi and pi", () => {
20
+ const angle = (5 / 4) * pi()
21
+ const expectedResult = (-3 / 4) * pi()
22
+
23
+ expect(toRange(angle)).toBeCloseTo(expectedResult)
24
+ })
25
+
26
+ test("it should convert an angle greater than 2pi to a range between -pi and pi", () => {
27
+ const angle = (13 / 4) * pi()
28
+ const expectedResult = (-3 / 4) * pi()
29
+
30
+ expect(toRange(angle)).toBeCloseTo(expectedResult)
31
+ })
32
+
33
+ test("it should convert an angle less than pi to a range between -pi and pi", () => {
34
+ const angle = (-5 / 4) * pi()
35
+ const expectedResult = (3 / 4) * pi()
36
+
37
+ expect(toRange(angle)).toBeCloseTo(expectedResult)
38
+ })
39
+
40
+ test("it should convert an angle less than 2pi to a range between -pi and pi", () => {
41
+ const angle = (-13 / 4) * pi()
42
+ const expectedResult = (3 / 4) * pi()
43
+
44
+ expect(toRange(angle)).toBeCloseTo(expectedResult)
45
+ })
46
+
47
+ test("it should not convert an angle already in the range [-pi, pi]", () => {
48
+ const angle = (3 / 4) * pi()
49
+ const expectedResult = (3 / 4) * pi()
50
+
51
+ expect(toRange(angle)).toBe(expectedResult)
52
+ })
@@ -1,63 +1,61 @@
1
- /**
2
- * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
- */
4
-
5
- import {
6
- clamp,
7
- multiply,
8
- zero,
9
- } from "@inglorious/utils/math/linear-algebra/vector.js"
10
- import { sum } from "@inglorious/utils/math/linear-algebra/vectors.js"
11
-
12
- import { applyFriction } from "./friction.js"
13
-
14
- const DEFAULT_OPTIONS = { dt: 0 } // Default options for the applyAcceleration function.
15
- const NO_FRICTION = 0 // No friction constant.
16
- const HALF_ACCELERATION = 0.5 // Half of the acceleration factor used in position calculation.
17
-
18
- /**
19
- * Applies acceleration to an object using Euler's integration method.
20
- *
21
- * Euler's Integration:
22
- * v += a * dt
23
- * p += v * dt + 1/2 * a * dt * dt
24
- *
25
- * @param {Object} params - The parameters for the function.
26
- * @param {number} params.maxAcceleration - The maximum allowed acceleration.
27
- * @param {number} params.maxSpeed - The maximum allowed speed.
28
- * @param {Vector3} [params.acceleration] - The current acceleration vector. Defaults to a zero vector.
29
- * @param {Vector3} [params.velocity] - The current velocity vector. Defaults to a zero vector.
30
- * @param {Vector3} [params.position] - The current position vector. Defaults to a zero vector.
31
- * @param {number} params.friction - The friction coefficient. Defaults to 0.
32
- * @param {Object} [options=DEFAULT_OPTIONS] - Additional options.
33
- * @param {number} options.dt - The time delta for the calculation. Defaults to 0.
34
- * @returns {Object} - The updated acceleration, velocity, and position.
35
- */
36
- export function applyAcceleration(params, options = DEFAULT_OPTIONS) {
37
- let {
38
- maxAcceleration,
39
- maxSpeed,
40
- acceleration = zero(),
41
- velocity = zero(),
42
- position = zero(),
43
- friction = NO_FRICTION,
44
- } = params
45
- const { dt } = options
46
-
47
- // Clamp acceleration to the maximum allowed range
48
- acceleration = clamp(acceleration, -maxAcceleration, maxAcceleration)
49
-
50
- // Update velocity with acceleration and clamp to the maximum allowed speed
51
- velocity = sum(velocity, multiply(acceleration, dt))
52
- velocity = clamp(velocity, -maxSpeed, maxSpeed)
53
- velocity = applyFriction({ velocity, friction }, options)
54
-
55
- // Update position with velocity and acceleration
56
- position = sum(
57
- position,
58
- multiply(velocity, dt),
59
- multiply(acceleration, HALF_ACCELERATION * dt * dt),
60
- )
61
-
62
- return { acceleration, velocity, position }
63
- }
1
+ /**
2
+ * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
+ */
4
+
5
+ import {
6
+ clamp,
7
+ multiply,
8
+ zero,
9
+ } from "@inglorious/utils/math/linear-algebra/vector.js"
10
+ import { sum } from "@inglorious/utils/math/linear-algebra/vectors.js"
11
+
12
+ import { applyFriction } from "./friction.js"
13
+
14
+ const DEFAULT_DT = 1 // Default time delta for the applyAcceleration function.
15
+ const NO_FRICTION = 0 // No friction constant.
16
+ const HALF_ACCELERATION = 0.5 // Half of the acceleration factor used in position calculation.
17
+
18
+ /**
19
+ * Applies acceleration to an object using Euler's integration method.
20
+ *
21
+ * Euler's Integration:
22
+ * v += a * dt
23
+ * p += v * dt + 1/2 * a * dt * dt
24
+ *
25
+ * @param {Object} params - The parameters for the function.
26
+ * @param {number} params.maxAcceleration - The maximum allowed acceleration.
27
+ * @param {number} params.maxSpeed - The maximum allowed speed.
28
+ * @param {Vector3} [params.acceleration] - The current acceleration vector. Defaults to a zero vector.
29
+ * @param {Vector3} [params.velocity] - The current velocity vector. Defaults to a zero vector.
30
+ * @param {Vector3} [params.position] - The current position vector. Defaults to a zero vector.
31
+ * @param {number} params.friction - The friction coefficient. Defaults to 0.
32
+ * @param {number} dt - The time delta for the calculation. Defaults to 0.
33
+ * @returns {Object} - The updated acceleration, velocity, and position.
34
+ */
35
+ export function applyAcceleration(params, dt = DEFAULT_DT) {
36
+ let {
37
+ maxAcceleration,
38
+ maxSpeed,
39
+ acceleration = zero(),
40
+ velocity = zero(),
41
+ position = zero(),
42
+ friction = NO_FRICTION,
43
+ } = params
44
+
45
+ // Clamp acceleration to the maximum allowed range
46
+ acceleration = clamp(acceleration, -maxAcceleration, maxAcceleration)
47
+
48
+ // Update velocity with acceleration and clamp to the maximum allowed speed
49
+ velocity = sum(velocity, multiply(acceleration, dt))
50
+ velocity = clamp(velocity, -maxSpeed, maxSpeed)
51
+ velocity = applyFriction({ velocity, friction }, dt)
52
+
53
+ // Update position with velocity and acceleration
54
+ position = sum(
55
+ position,
56
+ multiply(velocity, dt),
57
+ multiply(acceleration, HALF_ACCELERATION * dt * dt),
58
+ )
59
+
60
+ return { acceleration, velocity, position }
61
+ }
@@ -1,30 +1,28 @@
1
- /**
2
- * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
- */
4
-
5
- import {
6
- magnitude,
7
- setMagnitude,
8
- zero,
9
- } from "@inglorious/utils/math/linear-algebra/vector.js"
10
-
11
- const DEFAULT_OPTIONS = { dt: 0 } // Default options for the applyFriction function.
12
- const NO_FRICTION = 0 // No friction constant.
13
-
14
- /**
15
- * Applies friction to a given velocity vector.
16
- *
17
- * @param {Object} params - The parameters for the function.
18
- * @param {Vector3} params.velocity - The velocity vector. Defaults to a zero vector.
19
- * @param {number} params.friction - The friction coefficient. Defaults to 0.
20
- * @param {Object} [options=DEFAULT_OPTIONS] - Additional options.
21
- * @param {number} options.dt - The time delta for the calculation. Defaults to 0.
22
- * @returns {Vector3} - The updated velocity vector after applying friction.
23
- */
24
- export function applyFriction(params, options = DEFAULT_OPTIONS) {
25
- let { velocity = zero(), friction = NO_FRICTION } = params
26
- const { dt } = options
27
- const length = magnitude(velocity)
28
-
29
- return length ? setMagnitude(velocity, length - friction * dt) : velocity
30
- }
1
+ /**
2
+ * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
+ */
4
+
5
+ import {
6
+ magnitude,
7
+ setMagnitude,
8
+ zero,
9
+ } from "@inglorious/utils/math/linear-algebra/vector.js"
10
+
11
+ const DEFAULT_DT = 1 // Default time delta for the applyFriction function.
12
+ const NO_FRICTION = 0 // No friction constant.
13
+
14
+ /**
15
+ * Applies friction to a given velocity vector.
16
+ *
17
+ * @param {Object} params - The parameters for the function.
18
+ * @param {Vector3} params.velocity - The velocity vector. Defaults to a zero vector.
19
+ * @param {number} params.friction - The friction coefficient. Defaults to 0.
20
+ * @param {number} dt - The time delta for the calculation. Defaults to 1.
21
+ * @returns {Vector3} - The updated velocity vector after applying friction.
22
+ */
23
+ export function applyFriction(params, dt = DEFAULT_DT) {
24
+ let { velocity = zero(), friction = NO_FRICTION } = params
25
+ const length = magnitude(velocity)
26
+
27
+ return length ? setMagnitude(velocity, length - friction * dt) : velocity
28
+ }
@@ -1,44 +1,42 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { zero } from "../math/linear-algebra/vector.js"
4
- import { applyFriction } from "./friction.js"
5
-
6
- test("it should apply no friction on no velocity", () => {
7
- const friction = 250
8
- const dt = 1
9
-
10
- expect(applyFriction({ friction }, { dt })).toStrictEqual(zero())
11
- })
12
-
13
- test("it should apply no friction if no friction is passed", () => {
14
- const velocity = [0, 0, 0]
15
- const dt = 1
16
-
17
- expect(applyFriction({ velocity }, { dt })).toBe(velocity)
18
- })
19
-
20
- test("it should apply no friction if no time passed", () => {
21
- const velocity = [0, 0, 0]
22
- const friction = 5
23
-
24
- expect(applyFriction({ velocity, friction })).toBe(velocity)
25
- })
26
-
27
- test("it should apply friction to some velocity", () => {
28
- const velocity = [8, 0, 6]
29
- const friction = 5
30
- const dt = 1
31
- const expectedResult = [4, 0, 3]
32
-
33
- expect(applyFriction({ velocity, friction }, { dt })).toStrictEqual(
34
- expectedResult,
35
- )
36
- })
37
-
38
- test("it should stop movement when friction is equal to velocity", () => {
39
- const velocity = [8, 0, 6]
40
- const friction = 5
41
- const dt = 2
42
-
43
- expect(applyFriction({ velocity, friction }, { dt })).toStrictEqual(zero())
44
- })
1
+ import { expect, test } from "vitest"
2
+
3
+ import { zero } from "../math/linear-algebra/vector.js"
4
+ import { applyFriction } from "./friction.js"
5
+
6
+ test("it should apply friction to some velocity", () => {
7
+ const velocity = [8, 0, 6]
8
+ const friction = 5
9
+ const expectedResult = [4, 0, 3]
10
+
11
+ expect(applyFriction({ velocity, friction })).toStrictEqual(expectedResult)
12
+ })
13
+
14
+ test("it should stop movement when friction is equal to velocity", () => {
15
+ const velocity = [8, 0, 6]
16
+ const friction = 5
17
+ const dt = 2
18
+
19
+ expect(applyFriction({ velocity, friction }, dt)).toStrictEqual(zero())
20
+ })
21
+
22
+ test("it should apply no friction on no velocity", () => {
23
+ const velocity = zero()
24
+ const friction = 5
25
+
26
+ expect(applyFriction({ velocity, friction })).toBe(velocity)
27
+ })
28
+
29
+ test("it should apply no friction if no friction is passed", () => {
30
+ const velocity = [8, 0, 6]
31
+ const friction = 0
32
+
33
+ expect(applyFriction({ velocity, friction })).toStrictEqual(velocity)
34
+ })
35
+
36
+ test("it should apply no friction if no time passed", () => {
37
+ const velocity = [8, 0, 6]
38
+ const friction = 5
39
+ const dt = 0
40
+
41
+ expect(applyFriction({ velocity, friction }, dt)).toStrictEqual(velocity)
42
+ })