@zylem/game-lib 0.4.1 → 0.5.1

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