@zylem/game-lib 0.5.0 → 0.6.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 (441) hide show
  1. package/README.md +23 -41
  2. package/dist/actions.d.ts +25 -0
  3. package/dist/actions.js +287 -8
  4. package/dist/actions.js.map +1 -0
  5. package/dist/behaviors.d.ts +106 -0
  6. package/dist/behaviors.js +396 -6
  7. package/dist/behaviors.js.map +1 -0
  8. package/dist/blueprints-BOCc3Wve.d.ts +26 -0
  9. package/dist/{src/lib/camera/zylem-camera.d.ts → camera-CpbDr4-V.d.ts} +48 -27
  10. package/dist/camera.d.ts +5 -0
  11. package/dist/camera.js +608 -4
  12. package/dist/camera.js.map +1 -0
  13. package/dist/core-CZhozNRH.d.ts +466 -0
  14. package/dist/core.d.ts +10 -0
  15. package/dist/core.js +5761 -9
  16. package/dist/core.js.map +1 -0
  17. package/dist/entities-BAxfJOkk.d.ts +307 -0
  18. package/dist/entities.d.ts +6 -0
  19. package/dist/entities.js +2284 -17
  20. package/dist/entities.js.map +1 -0
  21. package/dist/{src/lib/interfaces/entity.d.ts → entity-Bq_eNEDI.d.ts} +8 -6
  22. package/dist/entity-COvRtFNG.d.ts +395 -0
  23. package/dist/main.d.ts +211 -0
  24. package/dist/main.js +7600 -56
  25. package/dist/main.js.map +1 -0
  26. package/dist/moveable-B_vyA6cw.d.ts +67 -0
  27. package/dist/stage-types-CD21XoIU.d.ts +338 -0
  28. package/dist/stage.d.ts +46 -0
  29. package/dist/stage.js +2765 -4
  30. package/dist/stage.js.map +1 -0
  31. package/dist/transformable-CUhvyuYO.d.ts +67 -0
  32. package/package.json +11 -47
  33. package/dist/.vite/manifest.json +0 -716
  34. package/dist/assets/zylem-logo.png +0 -0
  35. package/dist/examples/00-readme-example.d.ts +0 -2
  36. package/dist/examples/00-readme-example.d.ts.map +0 -1
  37. package/dist/examples/01-basic.d.ts +0 -2
  38. package/dist/examples/01-basic.d.ts.map +0 -1
  39. package/dist/examples/01.1-basic-ball.d.ts +0 -9
  40. package/dist/examples/01.1-basic-ball.d.ts.map +0 -1
  41. package/dist/examples/01.2-ricochet-test.d.ts +0 -2
  42. package/dist/examples/01.2-ricochet-test.d.ts.map +0 -1
  43. package/dist/examples/01.3-rect.d.ts +0 -2
  44. package/dist/examples/01.3-rect.d.ts.map +0 -1
  45. package/dist/examples/02-input.d.ts +0 -2
  46. package/dist/examples/02-input.d.ts.map +0 -1
  47. package/dist/examples/03-stage-test/03-stage-test.d.ts +0 -2
  48. package/dist/examples/03-stage-test/03-stage-test.d.ts.map +0 -1
  49. package/dist/examples/03-stage-test/stage0.d.ts +0 -2
  50. package/dist/examples/03-stage-test/stage0.d.ts.map +0 -1
  51. package/dist/examples/03-stage-test/stage1.d.ts +0 -2
  52. package/dist/examples/03-stage-test/stage1.d.ts.map +0 -1
  53. package/dist/examples/03-stage-test/stage2.d.ts +0 -2
  54. package/dist/examples/03-stage-test/stage2.d.ts.map +0 -1
  55. package/dist/examples/03-stage-test/stage3.d.ts +0 -2
  56. package/dist/examples/03-stage-test/stage3.d.ts.map +0 -1
  57. package/dist/examples/03.1-stage-variable.d.ts +0 -2
  58. package/dist/examples/03.1-stage-variable.d.ts.map +0 -1
  59. package/dist/examples/04-vessel-test.d.ts +0 -18
  60. package/dist/examples/04-vessel-test.d.ts.map +0 -1
  61. package/dist/examples/05-camera-test.d.ts +0 -2
  62. package/dist/examples/05-camera-test.d.ts.map +0 -1
  63. package/dist/examples/06-entity-test.d.ts +0 -2
  64. package/dist/examples/06-entity-test.d.ts.map +0 -1
  65. package/dist/examples/07-behaviors.d.ts +0 -2
  66. package/dist/examples/07-behaviors.d.ts.map +0 -1
  67. package/dist/examples/07.01-behavior-context.d.ts +0 -2
  68. package/dist/examples/07.01-behavior-context.d.ts.map +0 -1
  69. package/dist/examples/08-pong.d.ts +0 -2
  70. package/dist/examples/08-pong.d.ts.map +0 -1
  71. package/dist/examples/08.01-breakout.d.ts +0 -2
  72. package/dist/examples/08.01-breakout.d.ts.map +0 -1
  73. package/dist/examples/09-space-invaders.d.ts +0 -2
  74. package/dist/examples/09-space-invaders.d.ts.map +0 -1
  75. package/dist/examples/10-asteroids.d.ts +0 -2
  76. package/dist/examples/10-asteroids.d.ts.map +0 -1
  77. package/dist/examples/11-2d-platformer.d.ts +0 -2
  78. package/dist/examples/11-2d-platformer.d.ts.map +0 -1
  79. package/dist/examples/12-3d-platformer.d.ts +0 -2
  80. package/dist/examples/12-3d-platformer.d.ts.map +0 -1
  81. package/dist/examples/13-fps.d.ts +0 -2
  82. package/dist/examples/13-fps.d.ts.map +0 -1
  83. package/dist/examples/14-strategy.d.ts +0 -2
  84. package/dist/examples/14-strategy.d.ts.map +0 -1
  85. package/dist/examples/15-zylem-planet-demo.d.ts +0 -2
  86. package/dist/examples/15-zylem-planet-demo.d.ts.map +0 -1
  87. package/dist/examples/16-timbotron.d.ts +0 -2
  88. package/dist/examples/16-timbotron.d.ts.map +0 -1
  89. package/dist/examples/17-stress-test.d.ts +0 -2
  90. package/dist/examples/17-stress-test.d.ts.map +0 -1
  91. package/dist/examples/architecture-test.d.ts +0 -2
  92. package/dist/examples/architecture-test.d.ts.map +0 -1
  93. package/dist/examples/utils.d.ts +0 -10
  94. package/dist/examples/utils.d.ts.map +0 -1
  95. package/dist/lib/actions/behaviors/actions.js +0 -35
  96. package/dist/lib/actions/behaviors/boundaries/boundary.js +0 -40
  97. package/dist/lib/actions/behaviors/ricochet/ricochet-2d-collision.js +0 -100
  98. package/dist/lib/actions/behaviors/ricochet/ricochet-2d-in-bounds.js +0 -37
  99. package/dist/lib/actions/behaviors/ricochet/ricochet.js +0 -6
  100. package/dist/lib/actions/capabilities/moveable.js +0 -108
  101. package/dist/lib/actions/capabilities/rotatable.js +0 -82
  102. package/dist/lib/actions/capabilities/transformable.js +0 -9
  103. package/dist/lib/actions/global-change.js +0 -40
  104. package/dist/lib/camera/camera.js +0 -19
  105. package/dist/lib/camera/fixed-2d.js +0 -30
  106. package/dist/lib/camera/perspective.js +0 -10
  107. package/dist/lib/camera/third-person.js +0 -42
  108. package/dist/lib/camera/zylem-camera.js +0 -208
  109. package/dist/lib/collision/collision-builder.js +0 -46
  110. package/dist/lib/collision/collision-delegate.js +0 -6
  111. package/dist/lib/collision/utils.js +0 -24
  112. package/dist/lib/collision/world.js +0 -77
  113. package/dist/lib/core/base-node.js +0 -61
  114. package/dist/lib/core/entity-asset-loader.js +0 -54
  115. package/dist/lib/core/lifecycle-base.js +0 -20
  116. package/dist/lib/core/preset-shader.js +0 -26
  117. package/dist/lib/core/three-addons/Timer.js +0 -103
  118. package/dist/lib/core/utility/nodes.js +0 -31
  119. package/dist/lib/core/utility/strings.js +0 -14
  120. package/dist/lib/core/utility/vector.js +0 -8
  121. package/dist/lib/core/vessel.js +0 -26
  122. package/dist/lib/debug/console/console-state.js +0 -11
  123. package/dist/lib/debug/debug-state.js +0 -40
  124. package/dist/lib/device/aspect-ratio.js +0 -44
  125. package/dist/lib/entities/actor.js +0 -122
  126. package/dist/lib/entities/box.js +0 -68
  127. package/dist/lib/entities/builder.js +0 -79
  128. package/dist/lib/entities/create.js +0 -31
  129. package/dist/lib/entities/delegates/animation.js +0 -58
  130. package/dist/lib/entities/delegates/debug.js +0 -71
  131. package/dist/lib/entities/delegates/loader.js +0 -19
  132. package/dist/lib/entities/destroy.js +0 -15
  133. package/dist/lib/entities/entity-factory.js +0 -24
  134. package/dist/lib/entities/entity.js +0 -121
  135. package/dist/lib/entities/plane.js +0 -81
  136. package/dist/lib/entities/rect.js +0 -160
  137. package/dist/lib/entities/sphere.js +0 -68
  138. package/dist/lib/entities/sprite.js +0 -125
  139. package/dist/lib/entities/text.js +0 -140
  140. package/dist/lib/entities/zone.js +0 -103
  141. package/dist/lib/game/game-canvas.js +0 -57
  142. package/dist/lib/game/game-config.js +0 -78
  143. package/dist/lib/game/game-default.js +0 -23
  144. package/dist/lib/game/game-retro-resolutions.js +0 -80
  145. package/dist/lib/game/game-state.js +0 -17
  146. package/dist/lib/game/game.js +0 -131
  147. package/dist/lib/game/zylem-game.js +0 -140
  148. package/dist/lib/graphics/geometries/XZPlaneGeometry.js +0 -34
  149. package/dist/lib/graphics/material.js +0 -64
  150. package/dist/lib/graphics/mesh.js +0 -14
  151. package/dist/lib/graphics/render-pass.js +0 -56
  152. package/dist/lib/graphics/shaders/fragment/debug.glsl.js +0 -23
  153. package/dist/lib/graphics/shaders/fragment/fire.glsl.js +0 -52
  154. package/dist/lib/graphics/shaders/fragment/standard.glsl.js +0 -11
  155. package/dist/lib/graphics/shaders/fragment/stars.glsl.js +0 -44
  156. package/dist/lib/graphics/shaders/vertex/debug.glsl.js +0 -15
  157. package/dist/lib/graphics/shaders/vertex/object-shader.glsl.js +0 -11
  158. package/dist/lib/graphics/shaders/vertex/standard.glsl.js +0 -9
  159. package/dist/lib/graphics/zylem-scene.js +0 -75
  160. package/dist/lib/input/gamepad-provider.js +0 -58
  161. package/dist/lib/input/input-manager.js +0 -70
  162. package/dist/lib/input/keyboard-provider.js +0 -120
  163. package/dist/lib/stage/debug-entity-cursor.js +0 -53
  164. package/dist/lib/stage/entity-spawner.js +0 -27
  165. package/dist/lib/stage/stage-debug-delegate.js +0 -100
  166. package/dist/lib/stage/stage-default.js +0 -32
  167. package/dist/lib/stage/stage-factory.js +0 -22
  168. package/dist/lib/stage/stage-manager.js +0 -49
  169. package/dist/lib/stage/stage-state.js +0 -36
  170. package/dist/lib/stage/stage.js +0 -67
  171. package/dist/lib/stage/zylem-stage.js +0 -268
  172. package/dist/lib/systems/transformable.system.js +0 -43
  173. package/dist/node_modules/.pnpm/idb-keyval@6.2.2/node_modules/idb-keyval/dist/index.js +0 -34
  174. package/dist/node_modules/.pnpm/msgpackr@1.11.5/node_modules/msgpackr/pack.js +0 -520
  175. package/dist/node_modules/.pnpm/msgpackr@1.11.5/node_modules/msgpackr/unpack.js +0 -672
  176. package/dist/src/api/actions.d.ts +0 -5
  177. package/dist/src/api/actions.d.ts.map +0 -1
  178. package/dist/src/api/behaviors.d.ts +0 -4
  179. package/dist/src/api/behaviors.d.ts.map +0 -1
  180. package/dist/src/api/camera.d.ts +0 -4
  181. package/dist/src/api/camera.d.ts.map +0 -1
  182. package/dist/src/api/core.d.ts +0 -6
  183. package/dist/src/api/core.d.ts.map +0 -1
  184. package/dist/src/api/entities.d.ts +0 -9
  185. package/dist/src/api/entities.d.ts.map +0 -1
  186. package/dist/src/api/main.d.ts +0 -32
  187. package/dist/src/api/main.d.ts.map +0 -1
  188. package/dist/src/api/stage.d.ts +0 -5
  189. package/dist/src/api/stage.d.ts.map +0 -1
  190. package/dist/src/lib/actions/behaviors/actions.d.ts +0 -11
  191. package/dist/src/lib/actions/behaviors/actions.d.ts.map +0 -1
  192. package/dist/src/lib/actions/behaviors/behavior.d.ts +0 -6
  193. package/dist/src/lib/actions/behaviors/behavior.d.ts.map +0 -1
  194. package/dist/src/lib/actions/behaviors/boundaries/boundary.d.ts +0 -37
  195. package/dist/src/lib/actions/behaviors/boundaries/boundary.d.ts.map +0 -1
  196. package/dist/src/lib/actions/behaviors/character-controller.d.ts +0 -6
  197. package/dist/src/lib/actions/behaviors/character-controller.d.ts.map +0 -1
  198. package/dist/src/lib/actions/behaviors/debug/debug-collision.d.ts +0 -6
  199. package/dist/src/lib/actions/behaviors/debug/debug-collision.d.ts.map +0 -1
  200. package/dist/src/lib/actions/behaviors/debug/debug-update.d.ts +0 -5
  201. package/dist/src/lib/actions/behaviors/debug/debug-update.d.ts.map +0 -1
  202. package/dist/src/lib/actions/behaviors/debug/debug.d.ts +0 -10
  203. package/dist/src/lib/actions/behaviors/debug/debug.d.ts.map +0 -1
  204. package/dist/src/lib/actions/behaviors/movement/movement-sequence-2d.d.ts +0 -24
  205. package/dist/src/lib/actions/behaviors/movement/movement-sequence-2d.d.ts.map +0 -1
  206. package/dist/src/lib/actions/behaviors/ricochet/ricochet-2d-collision.d.ts +0 -11
  207. package/dist/src/lib/actions/behaviors/ricochet/ricochet-2d-collision.d.ts.map +0 -1
  208. package/dist/src/lib/actions/behaviors/ricochet/ricochet-2d-in-bounds.d.ts +0 -12
  209. package/dist/src/lib/actions/behaviors/ricochet/ricochet-2d-in-bounds.d.ts.map +0 -1
  210. package/dist/src/lib/actions/behaviors/ricochet/ricochet.d.ts +0 -44
  211. package/dist/src/lib/actions/behaviors/ricochet/ricochet.d.ts.map +0 -1
  212. package/dist/src/lib/actions/behaviors/zylem-behavior.d.ts +0 -2
  213. package/dist/src/lib/actions/behaviors/zylem-behavior.d.ts.map +0 -1
  214. package/dist/src/lib/actions/capabilities/moveable.d.ts +0 -125
  215. package/dist/src/lib/actions/capabilities/moveable.d.ts.map +0 -1
  216. package/dist/src/lib/actions/capabilities/rotatable.d.ts +0 -111
  217. package/dist/src/lib/actions/capabilities/rotatable.d.ts.map +0 -1
  218. package/dist/src/lib/actions/capabilities/transformable.d.ts +0 -7
  219. package/dist/src/lib/actions/capabilities/transformable.d.ts.map +0 -1
  220. package/dist/src/lib/actions/global-change.d.ts +0 -23
  221. package/dist/src/lib/actions/global-change.d.ts.map +0 -1
  222. package/dist/src/lib/camera/camera.d.ts +0 -16
  223. package/dist/src/lib/camera/camera.d.ts.map +0 -1
  224. package/dist/src/lib/camera/fixed-2d.d.ts +0 -32
  225. package/dist/src/lib/camera/fixed-2d.d.ts.map +0 -1
  226. package/dist/src/lib/camera/perspective.d.ts +0 -9
  227. package/dist/src/lib/camera/perspective.d.ts.map +0 -1
  228. package/dist/src/lib/camera/third-person.d.ts +0 -32
  229. package/dist/src/lib/camera/third-person.d.ts.map +0 -1
  230. package/dist/src/lib/camera/zylem-camera.d.ts.map +0 -1
  231. package/dist/src/lib/collision/collision-builder.d.ts +0 -17
  232. package/dist/src/lib/collision/collision-builder.d.ts.map +0 -1
  233. package/dist/src/lib/collision/collision-delegate.d.ts +0 -6
  234. package/dist/src/lib/collision/collision-delegate.d.ts.map +0 -1
  235. package/dist/src/lib/collision/collision-group.d.ts +0 -11
  236. package/dist/src/lib/collision/collision-group.d.ts.map +0 -1
  237. package/dist/src/lib/collision/collision-mask.d.ts +0 -18
  238. package/dist/src/lib/collision/collision-mask.d.ts.map +0 -1
  239. package/dist/src/lib/collision/collision.d.ts +0 -19
  240. package/dist/src/lib/collision/collision.d.ts.map +0 -1
  241. package/dist/src/lib/collision/utils.d.ts +0 -15
  242. package/dist/src/lib/collision/utils.d.ts.map +0 -1
  243. package/dist/src/lib/collision/world.d.ts +0 -23
  244. package/dist/src/lib/collision/world.d.ts.map +0 -1
  245. package/dist/src/lib/core/asset-manager.d.ts +0 -2
  246. package/dist/src/lib/core/asset-manager.d.ts.map +0 -1
  247. package/dist/src/lib/core/base-node-life-cycle.d.ts +0 -54
  248. package/dist/src/lib/core/base-node-life-cycle.d.ts.map +0 -1
  249. package/dist/src/lib/core/base-node.d.ts +0 -36
  250. package/dist/src/lib/core/base-node.d.ts.map +0 -1
  251. package/dist/src/lib/core/blueprints.d.ts +0 -22
  252. package/dist/src/lib/core/blueprints.d.ts.map +0 -1
  253. package/dist/src/lib/core/entity-asset-loader.d.ts +0 -16
  254. package/dist/src/lib/core/entity-asset-loader.d.ts.map +0 -1
  255. package/dist/src/lib/core/errors.d.ts +0 -5
  256. package/dist/src/lib/core/errors.d.ts.map +0 -1
  257. package/dist/src/lib/core/flags.d.ts +0 -3
  258. package/dist/src/lib/core/flags.d.ts.map +0 -1
  259. package/dist/src/lib/core/index.d.ts +0 -5
  260. package/dist/src/lib/core/index.d.ts.map +0 -1
  261. package/dist/src/lib/core/interfaces.d.ts +0 -25
  262. package/dist/src/lib/core/interfaces.d.ts.map +0 -1
  263. package/dist/src/lib/core/lazy-loader.d.ts +0 -80
  264. package/dist/src/lib/core/lazy-loader.d.ts.map +0 -1
  265. package/dist/src/lib/core/lifecycle-base.d.ts +0 -17
  266. package/dist/src/lib/core/lifecycle-base.d.ts.map +0 -1
  267. package/dist/src/lib/core/node-interface.d.ts +0 -12
  268. package/dist/src/lib/core/node-interface.d.ts.map +0 -1
  269. package/dist/src/lib/core/preset-shader.d.ts +0 -8
  270. package/dist/src/lib/core/preset-shader.d.ts.map +0 -1
  271. package/dist/src/lib/core/three-addons/Timer.d.ts +0 -92
  272. package/dist/src/lib/core/three-addons/Timer.d.ts.map +0 -1
  273. package/dist/src/lib/core/utility/nodes.d.ts +0 -13
  274. package/dist/src/lib/core/utility/nodes.d.ts.map +0 -1
  275. package/dist/src/lib/core/utility/strings.d.ts +0 -3
  276. package/dist/src/lib/core/utility/strings.d.ts.map +0 -1
  277. package/dist/src/lib/core/utility/vector.d.ts +0 -8
  278. package/dist/src/lib/core/utility/vector.d.ts.map +0 -1
  279. package/dist/src/lib/core/vector.d.ts +0 -4
  280. package/dist/src/lib/core/vector.d.ts.map +0 -1
  281. package/dist/src/lib/core/vessel.d.ts +0 -13
  282. package/dist/src/lib/core/vessel.d.ts.map +0 -1
  283. package/dist/src/lib/debug/console/console-state.d.ts +0 -20
  284. package/dist/src/lib/debug/console/console-state.d.ts.map +0 -1
  285. package/dist/src/lib/debug/console/console-store.d.ts +0 -6
  286. package/dist/src/lib/debug/console/console-store.d.ts.map +0 -1
  287. package/dist/src/lib/debug/debug-state.d.ts +0 -38
  288. package/dist/src/lib/debug/debug-state.d.ts.map +0 -1
  289. package/dist/src/lib/debug/debug-store.d.ts +0 -15
  290. package/dist/src/lib/debug/debug-store.d.ts.map +0 -1
  291. package/dist/src/lib/debug/state-based-debug-loader.d.ts +0 -8
  292. package/dist/src/lib/debug/state-based-debug-loader.d.ts.map +0 -1
  293. package/dist/src/lib/device/aspect-ratio.d.ts +0 -38
  294. package/dist/src/lib/device/aspect-ratio.d.ts.map +0 -1
  295. package/dist/src/lib/device/desktop.d.ts +0 -2
  296. package/dist/src/lib/device/desktop.d.ts.map +0 -1
  297. package/dist/src/lib/device/mobile.d.ts +0 -2
  298. package/dist/src/lib/device/mobile.d.ts.map +0 -1
  299. package/dist/src/lib/device/tablet.d.ts +0 -2
  300. package/dist/src/lib/device/tablet.d.ts.map +0 -1
  301. package/dist/src/lib/entities/actor.d.ts +0 -44
  302. package/dist/src/lib/entities/actor.d.ts.map +0 -1
  303. package/dist/src/lib/entities/box.d.ts +0 -27
  304. package/dist/src/lib/entities/box.d.ts.map +0 -1
  305. package/dist/src/lib/entities/builder.d.ts +0 -28
  306. package/dist/src/lib/entities/builder.d.ts.map +0 -1
  307. package/dist/src/lib/entities/create.d.ts +0 -15
  308. package/dist/src/lib/entities/create.d.ts.map +0 -1
  309. package/dist/src/lib/entities/delegates/animation.d.ts +0 -33
  310. package/dist/src/lib/entities/delegates/animation.d.ts.map +0 -1
  311. package/dist/src/lib/entities/delegates/debug.d.ts +0 -29
  312. package/dist/src/lib/entities/delegates/debug.d.ts.map +0 -1
  313. package/dist/src/lib/entities/delegates/loader.d.ts +0 -12
  314. package/dist/src/lib/entities/delegates/loader.d.ts.map +0 -1
  315. package/dist/src/lib/entities/destroy.d.ts +0 -4
  316. package/dist/src/lib/entities/destroy.d.ts.map +0 -1
  317. package/dist/src/lib/entities/entity-factory.d.ts +0 -10
  318. package/dist/src/lib/entities/entity-factory.d.ts.map +0 -1
  319. package/dist/src/lib/entities/entity.d.ts +0 -98
  320. package/dist/src/lib/entities/entity.d.ts.map +0 -1
  321. package/dist/src/lib/entities/index.d.ts +0 -12
  322. package/dist/src/lib/entities/index.d.ts.map +0 -1
  323. package/dist/src/lib/entities/plane.d.ts +0 -36
  324. package/dist/src/lib/entities/plane.d.ts.map +0 -1
  325. package/dist/src/lib/entities/rect.d.ts +0 -63
  326. package/dist/src/lib/entities/rect.d.ts.map +0 -1
  327. package/dist/src/lib/entities/sphere.d.ts +0 -29
  328. package/dist/src/lib/entities/sphere.d.ts.map +0 -1
  329. package/dist/src/lib/entities/sprite.d.ts +0 -54
  330. package/dist/src/lib/entities/sprite.d.ts.map +0 -1
  331. package/dist/src/lib/entities/text.d.ts +0 -49
  332. package/dist/src/lib/entities/text.d.ts.map +0 -1
  333. package/dist/src/lib/entities/zone.d.ts +0 -54
  334. package/dist/src/lib/entities/zone.d.ts.map +0 -1
  335. package/dist/src/lib/game/game-blueprint.d.ts +0 -38
  336. package/dist/src/lib/game/game-blueprint.d.ts.map +0 -1
  337. package/dist/src/lib/game/game-canvas.d.ts +0 -35
  338. package/dist/src/lib/game/game-canvas.d.ts.map +0 -1
  339. package/dist/src/lib/game/game-config.d.ts +0 -59
  340. package/dist/src/lib/game/game-config.d.ts.map +0 -1
  341. package/dist/src/lib/game/game-default.d.ts +0 -14
  342. package/dist/src/lib/game/game-default.d.ts.map +0 -1
  343. package/dist/src/lib/game/game-interfaces.d.ts +0 -29
  344. package/dist/src/lib/game/game-interfaces.d.ts.map +0 -1
  345. package/dist/src/lib/game/game-retro-resolutions.d.ts +0 -25
  346. package/dist/src/lib/game/game-retro-resolutions.d.ts.map +0 -1
  347. package/dist/src/lib/game/game-state.d.ts +0 -11
  348. package/dist/src/lib/game/game-state.d.ts.map +0 -1
  349. package/dist/src/lib/game/game.d.ts +0 -39
  350. package/dist/src/lib/game/game.d.ts.map +0 -1
  351. package/dist/src/lib/game/zylem-game.d.ts +0 -58
  352. package/dist/src/lib/game/zylem-game.d.ts.map +0 -1
  353. package/dist/src/lib/graphics/geometries/XZPlaneGeometry.d.ts +0 -8
  354. package/dist/src/lib/graphics/geometries/XZPlaneGeometry.d.ts.map +0 -1
  355. package/dist/src/lib/graphics/material.d.ts +0 -29
  356. package/dist/src/lib/graphics/material.d.ts.map +0 -1
  357. package/dist/src/lib/graphics/mesh.d.ts +0 -19
  358. package/dist/src/lib/graphics/mesh.d.ts.map +0 -1
  359. package/dist/src/lib/graphics/render-pass.d.ts +0 -17
  360. package/dist/src/lib/graphics/render-pass.d.ts.map +0 -1
  361. package/dist/src/lib/graphics/zylem-scene.d.ts +0 -50
  362. package/dist/src/lib/graphics/zylem-scene.d.ts.map +0 -1
  363. package/dist/src/lib/input/gamepad-provider.d.ts +0 -14
  364. package/dist/src/lib/input/gamepad-provider.d.ts.map +0 -1
  365. package/dist/src/lib/input/input-manager.d.ts +0 -15
  366. package/dist/src/lib/input/input-manager.d.ts.map +0 -1
  367. package/dist/src/lib/input/input-provider.d.ts +0 -7
  368. package/dist/src/lib/input/input-provider.d.ts.map +0 -1
  369. package/dist/src/lib/input/input.d.ts +0 -48
  370. package/dist/src/lib/input/input.d.ts.map +0 -1
  371. package/dist/src/lib/input/keyboard-provider.d.ts +0 -21
  372. package/dist/src/lib/input/keyboard-provider.d.ts.map +0 -1
  373. package/dist/src/lib/interfaces/entity.d.ts.map +0 -1
  374. package/dist/src/lib/sounds/index.d.ts +0 -3
  375. package/dist/src/lib/sounds/index.d.ts.map +0 -1
  376. package/dist/src/lib/sounds/ping-pong-sound.d.ts +0 -5
  377. package/dist/src/lib/sounds/ping-pong-sound.d.ts.map +0 -1
  378. package/dist/src/lib/sounds/ricochet-sound.d.ts +0 -5
  379. package/dist/src/lib/sounds/ricochet-sound.d.ts.map +0 -1
  380. package/dist/src/lib/stage/debug-entity-cursor.d.ts +0 -24
  381. package/dist/src/lib/stage/debug-entity-cursor.d.ts.map +0 -1
  382. package/dist/src/lib/stage/entity-spawner.d.ts +0 -9
  383. package/dist/src/lib/stage/entity-spawner.d.ts.map +0 -1
  384. package/dist/src/lib/stage/stage-camera-debug-delegate.d.ts +0 -14
  385. package/dist/src/lib/stage/stage-camera-debug-delegate.d.ts.map +0 -1
  386. package/dist/src/lib/stage/stage-debug-delegate.d.ts +0 -26
  387. package/dist/src/lib/stage/stage-debug-delegate.d.ts.map +0 -1
  388. package/dist/src/lib/stage/stage-default.d.ts +0 -3
  389. package/dist/src/lib/stage/stage-default.d.ts.map +0 -1
  390. package/dist/src/lib/stage/stage-factory.d.ts +0 -6
  391. package/dist/src/lib/stage/stage-factory.d.ts.map +0 -1
  392. package/dist/src/lib/stage/stage-manager.d.ts +0 -30
  393. package/dist/src/lib/stage/stage-manager.d.ts.map +0 -1
  394. package/dist/src/lib/stage/stage-state.d.ts +0 -14
  395. package/dist/src/lib/stage/stage-state.d.ts.map +0 -1
  396. package/dist/src/lib/stage/stage.d.ts +0 -35
  397. package/dist/src/lib/stage/stage.d.ts.map +0 -1
  398. package/dist/src/lib/stage/zylem-stage.d.ts +0 -128
  399. package/dist/src/lib/stage/zylem-stage.d.ts.map +0 -1
  400. package/dist/src/lib/systems/test-system.d.ts +0 -2
  401. package/dist/src/lib/systems/test-system.d.ts.map +0 -1
  402. package/dist/src/lib/systems/transformable.system.d.ts +0 -25
  403. package/dist/src/lib/systems/transformable.system.d.ts.map +0 -1
  404. package/dist/src/lib/types/entity-types.d.ts +0 -24
  405. package/dist/src/lib/types/entity-types.d.ts.map +0 -1
  406. package/dist/src/lib/types/index.d.ts +0 -3
  407. package/dist/src/lib/types/index.d.ts.map +0 -1
  408. package/dist/src/lib/types/stage-types.d.ts +0 -26
  409. package/dist/src/lib/types/stage-types.d.ts.map +0 -1
  410. package/dist/src/lib/ui/Debug.d.ts +0 -6
  411. package/dist/src/lib/ui/Debug.d.ts.map +0 -1
  412. package/dist/src/lib/ui/console/Console.d.ts +0 -7
  413. package/dist/src/lib/ui/console/Console.d.ts.map +0 -1
  414. package/dist/src/lib/ui/debug-panel/AccordionMenu.d.ts +0 -7
  415. package/dist/src/lib/ui/debug-panel/AccordionMenu.d.ts.map +0 -1
  416. package/dist/src/lib/ui/debug-panel/Menu.d.ts +0 -6
  417. package/dist/src/lib/ui/debug-panel/Menu.d.ts.map +0 -1
  418. package/dist/src/lib/ui/debug-panel/sections/EntitiesSection.d.ts +0 -4
  419. package/dist/src/lib/ui/debug-panel/sections/EntitiesSection.d.ts.map +0 -1
  420. package/dist/src/lib/ui/debug-panel/sections/GameSection.d.ts +0 -3
  421. package/dist/src/lib/ui/debug-panel/sections/GameSection.d.ts.map +0 -1
  422. package/dist/src/lib/ui/debug-panel/sections/StagesSection.d.ts +0 -3
  423. package/dist/src/lib/ui/debug-panel/sections/StagesSection.d.ts.map +0 -1
  424. package/dist/src/lib/ui/debug-panel/sections/all.d.ts +0 -4
  425. package/dist/src/lib/ui/debug-panel/sections/all.d.ts.map +0 -1
  426. package/dist/src/lib/ui/toolbar/Toolbar.d.ts +0 -6
  427. package/dist/src/lib/ui/toolbar/Toolbar.d.ts.map +0 -1
  428. package/dist/tests/e2e/basic-game.spec.d.ts +0 -2
  429. package/dist/tests/e2e/basic-game.spec.d.ts.map +0 -1
  430. package/dist/tests/integration/debug.sim.spec.d.ts +0 -2
  431. package/dist/tests/integration/debug.sim.spec.d.ts.map +0 -1
  432. package/dist/tests/unit/collision/collision.spec.d.ts +0 -2
  433. package/dist/tests/unit/collision/collision.spec.d.ts.map +0 -1
  434. package/dist/tests/unit/core/base-node.spec.d.ts +0 -2
  435. package/dist/tests/unit/core/base-node.spec.d.ts.map +0 -1
  436. package/dist/tests/unit/core/game.spec.d.ts +0 -2
  437. package/dist/tests/unit/core/game.spec.d.ts.map +0 -1
  438. package/dist/tests/unit/core/stage.spec.d.ts +0 -2
  439. package/dist/tests/unit/core/stage.spec.d.ts.map +0 -1
  440. package/dist/tests/unit/core/vessel.spec.d.ts +0 -2
  441. package/dist/tests/unit/core/vessel.spec.d.ts.map +0 -1
