@datamoc/mw_games 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. package/README.md +57 -32
  2. package/dist/actors/Appearances.js +1 -1
  3. package/dist/actors/Aura.d.ts +29 -0
  4. package/dist/actors/Aura.d.ts.map +1 -0
  5. package/dist/actors/Aura.js +69 -0
  6. package/dist/actors/Aura.js.map +1 -0
  7. package/dist/actors/ItemStatusEffect.d.ts +27 -0
  8. package/dist/actors/ItemStatusEffect.d.ts.map +1 -0
  9. package/dist/actors/ItemStatusEffect.js +35 -0
  10. package/dist/actors/ItemStatusEffect.js.map +1 -0
  11. package/dist/actors/Resource.d.ts.map +1 -1
  12. package/dist/actors/Resource.js +13 -5
  13. package/dist/actors/Resource.js.map +1 -1
  14. package/dist/actors/Support.d.ts +32 -0
  15. package/dist/actors/Support.d.ts.map +1 -0
  16. package/dist/actors/Support.js +60 -0
  17. package/dist/actors/Support.js.map +1 -0
  18. package/dist/actors/Traits.d.ts +29 -0
  19. package/dist/actors/Traits.d.ts.map +1 -0
  20. package/dist/actors/Traits.js +21 -0
  21. package/dist/actors/Traits.js.map +1 -0
  22. package/dist/actors/craft.d.ts.map +1 -1
  23. package/dist/actors/craft.js +6 -2
  24. package/dist/actors/craft.js.map +1 -1
  25. package/dist/actors/index.d.ts +8 -0
  26. package/dist/actors/index.d.ts.map +1 -1
  27. package/dist/actors/index.js +4 -0
  28. package/dist/actors/index.js.map +1 -1
  29. package/dist/assets/Streaming.d.ts +40 -0
  30. package/dist/assets/Streaming.d.ts.map +1 -0
  31. package/dist/assets/Streaming.js +79 -0
  32. package/dist/assets/Streaming.js.map +1 -0
  33. package/dist/assets/index.d.ts +14 -1
  34. package/dist/assets/index.d.ts.map +1 -1
  35. package/dist/assets/index.js +19 -0
  36. package/dist/assets/index.js.map +1 -1
  37. package/dist/audio/Captions.d.ts +15 -0
  38. package/dist/audio/Captions.d.ts.map +1 -0
  39. package/dist/audio/Captions.js +4 -0
  40. package/dist/audio/Captions.js.map +1 -0
  41. package/dist/audio/Midi.d.ts +75 -0
  42. package/dist/audio/Midi.d.ts.map +1 -0
  43. package/dist/audio/Midi.js +186 -0
  44. package/dist/audio/Midi.js.map +1 -0
  45. package/dist/audio/Orchestrator.d.ts +40 -0
  46. package/dist/audio/Orchestrator.d.ts.map +1 -0
  47. package/dist/audio/Orchestrator.js +48 -0
  48. package/dist/audio/Orchestrator.js.map +1 -0
  49. package/dist/audio/Sound.d.ts +3 -0
  50. package/dist/audio/Sound.d.ts.map +1 -1
  51. package/dist/audio/Sound.js +4 -0
  52. package/dist/audio/Sound.js.map +1 -1
  53. package/dist/audio/Synth.d.ts +35 -0
  54. package/dist/audio/Synth.d.ts.map +1 -0
  55. package/dist/audio/Synth.js +96 -0
  56. package/dist/audio/Synth.js.map +1 -0
  57. package/dist/audio/index.d.ts +8 -0
  58. package/dist/audio/index.d.ts.map +1 -1
  59. package/dist/audio/index.js +4 -0
  60. package/dist/audio/index.js.map +1 -1
  61. package/dist/battle/Party.d.ts.map +1 -1
  62. package/dist/battle/Party.js +2 -0
  63. package/dist/battle/Party.js.map +1 -1
  64. package/dist/board/Army.d.ts +17 -0
  65. package/dist/board/Army.d.ts.map +1 -0
  66. package/dist/board/Army.js +48 -0
  67. package/dist/board/Army.js.map +1 -0
  68. package/dist/board/Classics.d.ts.map +1 -1
  69. package/dist/board/Classics.js +14 -6
  70. package/dist/board/Classics.js.map +1 -1
  71. package/dist/board/FogOfWar.d.ts +23 -0
  72. package/dist/board/FogOfWar.d.ts.map +1 -0
  73. package/dist/board/FogOfWar.js +40 -0
  74. package/dist/board/FogOfWar.js.map +1 -0
  75. package/dist/board/Tactics.d.ts +2 -0
  76. package/dist/board/Tactics.d.ts.map +1 -1
  77. package/dist/board/Tactics.js +36 -8
  78. package/dist/board/Tactics.js.map +1 -1
  79. package/dist/board/index.d.ts +5 -1
  80. package/dist/board/index.d.ts.map +1 -1
  81. package/dist/board/index.js +3 -1
  82. package/dist/board/index.js.map +1 -1
  83. package/dist/core/Feedback.d.ts +23 -0
  84. package/dist/core/Feedback.d.ts.map +1 -0
  85. package/dist/core/Feedback.js +35 -0
  86. package/dist/core/Feedback.js.map +1 -0
  87. package/dist/core/Game.d.ts +27 -1
  88. package/dist/core/Game.d.ts.map +1 -1
  89. package/dist/core/Game.js +61 -5
  90. package/dist/core/Game.js.map +1 -1
  91. package/dist/core/Input.d.ts +59 -1
  92. package/dist/core/Input.d.ts.map +1 -1
  93. package/dist/core/Input.js +135 -0
  94. package/dist/core/Input.js.map +1 -1
  95. package/dist/core/Loading.d.ts +48 -0
  96. package/dist/core/Loading.d.ts.map +1 -0
  97. package/dist/core/Loading.js +102 -0
  98. package/dist/core/Loading.js.map +1 -0
  99. package/dist/core/News.d.ts +46 -0
  100. package/dist/core/News.d.ts.map +1 -0
  101. package/dist/core/News.js +79 -0
  102. package/dist/core/News.js.map +1 -0
  103. package/dist/core/PlayerInput.d.ts +38 -0
  104. package/dist/core/PlayerInput.d.ts.map +1 -0
  105. package/dist/core/PlayerInput.js +57 -0
  106. package/dist/core/PlayerInput.js.map +1 -0
  107. package/dist/core/Random.d.ts +2 -2
  108. package/dist/core/Random.js +2 -2
  109. package/dist/core/RunHistory.d.ts +43 -0
  110. package/dist/core/RunHistory.d.ts.map +1 -0
  111. package/dist/core/RunHistory.js +41 -0
  112. package/dist/core/RunHistory.js.map +1 -0
  113. package/dist/core/Sanitize.d.ts +56 -0
  114. package/dist/core/Sanitize.d.ts.map +1 -0
  115. package/dist/core/Sanitize.js +87 -0
  116. package/dist/core/Sanitize.js.map +1 -0
  117. package/dist/core/Save.d.ts +31 -7
  118. package/dist/core/Save.d.ts.map +1 -1
  119. package/dist/core/Save.js +56 -0
  120. package/dist/core/Save.js.map +1 -1
  121. package/dist/core/SaveSync.d.ts +26 -0
  122. package/dist/core/SaveSync.d.ts.map +1 -0
  123. package/dist/core/SaveSync.js +52 -0
  124. package/dist/core/SaveSync.js.map +1 -0
  125. package/dist/core/Scramble.d.ts +13 -0
  126. package/dist/core/Scramble.d.ts.map +1 -0
  127. package/dist/core/Scramble.js +44 -0
  128. package/dist/core/Scramble.js.map +1 -0
  129. package/dist/core/Session.d.ts +21 -0
  130. package/dist/core/Session.d.ts.map +1 -0
  131. package/dist/core/Session.js +11 -0
  132. package/dist/core/Session.js.map +1 -0
  133. package/dist/core/Spawner.d.ts +48 -0
  134. package/dist/core/Spawner.d.ts.map +1 -0
  135. package/dist/core/Spawner.js +65 -0
  136. package/dist/core/Spawner.js.map +1 -0
  137. package/dist/core/Tween.d.ts +25 -0
  138. package/dist/core/Tween.d.ts.map +1 -0
  139. package/dist/core/Tween.js +60 -0
  140. package/dist/core/Tween.js.map +1 -0
  141. package/dist/core/UndoHistory.d.ts +37 -0
  142. package/dist/core/UndoHistory.d.ts.map +1 -0
  143. package/dist/core/UndoHistory.js +49 -0
  144. package/dist/core/UndoHistory.js.map +1 -0
  145. package/dist/core/index.d.ts +22 -0
  146. package/dist/core/index.d.ts.map +1 -1
  147. package/dist/core/index.js +12 -0
  148. package/dist/core/index.js.map +1 -1
  149. package/dist/i18n/Fluent.d.ts +7 -0
  150. package/dist/i18n/Fluent.d.ts.map +1 -0
  151. package/dist/i18n/Fluent.js +86 -0
  152. package/dist/i18n/Fluent.js.map +1 -0
  153. package/dist/i18n/index.d.ts +15 -1
  154. package/dist/i18n/index.d.ts.map +1 -1
  155. package/dist/i18n/index.js +17 -2
  156. package/dist/i18n/index.js.map +1 -1
  157. package/dist/index.d.ts +1 -0
  158. package/dist/index.d.ts.map +1 -1
  159. package/dist/index.js +1 -0
  160. package/dist/index.js.map +1 -1
  161. package/dist/mw_games.global.js +351 -79
  162. package/dist/render/Camera.d.ts +32 -4
  163. package/dist/render/Camera.d.ts.map +1 -1
  164. package/dist/render/Camera.js +58 -23
  165. package/dist/render/Camera.js.map +1 -1
  166. package/dist/render/Capabilities.d.ts +51 -0
  167. package/dist/render/Capabilities.d.ts.map +1 -0
  168. package/dist/render/Capabilities.js +56 -0
  169. package/dist/render/Capabilities.js.map +1 -0
  170. package/dist/render/ColorBlindness.d.ts +16 -0
  171. package/dist/render/ColorBlindness.d.ts.map +1 -0
  172. package/dist/render/ColorBlindness.js +41 -0
  173. package/dist/render/ColorBlindness.js.map +1 -0
  174. package/dist/render/ColorTransformBatcher.d.ts +9 -0
  175. package/dist/render/ColorTransformBatcher.d.ts.map +1 -1
  176. package/dist/render/ColorTransformBatcher.js +131 -19
  177. package/dist/render/ColorTransformBatcher.js.map +1 -1
  178. package/dist/render/Minimap.d.ts +52 -0
  179. package/dist/render/Minimap.d.ts.map +1 -0
  180. package/dist/render/Minimap.js +95 -0
  181. package/dist/render/Minimap.js.map +1 -0
  182. package/dist/render/TileMap.d.ts +2 -2
  183. package/dist/render/TileMap.d.ts.map +1 -1
  184. package/dist/render/TileMap.js +12 -12
  185. package/dist/render/TileMap.js.map +1 -1
  186. package/dist/render/TintedSprite.d.ts +1 -8
  187. package/dist/render/TintedSprite.d.ts.map +1 -1
  188. package/dist/render/TintedSprite.js +3 -111
  189. package/dist/render/TintedSprite.js.map +1 -1
  190. package/dist/render/Viewport.d.ts +46 -0
  191. package/dist/render/Viewport.d.ts.map +1 -0
  192. package/dist/render/Viewport.js +52 -0
  193. package/dist/render/Viewport.js.map +1 -0
  194. package/dist/render/index.d.ts +9 -1
  195. package/dist/render/index.d.ts.map +1 -1
  196. package/dist/render/index.js +5 -1
  197. package/dist/render/index.js.map +1 -1
  198. package/dist/roguelike/FieldOfView.d.ts +1 -1
  199. package/dist/roguelike/Level.d.ts +2 -2
  200. package/dist/roguelike/Level.d.ts.map +1 -1
  201. package/dist/roguelike/Level.js +1 -1
  202. package/dist/roguelike/Level.js.map +1 -1
  203. package/dist/roguelike/Pathfinder.d.ts +3 -3
  204. package/dist/roguelike/Pathfinder.js +2 -2
  205. package/dist/roguelike/Scheduler.d.ts +1 -1
  206. package/dist/roguelike/Scheduler.js +1 -1
  207. package/dist/roguelike/Stealth.d.ts +34 -0
  208. package/dist/roguelike/Stealth.d.ts.map +1 -0
  209. package/dist/roguelike/Stealth.js +35 -0
  210. package/dist/roguelike/Stealth.js.map +1 -0
  211. package/dist/roguelike/generate.d.ts +3 -3
  212. package/dist/roguelike/generate.js +1 -1
  213. package/dist/roguelike/generate.js.map +1 -1
  214. package/dist/roguelike/index.d.ts +2 -0
  215. package/dist/roguelike/index.d.ts.map +1 -1
  216. package/dist/roguelike/index.js +1 -0
  217. package/dist/roguelike/index.js.map +1 -1
  218. package/dist/rpg/Collision.d.ts +42 -0
  219. package/dist/rpg/Collision.d.ts.map +1 -0
  220. package/dist/rpg/Collision.js +77 -0
  221. package/dist/rpg/Collision.js.map +1 -0
  222. package/dist/rpg/FreeMover.d.ts +45 -0
  223. package/dist/rpg/FreeMover.d.ts.map +1 -0
  224. package/dist/rpg/FreeMover.js +68 -0
  225. package/dist/rpg/FreeMover.js.map +1 -0
  226. package/dist/rpg/Marshal.d.ts +65 -0
  227. package/dist/rpg/Marshal.d.ts.map +1 -0
  228. package/dist/rpg/Marshal.js +393 -0
  229. package/dist/rpg/Marshal.js.map +1 -0
  230. package/dist/rpg/Quest.d.ts +41 -0
  231. package/dist/rpg/Quest.d.ts.map +1 -1
  232. package/dist/rpg/Quest.js +39 -6
  233. package/dist/rpg/Quest.js.map +1 -1
  234. package/dist/rpg/index.d.ts +7 -1
  235. package/dist/rpg/index.d.ts.map +1 -1
  236. package/dist/rpg/index.js +3 -0
  237. package/dist/rpg/index.js.map +1 -1
  238. package/dist/stage/DialogueStage.d.ts +2 -3
  239. package/dist/stage/DialogueStage.d.ts.map +1 -1
  240. package/dist/stage/DialogueStage.js +21 -30
  241. package/dist/stage/DialogueStage.js.map +1 -1
  242. package/dist/stage/index.d.ts +1 -1
  243. package/dist/stage/index.d.ts.map +1 -1
  244. package/dist/stage/script.d.ts +32 -3
  245. package/dist/stage/script.d.ts.map +1 -1
  246. package/dist/stage/script.js +0 -0
  247. package/dist/stage/script.js.map +1 -1
  248. package/dist/three-d/Character3D.d.ts +48 -0
  249. package/dist/three-d/Character3D.d.ts.map +1 -0
  250. package/dist/three-d/Character3D.js +96 -0
  251. package/dist/three-d/Character3D.js.map +1 -0
  252. package/dist/three-d/Engine3D.d.ts +23 -0
  253. package/dist/three-d/Engine3D.d.ts.map +1 -0
  254. package/dist/three-d/Engine3D.js +45 -0
  255. package/dist/three-d/Engine3D.js.map +1 -0
  256. package/dist/three-d/Grid.d.ts +14 -0
  257. package/dist/three-d/Grid.d.ts.map +1 -0
  258. package/dist/three-d/Grid.js +13 -0
  259. package/dist/three-d/Grid.js.map +1 -0
  260. package/dist/three-d/Heightmap.d.ts +35 -0
  261. package/dist/three-d/Heightmap.d.ts.map +1 -0
  262. package/dist/three-d/Heightmap.js +29 -0
  263. package/dist/three-d/Heightmap.js.map +1 -0
  264. package/dist/three-d/Models.d.ts +12 -0
  265. package/dist/three-d/Models.d.ts.map +1 -0
  266. package/dist/three-d/Models.js +14 -0
  267. package/dist/three-d/Models.js.map +1 -0
  268. package/dist/three-d/TileGrid3D.d.ts +21 -0
  269. package/dist/three-d/TileGrid3D.d.ts.map +1 -0
  270. package/dist/three-d/TileGrid3D.js +65 -0
  271. package/dist/three-d/TileGrid3D.js.map +1 -0
  272. package/dist/three-d/Vox.d.ts +24 -0
  273. package/dist/three-d/Vox.d.ts.map +1 -0
  274. package/dist/three-d/Vox.js +93 -0
  275. package/dist/three-d/Vox.js.map +1 -0
  276. package/dist/three-d/index.d.ts +13 -0
  277. package/dist/three-d/index.d.ts.map +1 -0
  278. package/dist/three-d/index.js +7 -0
  279. package/dist/three-d/index.js.map +1 -0
  280. package/dist/ui/Bar.d.ts +49 -0
  281. package/dist/ui/Bar.d.ts.map +1 -0
  282. package/dist/ui/Bar.js +70 -0
  283. package/dist/ui/Bar.js.map +1 -0
  284. package/dist/ui/BitmapLabel.d.ts +42 -0
  285. package/dist/ui/BitmapLabel.d.ts.map +1 -0
  286. package/dist/ui/BitmapLabel.js +59 -0
  287. package/dist/ui/BitmapLabel.js.map +1 -0
  288. package/dist/ui/Button.d.ts +52 -0
  289. package/dist/ui/Button.d.ts.map +1 -0
  290. package/dist/ui/Button.js +147 -0
  291. package/dist/ui/Button.js.map +1 -0
  292. package/dist/ui/FloatingText.d.ts +28 -0
  293. package/dist/ui/FloatingText.d.ts.map +1 -0
  294. package/dist/ui/FloatingText.js +39 -0
  295. package/dist/ui/FloatingText.js.map +1 -0
  296. package/dist/ui/HelpScreen.d.ts +29 -0
  297. package/dist/ui/HelpScreen.d.ts.map +1 -0
  298. package/dist/ui/HelpScreen.js +39 -0
  299. package/dist/ui/HelpScreen.js.map +1 -0
  300. package/dist/ui/IconGrid.d.ts +8 -0
  301. package/dist/ui/IconGrid.d.ts.map +1 -1
  302. package/dist/ui/IconGrid.js +27 -1
  303. package/dist/ui/IconGrid.js.map +1 -1
  304. package/dist/ui/Label.d.ts +10 -1
  305. package/dist/ui/Label.d.ts.map +1 -1
  306. package/dist/ui/Label.js +25 -2
  307. package/dist/ui/Label.js.map +1 -1
  308. package/dist/ui/ListView.d.ts +12 -1
  309. package/dist/ui/ListView.d.ts.map +1 -1
  310. package/dist/ui/ListView.js +56 -2
  311. package/dist/ui/ListView.js.map +1 -1
  312. package/dist/ui/LoadingScreen.d.ts +31 -0
  313. package/dist/ui/LoadingScreen.d.ts.map +1 -0
  314. package/dist/ui/LoadingScreen.js +60 -0
  315. package/dist/ui/LoadingScreen.js.map +1 -0
  316. package/dist/ui/MessageBox.d.ts +27 -1
  317. package/dist/ui/MessageBox.d.ts.map +1 -1
  318. package/dist/ui/MessageBox.js +63 -14
  319. package/dist/ui/MessageBox.js.map +1 -1
  320. package/dist/ui/RebindScreen.d.ts +55 -0
  321. package/dist/ui/RebindScreen.d.ts.map +1 -0
  322. package/dist/ui/RebindScreen.js +114 -0
  323. package/dist/ui/RebindScreen.js.map +1 -0
  324. package/dist/ui/Toast.d.ts +44 -0
  325. package/dist/ui/Toast.d.ts.map +1 -0
  326. package/dist/ui/Toast.js +89 -0
  327. package/dist/ui/Toast.js.map +1 -0
  328. package/dist/ui/VerticalLabel.d.ts +5 -0
  329. package/dist/ui/VerticalLabel.d.ts.map +1 -1
  330. package/dist/ui/VerticalLabel.js +18 -7
  331. package/dist/ui/VerticalLabel.js.map +1 -1
  332. package/dist/ui/Window.d.ts +6 -0
  333. package/dist/ui/Window.d.ts.map +1 -1
  334. package/dist/ui/Window.js +16 -1
  335. package/dist/ui/Window.js.map +1 -1
  336. package/dist/ui/WindowStack.d.ts +1 -0
  337. package/dist/ui/WindowStack.d.ts.map +1 -1
  338. package/dist/ui/WindowStack.js +4 -1
  339. package/dist/ui/WindowStack.js.map +1 -1
  340. package/dist/ui/index.d.ts +17 -1
  341. package/dist/ui/index.d.ts.map +1 -1
  342. package/dist/ui/index.js +9 -1
  343. package/dist/ui/index.js.map +1 -1
  344. package/dist/ui/theme.d.ts +21 -0
  345. package/dist/ui/theme.d.ts.map +1 -1
  346. package/dist/ui/theme.js +42 -0
  347. package/dist/ui/theme.js.map +1 -1
  348. package/dist/version.d.ts +13 -0
  349. package/dist/version.d.ts.map +1 -0
  350. package/dist/version.js +13 -0
  351. package/dist/version.js.map +1 -0
  352. package/dist/world/Environment.d.ts +35 -0
  353. package/dist/world/Environment.d.ts.map +1 -0
  354. package/dist/world/Environment.js +55 -0
  355. package/dist/world/Environment.js.map +1 -0
  356. package/dist/world/index.d.ts +2 -0
  357. package/dist/world/index.d.ts.map +1 -1
  358. package/dist/world/index.js +1 -0
  359. package/dist/world/index.js.map +1 -1
  360. package/package.json +40 -4
