emeraldengine 2.2.1 → 3.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 (208) hide show
  1. package/README.md +2198 -968
  2. package/dist/types/index.d.ts +75 -32
  3. package/dist/types/src/Animator.d.ts +50 -0
  4. package/dist/types/{BitmapText.d.ts → src/BitmapText.d.ts} +19 -21
  5. package/dist/types/src/Camera.d.ts +122 -0
  6. package/dist/types/src/CameraController.d.ts +107 -0
  7. package/dist/types/src/CanvasText.d.ts +91 -0
  8. package/dist/types/src/CollisionLayers.d.ts +58 -0
  9. package/dist/types/{Color.d.ts → src/Color.d.ts} +6 -6
  10. package/dist/types/src/Coroutine.d.ts +111 -0
  11. package/dist/types/src/DebugOverlay.d.ts +86 -0
  12. package/dist/types/src/Drawable.d.ts +271 -0
  13. package/dist/types/src/Easing.d.ts +22 -0
  14. package/dist/types/src/Emerald.d.ts +420 -0
  15. package/dist/types/src/EmeraldDB.d.ts +159 -0
  16. package/dist/types/{FPSCounter.d.ts → src/FPSCounter.d.ts} +1 -3
  17. package/dist/types/src/GLUtils.d.ts +4 -0
  18. package/dist/types/{Instance.d.ts → src/Instance.d.ts} +37 -15
  19. package/dist/types/{InstancedTexture.d.ts → src/InstancedTexture.d.ts} +75 -23
  20. package/dist/types/src/Interpolator.d.ts +66 -0
  21. package/dist/types/src/Material.d.ts +87 -0
  22. package/dist/types/src/MathUtils.d.ts +81 -0
  23. package/dist/types/src/ParticleEmitter.d.ts +131 -0
  24. package/dist/types/src/Physics.d.ts +337 -0
  25. package/dist/types/src/Pool.d.ts +53 -0
  26. package/dist/types/src/PostEffects.d.ts +68 -0
  27. package/dist/types/src/PostProcessor.d.ts +124 -0
  28. package/dist/types/src/RenderTarget.d.ts +56 -0
  29. package/dist/types/src/Scene.d.ts +62 -0
  30. package/dist/types/src/ScreenEffects.d.ts +111 -0
  31. package/dist/types/src/Serializer.d.ts +86 -0
  32. package/dist/types/src/Shaders.d.ts +2 -0
  33. package/dist/types/{Shapes.d.ts → src/Shapes.d.ts} +4 -6
  34. package/dist/types/src/SpatialGrid.d.ts +50 -0
  35. package/dist/types/src/SpriteBatch.d.ts +89 -0
  36. package/dist/types/src/StateMachine.d.ts +59 -0
  37. package/dist/types/src/Storage.d.ts +89 -0
  38. package/dist/types/{Texture.d.ts → src/Texture.d.ts} +3 -4
  39. package/dist/types/src/TextureAtlas.d.ts +55 -0
  40. package/dist/types/src/Tilemap.d.ts +91 -0
  41. package/dist/types/src/Time.d.ts +53 -0
  42. package/dist/types/src/Timer.d.ts +54 -0
  43. package/dist/types/src/Transform.d.ts +94 -0
  44. package/dist/types/src/Tween.d.ts +81 -0
  45. package/dist/types/src/UI.d.ts +121 -0
  46. package/dist/types/src/components/Behaviour.d.ts +71 -0
  47. package/dist/types/{components → src/components}/BoxCollider.d.ts +14 -14
  48. package/dist/types/src/components/BoxColliderDebug.d.ts +15 -0
  49. package/dist/types/{components → src/components}/CircleCollider.d.ts +14 -12
  50. package/dist/types/src/components/CircleColliderDebug.d.ts +15 -0
  51. package/dist/types/src/components/Collider.d.ts +102 -0
  52. package/dist/types/src/components/GameObject.d.ts +135 -0
  53. package/dist/types/src/components/PolygonCollider.d.ts +33 -0
  54. package/dist/types/src/components/RigidBody.d.ts +456 -0
  55. package/dist/types/src/importers/Aseprite.d.ts +79 -0
  56. package/dist/types/src/importers/ForgeLevel.d.ts +97 -0
  57. package/dist/types/src/importers/TiledMap.d.ts +62 -0
  58. package/dist/types/{lights → src/lights}/DirectionalLight.d.ts +7 -9
  59. package/dist/types/{lights → src/lights}/PointLight.d.ts +6 -9
  60. package/dist/types/src/managers/AssetManager.d.ts +116 -0
  61. package/dist/types/src/managers/AudioManager.d.ts +259 -0
  62. package/dist/types/{managers → src/managers}/CameraManager.d.ts +8 -8
  63. package/dist/types/{managers → src/managers}/EventManager.d.ts +46 -32
  64. package/dist/types/src/managers/GLManager.d.ts +84 -0
  65. package/dist/types/src/managers/GLState.d.ts +37 -0
  66. package/dist/types/src/managers/Gamepad.d.ts +102 -0
  67. package/dist/types/src/managers/IDManager.d.ts +31 -0
  68. package/dist/types/src/managers/InputManager.d.ts +381 -0
  69. package/dist/types/src/managers/NetworkManager.d.ts +93 -0
  70. package/dist/types/src/managers/RenderStats.d.ts +34 -0
  71. package/dist/types/src/managers/SceneManager.d.ts +44 -0
  72. package/dist/types/src/managers/ShaderManager.d.ts +55 -0
  73. package/dist/types/src/managers/TextureManager.d.ts +102 -0
  74. package/dist/types/src/particlesystem/Particle.d.ts +64 -0
  75. package/dist/types/{particlesystem → src/particlesystem}/ParticleSettings.d.ts +32 -24
  76. package/dist/types/{particlesystem → src/particlesystem}/Particles.d.ts +20 -12
  77. package/dist/types/src/physics/AABB.d.ts +92 -0
  78. package/dist/types/src/physics/Body.d.ts +435 -0
  79. package/dist/types/src/physics/BodyType.d.ts +6 -0
  80. package/dist/types/src/physics/BroadPhase.d.ts +210 -0
  81. package/dist/types/src/physics/Collision.d.ts +102 -0
  82. package/dist/types/src/physics/Contact.d.ts +206 -0
  83. package/dist/types/src/physics/ContactSolver.d.ts +108 -0
  84. package/dist/types/src/physics/Distance.d.ts +54 -0
  85. package/dist/types/src/physics/DistanceJoint.d.ts +90 -0
  86. package/dist/types/src/physics/Fixture.d.ts +221 -0
  87. package/dist/types/src/physics/Island.d.ts +52 -0
  88. package/dist/types/src/physics/Joint.d.ts +59 -0
  89. package/dist/types/src/physics/Math2D.d.ts +371 -0
  90. package/dist/types/src/physics/RevoluteJoint.d.ts +119 -0
  91. package/dist/types/src/physics/Settings.d.ts +22 -0
  92. package/dist/types/src/physics/Shapes.d.ts +207 -0
  93. package/dist/types/src/physics/TimeOfImpact.d.ts +22 -0
  94. package/dist/types/src/physics/World.d.ts +274 -0
  95. package/dist/types/src/physics/index.d.ts +34 -0
  96. package/index.js +78 -0
  97. package/package.json +73 -60
  98. package/src/Animator.js +95 -0
  99. package/src/BitmapText.js +6 -5
  100. package/src/Camera.js +183 -0
  101. package/src/CameraController.js +192 -0
  102. package/src/CanvasText.js +281 -0
  103. package/src/CollisionLayers.js +86 -0
  104. package/src/Color.js +26 -18
  105. package/src/Coroutine.js +259 -0
  106. package/src/DebugOverlay.js +246 -0
  107. package/src/Drawable.js +842 -582
  108. package/src/Easing.js +57 -0
  109. package/src/Emerald.js +1150 -459
  110. package/src/EmeraldDB.js +328 -0
  111. package/src/FPSCounter.js +43 -43
  112. package/src/GLUtils.js +60 -67
  113. package/src/Instance.js +41 -5
  114. package/src/InstancedTexture.js +308 -127
  115. package/src/Interpolator.js +124 -0
  116. package/src/Material.js +202 -0
  117. package/src/MathUtils.js +134 -0
  118. package/src/ParticleEmitter.js +284 -0
  119. package/src/Physics.js +431 -40
  120. package/src/Pool.js +85 -0
  121. package/src/PostEffects.js +296 -0
  122. package/src/PostProcessor.js +304 -0
  123. package/src/RenderTarget.js +134 -0
  124. package/src/Scene.js +115 -83
  125. package/src/ScreenEffects.js +266 -0
  126. package/src/Serializer.js +131 -0
  127. package/src/Shaders.js +150 -165
  128. package/src/Shapes.js +118 -129
  129. package/src/SpatialGrid.js +111 -0
  130. package/src/SpriteBatch.js +299 -0
  131. package/src/StateMachine.js +82 -0
  132. package/src/Storage.js +175 -47
  133. package/src/Texture.js +58 -67
  134. package/src/TextureAtlas.js +96 -0
  135. package/src/Tilemap.js +274 -0
  136. package/src/Time.js +51 -6
  137. package/src/Timer.js +99 -0
  138. package/src/Transform.js +100 -7
  139. package/src/Tween.js +160 -0
  140. package/src/UI.js +394 -0
  141. package/src/components/Behaviour.js +90 -0
  142. package/src/components/BoxCollider.js +29 -12
  143. package/src/components/BoxColliderDebug.js +3 -4
  144. package/src/components/CircleCollider.js +26 -12
  145. package/src/components/CircleColliderDebug.js +25 -24
  146. package/src/components/Collider.js +150 -34
  147. package/src/components/GameObject.js +130 -21
  148. package/src/components/PolygonCollider.js +55 -0
  149. package/src/components/RigidBody.js +556 -8
  150. package/src/importers/Aseprite.js +142 -0
  151. package/src/importers/ForgeLevel.js +581 -0
  152. package/src/importers/TiledMap.js +158 -0
  153. package/src/lights/DirectionalLight.js +6 -15
  154. package/src/lights/PointLight.js +4 -4
  155. package/src/managers/AssetManager.js +239 -0
  156. package/src/managers/AudioManager.js +565 -146
  157. package/src/managers/EventManager.js +488 -477
  158. package/src/managers/GLManager.js +57 -0
  159. package/src/managers/GLState.js +70 -0
  160. package/src/managers/Gamepad.js +126 -0
  161. package/src/managers/IDManager.js +24 -2
  162. package/src/managers/InputManager.js +905 -0
  163. package/src/managers/NetworkManager.js +178 -0
  164. package/src/managers/RenderStats.js +34 -0
  165. package/src/managers/SceneManager.js +30 -0
  166. package/src/managers/ShaderManager.js +0 -2
  167. package/src/managers/TextureManager.js +218 -0
  168. package/src/particlesystem/Particle.js +82 -7
  169. package/src/particlesystem/ParticleSettings.js +21 -3
  170. package/src/particlesystem/Particles.js +80 -31
  171. package/src/physics/AABB.js +207 -0
  172. package/src/physics/Body.js +862 -0
  173. package/src/physics/BodyType.js +16 -0
  174. package/src/physics/BroadPhase.js +641 -0
  175. package/src/physics/Collision.js +534 -0
  176. package/src/physics/Contact.js +500 -0
  177. package/src/physics/ContactSolver.js +526 -0
  178. package/src/physics/Distance.js +403 -0
  179. package/src/physics/DistanceJoint.js +227 -0
  180. package/src/physics/Fixture.js +346 -0
  181. package/src/physics/Island.js +203 -0
  182. package/src/physics/Joint.js +78 -0
  183. package/src/physics/Math2D.js +573 -0
  184. package/src/physics/RevoluteJoint.js +278 -0
  185. package/src/physics/Settings.js +78 -0
  186. package/src/physics/Shapes.js +549 -0
  187. package/src/physics/TimeOfImpact.js +87 -0
  188. package/src/physics/World.js +731 -0
  189. package/src/physics/index.js +79 -0
  190. package/dist/types/Drawable.d.ts +0 -157
  191. package/dist/types/Emerald.d.ts +0 -73
  192. package/dist/types/GLUtils.d.ts +0 -6
  193. package/dist/types/Physics.d.ts +0 -139
  194. package/dist/types/Scene.d.ts +0 -39
  195. package/dist/types/Shaders.d.ts +0 -4
  196. package/dist/types/Storage.d.ts +0 -46
  197. package/dist/types/Time.d.ts +0 -22
  198. package/dist/types/Transform.d.ts +0 -41
  199. package/dist/types/components/BoxColliderDebug.d.ts +0 -19
  200. package/dist/types/components/CircleColliderDebug.d.ts +0 -19
  201. package/dist/types/components/Collider.d.ts +0 -53
  202. package/dist/types/components/GameObject.d.ts +0 -72
  203. package/dist/types/components/RigidBody.d.ts +0 -104
  204. package/dist/types/managers/AudioManager.d.ts +0 -60
  205. package/dist/types/managers/GLManager.d.ts +0 -47
  206. package/dist/types/managers/IDManager.d.ts +0 -21
  207. package/dist/types/managers/SceneManager.d.ts +0 -22
  208. package/dist/types/particlesystem/Particle.d.ts +0 -42