package/dist/entities.js CHANGED
@@ -1,19 +1,2286 @@
1
- import { ZylemBox as e, box as t } from "./lib/entities/box.js";
2
- import { sphere as x } from "./lib/entities/sphere.js";
3
- import { sprite as f } from "./lib/entities/sprite.js";
4
- import { plane as c } from "./lib/entities/plane.js";
5
- import { zone as n } from "./lib/entities/zone.js";
6
- import { actor as b } from "./lib/entities/actor.js";
7
- import { text as i } from "./lib/entities/text.js";
8
- import { rect as z } from "./lib/entities/rect.js";
1
+ // src/lib/entities/box.ts
2
+ import { ColliderDesc as ColliderDesc2 } from "@dimforge/rapier3d-compat";
3
+ import { BoxGeometry, Color as Color4 } from "three";
4
+ import { Vector3 as Vector33 } from "three";
5
+
6
+ // src/lib/entities/entity.ts
7
+ import { ShaderMaterial } from "three";
8
+
9
+ // src/lib/systems/transformable.system.ts
10
+ import {
11
+ defineSystem,
12
+ defineQuery,
13
+ defineComponent,
14
+ Types,
15
+ removeQuery
16
+ } from "bitecs";
17
+ import { Quaternion } from "three";
18
+ var position = defineComponent({
19
+ x: Types.f32,
20
+ y: Types.f32,
21
+ z: Types.f32
22
+ });
23
+ var rotation = defineComponent({
24
+ x: Types.f32,
25
+ y: Types.f32,
26
+ z: Types.f32,
27
+ w: Types.f32
28
+ });
29
+ var scale = defineComponent({
30
+ x: Types.f32,
31
+ y: Types.f32,
32
+ z: Types.f32
33
+ });
34
+ var _tempQuaternion = new Quaternion();
35
+
36
+ // src/lib/core/flags.ts
37
+ var DEBUG_FLAG = import.meta.env.VITE_DEBUG_FLAG === "true";
38
+
39
+ // src/lib/core/base-node.ts
40
+ import { nanoid } from "nanoid";
41
+ var BaseNode = class _BaseNode {
42
+ parent = null;
43
+ children = [];
44
+ options;
45
+ eid = 0;
46
+ uuid = "";
47
+ name = "";
48
+ markedForRemoval = false;
49
+ /**
50
+ * Lifecycle callback arrays - use onSetup(), onUpdate(), etc. to add callbacks
51
+ */
52
+ lifecycleCallbacks = {
53
+ setup: [],
54
+ loaded: [],
55
+ update: [],
56
+ destroy: [],
57
+ cleanup: []
58
+ };
59
+ constructor(args = []) {
60
+ const options = args.filter((arg) => !(arg instanceof _BaseNode)).reduce((acc, opt) => ({ ...acc, ...opt }), {});
61
+ this.options = options;
62
+ this.uuid = nanoid();
63
+ }
64
+ // ─────────────────────────────────────────────────────────────────────────────
65
+ // Fluent API for adding lifecycle callbacks
66
+ // ─────────────────────────────────────────────────────────────────────────────
67
+ /**
68
+ * Add setup callbacks to be executed in order during nodeSetup
69
+ */
70
+ onSetup(...callbacks) {
71
+ this.lifecycleCallbacks.setup.push(...callbacks);
72
+ return this;
73
+ }
74
+ /**
75
+ * Add loaded callbacks to be executed in order during nodeLoaded
76
+ */
77
+ onLoaded(...callbacks) {
78
+ this.lifecycleCallbacks.loaded.push(...callbacks);
79
+ return this;
80
+ }
81
+ /**
82
+ * Add update callbacks to be executed in order during nodeUpdate
83
+ */
84
+ onUpdate(...callbacks) {
85
+ this.lifecycleCallbacks.update.push(...callbacks);
86
+ return this;
87
+ }
88
+ /**
89
+ * Add destroy callbacks to be executed in order during nodeDestroy
90
+ */
91
+ onDestroy(...callbacks) {
92
+ this.lifecycleCallbacks.destroy.push(...callbacks);
93
+ return this;
94
+ }
95
+ /**
96
+ * Add cleanup callbacks to be executed in order during nodeCleanup
97
+ */
98
+ onCleanup(...callbacks) {
99
+ this.lifecycleCallbacks.cleanup.push(...callbacks);
100
+ return this;
101
+ }
102
+ /**
103
+ * Prepend setup callbacks (run before existing ones)
104
+ */
105
+ prependSetup(...callbacks) {
106
+ this.lifecycleCallbacks.setup.unshift(...callbacks);
107
+ return this;
108
+ }
109
+ /**
110
+ * Prepend update callbacks (run before existing ones)
111
+ */
112
+ prependUpdate(...callbacks) {
113
+ this.lifecycleCallbacks.update.unshift(...callbacks);
114
+ return this;
115
+ }
116
+ // ─────────────────────────────────────────────────────────────────────────────
117
+ // Tree structure
118
+ // ─────────────────────────────────────────────────────────────────────────────
119
+ setParent(parent) {
120
+ this.parent = parent;
121
+ }
122
+ getParent() {
123
+ return this.parent;
124
+ }
125
+ add(baseNode) {
126
+ this.children.push(baseNode);
127
+ baseNode.setParent(this);
128
+ }
129
+ remove(baseNode) {
130
+ const index = this.children.indexOf(baseNode);
131
+ if (index !== -1) {
132
+ this.children.splice(index, 1);
133
+ baseNode.setParent(null);
134
+ }
135
+ }
136
+ getChildren() {
137
+ return this.children;
138
+ }
139
+ isComposite() {
140
+ return this.children.length > 0;
141
+ }
142
+ // ─────────────────────────────────────────────────────────────────────────────
143
+ // Node lifecycle execution - runs internal + callback arrays
144
+ // ─────────────────────────────────────────────────────────────────────────────
145
+ nodeSetup(params) {
146
+ if (DEBUG_FLAG) {
147
+ }
148
+ this.markedForRemoval = false;
149
+ if (typeof this._setup === "function") {
150
+ this._setup(params);
151
+ }
152
+ for (const callback of this.lifecycleCallbacks.setup) {
153
+ callback(params);
154
+ }
155
+ this.children.forEach((child) => child.nodeSetup(params));
156
+ }
157
+ nodeUpdate(params) {
158
+ if (this.markedForRemoval) {
159
+ return;
160
+ }
161
+ if (typeof this._update === "function") {
162
+ this._update(params);
163
+ }
164
+ for (const callback of this.lifecycleCallbacks.update) {
165
+ callback(params);
166
+ }
167
+ this.children.forEach((child) => child.nodeUpdate(params));
168
+ }
169
+ nodeDestroy(params) {
170
+ this.children.forEach((child) => child.nodeDestroy(params));
171
+ for (const callback of this.lifecycleCallbacks.destroy) {
172
+ callback(params);
173
+ }
174
+ if (typeof this._destroy === "function") {
175
+ this._destroy(params);
176
+ }
177
+ this.markedForRemoval = true;
178
+ }
179
+ async nodeLoaded(params) {
180
+ if (typeof this._loaded === "function") {
181
+ await this._loaded(params);
182
+ }
183
+ for (const callback of this.lifecycleCallbacks.loaded) {
184
+ callback(params);
185
+ }
186
+ }
187
+ async nodeCleanup(params) {
188
+ for (const callback of this.lifecycleCallbacks.cleanup) {
189
+ callback(params);
190
+ }
191
+ if (typeof this._cleanup === "function") {
192
+ await this._cleanup(params);
193
+ }
194
+ }
195
+ // ─────────────────────────────────────────────────────────────────────────────
196
+ // Options
197
+ // ─────────────────────────────────────────────────────────────────────────────
198
+ getOptions() {
199
+ return this.options;
200
+ }
201
+ setOptions(options) {
202
+ this.options = { ...this.options, ...options };
203
+ }
204
+ };
205
+
206
+ // src/lib/entities/entity.ts
207
+ var GameEntity = class extends BaseNode {
208
+ behaviors = [];
209
+ group;
210
+ mesh;
211
+ materials;
212
+ bodyDesc = null;
213
+ body = null;
214
+ colliderDesc;
215
+ collider;
216
+ custom = {};
217
+ debugInfo = {};
218
+ debugMaterial;
219
+ collisionDelegate = {
220
+ collision: []
221
+ };
222
+ collisionType;
223
+ behaviorCallbackMap = {
224
+ setup: [],
225
+ update: [],
226
+ destroy: [],
227
+ collision: []
228
+ };
229
+ constructor() {
230
+ super();
231
+ }
232
+ create() {
233
+ const { position: setupPosition } = this.options;
234
+ const { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };
235
+ this.behaviors = [
236
+ { component: position, values: { x, y, z } },
237
+ { component: scale, values: { x: 0, y: 0, z: 0 } },
238
+ { component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } }
239
+ ];
240
+ this.name = this.options.name || "";
241
+ return this;
242
+ }
243
+ /**
244
+ * Add collision callbacks
245
+ */
246
+ onCollision(...callbacks) {
247
+ const existing = this.collisionDelegate.collision ?? [];
248
+ this.collisionDelegate.collision = [...existing, ...callbacks];
249
+ return this;
250
+ }
251
+ /**
252
+ * Entity-specific setup - runs behavior callbacks
253
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)
254
+ */
255
+ _setup(params) {
256
+ this.behaviorCallbackMap.setup.forEach((callback) => {
257
+ callback({ ...params, me: this });
258
+ });
259
+ }
260
+ async _loaded(_params) {
261
+ }
262
+ /**
263
+ * Entity-specific update - updates materials and runs behavior callbacks
264
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)
265
+ */
266
+ _update(params) {
267
+ this.updateMaterials(params);
268
+ this.behaviorCallbackMap.update.forEach((callback) => {
269
+ callback({ ...params, me: this });
270
+ });
271
+ }
272
+ /**
273
+ * Entity-specific destroy - runs behavior callbacks
274
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.destroy)
275
+ */
276
+ _destroy(params) {
277
+ this.behaviorCallbackMap.destroy.forEach((callback) => {
278
+ callback({ ...params, me: this });
279
+ });
280
+ }
281
+ async _cleanup(_params) {
282
+ }
283
+ _collision(other, globals) {
284
+ if (this.collisionDelegate.collision?.length) {
285
+ const callbacks = this.collisionDelegate.collision;
286
+ callbacks.forEach((callback) => {
287
+ callback({ entity: this, other, globals });
288
+ });
289
+ }
290
+ this.behaviorCallbackMap.collision.forEach((callback) => {
291
+ callback({ entity: this, other, globals });
292
+ });
293
+ }
294
+ addBehavior(behaviorCallback) {
295
+ const handler = behaviorCallback.handler;
296
+ if (handler) {
297
+ this.behaviorCallbackMap[behaviorCallback.type].push(handler);
298
+ }
299
+ return this;
300
+ }
301
+ addBehaviors(behaviorCallbacks) {
302
+ behaviorCallbacks.forEach((callback) => {
303
+ const handler = callback.handler;
304
+ if (handler) {
305
+ this.behaviorCallbackMap[callback.type].push(handler);
306
+ }
307
+ });
308
+ return this;
309
+ }
310
+ updateMaterials(params) {
311
+ if (!this.materials?.length) {
312
+ return;
313
+ }
314
+ for (const material of this.materials) {
315
+ if (material instanceof ShaderMaterial) {
316
+ if (material.uniforms) {
317
+ material.uniforms.iTime && (material.uniforms.iTime.value += params.delta);
318
+ }
319
+ }
320
+ }
321
+ }
322
+ buildInfo() {
323
+ const info = {};
324
+ info.name = this.name;
325
+ info.uuid = this.uuid;
326
+ info.eid = this.eid.toString();
327
+ return info;
328
+ }
329
+ };
330
+
331
+ // src/lib/entities/builder.ts
332
+ import { BufferGeometry as BufferGeometry2, Mesh as Mesh3, Color as Color3 } from "three";
333
+
334
+ // src/lib/collision/collision-builder.ts
335
+ import { ActiveCollisionTypes, ColliderDesc, RigidBodyDesc, RigidBodyType, Vector3 } from "@dimforge/rapier3d-compat";
336
+ var typeToGroup = /* @__PURE__ */ new Map();
337
+ var nextGroupId = 0;
338
+ function getOrCreateCollisionGroupId(type) {
339
+ let groupId = typeToGroup.get(type);
340
+ if (groupId === void 0) {
341
+ groupId = nextGroupId++ % 16;
342
+ typeToGroup.set(type, groupId);
343
+ }
344
+ return groupId;
345
+ }
346
+ function createCollisionFilter(allowedTypes) {
347
+ let filter = 0;
348
+ allowedTypes.forEach((type) => {
349
+ const groupId = getOrCreateCollisionGroupId(type);
350
+ filter |= 1 << groupId;
351
+ });
352
+ return filter;
353
+ }
354
+ var CollisionBuilder = class {
355
+ static = false;
356
+ sensor = false;
357
+ gravity = new Vector3(0, 0, 0);
358
+ build(options) {
359
+ const bodyDesc = this.bodyDesc({
360
+ isDynamicBody: !this.static
361
+ });
362
+ const collider = this.collider(options);
363
+ const type = options.collisionType;
364
+ if (type) {
365
+ let groupId = getOrCreateCollisionGroupId(type);
366
+ let filter = 65535;
367
+ if (options.collisionFilter) {
368
+ filter = createCollisionFilter(options.collisionFilter);
369
+ }
370
+ collider.setCollisionGroups(groupId << 16 | filter);
371
+ }
372
+ const { KINEMATIC_FIXED, DEFAULT } = ActiveCollisionTypes;
373
+ collider.activeCollisionTypes = this.sensor ? KINEMATIC_FIXED : DEFAULT;
374
+ return [bodyDesc, collider];
375
+ }
376
+ withCollision(collisionOptions) {
377
+ this.sensor = collisionOptions?.sensor ?? this.sensor;
378
+ this.static = collisionOptions?.static ?? this.static;
379
+ return this;
380
+ }
381
+ collider(options) {
382
+ const size = options.size ?? new Vector3(1, 1, 1);
383
+ const half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };
384
+ let colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);
385
+ return colliderDesc;
386
+ }
387
+ bodyDesc({ isDynamicBody = true }) {
388
+ const type = isDynamicBody ? RigidBodyType.Dynamic : RigidBodyType.Fixed;
389
+ const bodyDesc = new RigidBodyDesc(type).setTranslation(0, 0, 0).setGravityScale(1).setCanSleep(false).setCcdEnabled(true);
390
+ return bodyDesc;
391
+ }
392
+ };
393
+
394
+ // src/lib/graphics/mesh.ts
395
+ import { Mesh as Mesh2 } from "three";
396
+ var MeshBuilder = class {
397
+ _build(meshOptions, geometry, materials) {
398
+ const { batched, material } = meshOptions;
399
+ if (batched) {
400
+ console.warn("warning: mesh batching is not implemented");
401
+ }
402
+ const mesh = new Mesh2(geometry, materials.at(-1));
403
+ mesh.position.set(0, 0, 0);
404
+ mesh.castShadow = true;
405
+ mesh.receiveShadow = true;
406
+ return mesh;
407
+ }
408
+ _postBuild() {
409
+ return;
410
+ }
411
+ };
412
+
413
+ // src/lib/graphics/material.ts
414
+ import {
415
+ Color as Color2,
416
+ MeshPhongMaterial,
417
+ MeshStandardMaterial,
418
+ RepeatWrapping,
419
+ ShaderMaterial as ShaderMaterial2,
420
+ TextureLoader,
421
+ Vector2,
422
+ Vector3 as Vector32
423
+ } from "three";
424
+
425
+ // src/lib/core/utility/strings.ts
426
+ function sortedStringify(obj) {
427
+ const sortedObj = Object.keys(obj).sort().reduce((acc, key) => {
428
+ acc[key] = obj[key];
429
+ return acc;
430
+ }, {});
431
+ return JSON.stringify(sortedObj);
432
+ }
433
+ function shortHash(objString) {
434
+ let hash = 0;
435
+ for (let i = 0; i < objString.length; i++) {
436
+ hash = Math.imul(31, hash) + objString.charCodeAt(i) | 0;
437
+ }
438
+ return hash.toString(36);
439
+ }
440
+
441
+ // src/lib/graphics/shaders/fragment/stars.glsl
442
+ var stars_default = "#include <common>\n\nuniform vec3 iResolution;\nuniform float iTime;\nvarying vec2 vUv;\n\n// Credit goes to:\n// https://www.shadertoy.com/view/mtyGWy\n\nvec3 palette( float t ) {\n vec3 a = vec3(0.5, 0.5, 0.5);\n vec3 b = vec3(0.5, 0.5, 0.5);\n vec3 c = vec3(1.0, 1.0, 1.0);\n vec3 d = vec3(0.263,0.416,0.557);\n\n return a + b*cos( 6.28318*(c*t+d) );\n}\n\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;\n vec2 uv0 = uv;\n vec3 finalColor = vec3(0.0);\n \n for (float i = 0.0; i < 4.0; i++) {\n uv = fract(uv * 1.5) - 0.5;\n\n float d = length(uv) * exp(-length(uv0));\n\n vec3 col = palette(length(uv0) + i*.4 + iTime*.4);\n\n d = sin(d*5. + iTime)/5.;\n d = abs(d);\n\n d = pow(0.01 / d, 1.2);\n\n finalColor += col * d;\n }\n \n fragColor = vec4(finalColor, 1.0);\n}\n \nvoid main() {\n mainImage(gl_FragColor, vUv);\n}";
443
+
444
+ // src/lib/graphics/shaders/fragment/fire.glsl
445
+ var fire_default = "#include <common>\n \nuniform vec3 iResolution;\nuniform float iTime;\nuniform vec2 iOffset;\nvarying vec2 vUv;\n\nfloat snoise(vec3 uv, float res)\n{\n const vec3 s = vec3(1e0, 1e2, 1e3);\n \n uv *= res;\n \n vec3 uv0 = floor(mod(uv, res))*s;\n vec3 uv1 = floor(mod(uv+vec3(1.), res))*s;\n \n vec3 f = fract(uv); f = f*f*(3.0-2.0*f);\n\n vec4 v = vec4(uv0.x+uv0.y+uv0.z, uv1.x+uv0.y+uv0.z,\n uv0.x+uv1.y+uv0.z, uv1.x+uv1.y+uv0.z);\n\n vec4 r = fract(sin(v*1e-1)*1e3);\n float r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);\n \n r = fract(sin((v + uv1.z - uv0.z)*1e-1)*1e3);\n float r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);\n \n return mix(r0, r1, f.z)*2.-1.;\n}\n\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 p = -.5 + fragCoord.xy / iResolution.xy;\n p.x *= iResolution.x/iResolution.y;\n \n float color = 3.0 - (3.*length(2.*p));\n \n vec3 coord = vec3(atan(p.x,p.y)/6.2832+.5, length(p)*.4, .5);\n \n for(int i = 1; i <= 7; i++)\n {\n float power = pow(2.0, float(i));\n color += (1.5 / power) * snoise(coord + vec3(0.,-iTime*.05, iTime*.01), power*16.);\n }\n fragColor = vec4( color, pow(max(color,0.),2.)*0.4, pow(max(color,0.),3.)*0.15 , 1.0);\n}\n\nvoid main() {\n mainImage(gl_FragColor, vUv);\n}";
446
+
447
+ // src/lib/graphics/shaders/fragment/standard.glsl
448
+ var standard_default = "uniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n vec4 texel = texture2D( tDiffuse, vUv );\n\n gl_FragColor = texel;\n}";
449
+
450
+ // src/lib/graphics/shaders/fragment/debug.glsl
451
+ var debug_default = "varying vec3 vBarycentric;\nuniform vec3 baseColor;\nuniform vec3 wireframeColor;\nuniform float wireframeThickness;\n\nfloat edgeFactor() {\n vec3 d = fwidth(vBarycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * wireframeThickness, vBarycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n\nvoid main() {\n float edge = edgeFactor();\n\n vec3 wireColor = wireframeColor;\n\n vec3 finalColor = mix(wireColor, baseColor, edge);\n \n gl_FragColor = vec4(finalColor, 1.0);\n}\n";
452
+
453
+ // src/lib/graphics/shaders/vertex/object-shader.glsl
454
+ var object_shader_default = "uniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n gl_Position = projectionMatrix * mvPosition;\n}";
455
+
456
+ // src/lib/graphics/shaders/vertex/debug.glsl
457
+ var debug_default2 = "varying vec3 vBarycentric;\n\nvoid main() {\n vec3 barycentric = vec3(0.0);\n int index = gl_VertexID % 3;\n if (index == 0) barycentric = vec3(1.0, 0.0, 0.0);\n else if (index == 1) barycentric = vec3(0.0, 1.0, 0.0);\n else barycentric = vec3(0.0, 0.0, 1.0);\n vBarycentric = barycentric;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n";
458
+
459
+ // src/lib/core/preset-shader.ts
460
+ var starShader = {
461
+ fragment: stars_default,
462
+ vertex: object_shader_default
463
+ };
464
+ var fireShader = {
465
+ fragment: fire_default,
466
+ vertex: object_shader_default
467
+ };
468
+ var standardShader = {
469
+ fragment: standard_default,
470
+ vertex: object_shader_default
471
+ };
472
+ var debugShader = {
473
+ fragment: debug_default,
474
+ vertex: debug_default2
475
+ };
476
+ var shaderMap = /* @__PURE__ */ new Map();
477
+ shaderMap.set("standard", standardShader);
478
+ shaderMap.set("fire", fireShader);
479
+ shaderMap.set("star", starShader);
480
+ shaderMap.set("debug", debugShader);
481
+ var preset_shader_default = shaderMap;
482
+
483
+ // src/lib/graphics/material.ts
484
+ var MaterialBuilder = class _MaterialBuilder {
485
+ static batchMaterialMap = /* @__PURE__ */ new Map();
486
+ materials = [];
487
+ batchMaterial(options, entityType) {
488
+ const batchKey = shortHash(sortedStringify(options));
489
+ const mappedObject = _MaterialBuilder.batchMaterialMap.get(batchKey);
490
+ if (mappedObject) {
491
+ const count = mappedObject.geometryMap.get(entityType);
492
+ if (count) {
493
+ mappedObject.geometryMap.set(entityType, count + 1);
494
+ } else {
495
+ mappedObject.geometryMap.set(entityType, 1);
496
+ }
497
+ } else {
498
+ _MaterialBuilder.batchMaterialMap.set(
499
+ batchKey,
500
+ {
501
+ geometryMap: /* @__PURE__ */ new Map([[entityType, 1]]),
502
+ material: this.materials[0]
503
+ }
504
+ );
505
+ }
506
+ }
507
+ async build(options, entityType) {
508
+ const { path, repeat, color, shader } = options;
509
+ if (shader) this.withShader(shader);
510
+ if (color) this.withColor(color);
511
+ await this.setTexture(path ?? null, repeat);
512
+ if (this.materials.length === 0) {
513
+ this.setColor(new Color2("#ffffff"));
514
+ }
515
+ this.batchMaterial(options, entityType);
516
+ }
517
+ withColor(color) {
518
+ this.setColor(color);
519
+ return this;
520
+ }
521
+ withShader(shaderType) {
522
+ this.setShader(shaderType);
523
+ return this;
524
+ }
525
+ async setTexture(texturePath = null, repeat = new Vector2(1, 1)) {
526
+ if (!texturePath) {
527
+ return;
528
+ }
529
+ const loader = new TextureLoader();
530
+ const texture = await loader.loadAsync(texturePath);
531
+ texture.repeat = repeat;
532
+ texture.wrapS = RepeatWrapping;
533
+ texture.wrapT = RepeatWrapping;
534
+ const material = new MeshPhongMaterial({
535
+ map: texture
536
+ });
537
+ this.materials.push(material);
538
+ }
539
+ setColor(color) {
540
+ const material = new MeshStandardMaterial({
541
+ color,
542
+ emissiveIntensity: 0.5,
543
+ lightMapIntensity: 0.5,
544
+ fog: true
545
+ });
546
+ this.materials.push(material);
547
+ }
548
+ setShader(customShader) {
549
+ const { fragment, vertex } = preset_shader_default.get(customShader) ?? preset_shader_default.get("standard");
550
+ const shader = new ShaderMaterial2({
551
+ uniforms: {
552
+ iResolution: { value: new Vector32(1, 1, 1) },
553
+ iTime: { value: 0 },
554
+ tDiffuse: { value: null },
555
+ tDepth: { value: null },
556
+ tNormal: { value: null }
557
+ },
558
+ vertexShader: vertex,
559
+ fragmentShader: fragment
560
+ });
561
+ this.materials.push(shader);
562
+ }
563
+ };
564
+
565
+ // src/lib/entities/builder.ts
566
+ var EntityCollisionBuilder = class extends CollisionBuilder {
567
+ };
568
+ var EntityMeshBuilder = class extends MeshBuilder {
569
+ build(options) {
570
+ return new BufferGeometry2();
571
+ }
572
+ postBuild() {
573
+ return;
574
+ }
575
+ };
576
+ var EntityBuilder = class {
577
+ meshBuilder;
578
+ collisionBuilder;
579
+ materialBuilder;
580
+ options;
581
+ entity;
582
+ constructor(options, entity, meshBuilder, collisionBuilder) {
583
+ this.options = options;
584
+ this.entity = entity;
585
+ this.meshBuilder = meshBuilder;
586
+ this.collisionBuilder = collisionBuilder;
587
+ this.materialBuilder = new MaterialBuilder();
588
+ const builders = {
589
+ meshBuilder: this.meshBuilder,
590
+ collisionBuilder: this.collisionBuilder,
591
+ materialBuilder: this.materialBuilder
592
+ };
593
+ this.options._builders = builders;
594
+ }
595
+ withPosition(setupPosition) {
596
+ this.options.position = setupPosition;
597
+ return this;
598
+ }
599
+ async withMaterial(options, entityType) {
600
+ if (this.materialBuilder) {
601
+ await this.materialBuilder.build(options, entityType);
602
+ }
603
+ return this;
604
+ }
605
+ applyMaterialToGroup(group, materials) {
606
+ group.traverse((child) => {
607
+ if (child instanceof Mesh3) {
608
+ if (child.type === "SkinnedMesh" && materials[0] && !child.material.map) {
609
+ child.material = materials[0];
610
+ }
611
+ }
612
+ child.castShadow = true;
613
+ child.receiveShadow = true;
614
+ });
615
+ }
616
+ async build() {
617
+ const entity = this.entity;
618
+ if (this.materialBuilder) {
619
+ entity.materials = this.materialBuilder.materials;
620
+ }
621
+ if (this.meshBuilder && entity.materials) {
622
+ const geometry = this.meshBuilder.build(this.options);
623
+ entity.mesh = this.meshBuilder._build(this.options, geometry, entity.materials);
624
+ this.meshBuilder.postBuild();
625
+ }
626
+ if (entity.group && entity.materials) {
627
+ this.applyMaterialToGroup(entity.group, entity.materials);
628
+ }
629
+ if (this.collisionBuilder) {
630
+ this.collisionBuilder.withCollision(this.options?.collision || {});
631
+ const [bodyDesc, colliderDesc] = this.collisionBuilder.build(this.options);
632
+ entity.bodyDesc = bodyDesc;
633
+ entity.colliderDesc = colliderDesc;
634
+ const { x, y, z } = this.options.position || { x: 0, y: 0, z: 0 };
635
+ entity.bodyDesc.setTranslation(x, y, z);
636
+ }
637
+ if (this.options.collisionType) {
638
+ entity.collisionType = this.options.collisionType;
639
+ }
640
+ if (this.options.color instanceof Color3) {
641
+ const applyColor = (material) => {
642
+ const anyMat = material;
643
+ if (anyMat && anyMat.color && anyMat.color.set) {
644
+ anyMat.color.set(this.options.color);
645
+ }
646
+ };
647
+ if (entity.materials?.length) {
648
+ for (const mat of entity.materials) applyColor(mat);
649
+ }
650
+ if (entity.mesh && entity.mesh.material) {
651
+ const mat = entity.mesh.material;
652
+ if (Array.isArray(mat)) mat.forEach(applyColor);
653
+ else applyColor(mat);
654
+ }
655
+ if (entity.group) {
656
+ entity.group.traverse((child) => {
657
+ if (child instanceof Mesh3 && child.material) {
658
+ const mat = child.material;
659
+ if (Array.isArray(mat)) mat.forEach(applyColor);
660
+ else applyColor(mat);
661
+ }
662
+ });
663
+ }
664
+ }
665
+ return entity;
666
+ }
667
+ };
668
+
669
+ // src/lib/entities/delegates/debug.ts
670
+ import { MeshStandardMaterial as MeshStandardMaterial2, MeshBasicMaterial, MeshPhongMaterial as MeshPhongMaterial2 } from "three";
671
+ function hasDebugInfo(obj) {
672
+ return obj && typeof obj.getDebugInfo === "function";
673
+ }
674
+ var DebugDelegate = class {
675
+ entity;
676
+ constructor(entity) {
677
+ this.entity = entity;
678
+ }
679
+ /**
680
+ * Get formatted position string
681
+ */
682
+ getPositionString() {
683
+ if (this.entity.mesh) {
684
+ const { x: x2, y: y2, z: z2 } = this.entity.mesh.position;
685
+ return `${x2.toFixed(2)}, ${y2.toFixed(2)}, ${z2.toFixed(2)}`;
686
+ }
687
+ const { x, y, z } = this.entity.options.position || { x: 0, y: 0, z: 0 };
688
+ return `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`;
689
+ }
690
+ /**
691
+ * Get formatted rotation string (in degrees)
692
+ */
693
+ getRotationString() {
694
+ if (this.entity.mesh) {
695
+ const { x: x2, y: y2, z: z2 } = this.entity.mesh.rotation;
696
+ const toDeg2 = (rad) => (rad * 180 / Math.PI).toFixed(1);
697
+ return `${toDeg2(x2)}\xB0, ${toDeg2(y2)}\xB0, ${toDeg2(z2)}\xB0`;
698
+ }
699
+ const { x, y, z } = this.entity.options.rotation || { x: 0, y: 0, z: 0 };
700
+ const toDeg = (rad) => (rad * 180 / Math.PI).toFixed(1);
701
+ return `${toDeg(x)}\xB0, ${toDeg(y)}\xB0, ${toDeg(z)}\xB0`;
702
+ }
703
+ /**
704
+ * Get material information
705
+ */
706
+ getMaterialInfo() {
707
+ if (!this.entity.mesh || !this.entity.mesh.material) {
708
+ return { type: "none" };
709
+ }
710
+ const material = Array.isArray(this.entity.mesh.material) ? this.entity.mesh.material[0] : this.entity.mesh.material;
711
+ const info = {
712
+ type: material.type
713
+ };
714
+ if (material instanceof MeshStandardMaterial2 || material instanceof MeshBasicMaterial || material instanceof MeshPhongMaterial2) {
715
+ info.color = `#${material.color.getHexString()}`;
716
+ info.opacity = material.opacity;
717
+ info.transparent = material.transparent;
718
+ }
719
+ if ("roughness" in material) {
720
+ info.roughness = material.roughness;
721
+ }
722
+ if ("metalness" in material) {
723
+ info.metalness = material.metalness;
724
+ }
725
+ return info;
726
+ }
727
+ getPhysicsInfo() {
728
+ if (!this.entity.body) {
729
+ return null;
730
+ }
731
+ const info = {
732
+ type: this.entity.body.bodyType(),
733
+ mass: this.entity.body.mass(),
734
+ isEnabled: this.entity.body.isEnabled(),
735
+ isSleeping: this.entity.body.isSleeping()
736
+ };
737
+ const velocity = this.entity.body.linvel();
738
+ info.velocity = `${velocity.x.toFixed(2)}, ${velocity.y.toFixed(2)}, ${velocity.z.toFixed(2)}`;
739
+ return info;
740
+ }
741
+ buildDebugInfo() {
742
+ const defaultInfo = {
743
+ name: this.entity.name || this.entity.uuid,
744
+ uuid: this.entity.uuid,
745
+ position: this.getPositionString(),
746
+ rotation: this.getRotationString(),
747
+ material: this.getMaterialInfo()
748
+ };
749
+ const physicsInfo = this.getPhysicsInfo();
750
+ if (physicsInfo) {
751
+ defaultInfo.physics = physicsInfo;
752
+ }
753
+ if (this.entity.behaviors.length > 0) {
754
+ defaultInfo.behaviors = this.entity.behaviors.map((b) => b.constructor.name);
755
+ }
756
+ if (hasDebugInfo(this.entity)) {
757
+ const customInfo = this.entity.getDebugInfo();
758
+ return { ...defaultInfo, ...customInfo };
759
+ }
760
+ return defaultInfo;
761
+ }
762
+ };
763
+
764
+ // src/lib/entities/delegates/loader.ts
765
+ function isLoadable(obj) {
766
+ return typeof obj?.load === "function" && typeof obj?.data === "function";
767
+ }
768
+ var EntityLoader = class {
769
+ entityReference;
770
+ constructor(entity) {
771
+ this.entityReference = entity;
772
+ }
773
+ async load() {
774
+ if (this.entityReference.load) {
775
+ await this.entityReference.load();
776
+ }
777
+ }
778
+ async data() {
779
+ if (this.entityReference.data) {
780
+ return this.entityReference.data();
781
+ }
782
+ return null;
783
+ }
784
+ };
785
+
786
+ // src/lib/entities/create.ts
787
+ async function createEntity(params) {
788
+ const {
789
+ args,
790
+ defaultConfig,
791
+ EntityClass,
792
+ BuilderClass,
793
+ entityType,
794
+ MeshBuilderClass,
795
+ CollisionBuilderClass
796
+ } = params;
797
+ let builder = null;
798
+ let configuration;
799
+ const configurationIndex = args.findIndex((node) => !(node instanceof BaseNode));
800
+ if (configurationIndex !== -1) {
801
+ const subArgs = args.splice(configurationIndex, 1);
802
+ configuration = subArgs.find((node) => !(node instanceof BaseNode));
803
+ }
804
+ const mergedConfiguration = configuration ? { ...defaultConfig, ...configuration } : defaultConfig;
805
+ args.push(mergedConfiguration);
806
+ for (const arg of args) {
807
+ if (arg instanceof BaseNode) {
808
+ continue;
809
+ }
810
+ let entityData = null;
811
+ const entity = new EntityClass(arg);
812
+ try {
813
+ if (isLoadable(entity)) {
814
+ const loader = new EntityLoader(entity);
815
+ await loader.load();
816
+ entityData = await loader.data();
817
+ }
818
+ } catch (error) {
819
+ console.error("Error creating entity with loader:", error);
820
+ }
821
+ builder = new BuilderClass(
822
+ arg,
823
+ entity,
824
+ MeshBuilderClass ? new MeshBuilderClass(entityData) : null,
825
+ CollisionBuilderClass ? new CollisionBuilderClass(entityData) : null
826
+ );
827
+ if (arg.material) {
828
+ await builder.withMaterial(arg.material, entityType);
829
+ }
830
+ }
831
+ if (!builder) {
832
+ throw new Error(`missing options for ${String(entityType)}, builder is not initialized.`);
833
+ }
834
+ return await builder.build();
835
+ }
836
+
837
+ // src/lib/entities/box.ts
838
+ var boxDefaults = {
839
+ size: new Vector33(1, 1, 1),
840
+ position: new Vector33(0, 0, 0),
841
+ collision: {
842
+ static: false
843
+ },
844
+ material: {
845
+ color: new Color4("#ffffff"),
846
+ shader: "standard"
847
+ }
848
+ };
849
+ var BoxCollisionBuilder = class extends EntityCollisionBuilder {
850
+ collider(options) {
851
+ const size = options.size || new Vector33(1, 1, 1);
852
+ const half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };
853
+ let colliderDesc = ColliderDesc2.cuboid(half.x, half.y, half.z);
854
+ return colliderDesc;
855
+ }
856
+ };
857
+ var BoxMeshBuilder = class extends EntityMeshBuilder {
858
+ build(options) {
859
+ const size = options.size ?? new Vector33(1, 1, 1);
860
+ return new BoxGeometry(size.x, size.y, size.z);
861
+ }
862
+ };
863
+ var BoxBuilder = class extends EntityBuilder {
864
+ createEntity(options) {
865
+ return new ZylemBox(options);
866
+ }
867
+ };
868
+ var BOX_TYPE = /* @__PURE__ */ Symbol("Box");
869
+ var ZylemBox = class _ZylemBox extends GameEntity {
870
+ static type = BOX_TYPE;
871
+ constructor(options) {
872
+ super();
873
+ this.options = { ...boxDefaults, ...options };
874
+ }
875
+ buildInfo() {
876
+ const delegate = new DebugDelegate(this);
877
+ const baseInfo = delegate.buildDebugInfo();
878
+ const { x: sizeX, y: sizeY, z: sizeZ } = this.options.size ?? { x: 1, y: 1, z: 1 };
879
+ return {
880
+ ...baseInfo,
881
+ type: String(_ZylemBox.type),
882
+ size: `${sizeX}, ${sizeY}, ${sizeZ}`
883
+ };
884
+ }
885
+ };
886
+ async function box(...args) {
887
+ return createEntity({
888
+ args,
889
+ defaultConfig: boxDefaults,
890
+ EntityClass: ZylemBox,
891
+ BuilderClass: BoxBuilder,
892
+ MeshBuilderClass: BoxMeshBuilder,
893
+ CollisionBuilderClass: BoxCollisionBuilder,
894
+ entityType: ZylemBox.type
895
+ });
896
+ }
897
+
898
+ // src/lib/entities/sphere.ts
899
+ import { ColliderDesc as ColliderDesc3 } from "@dimforge/rapier3d-compat";
900
+ import { Color as Color5, SphereGeometry } from "three";
901
+ import { Vector3 as Vector34 } from "three";
902
+ var sphereDefaults = {
903
+ radius: 1,
904
+ position: new Vector34(0, 0, 0),
905
+ collision: {
906
+ static: false
907
+ },
908
+ material: {
909
+ color: new Color5("#ffffff"),
910
+ shader: "standard"
911
+ }
912
+ };
913
+ var SphereCollisionBuilder = class extends EntityCollisionBuilder {
914
+ collider(options) {
915
+ const radius = options.radius ?? 1;
916
+ let colliderDesc = ColliderDesc3.ball(radius);
917
+ return colliderDesc;
918
+ }
919
+ };
920
+ var SphereMeshBuilder = class extends EntityMeshBuilder {
921
+ build(options) {
922
+ const radius = options.radius ?? 1;
923
+ return new SphereGeometry(radius);
924
+ }
925
+ };
926
+ var SphereBuilder = class extends EntityBuilder {
927
+ createEntity(options) {
928
+ return new ZylemSphere(options);
929
+ }
930
+ };
931
+ var SPHERE_TYPE = /* @__PURE__ */ Symbol("Sphere");
932
+ var ZylemSphere = class _ZylemSphere extends GameEntity {
933
+ static type = SPHERE_TYPE;
934
+ constructor(options) {
935
+ super();
936
+ this.options = { ...sphereDefaults, ...options };
937
+ }
938
+ buildInfo() {
939
+ const delegate = new DebugDelegate(this);
940
+ const baseInfo = delegate.buildDebugInfo();
941
+ const radius = this.options.radius ?? 1;
942
+ return {
943
+ ...baseInfo,
944
+ type: String(_ZylemSphere.type),
945
+ radius: radius.toFixed(2)
946
+ };
947
+ }
948
+ };
949
+ async function sphere(...args) {
950
+ return createEntity({
951
+ args,
952
+ defaultConfig: sphereDefaults,
953
+ EntityClass: ZylemSphere,
954
+ BuilderClass: SphereBuilder,
955
+ MeshBuilderClass: SphereMeshBuilder,
956
+ CollisionBuilderClass: SphereCollisionBuilder,
957
+ entityType: ZylemSphere.type
958
+ });
959
+ }
960
+
961
+ // src/lib/entities/sprite.ts
962
+ import { ColliderDesc as ColliderDesc4 } from "@dimforge/rapier3d-compat";
963
+ import { Color as Color6, Euler, Group as Group3, Quaternion as Quaternion2, Vector3 as Vector35 } from "three";
964
+ import {
965
+ TextureLoader as TextureLoader2,
966
+ SpriteMaterial,
967
+ Sprite as ThreeSprite
968
+ } from "three";
969
+ var spriteDefaults = {
970
+ size: new Vector35(1, 1, 1),
971
+ position: new Vector35(0, 0, 0),
972
+ collision: {
973
+ static: false
974
+ },
975
+ material: {
976
+ color: new Color6("#ffffff"),
977
+ shader: "standard"
978
+ },
979
+ images: [],
980
+ animations: []
981
+ };
982
+ var SpriteCollisionBuilder = class extends EntityCollisionBuilder {
983
+ collider(options) {
984
+ const size = options.collisionSize || options.size || new Vector35(1, 1, 1);
985
+ const half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };
986
+ let colliderDesc = ColliderDesc4.cuboid(half.x, half.y, half.z);
987
+ return colliderDesc;
988
+ }
989
+ };
990
+ var SpriteBuilder = class extends EntityBuilder {
991
+ createEntity(options) {
992
+ return new ZylemSprite(options);
993
+ }
994
+ };
995
+ var SPRITE_TYPE = /* @__PURE__ */ Symbol("Sprite");
996
+ var ZylemSprite = class _ZylemSprite extends GameEntity {
997
+ static type = SPRITE_TYPE;
998
+ sprites = [];
999
+ spriteMap = /* @__PURE__ */ new Map();
1000
+ currentSpriteIndex = 0;
1001
+ animations = /* @__PURE__ */ new Map();
1002
+ currentAnimation = null;
1003
+ currentAnimationFrame = "";
1004
+ currentAnimationIndex = 0;
1005
+ currentAnimationTime = 0;
1006
+ constructor(options) {
1007
+ super();
1008
+ this.options = { ...spriteDefaults, ...options };
1009
+ this.prependUpdate(this.spriteUpdate.bind(this));
1010
+ this.onDestroy(this.spriteDestroy.bind(this));
1011
+ }
1012
+ create() {
1013
+ this.sprites = [];
1014
+ this.spriteMap.clear();
1015
+ this.animations.clear();
1016
+ this.currentAnimation = null;
1017
+ this.currentAnimationFrame = "";
1018
+ this.currentAnimationIndex = 0;
1019
+ this.currentAnimationTime = 0;
1020
+ this.group = void 0;
1021
+ this.createSpritesFromImages(this.options?.images || []);
1022
+ this.createAnimations(this.options?.animations || []);
1023
+ return super.create();
1024
+ }
1025
+ createSpritesFromImages(images) {
1026
+ const textureLoader = new TextureLoader2();
1027
+ images.forEach((image, index) => {
1028
+ const spriteMap = textureLoader.load(image.file);
1029
+ const material = new SpriteMaterial({
1030
+ map: spriteMap,
1031
+ transparent: true
1032
+ });
1033
+ const _sprite = new ThreeSprite(material);
1034
+ _sprite.position.normalize();
1035
+ this.sprites.push(_sprite);
1036
+ this.spriteMap.set(image.name, index);
1037
+ });
1038
+ this.group = new Group3();
1039
+ this.group.add(...this.sprites);
1040
+ }
1041
+ createAnimations(animations) {
1042
+ animations.forEach((animation) => {
1043
+ const { name, frames, loop = false, speed = 1 } = animation;
1044
+ const internalAnimation = {
1045
+ frames: frames.map((frame, index) => ({
1046
+ key: frame,
1047
+ index,
1048
+ time: (typeof speed === "number" ? speed : speed[index]) * (index + 1),
1049
+ duration: typeof speed === "number" ? speed : speed[index]
1050
+ })),
1051
+ loop
1052
+ };
1053
+ this.animations.set(name, internalAnimation);
1054
+ });
1055
+ }
1056
+ setSprite(key) {
1057
+ const spriteIndex = this.spriteMap.get(key);
1058
+ const useIndex = spriteIndex ?? 0;
1059
+ this.currentSpriteIndex = useIndex;
1060
+ this.sprites.forEach((_sprite, i) => {
1061
+ _sprite.visible = this.currentSpriteIndex === i;
1062
+ });
1063
+ }
1064
+ setAnimation(name, delta) {
1065
+ const animation = this.animations.get(name);
1066
+ if (!animation) return;
1067
+ const { loop, frames } = animation;
1068
+ const frame = frames[this.currentAnimationIndex];
1069
+ if (name === this.currentAnimation) {
1070
+ this.currentAnimationFrame = frame.key;
1071
+ this.currentAnimationTime += delta;
1072
+ this.setSprite(this.currentAnimationFrame);
1073
+ } else {
1074
+ this.currentAnimation = name;
1075
+ }
1076
+ if (this.currentAnimationTime > frame.time) {
1077
+ this.currentAnimationIndex++;
1078
+ }
1079
+ if (this.currentAnimationIndex >= frames.length) {
1080
+ if (loop) {
1081
+ this.currentAnimationIndex = 0;
1082
+ this.currentAnimationTime = 0;
1083
+ } else {
1084
+ this.currentAnimationTime = frames[this.currentAnimationIndex].time;
1085
+ }
1086
+ }
1087
+ }
1088
+ async spriteUpdate(params) {
1089
+ this.sprites.forEach((_sprite) => {
1090
+ if (_sprite.material) {
1091
+ const q = this.body?.rotation();
1092
+ if (q) {
1093
+ const quat = new Quaternion2(q.x, q.y, q.z, q.w);
1094
+ const euler = new Euler().setFromQuaternion(quat, "XYZ");
1095
+ _sprite.material.rotation = euler.z;
1096
+ }
1097
+ _sprite.scale.set(this.options.size?.x ?? 1, this.options.size?.y ?? 1, this.options.size?.z ?? 1);
1098
+ }
1099
+ });
1100
+ }
1101
+ async spriteDestroy(params) {
1102
+ this.sprites.forEach((_sprite) => {
1103
+ _sprite.removeFromParent();
1104
+ });
1105
+ this.group?.remove(...this.sprites);
1106
+ this.group?.removeFromParent();
1107
+ }
1108
+ buildInfo() {
1109
+ const delegate = new DebugDelegate(this);
1110
+ const baseInfo = delegate.buildDebugInfo();
1111
+ return {
1112
+ ...baseInfo,
1113
+ type: String(_ZylemSprite.type)
1114
+ };
1115
+ }
1116
+ };
1117
+ async function sprite(...args) {
1118
+ return createEntity({
1119
+ args,
1120
+ defaultConfig: spriteDefaults,
1121
+ EntityClass: ZylemSprite,
1122
+ BuilderClass: SpriteBuilder,
1123
+ CollisionBuilderClass: SpriteCollisionBuilder,
1124
+ entityType: ZylemSprite.type
1125
+ });
1126
+ }
1127
+
1128
+ // src/lib/entities/plane.ts
1129
+ import { ColliderDesc as ColliderDesc5 } from "@dimforge/rapier3d-compat";
1130
+ import { Color as Color7, PlaneGeometry, Vector2 as Vector22, Vector3 as Vector36 } from "three";
1131
+
1132
+ // src/lib/graphics/geometries/XZPlaneGeometry.ts
1133
+ import { BufferGeometry as BufferGeometry3, Float32BufferAttribute } from "three";
1134
+ var XZPlaneGeometry = class _XZPlaneGeometry extends BufferGeometry3 {
1135
+ constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {
1136
+ super();
1137
+ this.type = "XZPlaneGeometry";
1138
+ this.parameters = {
1139
+ width,
1140
+ height,
1141
+ widthSegments,
1142
+ heightSegments
1143
+ };
1144
+ const width_half = width / 2;
1145
+ const height_half = height / 2;
1146
+ const gridX = Math.floor(widthSegments);
1147
+ const gridY = Math.floor(heightSegments);
1148
+ const gridX1 = gridX + 1;
1149
+ const gridY1 = gridY + 1;
1150
+ const segment_width = width / gridX;
1151
+ const segment_height = height / gridY;
1152
+ const indices = [];
1153
+ const vertices = [];
1154
+ const normals = [];
1155
+ const uvs = [];
1156
+ for (let iy = 0; iy < gridY1; iy++) {
1157
+ const z = iy * segment_height - height_half;
1158
+ for (let ix = 0; ix < gridX1; ix++) {
1159
+ const x = ix * segment_width - width_half;
1160
+ vertices.push(x, 0, z);
1161
+ normals.push(0, 1, 0);
1162
+ uvs.push(ix / gridX);
1163
+ uvs.push(1 - iy / gridY);
1164
+ }
1165
+ }
1166
+ for (let iy = 0; iy < gridY; iy++) {
1167
+ for (let ix = 0; ix < gridX; ix++) {
1168
+ const a = ix + gridX1 * iy;
1169
+ const b = ix + gridX1 * (iy + 1);
1170
+ const c = ix + 1 + gridX1 * (iy + 1);
1171
+ const d = ix + 1 + gridX1 * iy;
1172
+ indices.push(a, b, d);
1173
+ indices.push(b, c, d);
1174
+ }
1175
+ }
1176
+ this.setIndex(indices);
1177
+ this.setAttribute("position", new Float32BufferAttribute(vertices, 3));
1178
+ this.setAttribute("normal", new Float32BufferAttribute(normals, 3));
1179
+ this.setAttribute("uv", new Float32BufferAttribute(uvs, 2));
1180
+ }
1181
+ copy(source) {
1182
+ super.copy(source);
1183
+ this.parameters = Object.assign({}, source.parameters);
1184
+ return this;
1185
+ }
1186
+ static fromJSON(data) {
1187
+ return new _XZPlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);
1188
+ }
1189
+ };
1190
+
1191
+ // src/lib/entities/plane.ts
1192
+ var DEFAULT_SUBDIVISIONS = 4;
1193
+ var planeDefaults = {
1194
+ tile: new Vector22(10, 10),
1195
+ repeat: new Vector22(1, 1),
1196
+ position: new Vector36(0, 0, 0),
1197
+ collision: {
1198
+ static: true
1199
+ },
1200
+ material: {
1201
+ color: new Color7("#ffffff"),
1202
+ shader: "standard"
1203
+ },
1204
+ subdivisions: DEFAULT_SUBDIVISIONS
1205
+ };
1206
+ var PlaneCollisionBuilder = class extends EntityCollisionBuilder {
1207
+ collider(options) {
1208
+ const tile = options.tile ?? new Vector22(1, 1);
1209
+ const subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;
1210
+ const size = new Vector36(tile.x, 1, tile.y);
1211
+ const heightData = options._builders?.meshBuilder?.heightData;
1212
+ const scale2 = new Vector36(size.x, 1, size.z);
1213
+ let colliderDesc = ColliderDesc5.heightfield(
1214
+ subdivisions,
1215
+ subdivisions,
1216
+ heightData,
1217
+ scale2
1218
+ );
1219
+ return colliderDesc;
1220
+ }
1221
+ };
1222
+ var PlaneMeshBuilder = class extends EntityMeshBuilder {
1223
+ heightData = new Float32Array();
1224
+ columnsRows = /* @__PURE__ */ new Map();
1225
+ build(options) {
1226
+ const tile = options.tile ?? new Vector22(1, 1);
1227
+ const subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;
1228
+ const size = new Vector36(tile.x, 1, tile.y);
1229
+ const geometry = new XZPlaneGeometry(size.x, size.z, subdivisions, subdivisions);
1230
+ const vertexGeometry = new PlaneGeometry(size.x, size.z, subdivisions, subdivisions);
1231
+ const dx = size.x / subdivisions;
1232
+ const dy = size.z / subdivisions;
1233
+ const originalVertices = geometry.attributes.position.array;
1234
+ const vertices = vertexGeometry.attributes.position.array;
1235
+ const columsRows = /* @__PURE__ */ new Map();
1236
+ for (let i = 0; i < vertices.length; i += 3) {
1237
+ let row = Math.floor(Math.abs(vertices[i] + size.x / 2) / dx);
1238
+ let column = Math.floor(Math.abs(vertices[i + 1] - size.z / 2) / dy);
1239
+ const randomHeight = Math.random() * 4;
1240
+ vertices[i + 2] = randomHeight;
1241
+ originalVertices[i + 1] = randomHeight;
1242
+ if (!columsRows.get(column)) {
1243
+ columsRows.set(column, /* @__PURE__ */ new Map());
1244
+ }
1245
+ columsRows.get(column).set(row, randomHeight);
1246
+ }
1247
+ this.columnsRows = columsRows;
1248
+ return geometry;
1249
+ }
1250
+ postBuild() {
1251
+ const heights = [];
1252
+ for (let i = 0; i <= DEFAULT_SUBDIVISIONS; ++i) {
1253
+ for (let j = 0; j <= DEFAULT_SUBDIVISIONS; ++j) {
1254
+ const row = this.columnsRows.get(j);
1255
+ if (!row) {
1256
+ continue;
1257
+ }
1258
+ const data = row.get(i);
1259
+ heights.push(data);
1260
+ }
1261
+ }
1262
+ this.heightData = new Float32Array(heights);
1263
+ }
1264
+ };
1265
+ var PlaneBuilder = class extends EntityBuilder {
1266
+ createEntity(options) {
1267
+ return new ZylemPlane(options);
1268
+ }
1269
+ };
1270
+ var PLANE_TYPE = /* @__PURE__ */ Symbol("Plane");
1271
+ var ZylemPlane = class extends GameEntity {
1272
+ static type = PLANE_TYPE;
1273
+ constructor(options) {
1274
+ super();
1275
+ this.options = { ...planeDefaults, ...options };
1276
+ }
1277
+ };
1278
+ async function plane(...args) {
1279
+ return createEntity({
1280
+ args,
1281
+ defaultConfig: planeDefaults,
1282
+ EntityClass: ZylemPlane,
1283
+ BuilderClass: PlaneBuilder,
1284
+ MeshBuilderClass: PlaneMeshBuilder,
1285
+ CollisionBuilderClass: PlaneCollisionBuilder,
1286
+ entityType: ZylemPlane.type
1287
+ });
1288
+ }
1289
+
1290
+ // src/lib/entities/zone.ts
1291
+ import { ActiveCollisionTypes as ActiveCollisionTypes2, ColliderDesc as ColliderDesc6 } from "@dimforge/rapier3d-compat";
1292
+ import { Vector3 as Vector37 } from "three";
1293
+
1294
+ // src/lib/game/game-state.ts
1295
+ import { proxy, subscribe } from "valtio/vanilla";
1296
+ var state = proxy({
1297
+ id: "",
1298
+ globals: {},
1299
+ time: 0
1300
+ });
1301
+
1302
+ // src/lib/entities/zone.ts
1303
+ var zoneDefaults = {
1304
+ size: new Vector37(1, 1, 1),
1305
+ position: new Vector37(0, 0, 0),
1306
+ collision: {
1307
+ static: true
1308
+ },
1309
+ material: {
1310
+ shader: "standard"
1311
+ }
1312
+ };
1313
+ var ZoneCollisionBuilder = class extends EntityCollisionBuilder {
1314
+ collider(options) {
1315
+ const size = options.size || new Vector37(1, 1, 1);
1316
+ const half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };
1317
+ let colliderDesc = ColliderDesc6.cuboid(half.x, half.y, half.z);
1318
+ colliderDesc.setSensor(true);
1319
+ colliderDesc.activeCollisionTypes = ActiveCollisionTypes2.KINEMATIC_FIXED;
1320
+ return colliderDesc;
1321
+ }
1322
+ };
1323
+ var ZoneBuilder = class extends EntityBuilder {
1324
+ createEntity(options) {
1325
+ return new ZylemZone(options);
1326
+ }
1327
+ };
1328
+ var ZONE_TYPE = /* @__PURE__ */ Symbol("Zone");
1329
+ var ZylemZone = class extends GameEntity {
1330
+ static type = ZONE_TYPE;
1331
+ _enteredZone = /* @__PURE__ */ new Map();
1332
+ _exitedZone = /* @__PURE__ */ new Map();
1333
+ _zoneEntities = /* @__PURE__ */ new Map();
1334
+ constructor(options) {
1335
+ super();
1336
+ this.options = { ...zoneDefaults, ...options };
1337
+ }
1338
+ handlePostCollision({ delta }) {
1339
+ this._enteredZone.forEach((val, key) => {
1340
+ this.exited(delta, key);
1341
+ });
1342
+ return this._enteredZone.size > 0;
1343
+ }
1344
+ handleIntersectionEvent({ other, delta }) {
1345
+ const hasEntered = this._enteredZone.get(other.uuid);
1346
+ if (!hasEntered) {
1347
+ this.entered(other);
1348
+ this._zoneEntities.set(other.uuid, other);
1349
+ } else {
1350
+ this.held(delta, other);
1351
+ }
1352
+ }
1353
+ onEnter(callback) {
1354
+ this.options.onEnter = callback;
1355
+ return this;
1356
+ }
1357
+ onHeld(callback) {
1358
+ this.options.onHeld = callback;
1359
+ return this;
1360
+ }
1361
+ onExit(callback) {
1362
+ this.options.onExit = callback;
1363
+ return this;
1364
+ }
1365
+ entered(other) {
1366
+ this._enteredZone.set(other.uuid, 1);
1367
+ if (this.options.onEnter) {
1368
+ this.options.onEnter({
1369
+ self: this,
1370
+ visitor: other,
1371
+ globals: state.globals
1372
+ });
1373
+ }
1374
+ }
1375
+ exited(delta, key) {
1376
+ const hasExited = this._exitedZone.get(key);
1377
+ if (hasExited && hasExited > 1 + delta) {
1378
+ this._exitedZone.delete(key);
1379
+ this._enteredZone.delete(key);
1380
+ const other = this._zoneEntities.get(key);
1381
+ if (this.options.onExit) {
1382
+ this.options.onExit({
1383
+ self: this,
1384
+ visitor: other,
1385
+ globals: state.globals
1386
+ });
1387
+ }
1388
+ return;
1389
+ }
1390
+ this._exitedZone.set(key, 1 + delta);
1391
+ }
1392
+ held(delta, other) {
1393
+ const heldTime = this._enteredZone.get(other.uuid) ?? 0;
1394
+ this._enteredZone.set(other.uuid, heldTime + delta);
1395
+ this._exitedZone.set(other.uuid, 1);
1396
+ if (this.options.onHeld) {
1397
+ this.options.onHeld({
1398
+ delta,
1399
+ self: this,
1400
+ visitor: other,
1401
+ globals: state.globals,
1402
+ heldTime
1403
+ });
1404
+ }
1405
+ }
1406
+ };
1407
+ async function zone(...args) {
1408
+ return createEntity({
1409
+ args,
1410
+ defaultConfig: zoneDefaults,
1411
+ EntityClass: ZylemZone,
1412
+ BuilderClass: ZoneBuilder,
1413
+ CollisionBuilderClass: ZoneCollisionBuilder,
1414
+ entityType: ZylemZone.type
1415
+ });
1416
+ }
1417
+
1418
+ // src/lib/entities/actor.ts
1419
+ import { ActiveCollisionTypes as ActiveCollisionTypes3, ColliderDesc as ColliderDesc7 } from "@dimforge/rapier3d-compat";
1420
+ import { SkinnedMesh, Group as Group4, Vector3 as Vector38 } from "three";
1421
+
1422
+ // src/lib/core/entity-asset-loader.ts
1423
+ import { FBXLoader } from "three/addons/loaders/FBXLoader.js";
1424
+ import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
1425
+ var FBXAssetLoader = class {
1426
+ loader = new FBXLoader();
1427
+ isSupported(file) {
1428
+ return file.toLowerCase().endsWith("fbx" /* FBX */);
1429
+ }
1430
+ async load(file) {
1431
+ return new Promise((resolve, reject) => {
1432
+ this.loader.load(
1433
+ file,
1434
+ (object) => {
1435
+ const animation = object.animations[0];
1436
+ resolve({
1437
+ object,
1438
+ animation
1439
+ });
1440
+ },
1441
+ void 0,
1442
+ reject
1443
+ );
1444
+ });
1445
+ }
1446
+ };
1447
+ var GLTFAssetLoader = class {
1448
+ loader = new GLTFLoader();
1449
+ isSupported(file) {
1450
+ return file.toLowerCase().endsWith("gltf" /* GLTF */);
1451
+ }
1452
+ async load(file) {
1453
+ return new Promise((resolve, reject) => {
1454
+ this.loader.load(
1455
+ file,
1456
+ (gltf) => {
1457
+ resolve({
1458
+ object: gltf.scene,
1459
+ gltf
1460
+ });
1461
+ },
1462
+ void 0,
1463
+ reject
1464
+ );
1465
+ });
1466
+ }
1467
+ };
1468
+ var EntityAssetLoader = class {
1469
+ loaders = [
1470
+ new FBXAssetLoader(),
1471
+ new GLTFAssetLoader()
1472
+ ];
1473
+ async loadFile(file) {
1474
+ const loader = this.loaders.find((l) => l.isSupported(file));
1475
+ if (!loader) {
1476
+ throw new Error(`Unsupported file type: ${file}`);
1477
+ }
1478
+ return loader.load(file);
1479
+ }
1480
+ };
1481
+
1482
+ // src/lib/entities/delegates/animation.ts
1483
+ import {
1484
+ AnimationMixer,
1485
+ LoopOnce,
1486
+ LoopRepeat
1487
+ } from "three";
1488
+ var AnimationDelegate = class {
1489
+ constructor(target) {
1490
+ this.target = target;
1491
+ }
1492
+ _mixer = null;
1493
+ _actions = {};
1494
+ _animations = [];
1495
+ _currentAction = null;
1496
+ _pauseAtPercentage = 0;
1497
+ _isPaused = false;
1498
+ _queuedKey = null;
1499
+ _fadeDuration = 0.5;
1500
+ _currentKey = "";
1501
+ _assetLoader = new EntityAssetLoader();
1502
+ async loadAnimations(animations) {
1503
+ if (!animations.length) return;
1504
+ const results = await Promise.all(animations.map((a) => this._assetLoader.loadFile(a.path)));
1505
+ this._animations = results.filter((r) => !!r.animation).map((r) => r.animation);
1506
+ if (!this._animations.length) return;
1507
+ this._mixer = new AnimationMixer(this.target);
1508
+ this._animations.forEach((clip, i) => {
1509
+ const key = animations[i].key || i.toString();
1510
+ this._actions[key] = this._mixer.clipAction(clip);
1511
+ });
1512
+ this.playAnimation({ key: Object.keys(this._actions)[0] });
1513
+ }
1514
+ update(delta) {
1515
+ if (!this._mixer || !this._currentAction) return;
1516
+ this._mixer.update(delta);
1517
+ const pauseAtTime = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);
1518
+ if (!this._isPaused && this._pauseAtPercentage > 0 && this._currentAction.time >= pauseAtTime) {
1519
+ this._currentAction.time = pauseAtTime;
1520
+ this._currentAction.paused = true;
1521
+ this._isPaused = true;
1522
+ if (this._queuedKey !== null) {
1523
+ const next = this._actions[this._queuedKey];
1524
+ next.reset().play();
1525
+ this._currentAction.crossFadeTo(next, this._fadeDuration, false);
1526
+ this._currentAction = next;
1527
+ this._currentKey = this._queuedKey;
1528
+ this._queuedKey = null;
1529
+ }
1530
+ }
1531
+ }
1532
+ playAnimation(opts) {
1533
+ if (!this._mixer) return;
1534
+ const { key, pauseAtPercentage = 0, pauseAtEnd = false, fadeToKey, fadeDuration = 0.5 } = opts;
1535
+ if (key === this._currentKey) return;
1536
+ this._queuedKey = fadeToKey || null;
1537
+ this._fadeDuration = fadeDuration;
1538
+ this._pauseAtPercentage = pauseAtEnd ? 100 : pauseAtPercentage;
1539
+ this._isPaused = false;
1540
+ const prev = this._currentAction;
1541
+ if (prev) prev.stop();
1542
+ const action = this._actions[key];
1543
+ if (!action) return;
1544
+ if (this._pauseAtPercentage > 0) {
1545
+ action.setLoop(LoopOnce, Infinity);
1546
+ action.clampWhenFinished = true;
1547
+ } else {
1548
+ action.setLoop(LoopRepeat, Infinity);
1549
+ action.clampWhenFinished = false;
1550
+ }
1551
+ if (prev) {
1552
+ prev.crossFadeTo(action, fadeDuration, false);
1553
+ }
1554
+ action.reset().play();
1555
+ this._currentAction = action;
1556
+ this._currentKey = key;
1557
+ }
1558
+ /**
1559
+ * Dispose of all animation resources
1560
+ */
1561
+ dispose() {
1562
+ Object.values(this._actions).forEach((action) => {
1563
+ action.stop();
1564
+ });
1565
+ if (this._mixer) {
1566
+ this._mixer.stopAllAction();
1567
+ this._mixer.uncacheRoot(this.target);
1568
+ this._mixer = null;
1569
+ }
1570
+ this._actions = {};
1571
+ this._animations = [];
1572
+ this._currentAction = null;
1573
+ this._currentKey = "";
1574
+ }
1575
+ get currentAnimationKey() {
1576
+ return this._currentKey;
1577
+ }
1578
+ get animations() {
1579
+ return this._animations;
1580
+ }
1581
+ };
1582
+
1583
+ // src/lib/entities/actor.ts
1584
+ var actorDefaults = {
1585
+ position: { x: 0, y: 0, z: 0 },
1586
+ collision: {
1587
+ static: false,
1588
+ size: new Vector38(0.5, 0.5, 0.5),
1589
+ position: new Vector38(0, 0, 0)
1590
+ },
1591
+ material: {
1592
+ shader: "standard"
1593
+ },
1594
+ animations: [],
1595
+ models: []
1596
+ };
1597
+ var ActorCollisionBuilder = class extends EntityCollisionBuilder {
1598
+ height = 1;
1599
+ objectModel = null;
1600
+ constructor(data) {
1601
+ super();
1602
+ this.objectModel = data.objectModel;
1603
+ }
1604
+ createColliderFromObjectModel(objectModel) {
1605
+ if (!objectModel) return ColliderDesc7.capsule(1, 1);
1606
+ const skinnedMesh = objectModel.children.find((child) => child instanceof SkinnedMesh);
1607
+ const geometry = skinnedMesh.geometry;
1608
+ if (geometry) {
1609
+ geometry.computeBoundingBox();
1610
+ if (geometry.boundingBox) {
1611
+ const maxY = geometry.boundingBox.max.y;
1612
+ const minY = geometry.boundingBox.min.y;
1613
+ this.height = maxY - minY;
1614
+ }
1615
+ }
1616
+ this.height = 1;
1617
+ let colliderDesc = ColliderDesc7.capsule(this.height / 2, 1);
1618
+ colliderDesc.setSensor(false);
1619
+ colliderDesc.setTranslation(0, this.height + 0.5, 0);
1620
+ colliderDesc.activeCollisionTypes = ActiveCollisionTypes3.DEFAULT;
1621
+ return colliderDesc;
1622
+ }
1623
+ collider(options) {
1624
+ let colliderDesc = this.createColliderFromObjectModel(this.objectModel);
1625
+ return colliderDesc;
1626
+ }
1627
+ };
1628
+ var ActorBuilder = class extends EntityBuilder {
1629
+ createEntity(options) {
1630
+ return new ZylemActor(options);
1631
+ }
1632
+ };
1633
+ var ACTOR_TYPE = /* @__PURE__ */ Symbol("Actor");
1634
+ var ZylemActor = class extends GameEntity {
1635
+ static type = ACTOR_TYPE;
1636
+ _object = null;
1637
+ _animationDelegate = null;
1638
+ _modelFileNames = [];
1639
+ _assetLoader = new EntityAssetLoader();
1640
+ controlledRotation = false;
1641
+ constructor(options) {
1642
+ super();
1643
+ this.options = { ...actorDefaults, ...options };
1644
+ this.prependUpdate(this.actorUpdate.bind(this));
1645
+ this.controlledRotation = true;
1646
+ }
1647
+ async load() {
1648
+ this._modelFileNames = this.options.models || [];
1649
+ await this.loadModels();
1650
+ if (this._object) {
1651
+ this._animationDelegate = new AnimationDelegate(this._object);
1652
+ await this._animationDelegate.loadAnimations(this.options.animations || []);
1653
+ }
1654
+ }
1655
+ async data() {
1656
+ return {
1657
+ animations: this._animationDelegate?.animations,
1658
+ objectModel: this._object
1659
+ };
1660
+ }
1661
+ async actorUpdate(params) {
1662
+ this._animationDelegate?.update(params.delta);
1663
+ }
1664
+ /**
1665
+ * Clean up actor resources including animations, models, and groups
1666
+ */
1667
+ actorDestroy() {
1668
+ if (this._animationDelegate) {
1669
+ this._animationDelegate.dispose();
1670
+ this._animationDelegate = null;
1671
+ }
1672
+ if (this._object) {
1673
+ this._object.traverse((child) => {
1674
+ if (child.isMesh) {
1675
+ const mesh = child;
1676
+ mesh.geometry?.dispose();
1677
+ if (Array.isArray(mesh.material)) {
1678
+ mesh.material.forEach((m) => m.dispose());
1679
+ } else if (mesh.material) {
1680
+ mesh.material.dispose();
1681
+ }
1682
+ }
1683
+ });
1684
+ this._object = null;
1685
+ }
1686
+ if (this.group) {
1687
+ this.group.clear();
1688
+ this.group = null;
1689
+ }
1690
+ this._modelFileNames = [];
1691
+ }
1692
+ async loadModels() {
1693
+ if (this._modelFileNames.length === 0) return;
1694
+ const promises = this._modelFileNames.map((file) => this._assetLoader.loadFile(file));
1695
+ const results = await Promise.all(promises);
1696
+ if (results[0]?.object) {
1697
+ this._object = results[0].object;
1698
+ }
1699
+ if (this._object) {
1700
+ this.group = new Group4();
1701
+ this.group.attach(this._object);
1702
+ this.group.scale.set(
1703
+ this.options.scale?.x || 1,
1704
+ this.options.scale?.y || 1,
1705
+ this.options.scale?.z || 1
1706
+ );
1707
+ }
1708
+ }
1709
+ playAnimation(animationOptions) {
1710
+ this._animationDelegate?.playAnimation(animationOptions);
1711
+ }
1712
+ get object() {
1713
+ return this._object;
1714
+ }
1715
+ /**
1716
+ * Provide custom debug information for the actor
1717
+ * This will be merged with the default debug information
1718
+ */
1719
+ getDebugInfo() {
1720
+ const debugInfo = {
1721
+ type: "Actor",
1722
+ models: this._modelFileNames.length > 0 ? this._modelFileNames : "none",
1723
+ modelLoaded: !!this._object,
1724
+ scale: this.options.scale ? `${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}` : "1, 1, 1"
1725
+ };
1726
+ if (this._animationDelegate) {
1727
+ debugInfo.currentAnimation = this._animationDelegate.currentAnimationKey || "none";
1728
+ debugInfo.animationsCount = this.options.animations?.length || 0;
1729
+ }
1730
+ if (this._object) {
1731
+ let meshCount = 0;
1732
+ let vertexCount = 0;
1733
+ this._object.traverse((child) => {
1734
+ if (child.isMesh) {
1735
+ meshCount++;
1736
+ const geometry = child.geometry;
1737
+ if (geometry && geometry.attributes.position) {
1738
+ vertexCount += geometry.attributes.position.count;
1739
+ }
1740
+ }
1741
+ });
1742
+ debugInfo.meshCount = meshCount;
1743
+ debugInfo.vertexCount = vertexCount;
1744
+ }
1745
+ return debugInfo;
1746
+ }
1747
+ };
1748
+ async function actor(...args) {
1749
+ return await createEntity({
1750
+ args,
1751
+ defaultConfig: actorDefaults,
1752
+ EntityClass: ZylemActor,
1753
+ BuilderClass: ActorBuilder,
1754
+ CollisionBuilderClass: ActorCollisionBuilder,
1755
+ entityType: ZylemActor.type
1756
+ });
1757
+ }
1758
+
1759
+ // src/lib/entities/text.ts
1760
+ import { Color as Color8, Group as Group5, Sprite as ThreeSprite2, SpriteMaterial as SpriteMaterial2, CanvasTexture, LinearFilter, Vector2 as Vector23, ClampToEdgeWrapping } from "three";
1761
+ var textDefaults = {
1762
+ position: void 0,
1763
+ text: "",
1764
+ fontFamily: 'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
1765
+ fontSize: 18,
1766
+ fontColor: "#FFFFFF",
1767
+ backgroundColor: null,
1768
+ padding: 4,
1769
+ stickToViewport: true,
1770
+ screenPosition: new Vector23(24, 24),
1771
+ zDistance: 1
1772
+ };
1773
+ var TextBuilder = class extends EntityBuilder {
1774
+ createEntity(options) {
1775
+ return new ZylemText(options);
1776
+ }
1777
+ };
1778
+ var TEXT_TYPE = /* @__PURE__ */ Symbol("Text");
1779
+ var ZylemText = class _ZylemText extends GameEntity {
1780
+ static type = TEXT_TYPE;
1781
+ _sprite = null;
1782
+ _texture = null;
1783
+ _canvas = null;
1784
+ _ctx = null;
1785
+ _cameraRef = null;
1786
+ _lastCanvasW = 0;
1787
+ _lastCanvasH = 0;
1788
+ constructor(options) {
1789
+ super();
1790
+ this.options = { ...textDefaults, ...options };
1791
+ this.prependSetup(this.textSetup.bind(this));
1792
+ this.prependUpdate(this.textUpdate.bind(this));
1793
+ this.onDestroy(this.textDestroy.bind(this));
1794
+ }
1795
+ create() {
1796
+ this._sprite = null;
1797
+ this._texture = null;
1798
+ this._canvas = null;
1799
+ this._ctx = null;
1800
+ this._lastCanvasW = 0;
1801
+ this._lastCanvasH = 0;
1802
+ this.group = new Group5();
1803
+ this.createSprite();
1804
+ return super.create();
1805
+ }
1806
+ createSprite() {
1807
+ this._canvas = document.createElement("canvas");
1808
+ this._ctx = this._canvas.getContext("2d");
1809
+ this._texture = new CanvasTexture(this._canvas);
1810
+ this._texture.minFilter = LinearFilter;
1811
+ this._texture.magFilter = LinearFilter;
1812
+ const material = new SpriteMaterial2({
1813
+ map: this._texture,
1814
+ transparent: true,
1815
+ depthTest: false,
1816
+ depthWrite: false,
1817
+ alphaTest: 0.5
1818
+ });
1819
+ this._sprite = new ThreeSprite2(material);
1820
+ this.group?.add(this._sprite);
1821
+ this.redrawText(this.options.text ?? "");
1822
+ }
1823
+ measureAndResizeCanvas(text2, fontSize, fontFamily, padding) {
1824
+ if (!this._canvas || !this._ctx) return { sizeChanged: false };
1825
+ this._ctx.font = `${fontSize}px ${fontFamily}`;
1826
+ const metrics = this._ctx.measureText(text2);
1827
+ const textWidth = Math.ceil(metrics.width);
1828
+ const textHeight = Math.ceil(fontSize * 1.4);
1829
+ const nextW = Math.max(2, textWidth + padding * 2);
1830
+ const nextH = Math.max(2, textHeight + padding * 2);
1831
+ const sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;
1832
+ this._canvas.width = nextW;
1833
+ this._canvas.height = nextH;
1834
+ this._lastCanvasW = nextW;
1835
+ this._lastCanvasH = nextH;
1836
+ return { sizeChanged };
1837
+ }
1838
+ drawCenteredText(text2, fontSize, fontFamily) {
1839
+ if (!this._canvas || !this._ctx) return;
1840
+ this._ctx.font = `${fontSize}px ${fontFamily}`;
1841
+ this._ctx.textAlign = "center";
1842
+ this._ctx.textBaseline = "middle";
1843
+ this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
1844
+ if (this.options.backgroundColor) {
1845
+ this._ctx.fillStyle = this.toCssColor(this.options.backgroundColor);
1846
+ this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);
1847
+ }
1848
+ this._ctx.fillStyle = this.toCssColor(this.options.fontColor ?? "#FFFFFF");
1849
+ this._ctx.fillText(text2, this._canvas.width / 2, this._canvas.height / 2);
1850
+ }
1851
+ updateTexture(sizeChanged) {
1852
+ if (!this._texture || !this._canvas) return;
1853
+ if (sizeChanged) {
1854
+ this._texture.dispose();
1855
+ this._texture = new CanvasTexture(this._canvas);
1856
+ this._texture.minFilter = LinearFilter;
1857
+ this._texture.magFilter = LinearFilter;
1858
+ this._texture.wrapS = ClampToEdgeWrapping;
1859
+ this._texture.wrapT = ClampToEdgeWrapping;
1860
+ }
1861
+ this._texture.image = this._canvas;
1862
+ this._texture.needsUpdate = true;
1863
+ if (this._sprite && this._sprite.material) {
1864
+ this._sprite.material.map = this._texture;
1865
+ this._sprite.material.needsUpdate = true;
1866
+ }
1867
+ }
1868
+ redrawText(_text) {
1869
+ if (!this._canvas || !this._ctx) return;
1870
+ const fontSize = this.options.fontSize ?? 18;
1871
+ const fontFamily = this.options.fontFamily ?? textDefaults.fontFamily;
1872
+ const padding = this.options.padding ?? 4;
1873
+ const { sizeChanged } = this.measureAndResizeCanvas(_text, fontSize, fontFamily, padding);
1874
+ this.drawCenteredText(_text, fontSize, fontFamily);
1875
+ this.updateTexture(Boolean(sizeChanged));
1876
+ if (this.options.stickToViewport && this._cameraRef) {
1877
+ this.updateStickyTransform();
1878
+ }
1879
+ }
1880
+ toCssColor(color) {
1881
+ if (typeof color === "string") return color;
1882
+ const c = color instanceof Color8 ? color : new Color8(color);
1883
+ return `#${c.getHexString()}`;
1884
+ }
1885
+ textSetup(params) {
1886
+ this._cameraRef = params.camera;
1887
+ if (this.options.stickToViewport && this._cameraRef) {
1888
+ this._cameraRef.camera.add(this.group);
1889
+ this.updateStickyTransform();
1890
+ }
1891
+ }
1892
+ textUpdate(params) {
1893
+ if (!this._sprite) return;
1894
+ if (this.options.stickToViewport && this._cameraRef) {
1895
+ this.updateStickyTransform();
1896
+ }
1897
+ }
1898
+ getResolution() {
1899
+ return {
1900
+ width: this._cameraRef?.screenResolution.x ?? 1,
1901
+ height: this._cameraRef?.screenResolution.y ?? 1
1902
+ };
1903
+ }
1904
+ getScreenPixels(sp, width, height) {
1905
+ const isPercentX = sp.x >= 0 && sp.x <= 1;
1906
+ const isPercentY = sp.y >= 0 && sp.y <= 1;
1907
+ return {
1908
+ px: isPercentX ? sp.x * width : sp.x,
1909
+ py: isPercentY ? sp.y * height : sp.y
1910
+ };
1911
+ }
1912
+ computeWorldExtents(camera, zDist) {
1913
+ let worldHalfW = 1;
1914
+ let worldHalfH = 1;
1915
+ if (camera.isPerspectiveCamera) {
1916
+ const pc = camera;
1917
+ const halfH = Math.tan(pc.fov * Math.PI / 180 / 2) * zDist;
1918
+ const halfW = halfH * pc.aspect;
1919
+ worldHalfW = halfW;
1920
+ worldHalfH = halfH;
1921
+ } else if (camera.isOrthographicCamera) {
1922
+ const oc = camera;
1923
+ worldHalfW = (oc.right - oc.left) / 2;
1924
+ worldHalfH = (oc.top - oc.bottom) / 2;
1925
+ }
1926
+ return { worldHalfW, worldHalfH };
1927
+ }
1928
+ updateSpriteScale(worldHalfH, viewportHeight) {
1929
+ if (!this._canvas || !this._sprite) return;
1930
+ const planeH = worldHalfH * 2;
1931
+ const unitsPerPixel = planeH / viewportHeight;
1932
+ const pixelH = this._canvas.height;
1933
+ const scaleY = Math.max(1e-4, pixelH * unitsPerPixel);
1934
+ const aspect = this._canvas.width / this._canvas.height;
1935
+ const scaleX = scaleY * aspect;
1936
+ this._sprite.scale.set(scaleX, scaleY, 1);
1937
+ }
1938
+ updateStickyTransform() {
1939
+ if (!this._sprite || !this._cameraRef) return;
1940
+ const camera = this._cameraRef.camera;
1941
+ const { width, height } = this.getResolution();
1942
+ const sp = this.options.screenPosition ?? new Vector23(24, 24);
1943
+ const { px, py } = this.getScreenPixels(sp, width, height);
1944
+ const zDist = Math.max(1e-3, this.options.zDistance ?? 1);
1945
+ const { worldHalfW, worldHalfH } = this.computeWorldExtents(camera, zDist);
1946
+ const ndcX = px / width * 2 - 1;
1947
+ const ndcY = 1 - py / height * 2;
1948
+ const localX = ndcX * worldHalfW;
1949
+ const localY = ndcY * worldHalfH;
1950
+ this.group?.position.set(localX, localY, -zDist);
1951
+ this.updateSpriteScale(worldHalfH, height);
1952
+ }
1953
+ updateText(_text) {
1954
+ this.options.text = _text;
1955
+ this.redrawText(_text);
1956
+ if (this.options.stickToViewport && this._cameraRef) {
1957
+ this.updateStickyTransform();
1958
+ }
1959
+ }
1960
+ buildInfo() {
1961
+ const delegate = new DebugDelegate(this);
1962
+ const baseInfo = delegate.buildDebugInfo();
1963
+ return {
1964
+ ...baseInfo,
1965
+ type: String(_ZylemText.type),
1966
+ text: this.options.text ?? "",
1967
+ sticky: this.options.stickToViewport
1968
+ };
1969
+ }
1970
+ /**
1971
+ * Dispose of Three.js resources when the entity is destroyed.
1972
+ */
1973
+ async textDestroy() {
1974
+ this._texture?.dispose();
1975
+ if (this._sprite?.material) {
1976
+ this._sprite.material.dispose();
1977
+ }
1978
+ if (this._sprite) {
1979
+ this._sprite.removeFromParent();
1980
+ }
1981
+ this.group?.removeFromParent();
1982
+ this._sprite = null;
1983
+ this._texture = null;
1984
+ this._canvas = null;
1985
+ this._ctx = null;
1986
+ this._cameraRef = null;
1987
+ }
1988
+ };
1989
+ async function text(...args) {
1990
+ return createEntity({
1991
+ args,
1992
+ defaultConfig: { ...textDefaults },
1993
+ EntityClass: ZylemText,
1994
+ BuilderClass: TextBuilder,
1995
+ entityType: ZylemText.type
1996
+ });
1997
+ }
1998
+
1999
+ // src/lib/entities/rect.ts
2000
+ import { Color as Color9, Group as Group6, Sprite as ThreeSprite3, SpriteMaterial as SpriteMaterial3, CanvasTexture as CanvasTexture2, LinearFilter as LinearFilter2, Vector2 as Vector24, ClampToEdgeWrapping as ClampToEdgeWrapping2, ShaderMaterial as ShaderMaterial3, Mesh as Mesh4, PlaneGeometry as PlaneGeometry2, Vector3 as Vector39 } from "three";
2001
+ var rectDefaults = {
2002
+ position: void 0,
2003
+ width: 120,
2004
+ height: 48,
2005
+ fillColor: "#FFFFFF",
2006
+ strokeColor: null,
2007
+ strokeWidth: 0,
2008
+ radius: 0,
2009
+ padding: 0,
2010
+ stickToViewport: true,
2011
+ screenPosition: new Vector24(24, 24),
2012
+ zDistance: 1,
2013
+ anchor: new Vector24(0, 0)
2014
+ };
2015
+ var RectBuilder = class extends EntityBuilder {
2016
+ createEntity(options) {
2017
+ return new ZylemRect(options);
2018
+ }
2019
+ };
2020
+ var RECT_TYPE = /* @__PURE__ */ Symbol("Rect");
2021
+ var ZylemRect = class _ZylemRect extends GameEntity {
2022
+ static type = RECT_TYPE;
2023
+ _sprite = null;
2024
+ _mesh = null;
2025
+ _texture = null;
2026
+ _canvas = null;
2027
+ _ctx = null;
2028
+ _cameraRef = null;
2029
+ _lastCanvasW = 0;
2030
+ _lastCanvasH = 0;
2031
+ constructor(options) {
2032
+ super();
2033
+ this.options = { ...rectDefaults, ...options };
2034
+ this.group = new Group6();
2035
+ this.createSprite();
2036
+ this.prependSetup(this.rectSetup.bind(this));
2037
+ this.prependUpdate(this.rectUpdate.bind(this));
2038
+ }
2039
+ createSprite() {
2040
+ this._canvas = document.createElement("canvas");
2041
+ this._ctx = this._canvas.getContext("2d");
2042
+ this._texture = new CanvasTexture2(this._canvas);
2043
+ this._texture.minFilter = LinearFilter2;
2044
+ this._texture.magFilter = LinearFilter2;
2045
+ const material = new SpriteMaterial3({
2046
+ map: this._texture,
2047
+ transparent: true,
2048
+ depthTest: false,
2049
+ depthWrite: false,
2050
+ alphaTest: 0.5
2051
+ });
2052
+ this._sprite = new ThreeSprite3(material);
2053
+ this.group?.add(this._sprite);
2054
+ this.redrawRect();
2055
+ }
2056
+ redrawRect() {
2057
+ if (!this._canvas || !this._ctx) return;
2058
+ const width = Math.max(2, Math.floor(this.options.width ?? 120));
2059
+ const height = Math.max(2, Math.floor(this.options.height ?? 48));
2060
+ const padding = this.options.padding ?? 0;
2061
+ const strokeWidth = this.options.strokeWidth ?? 0;
2062
+ const totalW = width + padding * 2 + strokeWidth;
2063
+ const totalH = height + padding * 2 + strokeWidth;
2064
+ const nextW = Math.max(2, totalW);
2065
+ const nextH = Math.max(2, totalH);
2066
+ const sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;
2067
+ this._canvas.width = nextW;
2068
+ this._canvas.height = nextH;
2069
+ this._lastCanvasW = nextW;
2070
+ this._lastCanvasH = nextH;
2071
+ this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
2072
+ const radius = Math.max(0, this.options.radius ?? 0);
2073
+ const rectX = Math.floor(padding + strokeWidth / 2);
2074
+ const rectY = Math.floor(padding + strokeWidth / 2);
2075
+ const rectW = Math.floor(width);
2076
+ const rectH = Math.floor(height);
2077
+ this._ctx.beginPath();
2078
+ if (radius > 0) {
2079
+ this.roundedRectPath(this._ctx, rectX, rectY, rectW, rectH, radius);
2080
+ } else {
2081
+ this._ctx.rect(rectX, rectY, rectW, rectH);
2082
+ }
2083
+ if (this.options.fillColor) {
2084
+ this._ctx.fillStyle = this.toCssColor(this.options.fillColor);
2085
+ this._ctx.fill();
2086
+ }
2087
+ if (this.options.strokeColor && strokeWidth > 0) {
2088
+ this._ctx.lineWidth = strokeWidth;
2089
+ this._ctx.strokeStyle = this.toCssColor(this.options.strokeColor);
2090
+ this._ctx.stroke();
2091
+ }
2092
+ if (this._texture) {
2093
+ if (sizeChanged) {
2094
+ this._texture.dispose();
2095
+ this._texture = new CanvasTexture2(this._canvas);
2096
+ this._texture.minFilter = LinearFilter2;
2097
+ this._texture.magFilter = LinearFilter2;
2098
+ this._texture.wrapS = ClampToEdgeWrapping2;
2099
+ this._texture.wrapT = ClampToEdgeWrapping2;
2100
+ if (this._sprite && this._sprite.material instanceof ShaderMaterial3) {
2101
+ const shader = this._sprite.material;
2102
+ if (shader.uniforms?.tDiffuse) shader.uniforms.tDiffuse.value = this._texture;
2103
+ if (shader.uniforms?.iResolution) shader.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);
2104
+ }
2105
+ }
2106
+ this._texture.image = this._canvas;
2107
+ this._texture.needsUpdate = true;
2108
+ if (this._sprite && this._sprite.material) {
2109
+ this._sprite.material.map = this._texture;
2110
+ this._sprite.material.needsUpdate = true;
2111
+ }
2112
+ }
2113
+ }
2114
+ roundedRectPath(ctx, x, y, w, h, r) {
2115
+ const radius = Math.min(r, Math.floor(Math.min(w, h) / 2));
2116
+ ctx.moveTo(x + radius, y);
2117
+ ctx.lineTo(x + w - radius, y);
2118
+ ctx.quadraticCurveTo(x + w, y, x + w, y + radius);
2119
+ ctx.lineTo(x + w, y + h - radius);
2120
+ ctx.quadraticCurveTo(x + w, y + h, x + w - radius, y + h);
2121
+ ctx.lineTo(x + radius, y + h);
2122
+ ctx.quadraticCurveTo(x, y + h, x, y + h - radius);
2123
+ ctx.lineTo(x, y + radius);
2124
+ ctx.quadraticCurveTo(x, y, x + radius, y);
2125
+ }
2126
+ toCssColor(color) {
2127
+ if (typeof color === "string") return color;
2128
+ const c = color instanceof Color9 ? color : new Color9(color);
2129
+ return `#${c.getHexString()}`;
2130
+ }
2131
+ rectSetup(params) {
2132
+ this._cameraRef = params.camera;
2133
+ if (this.options.stickToViewport && this._cameraRef) {
2134
+ this._cameraRef.camera.add(this.group);
2135
+ }
2136
+ if (this.materials?.length && this._sprite) {
2137
+ const mat = this.materials[0];
2138
+ if (mat instanceof ShaderMaterial3) {
2139
+ mat.transparent = true;
2140
+ mat.depthTest = false;
2141
+ mat.depthWrite = false;
2142
+ if (this._texture) {
2143
+ if (mat.uniforms?.tDiffuse) mat.uniforms.tDiffuse.value = this._texture;
2144
+ if (mat.uniforms?.iResolution && this._canvas) mat.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);
2145
+ }
2146
+ this._mesh = new Mesh4(new PlaneGeometry2(1, 1), mat);
2147
+ this.group?.add(this._mesh);
2148
+ this._sprite.visible = false;
2149
+ }
2150
+ }
2151
+ }
2152
+ rectUpdate(params) {
2153
+ if (!this._sprite) return;
2154
+ if (this._cameraRef && this.options.bounds) {
2155
+ const dom = this._cameraRef.renderer.domElement;
2156
+ const screen = this.computeScreenBoundsFromOptions(this.options.bounds);
2157
+ if (screen) {
2158
+ const { x, y, width, height } = screen;
2159
+ const desiredW = Math.max(2, Math.floor(width));
2160
+ const desiredH = Math.max(2, Math.floor(height));
2161
+ const changed = desiredW !== (this.options.width ?? 0) || desiredH !== (this.options.height ?? 0);
2162
+ this.options.screenPosition = new Vector24(Math.floor(x), Math.floor(y));
2163
+ this.options.width = desiredW;
2164
+ this.options.height = desiredH;
2165
+ this.options.anchor = new Vector24(0, 0);
2166
+ if (changed) {
2167
+ this.redrawRect();
2168
+ }
2169
+ }
2170
+ }
2171
+ if (this.options.stickToViewport && this._cameraRef) {
2172
+ this.updateStickyTransform();
2173
+ }
2174
+ }
2175
+ updateStickyTransform() {
2176
+ if (!this._sprite || !this._cameraRef) return;
2177
+ const camera = this._cameraRef.camera;
2178
+ const dom = this._cameraRef.renderer.domElement;
2179
+ const width = dom.clientWidth;
2180
+ const height = dom.clientHeight;
2181
+ const px = (this.options.screenPosition ?? new Vector24(24, 24)).x;
2182
+ const py = (this.options.screenPosition ?? new Vector24(24, 24)).y;
2183
+ const zDist = Math.max(1e-3, this.options.zDistance ?? 1);
2184
+ let worldHalfW = 1;
2185
+ let worldHalfH = 1;
2186
+ if (camera.isPerspectiveCamera) {
2187
+ const pc = camera;
2188
+ const halfH = Math.tan(pc.fov * Math.PI / 180 / 2) * zDist;
2189
+ const halfW = halfH * pc.aspect;
2190
+ worldHalfW = halfW;
2191
+ worldHalfH = halfH;
2192
+ } else if (camera.isOrthographicCamera) {
2193
+ const oc = camera;
2194
+ worldHalfW = (oc.right - oc.left) / 2;
2195
+ worldHalfH = (oc.top - oc.bottom) / 2;
2196
+ }
2197
+ const ndcX = px / width * 2 - 1;
2198
+ const ndcY = 1 - py / height * 2;
2199
+ const localX = ndcX * worldHalfW;
2200
+ const localY = ndcY * worldHalfH;
2201
+ let scaleX = 1;
2202
+ let scaleY = 1;
2203
+ if (this._canvas) {
2204
+ const planeH = worldHalfH * 2;
2205
+ const unitsPerPixel = planeH / height;
2206
+ const pixelH = this._canvas.height;
2207
+ scaleY = Math.max(1e-4, pixelH * unitsPerPixel);
2208
+ const aspect = this._canvas.width / this._canvas.height;
2209
+ scaleX = scaleY * aspect;
2210
+ this._sprite.scale.set(scaleX, scaleY, 1);
2211
+ if (this._mesh) this._mesh.scale.set(scaleX, scaleY, 1);
2212
+ }
2213
+ const anchor = this.options.anchor ?? new Vector24(0, 0);
2214
+ const ax = Math.min(100, Math.max(0, anchor.x)) / 100;
2215
+ const ay = Math.min(100, Math.max(0, anchor.y)) / 100;
2216
+ const offsetX = (0.5 - ax) * scaleX;
2217
+ const offsetY = (ay - 0.5) * scaleY;
2218
+ this.group?.position.set(localX + offsetX, localY + offsetY, -zDist);
2219
+ }
2220
+ worldToScreen(point) {
2221
+ if (!this._cameraRef) return { x: 0, y: 0 };
2222
+ const camera = this._cameraRef.camera;
2223
+ const dom = this._cameraRef.renderer.domElement;
2224
+ const v = point.clone().project(camera);
2225
+ const x = (v.x + 1) / 2 * dom.clientWidth;
2226
+ const y = (1 - v.y) / 2 * dom.clientHeight;
2227
+ return { x, y };
2228
+ }
2229
+ computeScreenBoundsFromOptions(bounds) {
2230
+ if (!this._cameraRef) return null;
2231
+ const dom = this._cameraRef.renderer.domElement;
2232
+ if (bounds.screen) {
2233
+ return { ...bounds.screen };
2234
+ }
2235
+ if (bounds.world) {
2236
+ const { left, right, top, bottom, z = 0 } = bounds.world;
2237
+ const tl = this.worldToScreen(new Vector39(left, top, z));
2238
+ const br = this.worldToScreen(new Vector39(right, bottom, z));
2239
+ const x = Math.min(tl.x, br.x);
2240
+ const y = Math.min(tl.y, br.y);
2241
+ const width = Math.abs(br.x - tl.x);
2242
+ const height = Math.abs(br.y - tl.y);
2243
+ return { x, y, width, height };
2244
+ }
2245
+ return null;
2246
+ }
2247
+ updateRect(options) {
2248
+ this.options = { ...this.options, ...options };
2249
+ this.redrawRect();
2250
+ if (this.options.stickToViewport && this._cameraRef) {
2251
+ this.updateStickyTransform();
2252
+ }
2253
+ }
2254
+ buildInfo() {
2255
+ const delegate = new DebugDelegate(this);
2256
+ const baseInfo = delegate.buildDebugInfo();
2257
+ return {
2258
+ ...baseInfo,
2259
+ type: String(_ZylemRect.type),
2260
+ width: this.options.width ?? 0,
2261
+ height: this.options.height ?? 0,
2262
+ sticky: this.options.stickToViewport
2263
+ };
2264
+ }
2265
+ };
2266
+ async function rect(...args) {
2267
+ return createEntity({
2268
+ args,
2269
+ defaultConfig: { ...rectDefaults },
2270
+ EntityClass: ZylemRect,
2271
+ BuilderClass: RectBuilder,
2272
+ entityType: ZylemRect.type
2273
+ });
2274
+ }
9
2275
  export {
10
- e as ZylemBox,
11
- b as actor,
12
- t as box,
13
- c as plane,
14
- z as rect,
15
- x as sphere,
16
- f as sprite,
17
- i as text,
18
- n as zone
2276
+ ZylemBox,
2277
+ actor,
2278
+ box,
2279
+ plane,
2280
+ rect,
2281
+ sphere,
2282
+ sprite,
2283
+ text,
2284
+ zone
19
2285
  };
2286
+ //# sourceMappingURL=entities.js.map