@@ -0,0 +1,35 @@
1
+ import type { GroundMesh } from '@babylonjs/core/Meshes/groundMesh.js';
2
+ import type { Scene } from '@babylonjs/core/scene.js';
3
+ /**
4
+ * Already-decoded pixel bytes, top-left origin, row-major, 4 bytes (RGBA) per pixel - a
5
+ * canvas `getImageData().data` is exactly this shape.
6
+ */
7
+ export interface HeightmapSource {
8
+ data: Uint8Array;
9
+ width: number;
10
+ height: number;
11
+ }
12
+ export interface HeightmapTerrain3DOptions {
13
+ /** world-space size along X; defaults to 10 */
14
+ width?: number;
15
+ /** world-space size along Z; defaults to 10 */
16
+ depth?: number;
17
+ /** vertices per side; defaults to one per source pixel along the shorter dimension */
18
+ subdivisions?: number;
19
+ minHeight?: number;
20
+ maxHeight?: number;
21
+ }
22
+ /**
23
+ * Builds a continuous mesh displaced by a greyscale heightmap - a different technique from
24
+ * `createTileGrid3D`'s discrete, per-cell elevation columns, for a game wanting rolling
25
+ * ground instead of stepped blocks.
26
+ *
27
+ * Takes already-decoded pixel bytes rather than a URL Babylon would fetch and decode
28
+ * itself, the same shape `parseVox` already takes raw bytes rather than a path: decoding an
29
+ * image is `mwg/assets`'/a game's own job (a loaded texture read back through a canvas, or
30
+ * any other decoder), keeping this module - like every other loader in `mwg/3d` - ignorant
31
+ * of where its bytes came from and safe to call from `file://` without touching the network
32
+ * itself.
33
+ */
34
+ export declare function createHeightmapTerrain3D(scene: Scene, source: HeightmapSource, options?: HeightmapTerrain3DOptions): GroundMesh;
35
+ //# sourceMappingURL=Heightmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Heightmap.d.ts","sourceRoot":"","sources":["../../src/three-d/Heightmap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACzC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,GAAE,yBAA8B,GAAG,UAAU,CAmBnI"}
@@ -0,0 +1,29 @@
1
+ import { CreateGroundFromHeightMap } from '@babylonjs/core/Meshes/Builders/groundBuilder.pure.js';
2
+ /**
3
+ * Builds a continuous mesh displaced by a greyscale heightmap - a different technique from
4
+ * `createTileGrid3D`'s discrete, per-cell elevation columns, for a game wanting rolling
5
+ * ground instead of stepped blocks.
6
+ *
7
+ * Takes already-decoded pixel bytes rather than a URL Babylon would fetch and decode
8
+ * itself, the same shape `parseVox` already takes raw bytes rather than a path: decoding an
9
+ * image is `mwg/assets`'/a game's own job (a loaded texture read back through a canvas, or
10
+ * any other decoder), keeping this module - like every other loader in `mwg/3d` - ignorant
11
+ * of where its bytes came from and safe to call from `file://` without touching the network
12
+ * itself.
13
+ */
14
+ export function createHeightmapTerrain3D(scene, source, options = {}) {
15
+ if (!(source.width > 0) || !(source.height > 0))
16
+ throw new Error('heightmap source needs positive dimensions');
17
+ if (source.data.length < source.width * source.height * 4) {
18
+ throw new Error('heightmap source data is smaller than width * height * 4 (RGBA)');
19
+ }
20
+ return CreateGroundFromHeightMap('heightmap-terrain', { data: source.data, width: source.width, height: source.height }, {
21
+ width: options.width ?? 10,
22
+ height: options.depth ?? 10,
23
+ subdivisions: options.subdivisions ?? Math.max(1, Math.min(source.width, source.height) - 1),
24
+ minHeight: options.minHeight ?? 0,
25
+ maxHeight: options.maxHeight ?? 1,
26
+ updatable: false,
27
+ }, scene);
28
+ }
29
+ //# sourceMappingURL=Heightmap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Heightmap.js","sourceRoot":"","sources":["../../src/three-d/Heightmap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAyBlG;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAY,EAAE,MAAuB,EAAE,OAAO,GAA8B,EAAE;IACtH,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC/G,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,yBAAyB,CAC/B,mBAAmB,EACnB,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EACjE;QACC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC1B,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC3B,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5F,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,CAAC;QACjC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,CAAC;QACjC,SAAS,EAAE,KAAK;KAChB,EACD,KAAK,CACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ import '@babylonjs/loaders/glTF/index.js';
2
+ import type { ImportMeshOptions, ISceneLoaderAsyncResult } from '@babylonjs/core/Loading/sceneLoader.js';
3
+ import type { Scene } from '@babylonjs/core/scene.js';
4
+ export type ModelSource3D = string | File | ArrayBufferView;
5
+ /**
6
+ * Loads glTF/GLB from an asset path, data/blob/http(s) URI, File, or in-memory byte view. An
7
+ * asset path is resolved through `mwg/assets` first, the same way every other loader in the
8
+ * framework becomes `file://`-safe once assets are compiled to `data:` URIs; a URI that is
9
+ * already resolved is passed through unchanged.
10
+ */
11
+ export declare function loadModel3D(source: ModelSource3D, scene: Scene, options?: ImportMeshOptions): Promise<ISceneLoaderAsyncResult>;
12
+ //# sourceMappingURL=Models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Models.d.ts","sourceRoot":"","sources":["../../src/three-d/Models.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACzG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAItD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,IAAI,GAAG,eAAe,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAG9H"}
@@ -0,0 +1,14 @@
1
+ import '@babylonjs/loaders/glTF/index.js';
2
+ import { ImportMeshAsync } from '@babylonjs/core/Loading/sceneLoader.js';
3
+ import { resolve } from '../assets/index.js';
4
+ /**
5
+ * Loads glTF/GLB from an asset path, data/blob/http(s) URI, File, or in-memory byte view. An
6
+ * asset path is resolved through `mwg/assets` first, the same way every other loader in the
7
+ * framework becomes `file://`-safe once assets are compiled to `data:` URIs; a URI that is
8
+ * already resolved is passed through unchanged.
9
+ */
10
+ export function loadModel3D(source, scene, options) {
11
+ const resolved = typeof source === 'string' && !/^(?:data|blob|https?):/i.test(source) ? resolve(source) : source;
12
+ return ImportMeshAsync(resolved, scene, options);
13
+ }
14
+ //# sourceMappingURL=Models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Models.js","sourceRoot":"","sources":["../../src/three-d/Models.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAIzE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAI7C;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,MAAqB,EAAE,KAAY,EAAE,OAA2B;IAC3F,MAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAClH,OAAO,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import '@babylonjs/core/Meshes/thinInstanceMesh.js';
2
+ import type { Mesh } from '@babylonjs/core/Meshes/mesh.js';
3
+ import type { Scene } from '@babylonjs/core/scene.js';
4
+ import type { GridCell3D, GridShape3D } from './Grid.ts';
5
+ export interface TileGrid3DOptions {
6
+ shape: GridShape3D;
7
+ tileSize?: number;
8
+ heightStep?: number;
9
+ tileThickness?: number;
10
+ tileColor?: number;
11
+ columnColor?: number;
12
+ origin?: readonly [number, number, number];
13
+ }
14
+ export interface TileGrid3DMeshes {
15
+ tiles: Mesh;
16
+ columns: Mesh | null;
17
+ dispose(): void;
18
+ }
19
+ /** Builds an instanced square or flat-top hex floor with optional raised columns. */
20
+ export declare function createTileGrid3D(scene: Scene, cells: readonly GridCell3D[], options: TileGrid3DOptions): TileGrid3DMeshes;
21
+ //# sourceMappingURL=TileGrid3D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TileGrid3D.d.ts","sourceRoot":"","sources":["../../src/three-d/TileGrid3D.ts"],"names":[],"mappings":"AAKA,OAAO,4CAA4C,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAiDzH"}
@@ -0,0 +1,65 @@
1
+ import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial.js';
2
+ import { Color3 } from '@babylonjs/core/Maths/math.color.js';
3
+ import { Matrix, Quaternion, Vector3 } from '@babylonjs/core/Maths/math.vector.js';
4
+ import { CreateBox } from '@babylonjs/core/Meshes/Builders/boxBuilder.pure.js';
5
+ import { CreateCylinder } from '@babylonjs/core/Meshes/Builders/cylinderBuilder.pure.js';
6
+ import '@babylonjs/core/Meshes/thinInstanceMesh.js';
7
+ import { gridPoint3D } from './Grid.js';
8
+ /** Builds an instanced square or flat-top hex floor with optional raised columns. */
9
+ export function createTileGrid3D(scene, cells, options) {
10
+ const tileSize = options.tileSize ?? 1;
11
+ const heightStep = options.heightStep ?? 1;
12
+ const thickness = options.tileThickness ?? 0.12;
13
+ if (!(thickness > 0))
14
+ throw new Error('3D tile thickness must be positive');
15
+ const origin = options.origin ?? [0, 0, 0];
16
+ const tiles = options.shape === 'square'
17
+ ? CreateBox('square-tiles', { width: tileSize * 0.94, height: thickness, depth: tileSize * 0.94 }, scene)
18
+ : CreateCylinder('hex-tiles', { diameter: tileSize * 1.9, height: thickness, tessellation: 6 }, scene);
19
+ const tileMaterial = material(scene, 'tile-material', options.tileColor ?? 0x5f8f62);
20
+ tiles.material = tileMaterial;
21
+ setMatrices(tiles, cells.map((cell) => {
22
+ const point = gridPoint3D(options.shape, cell.x, cell.y, tileSize, cell.height ?? 0, heightStep);
23
+ return Matrix.Translation(point.x + origin[0], point.y + origin[1] - thickness / 2, point.z + origin[2]);
24
+ }));
25
+ const raised = cells.filter((cell) => (cell.height ?? 0) !== 0);
26
+ let columns = null;
27
+ let columnMaterial = null;
28
+ if (raised.length) {
29
+ columns = options.shape === 'square'
30
+ ? CreateBox('square-columns', { size: 1 }, scene)
31
+ : CreateCylinder('hex-columns', { diameter: 1.9, height: 1, tessellation: 6 }, scene);
32
+ columnMaterial = material(scene, 'column-material', options.columnColor ?? 0x3f6048);
33
+ columns.material = columnMaterial;
34
+ setMatrices(columns, raised.map((cell) => {
35
+ const levels = cell.height ?? 0;
36
+ const point = gridPoint3D(options.shape, cell.x, cell.y, tileSize, 0, heightStep);
37
+ const height = Math.abs(levels * heightStep);
38
+ const centerY = origin[1] + Math.sign(levels) * height / 2;
39
+ const horizontal = options.shape === 'square' ? tileSize * 0.94 : tileSize;
40
+ return Matrix.Compose(new Vector3(horizontal, height, horizontal), Quaternion.Identity(), new Vector3(point.x + origin[0], centerY, point.z + origin[2]));
41
+ }));
42
+ }
43
+ return {
44
+ tiles,
45
+ columns,
46
+ dispose() {
47
+ tiles.dispose();
48
+ columns?.dispose();
49
+ tileMaterial.dispose();
50
+ columnMaterial?.dispose();
51
+ },
52
+ };
53
+ }
54
+ function setMatrices(mesh, matrices) {
55
+ const data = new Float32Array(matrices.length * 16);
56
+ for (let index = 0; index < matrices.length; index++)
57
+ matrices[index].copyToArray(data, index * 16);
58
+ mesh.thinInstanceSetBuffer('matrix', data, 16, true);
59
+ }
60
+ function material(scene, name, color) {
61
+ const value = new StandardMaterial(name, scene);
62
+ value.diffuseColor = new Color3(((color >> 16) & 0xff) / 255, ((color >> 8) & 0xff) / 255, (color & 0xff) / 255);
63
+ return value;
64
+ }
65
+ //# sourceMappingURL=TileGrid3D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TileGrid3D.js","sourceRoot":"","sources":["../../src/three-d/TileGrid3D.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import '@babylonjs/core/Meshes/thinInstanceMesh.js';
2
+ import { TransformNode } from '@babylonjs/core/Meshes/transformNode.js';
3
+ import type { Scene } from '@babylonjs/core/scene.js';
4
+ export interface VoxSize {
5
+ x: number;
6
+ y: number;
7
+ z: number;
8
+ }
9
+ export interface Voxel {
10
+ x: number;
11
+ y: number;
12
+ z: number;
13
+ color: number;
14
+ }
15
+ export interface VoxModel {
16
+ size: VoxSize;
17
+ voxels: readonly Voxel[];
18
+ palette: Uint32Array;
19
+ }
20
+ /** Reads one MagicaVoxel VOX model, including an optional RGBA palette chunk. */
21
+ export declare function parseVox(data: ArrayBuffer | ArrayBufferView): VoxModel;
22
+ /** Turns parsed voxels into color-batched Babylon thin instances under one transform node. */
23
+ export declare function createVoxModel3D(scene: Scene, model: VoxModel, voxelSize?: number): TransformNode;
24
+ //# sourceMappingURL=Vox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Vox.d.ts","sourceRoot":"","sources":["../../src/three-d/Vox.ts"],"names":[],"mappings":"AAIA,OAAO,4CAA4C,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,MAAM,WAAW,OAAO;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;CAAE;AAC7D,MAAM,WAAW,KAAK;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAAE;AAC1E,MAAM,WAAW,QAAQ;IAAG,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAAC,OAAO,EAAE,WAAW,CAAC;CAAE;AAE5F,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,GAAG,QAAQ,CAoCtE;AAED,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,SAAI,GAAG,aAAa,CA0B5F"}
@@ -0,0 +1,93 @@
1
+ import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial.js';
2
+ import { Color3 } from '@babylonjs/core/Maths/math.color.js';
3
+ import { Matrix } from '@babylonjs/core/Maths/math.vector.js';
4
+ import { CreateBox } from '@babylonjs/core/Meshes/Builders/boxBuilder.pure.js';
5
+ import '@babylonjs/core/Meshes/thinInstanceMesh.js';
6
+ import { TransformNode } from '@babylonjs/core/Meshes/transformNode.js';
7
+ /** Reads one MagicaVoxel VOX model, including an optional RGBA palette chunk. */
8
+ export function parseVox(data) {
9
+ const bytes = data instanceof ArrayBuffer
10
+ ? new Uint8Array(data)
11
+ : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
12
+ if (bytes.length < 20 || text(bytes, 0) !== 'VOX ')
13
+ throw new Error('invalid VOX header');
14
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
15
+ let offset = 8;
16
+ let size = null;
17
+ let voxels = null;
18
+ const palette = defaultPalette();
19
+ while (offset + 12 <= bytes.length) {
20
+ const id = text(bytes, offset);
21
+ const contentSize = view.getUint32(offset + 4, true);
22
+ const childrenSize = view.getUint32(offset + 8, true);
23
+ const content = offset + 12;
24
+ const end = content + contentSize;
25
+ if (end + childrenSize > bytes.length)
26
+ throw new Error(`truncated VOX ${id} chunk`);
27
+ if (id === 'SIZE') {
28
+ if (contentSize < 12)
29
+ throw new Error('invalid VOX SIZE chunk');
30
+ size = { x: view.getUint32(content, true), y: view.getUint32(content + 4, true), z: view.getUint32(content + 8, true) };
31
+ }
32
+ else if (id === 'XYZI') {
33
+ const count = view.getUint32(content, true);
34
+ if (contentSize < 4 + count * 4)
35
+ throw new Error('invalid VOX XYZI chunk');
36
+ voxels = Array.from({ length: count }, (_, index) => {
37
+ const at = content + 4 + index * 4;
38
+ return { x: bytes[at], y: bytes[at + 1], z: bytes[at + 2], color: bytes[at + 3] };
39
+ });
40
+ }
41
+ else if (id === 'RGBA') {
42
+ if (contentSize < 1024)
43
+ throw new Error('invalid VOX RGBA chunk');
44
+ for (let index = 0; index < 256; index++)
45
+ palette[index] = view.getUint32(content + index * 4, true);
46
+ }
47
+ offset = end;
48
+ }
49
+ if (!size || !voxels)
50
+ throw new Error('VOX file needs SIZE and XYZI chunks');
51
+ return { size, voxels, palette };
52
+ }
53
+ /** Turns parsed voxels into color-batched Babylon thin instances under one transform node. */
54
+ export function createVoxModel3D(scene, model, voxelSize = 1) {
55
+ if (!(voxelSize > 0))
56
+ throw new Error('voxel size must be positive');
57
+ const root = new TransformNode('vox-model', scene);
58
+ const groups = new Map();
59
+ for (const voxel of model.voxels) {
60
+ const group = groups.get(voxel.color) ?? [];
61
+ group.push(voxel);
62
+ groups.set(voxel.color, group);
63
+ }
64
+ for (const [color, voxels] of groups) {
65
+ const box = CreateBox(`voxels-${color}`, { size: voxelSize }, scene);
66
+ box.parent = root;
67
+ const rgba = model.palette[Math.max(0, color - 1)];
68
+ const material = new StandardMaterial(`voxel-${color}`, scene);
69
+ material.diffuseColor = new Color3((rgba & 0xff) / 255, ((rgba >> 8) & 0xff) / 255, ((rgba >> 16) & 0xff) / 255);
70
+ material.alpha = ((rgba >>> 24) & 0xff) / 255;
71
+ box.material = material;
72
+ const matrices = new Float32Array(voxels.length * 16);
73
+ for (let index = 0; index < voxels.length; index++) {
74
+ const voxel = voxels[index];
75
+ Matrix.Translation(voxel.x * voxelSize, voxel.z * voxelSize, voxel.y * voxelSize)
76
+ .copyToArray(matrices, index * 16);
77
+ }
78
+ box.thinInstanceSetBuffer('matrix', matrices, 16, true);
79
+ }
80
+ return root;
81
+ }
82
+ function text(bytes, offset) {
83
+ return String.fromCharCode(...bytes.subarray(offset, offset + 4));
84
+ }
85
+ function defaultPalette() {
86
+ const palette = new Uint32Array(256);
87
+ for (let index = 0; index < 256; index++) {
88
+ const shade = index & 0xff;
89
+ palette[index] = shade | (shade << 8) | (shade << 16) | 0xff000000;
90
+ }
91
+ return palette;
92
+ }
93
+ //# sourceMappingURL=Vox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Vox.js","sourceRoot":"","sources":["../../src/three-d/Vox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export { Engine3D } from './Engine3D.ts';
2
+ export type { Engine3DOptions, Frame3D } from './Engine3D.ts';
3
+ export { gridPoint3D } from './Grid.ts';
4
+ export type { GridCell3D, GridShape3D, Point3D } from './Grid.ts';
5
+ export { createTileGrid3D } from './TileGrid3D.ts';
6
+ export type { TileGrid3DMeshes, TileGrid3DOptions } from './TileGrid3D.ts';
7
+ export { Character3D } from './Character3D.ts';
8
+ export type { Billboard3DOptions } from './Character3D.ts';
9
+ export { parseVox, createVoxModel3D } from './Vox.ts';
10
+ export type { VoxModel, VoxSize, Voxel } from './Vox.ts';
11
+ export { createHeightmapTerrain3D } from './Heightmap.ts';
12
+ export type { HeightmapSource, HeightmapTerrain3DOptions } from './Heightmap.ts';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/three-d/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { Engine3D } from './Engine3D.js';
2
+ export { gridPoint3D } from './Grid.js';
3
+ export { createTileGrid3D } from './TileGrid3D.js';
4
+ export { Character3D } from './Character3D.js';
5
+ export { parseVox, createVoxModel3D } from './Vox.js';
6
+ export { createHeightmapTerrain3D } from './Heightmap.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/three-d/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { Container, type Texture } from 'pixi.js';
2
+ export interface BarOptions {
3
+ width: number;
4
+ height: number;
5
+ /** the filled colour; defaults to the theme's highlight colour. Tints `fillTexture` too, when both are given */
6
+ color?: number;
7
+ /** starting value, read the same way `setValue` is; defaults to full */
8
+ value?: number;
9
+ max?: number;
10
+ /** the fill's own art, stretched to the filled width; a plain colour rect (the default) when omitted */
11
+ fillTexture?: Texture;
12
+ /** the track's own art; a plain colour rect (the theme's panel fill) when omitted */
13
+ backgroundTexture?: Texture;
14
+ /**
15
+ * Rounds the filled width up to the next whole pixel instead of a fractional one, so a
16
+ * sliver of value (1 hp of 300, say) never rounds down to nothing. Off by default, since
17
+ * it very slightly overstates the fraction at low values - a game where that sliver
18
+ * matters more than the precision opts in.
19
+ */
20
+ roundUpToPixel?: boolean;
21
+ }
22
+ /**
23
+ * A filled proportion of a track - a health, mana or experience bar.
24
+ *
25
+ * Closer to a small, focused primitive than a general-purpose progress-bar widget: it draws
26
+ * a background track and a foreground fill sized to `value / max`, and nothing else. Colour
27
+ * follows the theme the way `Label` does, unless a game gives one of its own.
28
+ */
29
+ export declare class Bar extends Container {
30
+ private track;
31
+ private fill;
32
+ private width_;
33
+ private height_;
34
+ private readonly explicitColor;
35
+ private color;
36
+ private fraction;
37
+ private readonly fillTexture?;
38
+ private readonly backgroundTexture?;
39
+ private readonly roundUpToPixel;
40
+ private readonly themeListener;
41
+ constructor(options: BarOptions);
42
+ /** the current fill, 0 to 1 */
43
+ get value(): number;
44
+ setValue(value: number, max?: number): void;
45
+ resize(width: number, height: number): void;
46
+ private draw;
47
+ destroy(options?: Parameters<Container['destroy']>[0]): void;
48
+ }
49
+ //# sourceMappingURL=Bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bar.d.ts","sourceRoot":"","sources":["../../src/ui/Bar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAG5D,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IAEf,gHAAgH;IAChH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,wGAAwG;IACxG,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;GAMG;AACH,qBAAa,GAAI,SAAQ,SAAS;IACjC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,IAAI,CAAkB;IAE9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAU;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IAEzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IAEnD,YAAY,OAAO,EAAE,UAAU,EAiB9B;IAED,+BAA+B;IAC/B,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAI,GAAG,IAAI,CAGrC;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAI1C;IAED,OAAO,CAAC,IAAI;IAwBH,OAAO,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAGpE;CACD"}
package/dist/ui/Bar.js ADDED
@@ -0,0 +1,70 @@
1
+ import { Container, Graphics } from 'pixi.js';
2
+ import { theme, themeChanged } from './theme.js';
3
+ /**
4
+ * A filled proportion of a track - a health, mana or experience bar.
5
+ *
6
+ * Closer to a small, focused primitive than a general-purpose progress-bar widget: it draws
7
+ * a background track and a foreground fill sized to `value / max`, and nothing else. Colour
8
+ * follows the theme the way `Label` does, unless a game gives one of its own.
9
+ */
10
+ export class Bar extends Container {
11
+ constructor(options) {
12
+ super();
13
+ this.track = new Graphics();
14
+ this.fill = new Graphics();
15
+ this.themeListener = () => this.draw();
16
+ this.width_ = options.width;
17
+ this.height_ = options.height;
18
+ this.explicitColor = options.color !== undefined;
19
+ this.color = options.color ?? theme().color.textHighlight;
20
+ this.fraction = clamp((options.value ?? 1) / (options.max ?? 1));
21
+ this.fillTexture = options.fillTexture;
22
+ this.backgroundTexture = options.backgroundTexture;
23
+ this.roundUpToPixel = options.roundUpToPixel ?? false;
24
+ this.addChild(this.track);
25
+ this.addChild(this.fill);
26
+ this.draw();
27
+ themeChanged.add(this.themeListener);
28
+ }
29
+ /** the current fill, 0 to 1 */
30
+ get value() {
31
+ return this.fraction;
32
+ }
33
+ setValue(value, max = 1) {
34
+ this.fraction = clamp(max > 0 ? value / max : 0);
35
+ this.draw();
36
+ }
37
+ resize(width, height) {
38
+ this.width_ = width;
39
+ this.height_ = height;
40
+ this.draw();
41
+ }
42
+ draw() {
43
+ const t = theme();
44
+ if (!this.explicitColor)
45
+ this.color = t.color.textHighlight;
46
+ this.track.clear().rect(0, 0, this.width_, this.height_);
47
+ this.track.fill(this.backgroundTexture ? { texture: this.backgroundTexture } : { color: t.color.panelFill });
48
+ this.fill.clear();
49
+ if (this.fraction > 0) {
50
+ const rawWidth = this.width_ * this.fraction;
51
+ const width = this.roundUpToPixel ? Math.ceil(rawWidth) : rawWidth;
52
+ this.fill.rect(0, 0, width, this.height_);
53
+ //an explicit colour tints art the same way it recolours a flat fill; an
54
+ //untinted texture is left to its own colours when none was given
55
+ this.fill.fill(this.fillTexture
56
+ ? this.explicitColor
57
+ ? { texture: this.fillTexture, color: this.color }
58
+ : { texture: this.fillTexture }
59
+ : { color: this.color });
60
+ }
61
+ }
62
+ destroy(options) {
63
+ themeChanged.remove(this.themeListener);
64
+ super.destroy(options);
65
+ }
66
+ }
67
+ function clamp(fraction) {
68
+ return Math.max(0, Math.min(1, fraction));
69
+ }
70
+ //# sourceMappingURL=Bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bar.js","sourceRoot":"","sources":["../../src/ui/Bar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { BitmapText } from 'pixi.js';
2
+ import type { TextStyleOptions } from 'pixi.js';
3
+ import { type Theme } from './theme.ts';
4
+ export interface BitmapLabelOptions {
5
+ text?: string;
6
+ color?: number;
7
+ size?: number;
8
+ /** wraps at this width in pixels; omit for a single unwrapped line */
9
+ wrapWidth?: number;
10
+ align?: 'left' | 'center' | 'right';
11
+ bold?: boolean;
12
+ }
13
+ /**
14
+ * A piece of text baked into a glyph-atlas texture instead of rasterised fresh on every
15
+ * change, the way `Label` (a thin wrapper over Pixi's `Text`) does. `Label`'s own doc
16
+ * comment already names the cost this exists to avoid: "wasteful for something updated
17
+ * every frame". A live HUD counter, a scrolling log, or a fixed pixel font a pixel-art game
18
+ * wants for all its UI copy are what this is for; a game whose text rarely changes has no
19
+ * reason to prefer it over `Label`.
20
+ *
21
+ * Pixi generates and caches the underlying bitmap font itself the first time a given
22
+ * family/size/colour/weight combination is used (see `BitmapText`'s "Dynamic Bitmap Fonts"
23
+ * behaviour) - nothing here downloads or ships a font file, keeping this the same
24
+ * generated-not-borrowed shape as every other asset in this project.
25
+ */
26
+ export declare class BitmapLabel extends BitmapText {
27
+ private readonly opts;
28
+ private readonly themeListener;
29
+ constructor(options?: BitmapLabelOptions | string);
30
+ /** avoids the atlas relookup when the text has not actually changed */
31
+ setText(value: string): void;
32
+ /**
33
+ * Reapplies whichever style fields were never given an explicit option, so an explicit
34
+ * `color`/`size` a game passed in survives a theme change untouched while anything left
35
+ * to the theme's own defaults picks up the new one - the same rule `Label.restyle` follows.
36
+ */
37
+ private restyle;
38
+ destroy(options?: Parameters<BitmapText['destroy']>[0]): void;
39
+ }
40
+ /** the pure style-mapping `BitmapLabel` builds its underlying `BitmapText` style from, exported for testing without constructing a `BitmapText` (which needs a real DOM `document`, unlike `Text`) */
41
+ export declare function bitmapLabelStyle(opts: BitmapLabelOptions, t: Theme): TextStyleOptions;
42
+ //# sourceMappingURL=BitmapLabel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BitmapLabel.d.ts","sourceRoot":"","sources":["../../src/ui/BitmapLabel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAuB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAY,SAAQ,UAAU;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiC;IAE/D,YAAY,OAAO,GAAE,kBAAkB,GAAG,MAAW,EAWpD;IAED,uEAAuE;IACvE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE3B;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAIN,OAAO,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAGrE;CACD;AAED,sMAAsM;AACtM,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE,KAAK,GAAG,gBAAgB,CAWrF"}
@@ -0,0 +1,59 @@
1
+ import { BitmapText } from 'pixi.js';
2
+ import { theme, themeChanged } from './theme.js';
3
+ /**
4
+ * A piece of text baked into a glyph-atlas texture instead of rasterised fresh on every
5
+ * change, the way `Label` (a thin wrapper over Pixi's `Text`) does. `Label`'s own doc
6
+ * comment already names the cost this exists to avoid: "wasteful for something updated
7
+ * every frame". A live HUD counter, a scrolling log, or a fixed pixel font a pixel-art game
8
+ * wants for all its UI copy are what this is for; a game whose text rarely changes has no
9
+ * reason to prefer it over `Label`.
10
+ *
11
+ * Pixi generates and caches the underlying bitmap font itself the first time a given
12
+ * family/size/colour/weight combination is used (see `BitmapText`'s "Dynamic Bitmap Fonts"
13
+ * behaviour) - nothing here downloads or ships a font file, keeping this the same
14
+ * generated-not-borrowed shape as every other asset in this project.
15
+ */
16
+ export class BitmapLabel extends BitmapText {
17
+ constructor(options = {}) {
18
+ const opts = typeof options === 'string' ? { text: options } : options;
19
+ const t = theme();
20
+ super({
21
+ text: opts.text ?? '',
22
+ style: bitmapLabelStyle(opts, t),
23
+ });
24
+ this.themeListener = (t) => this.restyle(t);
25
+ this.opts = opts;
26
+ themeChanged.add(this.themeListener);
27
+ }
28
+ /** avoids the atlas relookup when the text has not actually changed */
29
+ setText(value) {
30
+ if (this.text !== value)
31
+ this.text = value;
32
+ }
33
+ /**
34
+ * Reapplies whichever style fields were never given an explicit option, so an explicit
35
+ * `color`/`size` a game passed in survives a theme change untouched while anything left
36
+ * to the theme's own defaults picks up the new one - the same rule `Label.restyle` follows.
37
+ */
38
+ restyle(t) {
39
+ this.style = bitmapLabelStyle(this.opts, t);
40
+ }
41
+ destroy(options) {
42
+ themeChanged.remove(this.themeListener);
43
+ super.destroy(options);
44
+ }
45
+ }
46
+ /** the pure style-mapping `BitmapLabel` builds its underlying `BitmapText` style from, exported for testing without constructing a `BitmapText` (which needs a real DOM `document`, unlike `Text`) */
47
+ export function bitmapLabelStyle(opts, t) {
48
+ return {
49
+ fontFamily: t.font.family,
50
+ fontSize: opts.size ?? t.font.size,
51
+ fontWeight: opts.bold ? 'bold' : 'normal',
52
+ fill: opts.color ?? t.color.text,
53
+ align: opts.align ?? (t.direction === 'rtl' ? 'right' : 'left'),
54
+ wordWrap: opts.wrapWidth !== undefined,
55
+ wordWrapWidth: opts.wrapWidth ?? 0,
56
+ breakWords: true,
57
+ };
58
+ }
59
+ //# sourceMappingURL=BitmapLabel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BitmapLabel.js","sourceRoot":"","sources":["../../src/ui/BitmapLabel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAY7D;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,WAAY,SAAQ,UAAU;IAI1C,YAAY,OAAO,GAAgC,EAAE;QACpD,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACvE,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;QAElB,KAAK,CAAC;YACL,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACrB,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;SAChC,CAAC,CAAC;QATa,kBAAa,GAAG,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAW9D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACtC,CAAC;IAED,uEAAuE;IACvE,OAAO,CAAC,KAAa;QACpB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;YAAE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACK,OAAO,CAAC,CAAQ;QACvB,IAAI,CAAC,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAEQ,OAAO,CAAC,OAA8C;QAC9D,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;CACD;AAED,sMAAsM;AACtM,MAAM,UAAU,gBAAgB,CAAC,IAAwB,EAAE,CAAQ;IAClE,OAAO;QACN,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;QACzB,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI;QAClC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;QACzC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI;QAChC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/D,QAAQ,EAAE,IAAI,CAAC,SAAS,KAAK,SAAS;QACtC,aAAa,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC;QAClC,UAAU,EAAE,IAAI;KAChB,CAAC;AACH,CAAC"}