@@ -34,8 +34,8 @@ export default class Particles {
34
34
  this.rotation = this.settings.rotation;
35
35
  this.scale = this.settings.scale;
36
36
  this.particles = [];
37
- this.duration = duration; // How long the effect lasts in seconds
38
- this.offset = this.settings.offset; // Distance from center
37
+ this.duration = duration;
38
+ this.offset = this.settings.offset;
39
39
  this.elapsed = 0;
40
40
  this.active = false;
41
41
  this.instanceCount = this.settings.amount;
@@ -56,12 +56,14 @@ export default class Particles {
56
56
  framesPerRow,
57
57
  totalFrames,
58
58
  this.settings.animation ? this.settings.animation.speed : 0,
59
- this.settings.animation ? true : false,
59
+ this.settings.animation ? true : false
60
60
  );
61
- this.instancedTexture.clearInstances(); // Ensure clean state on creation
61
+ this.instancedTexture.clearInstances();
62
62
  this.gameObject.addComponent(this.instancedTexture);
63
-
64
- // Initialize clean state
63
+
64
+ /** @private */
65
+ this._pool = [];
66
+
65
67
  this.particles = [];
66
68
  this.active = false;
67
69
  this.elapsed = 0;
@@ -85,10 +87,8 @@ export default class Particles {
85
87
  this.stopped = false;
86
88
  this.lastEmitPosition = newPosition;
87
89
  if (this.settings.emissionRate === Infinity) {
88
- // One-shot: emit all at once
89
90
  this.emitParticles(this.settings.amount, newPosition);
90
91
  }
91
- // For continuous, particles will be emitted in update()
92
92
  }
93
93
 
94
94
  /**
@@ -113,27 +113,78 @@ export default class Particles {
113
113
  x: Math.cos(finalAngle) * speed,
114
114
  y: Math.sin(finalAngle) * speed,
115
115
  };
116
- const offsetVariation = (Math.random() - 0.5) * this.offset * 0.5;
116
+ const spawn = this._spawnOffset(finalAngle);
117
117
  const pos = new Vector3(
118
- position.x + Math.cos(finalAngle) * (this.offset + offsetVariation),
119
- position.y + Math.sin(finalAngle) * (this.offset + offsetVariation),
118
+ position.x + spawn.x,
119
+ position.y + spawn.y,
120
120
  position.z
121
121
  );
122
- const particleSettings = new ParticleSettings({
123
- ...this.settings,
124
- velocity,
125
- });
126
- if(this.particles.length < this.instanceCount) {
127
- let particle = new Particle(
128
- this.instancedTexture,
129
- pos,
130
- this.rotation,
131
- this.scale,
132
- particleSettings
133
- );
122
+ if (this.particles.length < this.instanceCount) {
123
+ let particle = this._pool.pop();
124
+ if (particle) {
125
+ particle.reset(
126
+ this.instancedTexture,
127
+ pos,
128
+ this.rotation,
129
+ this.scale,
130
+ this.settings,
131
+ velocity
132
+ );
133
+ } else {
134
+ particle = new Particle(
135
+ this.instancedTexture,
136
+ pos,
137
+ this.rotation,
138
+ this.scale,
139
+ this.settings,
140
+ velocity
141
+ );
142
+ }
134
143
  this.particles.push(particle);
135
144
  }
136
-
145
+ }
146
+ }
147
+
148
+ /**
149
+ * @method _spawnOffset
150
+ * @description Returns a spawn offset { x, y } from the emitter center based on
151
+ * the configured emitter shape.
152
+ * @param {number} finalAngle - The chosen emission angle (for the cone shape)
153
+ * @private
154
+ */
155
+ _spawnOffset(finalAngle) {
156
+ const s = this.settings;
157
+ const radius = s.shapeRadius || 0;
158
+ switch (s.shape) {
159
+ case "point":
160
+ return { x: 0, y: 0 };
161
+ case "circle": {
162
+ const a = Math.random() * Math.PI * 2;
163
+ const r = Math.sqrt(Math.random()) * radius;
164
+ return { x: Math.cos(a) * r, y: Math.sin(a) * r };
165
+ }
166
+ case "ring": {
167
+ const a = Math.random() * Math.PI * 2;
168
+ return { x: Math.cos(a) * radius, y: Math.sin(a) * radius };
169
+ }
170
+ case "box": {
171
+ const w = s.shapeSize ? s.shapeSize.x : 0;
172
+ const h = s.shapeSize ? s.shapeSize.y : 0;
173
+ return {
174
+ x: (Math.random() - 0.5) * w,
175
+ y: (Math.random() - 0.5) * h,
176
+ };
177
+ }
178
+ case "cone":
179
+ default: {
180
+ const baseOffset = this.offset || 0;
181
+ const offsetVariation = (Math.random() - 0.5) * baseOffset * 0.5;
182
+ const dist = baseOffset + offsetVariation;
183
+ return {
184
+ x: Math.cos(finalAngle) * dist,
185
+ y: Math.sin(finalAngle) * dist,
186
+ };
187
+ }
137
188
  }
138
189
  }
139
190
 
@@ -145,7 +196,6 @@ export default class Particles {
145
196
  update(deltaTime) {
146
197
  if (!this.active || this.stopped) return;
147
198
  this.elapsed += deltaTime;
148
- // Continuous emission
149
199
  if (
150
200
  this.settings.emissionRate !== Infinity &&
151
201
  this.elapsed <= this.duration
@@ -164,25 +214,24 @@ export default class Particles {
164
214
  this.emittedParticles += toEmit;
165
215
  }
166
216
  }
167
- // Update all particles and remove dead ones
168
217
  this.particles = this.particles.filter((particle) => {
169
218
  particle.update(deltaTime);
170
219
  if (!particle.isAlive()) {
171
220
  particle.destroy();
221
+ this._pool.push(particle);
172
222
  return false;
173
223
  }
174
224
  return true;
175
225
  });
176
- if (
177
- this.elapsed >= this.duration &&
178
- this.settings.emissionRate !== Infinity
179
- ) {
226
+ const pastDuration = this.elapsed >= this.duration;
227
+ if (pastDuration && this.settings.emissionRate !== Infinity) {
180
228
  this.stopped = true;
181
229
  }
182
- if (this.stopped && this.particles.length === 0) {
230
+ if ((this.stopped || pastDuration) && this.particles.length === 0) {
183
231
  this.instancedTexture.clearInstances();
184
232
  this.particles = [];
185
233
  this.active = false;
234
+ this.stopped = true;
186
235
  }
187
236
  }
188
237
 
@@ -0,0 +1,207 @@
1
+ import { Vec2 } from "./Math2D.js";
2
+
3
+ /**
4
+ * @class AABB
5
+ * @description An axis-aligned bounding box in physics space. Used by the
6
+ * broadphase to reject pairs long before any real collision maths runs.
7
+ */
8
+ class AABB {
9
+ constructor(lowerX = 0, lowerY = 0, upperX = 0, upperY = 0) {
10
+ this.lowerBound = new Vec2(lowerX, lowerY);
11
+ this.upperBound = new Vec2(upperX, upperY);
12
+ }
13
+
14
+ /**
15
+ * @method set
16
+ * @description Sets all four bounds in place.
17
+ * @param {number} lx
18
+ * @param {number} ly
19
+ * @param {number} ux
20
+ * @param {number} uy
21
+ * @returns {AABB} - this
22
+ */
23
+ set(lx, ly, ux, uy) {
24
+ this.lowerBound.set(lx, ly);
25
+ this.upperBound.set(ux, uy);
26
+ return this;
27
+ }
28
+
29
+ /**
30
+ * @method copy
31
+ * @description Copies another AABB.
32
+ * @param {AABB} other
33
+ * @returns {AABB} - this
34
+ */
35
+ copy(other) {
36
+ this.lowerBound.copy(other.lowerBound);
37
+ this.upperBound.copy(other.upperBound);
38
+ return this;
39
+ }
40
+
41
+ /**
42
+ * @method getCenter
43
+ * @description Returns the box center.
44
+ * @returns {Vec2}
45
+ */
46
+ getCenter() {
47
+ return new Vec2(
48
+ 0.5 * (this.lowerBound.x + this.upperBound.x),
49
+ 0.5 * (this.lowerBound.y + this.upperBound.y)
50
+ );
51
+ }
52
+
53
+ /**
54
+ * @method getExtents
55
+ * @description Returns the box half-extents.
56
+ * @returns {Vec2}
57
+ */
58
+ getExtents() {
59
+ return new Vec2(
60
+ 0.5 * (this.upperBound.x - this.lowerBound.x),
61
+ 0.5 * (this.upperBound.y - this.lowerBound.y)
62
+ );
63
+ }
64
+
65
+ /**
66
+ * @method getPerimeter
67
+ * @description Perimeter of the box, the cost function the AABB tree
68
+ * minimizes when choosing where to insert a leaf.
69
+ * @returns {number}
70
+ */
71
+ getPerimeter() {
72
+ return (
73
+ 2 *
74
+ (this.upperBound.x -
75
+ this.lowerBound.x +
76
+ (this.upperBound.y - this.lowerBound.y))
77
+ );
78
+ }
79
+
80
+ /**
81
+ * @method combine
82
+ * @description Sets this box to the union of two others.
83
+ * @param {AABB} a
84
+ * @param {AABB} b
85
+ * @returns {AABB} - this
86
+ */
87
+ combine(a, b) {
88
+ this.lowerBound.x = Math.min(a.lowerBound.x, b.lowerBound.x);
89
+ this.lowerBound.y = Math.min(a.lowerBound.y, b.lowerBound.y);
90
+ this.upperBound.x = Math.max(a.upperBound.x, b.upperBound.x);
91
+ this.upperBound.y = Math.max(a.upperBound.y, b.upperBound.y);
92
+ return this;
93
+ }
94
+
95
+ /**
96
+ * @method extend
97
+ * @description Grows the box by `amount` on every side.
98
+ * @param {number} amount
99
+ * @returns {AABB} - this
100
+ */
101
+ extend(amount) {
102
+ this.lowerBound.x -= amount;
103
+ this.lowerBound.y -= amount;
104
+ this.upperBound.x += amount;
105
+ this.upperBound.y += amount;
106
+ return this;
107
+ }
108
+
109
+ /**
110
+ * @method contains
111
+ * @description True when `other` lies entirely inside this box.
112
+ * @param {AABB} other
113
+ * @returns {boolean}
114
+ */
115
+ contains(other) {
116
+ return (
117
+ this.lowerBound.x <= other.lowerBound.x &&
118
+ this.lowerBound.y <= other.lowerBound.y &&
119
+ other.upperBound.x <= this.upperBound.x &&
120
+ other.upperBound.y <= this.upperBound.y
121
+ );
122
+ }
123
+
124
+ /**
125
+ * @method containsPoint
126
+ * @description True when a point lies inside this box.
127
+ * @param {Object} p - `{ x, y }`
128
+ * @returns {boolean}
129
+ */
130
+ containsPoint(p) {
131
+ return (
132
+ this.lowerBound.x <= p.x &&
133
+ p.x <= this.upperBound.x &&
134
+ this.lowerBound.y <= p.y &&
135
+ p.y <= this.upperBound.y
136
+ );
137
+ }
138
+
139
+ /**
140
+ * @method testOverlap
141
+ * @description True when two boxes overlap.
142
+ * @param {AABB} a
143
+ * @param {AABB} b
144
+ * @returns {boolean}
145
+ */
146
+ static testOverlap(a, b) {
147
+ return !(
148
+ b.lowerBound.x - a.upperBound.x > 0 ||
149
+ b.lowerBound.y - a.upperBound.y > 0 ||
150
+ a.lowerBound.x - b.upperBound.x > 0 ||
151
+ a.lowerBound.y - b.upperBound.y > 0
152
+ );
153
+ }
154
+
155
+ /**
156
+ * @method rayCast
157
+ * @description Slab test of a ray against this box.
158
+ * @param {Object} input - `{ p1, p2, maxFraction }`
159
+ * @returns {boolean} - True if the ray hits the box within maxFraction
160
+ */
161
+ rayCast(input) {
162
+ let tmin = -Number.MAX_VALUE;
163
+ let tmax = Number.MAX_VALUE;
164
+
165
+ const p = input.p1;
166
+ const dx = input.p2.x - input.p1.x;
167
+ const dy = input.p2.y - input.p1.y;
168
+ const absDx = Math.abs(dx);
169
+ const absDy = Math.abs(dy);
170
+
171
+ if (absDx < 1e-12) {
172
+ if (p.x < this.lowerBound.x || this.upperBound.x < p.x) return false;
173
+ } else {
174
+ const invD = 1 / dx;
175
+ let t1 = (this.lowerBound.x - p.x) * invD;
176
+ let t2 = (this.upperBound.x - p.x) * invD;
177
+ if (t1 > t2) {
178
+ const t = t1;
179
+ t1 = t2;
180
+ t2 = t;
181
+ }
182
+ tmin = Math.max(tmin, t1);
183
+ tmax = Math.min(tmax, t2);
184
+ if (tmin > tmax) return false;
185
+ }
186
+
187
+ if (absDy < 1e-12) {
188
+ if (p.y < this.lowerBound.y || this.upperBound.y < p.y) return false;
189
+ } else {
190
+ const invD = 1 / dy;
191
+ let t1 = (this.lowerBound.y - p.y) * invD;
192
+ let t2 = (this.upperBound.y - p.y) * invD;
193
+ if (t1 > t2) {
194
+ const t = t1;
195
+ t1 = t2;
196
+ t2 = t;
197
+ }
198
+ tmin = Math.max(tmin, t1);
199
+ tmax = Math.min(tmax, t2);
200
+ if (tmin > tmax) return false;
201
+ }
202
+
203
+ return tmax >= 0 && tmin <= (input.maxFraction ?? 1);
204
+ }
205
+ }
206
+
207
+ export default AABB;