@bloopjs/toodle 0.0.100

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 (358) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/dist/Toodle.d.ts +304 -0
  4. package/dist/Toodle.d.ts.map +1 -0
  5. package/dist/colors/mod.d.ts +872 -0
  6. package/dist/colors/mod.d.ts.map +1 -0
  7. package/dist/coreTypes/Color.d.ts +7 -0
  8. package/dist/coreTypes/Color.d.ts.map +1 -0
  9. package/dist/coreTypes/Point.d.ts +8 -0
  10. package/dist/coreTypes/Point.d.ts.map +1 -0
  11. package/dist/coreTypes/Size.d.ts +5 -0
  12. package/dist/coreTypes/Size.d.ts.map +1 -0
  13. package/dist/coreTypes/Transform.d.ts +16 -0
  14. package/dist/coreTypes/Transform.d.ts.map +1 -0
  15. package/dist/coreTypes/Vec2.d.ts +8 -0
  16. package/dist/coreTypes/Vec2.d.ts.map +1 -0
  17. package/dist/coreTypes/mod.d.ts +6 -0
  18. package/dist/coreTypes/mod.d.ts.map +1 -0
  19. package/dist/docs/snippets/add-remove-children.d.ts +1 -0
  20. package/dist/docs/snippets/basic-quad.d.ts +1 -0
  21. package/dist/docs/snippets/filter-linear.d.ts +1 -0
  22. package/dist/docs/snippets/filter-nearest.d.ts +1 -0
  23. package/dist/docs/snippets/flipxy.d.ts +1 -0
  24. package/dist/docs/snippets/hello-text.d.ts +1 -0
  25. package/dist/docs/snippets/jumbo-textures.d.ts +1 -0
  26. package/dist/docs/snippets/layer.d.ts +1 -0
  27. package/dist/docs/snippets/layout-edges.d.ts +1 -0
  28. package/dist/docs/snippets/layout-screen-and-world-space.d.ts +1 -0
  29. package/dist/docs/snippets/postprocess.d.ts +1 -0
  30. package/dist/docs/snippets/quad-size-scale.d.ts +1 -0
  31. package/dist/docs/snippets/quickstart.d.ts +1 -0
  32. package/dist/docs/snippets/repeat-texture-loading.d.ts +1 -0
  33. package/dist/docs/snippets/screen-shaders.d.ts +1 -0
  34. package/dist/docs/snippets/shader-color-flash.d.ts +1 -0
  35. package/dist/docs/snippets/shader-default.d.ts +1 -0
  36. package/dist/docs/snippets/shader-fill.d.ts +1 -0
  37. package/dist/docs/snippets/shapes-line.d.ts +1 -0
  38. package/dist/docs/snippets/sprite-region.d.ts +1 -0
  39. package/dist/docs/snippets/text-alignment.d.ts +1 -0
  40. package/dist/docs/snippets/text-shrink-to-fit.d.ts +1 -0
  41. package/dist/docs/snippets/text-word-wrap.d.ts +1 -0
  42. package/dist/docs/snippets/texture-bundles-prebaked.d.ts +1 -0
  43. package/dist/docs/snippets/texture-bundles.d.ts +1 -0
  44. package/dist/docs/snippets/transforms.d.ts +1 -0
  45. package/dist/docs/snippets/transparent-cropping.d.ts +1 -0
  46. package/dist/examples/0-hello.d.ts +1 -0
  47. package/dist/examples/1-hello.d.ts +1 -0
  48. package/dist/examples/1-hello.d.ts.map +1 -0
  49. package/dist/examples/1-quad.d.ts +1 -0
  50. package/dist/examples/10-resize.d.ts +1 -0
  51. package/dist/examples/10-resize.d.ts.map +1 -0
  52. package/dist/examples/11-bundle-test.d.ts +1 -0
  53. package/dist/examples/11-bundle-test.d.ts.map +1 -0
  54. package/dist/examples/12-transparent-pixel-cropping.d.ts +1 -0
  55. package/dist/examples/12-transparent-pixel-cropping.d.ts.map +1 -0
  56. package/dist/examples/13-crop.d.ts +1 -0
  57. package/dist/examples/13-crop.d.ts.map +1 -0
  58. package/dist/examples/14-bundle-bench.d.ts +1 -0
  59. package/dist/examples/14-bundle-bench.d.ts.map +1 -0
  60. package/dist/examples/15-text-layer.d.ts +1 -0
  61. package/dist/examples/15-text-layer.d.ts.map +1 -0
  62. package/dist/examples/16-jumbo-texture.d.ts +1 -0
  63. package/dist/examples/16-jumbo-textures.d.ts +1 -0
  64. package/dist/examples/16-screen-shader.d.ts +1 -0
  65. package/dist/examples/16-screen-shader.d.ts.map +1 -0
  66. package/dist/examples/17-lighting.d.ts +1 -0
  67. package/dist/examples/17-lighting.d.ts.map +1 -0
  68. package/dist/examples/17-translations.d.ts +1 -0
  69. package/dist/examples/18-blur.d.ts +1 -0
  70. package/dist/examples/19-postprocess.d.ts +1 -0
  71. package/dist/examples/19-screenshader.d.ts +1 -0
  72. package/dist/examples/2-shapes.d.ts +1 -0
  73. package/dist/examples/2-shapes.d.ts.map +1 -0
  74. package/dist/examples/3-shader.d.ts +1 -0
  75. package/dist/examples/3-shader.d.ts.map +1 -0
  76. package/dist/examples/4-shader-bench.d.ts +1 -0
  77. package/dist/examples/4-shader-bench.d.ts.map +1 -0
  78. package/dist/examples/5-z.d.ts +1 -0
  79. package/dist/examples/5-z.d.ts.map +1 -0
  80. package/dist/examples/6-atlas.d.ts +1 -0
  81. package/dist/examples/6-atlas.d.ts.map +1 -0
  82. package/dist/examples/7-text.d.ts +1 -0
  83. package/dist/examples/7-text.d.ts.map +1 -0
  84. package/dist/examples/8-text-bench.d.ts +1 -0
  85. package/dist/examples/8-text-bench.d.ts.map +1 -0
  86. package/dist/examples/9-alignment.d.ts +1 -0
  87. package/dist/examples/9-alignment.d.ts.map +1 -0
  88. package/dist/examples/main.d.ts +1 -0
  89. package/dist/examples/main.d.ts.map +1 -0
  90. package/dist/examples/util.d.ts +82 -0
  91. package/dist/examples/util.d.ts.map +1 -0
  92. package/dist/limits.d.ts +23 -0
  93. package/dist/limits.d.ts.map +1 -0
  94. package/dist/math/angle.d.ts +13 -0
  95. package/dist/math/angle.d.ts.map +1 -0
  96. package/dist/math/matrix.d.ts +26 -0
  97. package/dist/math/matrix.d.ts.map +1 -0
  98. package/dist/math/mod.d.ts +3 -0
  99. package/dist/math/mod.d.ts.map +1 -0
  100. package/dist/mod.d.ts +17 -0
  101. package/dist/mod.d.ts.map +1 -0
  102. package/dist/mod.js +19665 -0
  103. package/dist/mod.js.map +41 -0
  104. package/dist/postprocess.d.ts +10 -0
  105. package/dist/postprocess.d.ts.map +1 -0
  106. package/dist/scene/Batcher.d.ts +20 -0
  107. package/dist/scene/Batcher.d.ts.map +1 -0
  108. package/dist/scene/Camera.d.ts +16 -0
  109. package/dist/scene/Camera.d.ts.map +1 -0
  110. package/dist/scene/JumboQuadNode.d.ts +29 -0
  111. package/dist/scene/JumboQuadNode.d.ts.map +1 -0
  112. package/dist/scene/QuadNode.d.ts +159 -0
  113. package/dist/scene/QuadNode.d.ts.map +1 -0
  114. package/dist/scene/RenderComponent.d.ts +11 -0
  115. package/dist/scene/RenderComponent.d.ts.map +1 -0
  116. package/dist/scene/SceneNode.d.ts +300 -0
  117. package/dist/scene/SceneNode.d.ts.map +1 -0
  118. package/dist/scene/mod.d.ts +5 -0
  119. package/dist/scene/mod.d.ts.map +1 -0
  120. package/dist/screen/mod.d.ts +2 -0
  121. package/dist/screen/mod.d.ts.map +1 -0
  122. package/dist/screen/resolution.d.ts +5 -0
  123. package/dist/screen/resolution.d.ts.map +1 -0
  124. package/dist/shaders/EngineUniform.d.ts +9 -0
  125. package/dist/shaders/EngineUniform.d.ts.map +1 -0
  126. package/dist/shaders/IShader.d.ts +15 -0
  127. package/dist/shaders/IShader.d.ts.map +1 -0
  128. package/dist/shaders/QuadShader.d.ts +18 -0
  129. package/dist/shaders/QuadShader.d.ts.map +1 -0
  130. package/dist/shaders/ShaderDescriptor.d.ts +7 -0
  131. package/dist/shaders/ShaderDescriptor.d.ts.map +1 -0
  132. package/dist/shaders/mod.d.ts +6 -0
  133. package/dist/shaders/mod.d.ts.map +1 -0
  134. package/dist/shaders/parser.d.ts +8 -0
  135. package/dist/shaders/parser.d.ts.map +1 -0
  136. package/dist/shaders/postprocess/blur.d.ts +3 -0
  137. package/dist/shaders/postprocess/blur.d.ts.map +1 -0
  138. package/dist/shaders/postprocess/mod.d.ts +17 -0
  139. package/dist/shaders/postprocess/mod.d.ts.map +1 -0
  140. package/dist/shaders/samplers.d.ts +3 -0
  141. package/dist/shaders/samplers.d.ts.map +1 -0
  142. package/dist/shaders/wgsl/example.wgsl.d.ts +3 -0
  143. package/dist/shaders/wgsl/example.wgsl.d.ts.map +1 -0
  144. package/dist/shaders/wgsl/hello.wgsl.d.ts +3 -0
  145. package/dist/shaders/wgsl/hello.wgsl.d.ts.map +1 -0
  146. package/dist/shaders/wgsl/helloInstanced.wgsl.d.ts +3 -0
  147. package/dist/shaders/wgsl/helloInstanced.wgsl.d.ts.map +1 -0
  148. package/dist/shaders/wgsl/quad.wgsl.d.ts +3 -0
  149. package/dist/shaders/wgsl/quad.wgsl.d.ts.map +1 -0
  150. package/dist/src/Toodle.d.ts +303 -0
  151. package/dist/src/Toodle.d.ts.map +1 -0
  152. package/dist/src/colors/mod.d.ts +871 -0
  153. package/dist/src/coreTypes/Color.d.ts +6 -0
  154. package/dist/src/coreTypes/Color.d.ts.map +1 -0
  155. package/dist/src/coreTypes/Point.d.ts +7 -0
  156. package/dist/src/coreTypes/Point.d.ts.map +1 -0
  157. package/dist/src/coreTypes/Size.d.ts +4 -0
  158. package/dist/src/coreTypes/Size.d.ts.map +1 -0
  159. package/dist/src/coreTypes/Transform.d.ts +15 -0
  160. package/dist/src/coreTypes/Transform.d.ts.map +1 -0
  161. package/dist/src/coreTypes/Vec2.d.ts +7 -0
  162. package/dist/src/coreTypes/Vec2.d.ts.map +1 -0
  163. package/dist/src/coreTypes/mod.d.ts +5 -0
  164. package/dist/src/coreTypes/mod.d.ts.map +1 -0
  165. package/dist/src/limits.d.ts +22 -0
  166. package/dist/src/limits.d.ts.map +1 -0
  167. package/dist/src/math/angle.d.ts +12 -0
  168. package/dist/src/math/angle.d.ts.map +1 -0
  169. package/dist/src/math/matrix.d.ts +25 -0
  170. package/dist/src/math/matrix.d.ts.map +1 -0
  171. package/dist/src/math/mod.d.ts +2 -0
  172. package/dist/src/math/mod.d.ts.map +1 -0
  173. package/dist/src/mod.d.ts +16 -0
  174. package/dist/src/mod.d.ts.map +1 -0
  175. package/dist/src/postprocess.d.ts +10 -0
  176. package/dist/src/postprocess.d.ts.map +1 -0
  177. package/dist/src/scene/Batcher.d.ts +19 -0
  178. package/dist/src/scene/Batcher.d.ts.map +1 -0
  179. package/dist/src/scene/Camera.d.ts +15 -0
  180. package/dist/src/scene/Camera.d.ts.map +1 -0
  181. package/dist/src/scene/JumboQuadNode.d.ts +28 -0
  182. package/dist/src/scene/QuadNode.d.ts +158 -0
  183. package/dist/src/scene/QuadNode.d.ts.map +1 -0
  184. package/dist/src/scene/RenderComponent.d.ts +10 -0
  185. package/dist/src/scene/RenderComponent.d.ts.map +1 -0
  186. package/dist/src/scene/SceneNode.d.ts +299 -0
  187. package/dist/src/scene/SceneNode.d.ts.map +1 -0
  188. package/dist/src/scene/mod.d.ts +4 -0
  189. package/dist/src/scene/mod.d.ts.map +1 -0
  190. package/dist/src/screen/mod.d.ts +1 -0
  191. package/dist/src/screen/mod.d.ts.map +1 -0
  192. package/dist/src/screen/resolution.d.ts +4 -0
  193. package/dist/src/screen/resolution.d.ts.map +1 -0
  194. package/dist/src/shaders/EngineUniform.d.ts +8 -0
  195. package/dist/src/shaders/EngineUniform.d.ts.map +1 -0
  196. package/dist/src/shaders/IShader.d.ts +14 -0
  197. package/dist/src/shaders/IShader.d.ts.map +1 -0
  198. package/dist/src/shaders/QuadShader.d.ts +17 -0
  199. package/dist/src/shaders/QuadShader.d.ts.map +1 -0
  200. package/dist/src/shaders/ShaderDescriptor.d.ts +6 -0
  201. package/dist/src/shaders/ShaderDescriptor.d.ts.map +1 -0
  202. package/dist/src/shaders/mod.d.ts +5 -0
  203. package/dist/src/shaders/mod.d.ts.map +1 -0
  204. package/dist/src/shaders/parser.d.ts +7 -0
  205. package/dist/src/shaders/parser.d.ts.map +1 -0
  206. package/dist/src/shaders/postprocess/blur.d.ts +2 -0
  207. package/dist/src/shaders/postprocess/mod.d.ts +16 -0
  208. package/dist/src/shaders/postprocess/postprocess.d.ts +8 -0
  209. package/dist/src/shaders/postprocess/util.d.ts +2 -0
  210. package/dist/src/shaders/samplers.d.ts +2 -0
  211. package/dist/src/shaders/samplers.d.ts.map +1 -0
  212. package/dist/src/shaders/wgsl/example.wgsl.d.ts +2 -0
  213. package/dist/src/shaders/wgsl/example.wgsl.d.ts.map +1 -0
  214. package/dist/src/shaders/wgsl/hello.wgsl.d.ts +2 -0
  215. package/dist/src/shaders/wgsl/hello.wgsl.d.ts.map +1 -0
  216. package/dist/src/shaders/wgsl/helloInstanced.wgsl.d.ts +2 -0
  217. package/dist/src/shaders/wgsl/helloInstanced.wgsl.d.ts.map +1 -0
  218. package/dist/src/shaders/wgsl/quad.wgsl.d.ts +2 -0
  219. package/dist/src/shaders/wgsl/quad.wgsl.d.ts.map +1 -0
  220. package/dist/src/text/FontPipeline.d.ts +13 -0
  221. package/dist/src/text/FontPipeline.d.ts.map +1 -0
  222. package/dist/src/text/MsdfFont.d.ts +81 -0
  223. package/dist/src/text/MsdfFont.d.ts.map +1 -0
  224. package/dist/src/text/TextFormatting.d.ts +18 -0
  225. package/dist/src/text/TextFormatting.d.ts.map +1 -0
  226. package/dist/src/text/TextNode.d.ts +18 -0
  227. package/dist/src/text/TextNode.d.ts.map +1 -0
  228. package/dist/src/text/TextShader.d.ts +14 -0
  229. package/dist/src/text/TextShader.d.ts.map +1 -0
  230. package/dist/src/text/mod.d.ts +3 -0
  231. package/dist/src/text/mod.d.ts.map +1 -0
  232. package/dist/src/text/shaping.d.ts +38 -0
  233. package/dist/src/text/shaping.d.ts.map +1 -0
  234. package/dist/src/text/text.wgsl.d.ts +2 -0
  235. package/dist/src/text/text.wgsl.d.ts.map +1 -0
  236. package/dist/src/textures/AssetManager.d.ts +181 -0
  237. package/dist/src/textures/AssetManager.d.ts.map +1 -0
  238. package/dist/src/textures/NewTextureComputeShader.d.ts +28 -0
  239. package/dist/src/textures/TextureComputeShader.d.ts +20 -0
  240. package/dist/src/textures/TextureComputeShader.d.ts.map +1 -0
  241. package/dist/src/textures/crop.wgsl.d.ts +2 -0
  242. package/dist/src/textures/mod.d.ts +1 -0
  243. package/dist/src/textures/mod.d.ts.map +1 -0
  244. package/dist/src/textures/pixel-scraping.wgsl.d.ts +2 -0
  245. package/dist/src/textures/pixel-scraping.wgsl.d.ts.map +1 -0
  246. package/dist/src/textures/texture-processing.wgsl.d.ts +2 -0
  247. package/dist/src/textures/types.d.ts +176 -0
  248. package/dist/src/textures/types.d.ts.map +1 -0
  249. package/dist/src/textures/util.d.ts +7 -0
  250. package/dist/src/textures/util.d.ts.map +1 -0
  251. package/dist/src/utils/assert.d.ts +1 -0
  252. package/dist/src/utils/assert.d.ts.map +1 -0
  253. package/dist/src/utils/boilerplate.d.ts +10 -0
  254. package/dist/src/utils/boilerplate.d.ts.map +1 -0
  255. package/dist/src/utils/error.d.ts +7 -0
  256. package/dist/src/utils/error.d.ts.map +1 -0
  257. package/dist/src/utils/mod.d.ts +2 -0
  258. package/dist/src/utils/mod.d.ts.map +1 -0
  259. package/dist/src/utils/pool.d.ts +22 -0
  260. package/dist/src/utils/pool.d.ts.map +1 -0
  261. package/dist/test/math/matrix.test.d.ts +1 -0
  262. package/dist/test/scene/Batcher.test.d.ts +1 -0
  263. package/dist/test/scene/SceneNode.test.d.ts +1 -0
  264. package/dist/test/shader/parser.test.d.ts +1 -0
  265. package/dist/text/FontPipeline.d.ts +14 -0
  266. package/dist/text/FontPipeline.d.ts.map +1 -0
  267. package/dist/text/MsdfFont.d.ts +82 -0
  268. package/dist/text/MsdfFont.d.ts.map +1 -0
  269. package/dist/text/TextFormatting.d.ts +19 -0
  270. package/dist/text/TextFormatting.d.ts.map +1 -0
  271. package/dist/text/TextNode.d.ts +19 -0
  272. package/dist/text/TextNode.d.ts.map +1 -0
  273. package/dist/text/TextShader.d.ts +15 -0
  274. package/dist/text/TextShader.d.ts.map +1 -0
  275. package/dist/text/mod.d.ts +4 -0
  276. package/dist/text/mod.d.ts.map +1 -0
  277. package/dist/text/shaping.d.ts +39 -0
  278. package/dist/text/shaping.d.ts.map +1 -0
  279. package/dist/text/text.wgsl.d.ts +3 -0
  280. package/dist/text/text.wgsl.d.ts.map +1 -0
  281. package/dist/textures/AssetManager.d.ts +182 -0
  282. package/dist/textures/AssetManager.d.ts.map +1 -0
  283. package/dist/textures/TextureComputeShader.d.ts +21 -0
  284. package/dist/textures/TextureComputeShader.d.ts.map +1 -0
  285. package/dist/textures/mod.d.ts +2 -0
  286. package/dist/textures/mod.d.ts.map +1 -0
  287. package/dist/textures/pixel-scraping.wgsl.d.ts +3 -0
  288. package/dist/textures/pixel-scraping.wgsl.d.ts.map +1 -0
  289. package/dist/textures/types.d.ts +177 -0
  290. package/dist/textures/types.d.ts.map +1 -0
  291. package/dist/textures/util.d.ts +8 -0
  292. package/dist/textures/util.d.ts.map +1 -0
  293. package/dist/utils/assert.d.ts +2 -0
  294. package/dist/utils/assert.d.ts.map +1 -0
  295. package/dist/utils/boilerplate.d.ts +11 -0
  296. package/dist/utils/boilerplate.d.ts.map +1 -0
  297. package/dist/utils/error.d.ts +8 -0
  298. package/dist/utils/error.d.ts.map +1 -0
  299. package/dist/utils/mod.d.ts +3 -0
  300. package/dist/utils/mod.d.ts.map +1 -0
  301. package/dist/utils/pool.d.ts +23 -0
  302. package/dist/utils/pool.d.ts.map +1 -0
  303. package/package.json +47 -0
  304. package/src/Toodle.ts +853 -0
  305. package/src/colors/mod.ts +151 -0
  306. package/src/coreTypes/Color.ts +1 -0
  307. package/src/coreTypes/Point.ts +7 -0
  308. package/src/coreTypes/Size.ts +4 -0
  309. package/src/coreTypes/Transform.ts +16 -0
  310. package/src/coreTypes/Vec2.ts +7 -0
  311. package/src/coreTypes/mod.ts +5 -0
  312. package/src/globals.d.ts +4 -0
  313. package/src/limits.ts +23 -0
  314. package/src/math/angle.ts +17 -0
  315. package/src/math/matrix.ts +99 -0
  316. package/src/math/mod.ts +2 -0
  317. package/src/mod.ts +22 -0
  318. package/src/scene/Batcher.ts +61 -0
  319. package/src/scene/Camera.ts +69 -0
  320. package/src/scene/JumboQuadNode.ts +219 -0
  321. package/src/scene/QuadNode.ts +403 -0
  322. package/src/scene/RenderComponent.ts +12 -0
  323. package/src/scene/SceneNode.ts +668 -0
  324. package/src/scene/mod.ts +4 -0
  325. package/src/screen/mod.ts +1 -0
  326. package/src/screen/resolution.ts +1 -0
  327. package/src/shaders/EngineUniform.ts +11 -0
  328. package/src/shaders/IShader.ts +20 -0
  329. package/src/shaders/QuadShader.ts +288 -0
  330. package/src/shaders/ShaderDescriptor.ts +6 -0
  331. package/src/shaders/mod.ts +5 -0
  332. package/src/shaders/parser.ts +221 -0
  333. package/src/shaders/postprocess/blur.ts +245 -0
  334. package/src/shaders/postprocess/mod.ts +71 -0
  335. package/src/shaders/samplers.ts +13 -0
  336. package/src/shaders/wgsl/example.wgsl.ts +24 -0
  337. package/src/shaders/wgsl/hello.wgsl.ts +62 -0
  338. package/src/shaders/wgsl/helloInstanced.wgsl.ts +46 -0
  339. package/src/shaders/wgsl/quad.wgsl.ts +140 -0
  340. package/src/text/FontPipeline.ts +212 -0
  341. package/src/text/MsdfFont.ts +190 -0
  342. package/src/text/TextFormatting.ts +28 -0
  343. package/src/text/TextNode.ts +82 -0
  344. package/src/text/TextShader.ts +223 -0
  345. package/src/text/mod.ts +8 -0
  346. package/src/text/shaping.ts +280 -0
  347. package/src/text/text.wgsl.ts +149 -0
  348. package/src/textures/AssetManager.ts +746 -0
  349. package/src/textures/TextureComputeShader.ts +434 -0
  350. package/src/textures/mod.ts +1 -0
  351. package/src/textures/pixel-scraping.wgsl.ts +131 -0
  352. package/src/textures/types.ts +182 -0
  353. package/src/textures/util.ts +352 -0
  354. package/src/utils/assert.ts +5 -0
  355. package/src/utils/boilerplate.ts +110 -0
  356. package/src/utils/error.ts +14 -0
  357. package/src/utils/mod.ts +2 -0
  358. package/src/utils/pool.ts +42 -0
@@ -0,0 +1,182 @@
1
+ // types.ts should exclusively contain typescript types and no runtime js code.
2
+ // that way it is safe to import/export for consumers
3
+ // without accidentally including browser code via tree-shaking.
4
+
5
+ import type { Size, Vec2 } from "../coreTypes/mod";
6
+
7
+ export type AtlasCoords = TextureRegion & {
8
+ atlasIndex: number;
9
+ };
10
+
11
+ /**
12
+ * A TextureRegion is a region of the texture atlas in normalized texels.
13
+ *
14
+ * It is a combination of a UvRegion and a cropOffset.
15
+ */
16
+ export type TextureRegion = UvRegion & {
17
+ /** the offset from the top left of the texture in texels to begin drawing */
18
+ cropOffset: Vec2;
19
+ /** the original size of the texture in texels */
20
+ originalSize: Size;
21
+ };
22
+
23
+ /**
24
+ * A UvRegion is a region of the texture atlas in normalized texels.
25
+ */
26
+ export type UvRegion = {
27
+ /**
28
+ * The offset of the UVs in normalized atlas texels. Relative to the un-cropped texture.
29
+ *
30
+ * @example
31
+ *
32
+ * { x: 10 / 4096, y: 10 / 4096 }
33
+ */
34
+ uvOffset: Vec2;
35
+ /**
36
+ * The scale of the UVs in normalized texels. Derived from the width and height of the un-cropped texture.
37
+ *
38
+ * @example
39
+ *
40
+ * { width: 1 / 4096, height: 1 / 4096 }
41
+ */
42
+ uvScale: Size;
43
+ /**
44
+ * The scale of the UVs in normalized texels. Derived from the width and height of the cropped texture.
45
+ *
46
+ * @example
47
+ *
48
+ * { width: 1 / 4096, height: 1 / 4096 }
49
+ */
50
+ uvScaleCropped?: Size;
51
+ };
52
+
53
+ /**
54
+ * A CpuTextureAtlas is a texture atlas that has been loaded into memory.
55
+ *
56
+ * It contains the texture and a map of texture ids to TextureRegions.
57
+ */
58
+ export type CpuTextureAtlas = {
59
+ texture: ImageBitmap;
60
+ rg8Bytes?: Uint8Array<ArrayBuffer>;
61
+ textureRegions: Map<string, TextureRegion>;
62
+ width: number;
63
+ height: number;
64
+ };
65
+
66
+ /**
67
+ * A TextureWithMetadata is a texture that has been loaded into the gpu.
68
+ *
69
+ * It contains the gpu texture data and a cropOffset and originalSize for use with cropped textures.
70
+ */
71
+ export type TextureWithMetadata = {
72
+ texture: GPUTexture;
73
+ /** crop offset from center in texel units */
74
+ cropOffset: Vec2;
75
+ /** original size in texel units before cropping */
76
+ originalSize: Size;
77
+ };
78
+
79
+ /** A definition for a pre-baked texture atlas */
80
+ export type AtlasDef =
81
+ | {
82
+ /** The url of the atlas png file, if empty the png is assumed to be next to the json file */
83
+ png?: URL;
84
+ /** The url of the atlas json file, if empty the json is assumed to be next to the png file */
85
+ json: URL;
86
+ }
87
+ | {
88
+ /** The url of the atlas png file, if empty the png is assumed to be next to the json file */
89
+ png: URL;
90
+ /** The url of the atlas json file, if empty the json is assumed to be next to the png file */
91
+ json?: URL;
92
+ };
93
+
94
+ /** Bundle options for registering multiple individual textures */
95
+ export type TextureBundleOpts = {
96
+ /**
97
+ * A record of texture ids and URLs.
98
+ * ids must be unique within a bundle
99
+ *
100
+ */
101
+ textures: Record<string, URL>;
102
+
103
+ /**
104
+ * Whether the image should be cropped down to the minimal bounding box for non-transparent pixels.
105
+ *
106
+ * See [Transparent Pixel Cropping](https://toodle.gg/f849595b3ed13fc956fc1459a5cb5f0228f9d259/examples/transparent-cropping.html) for more information.
107
+ */
108
+ cropTransparentPixels?: boolean;
109
+ /**
110
+ * Whether the bundle should be loaded automatically on registration
111
+ */
112
+ autoLoad?: boolean;
113
+ };
114
+
115
+ /** Bundle options for registering pre-generated texture atlases */
116
+ export type AtlasBundleOpts = {
117
+ /**
118
+ * atlas definitions as pregenerated by a texture packer like https://github.com/pixijs/assetpack
119
+ *
120
+ * @example
121
+ *
122
+ * [
123
+ * {
124
+ * json: new URL('https://example.com/atlas.json'),
125
+ * },
126
+ * {
127
+ * png: new URL('https://example.com/atlas.png'),
128
+ * },
129
+ * {
130
+ * json: new URL('https://example.com/metadata/atlas.json'),
131
+ * png: new URL('https://example.com/images/atlas.png'),
132
+ * },
133
+ * ]
134
+ */
135
+ atlases: AtlasDef[];
136
+
137
+ /**
138
+ * Whether the bundle should be loaded automatically on registration
139
+ */
140
+ autoLoad?: boolean;
141
+
142
+ /**
143
+ * If true, png urls will be ignored and the texture path will be inferred to be next to the json file
144
+ * with a .rg8.gz extension.
145
+ */
146
+ rg8?: boolean;
147
+ };
148
+
149
+ /**
150
+ * A texel region defines a subregion of an individual texture in texel units.
151
+ *
152
+ * (0,0) is the top left corner of the original texture.
153
+ * (width, height) is the bottom right corner of the original texture.
154
+ *
155
+ * @example
156
+ * This is useful for something like spritesheet animations,
157
+ * for eg a 3-frame pose of a 32x32 character sprite might be 96x32 texels, and the animation could
158
+ * be done by alternating between:
159
+ *
160
+ * { x: 0, y: 0, width: 32, height: 32 }
161
+ * { x: 32, y: 0, width: 32, height: 32 }
162
+ * { x: 64, y: 0, width: 32, height: 32 }
163
+ *
164
+ */
165
+ export type TexelRegion = {
166
+ x: number;
167
+ y: number;
168
+ width: number;
169
+ height: number;
170
+ };
171
+
172
+ /** A region specification from a pixi.js spritesheet or atlas paced with assetPack */
173
+ export type PixiRegion = {
174
+ /** the position and size of the cropped region in the atlas, measured in texels*/
175
+ frame: { x: number; y: number; w: number; h: number };
176
+ rotated: boolean;
177
+ trimmed: boolean;
178
+ /** the original size of the texture in texels */
179
+ sourceSize: { w: number; h: number };
180
+ /** the position and size of the cropped region of the texture prior to packing in the atlas, measured in texels */
181
+ spriteSourceSize: { x: number; y: number; w: number; h: number };
182
+ };
@@ -0,0 +1,352 @@
1
+ import { unzipSync } from "fflate";
2
+ import type {
3
+ CpuTextureAtlas,
4
+ TextureRegion,
5
+ TextureWithMetadata,
6
+ } from "./types";
7
+
8
+ export async function getBitmapFromUrl(url: URL): Promise<ImageBitmap> {
9
+ try {
10
+ const response = await fetch(url);
11
+ const blob = await response.blob();
12
+ return await createImageBitmap(blob);
13
+ } catch (e) {
14
+ console.error(`Failed to load texture from ${url.href}`, e);
15
+ throw e;
16
+ }
17
+ }
18
+
19
+ /**
20
+ * Converts an image Blob to ImageData.
21
+ *
22
+ * @param blob - The Blob containing the image.
23
+ * @returns A Promise resolving to the image as ImageData.
24
+ */
25
+ async function blobToImageData(blob: Blob) {
26
+ const imageBitmap: ImageBitmap = await createImageBitmap(blob);
27
+
28
+ const canvas = document.createElement("canvas");
29
+ const ctx = canvas.getContext("2d");
30
+
31
+ if (!ctx) {
32
+ throw new Error("Failed to get 2D context from canvas");
33
+ }
34
+
35
+ canvas.width = imageBitmap.width;
36
+ canvas.height = imageBitmap.height;
37
+
38
+ ctx.drawImage(imageBitmap, 0, 0);
39
+
40
+ const imageData: ImageData = ctx.getImageData(
41
+ 0,
42
+ 0,
43
+ canvas.width,
44
+ canvas.height,
45
+ );
46
+
47
+ imageBitmap.close();
48
+
49
+ return imageData;
50
+ }
51
+
52
+ /**
53
+ * Creates a checkerboard pattern ImageData in black and purple.
54
+ *
55
+ * @param width - Width of the image.
56
+ * @param height - Height of the image.
57
+ * @param tileSize - Size of each checker tile (default is 8).
58
+ * @returns The generated ImageData object.
59
+ */
60
+ function createCheckerboardImageData(
61
+ width: number,
62
+ height: number,
63
+ tileSize = 8,
64
+ ): ImageData {
65
+ const data = new Uint8ClampedArray(width * height * 4);
66
+
67
+ const purple = [128, 0, 128, 255]; // #800080
68
+ const black = [0, 0, 0, 255]; // #000000
69
+
70
+ for (let y = 0; y < height; y++) {
71
+ for (let x = 0; x < width; x++) {
72
+ const usePurple =
73
+ (Math.floor(x / tileSize) + Math.floor(y / tileSize)) % 2 === 0;
74
+ const color = usePurple ? purple : black;
75
+ const idx = (y * width + x) * 4;
76
+
77
+ data.set(color, idx);
78
+ }
79
+ }
80
+
81
+ return new ImageData(data, width, height);
82
+ }
83
+
84
+ export async function loadZip(
85
+ zipUrl: URL,
86
+ ): Promise<{ path: string; bitmap: ImageBitmap }[]> {
87
+ console.time("fetch zip");
88
+ const zip = await fetch(zipUrl);
89
+ const zipBlob = await zip.blob();
90
+ const zipUint8Array = await zipBlob.arrayBuffer();
91
+ console.timeEnd("fetch zip");
92
+
93
+ console.time("unzip");
94
+ const files = unzipSync(new Uint8Array(zipUint8Array));
95
+ console.timeEnd("unzip");
96
+
97
+ console.time("create bitmaps");
98
+ const validFiles = Object.entries(files).filter(
99
+ ([path]) => !path.match("__MACOS") && path.endsWith(".png"),
100
+ );
101
+
102
+ return await Promise.all(
103
+ validFiles.map(async ([path, file]) => {
104
+ const bitmap = await createImageBitmap(new Blob([file]));
105
+ return { path, bitmap };
106
+ }),
107
+ );
108
+ }
109
+
110
+ export async function packBitmapsToAtlas(
111
+ images: Map<string, TextureWithMetadata>,
112
+ textureSize: number,
113
+ device: GPUDevice,
114
+ ): Promise<CpuTextureAtlas[]> {
115
+ const cpuTextureAtlases: CpuTextureAtlas[] = [];
116
+ const packed: PackedTexture[] = [];
117
+ const spaces: Rectangle[] = [
118
+ { x: 0, y: 0, width: textureSize, height: textureSize },
119
+ ];
120
+
121
+ let atlasRegionMap = new Map<string, TextureRegion>();
122
+
123
+ for (const [id, { texture, cropOffset: offset, originalSize }] of images) {
124
+ // Find best fitting space using guillotine method
125
+ let bestSpace = -1;
126
+ let bestScore = Number.POSITIVE_INFINITY;
127
+
128
+ for (let i = 0; i < spaces.length; i++) {
129
+ const space = spaces[i];
130
+ if (texture.width <= space.width && texture.height <= space.height) {
131
+ // Score based on how well it fits (smaller score is better)
132
+ const score = Math.abs(
133
+ space.width * space.height - texture.width * texture.height,
134
+ );
135
+ if (score < bestScore) {
136
+ bestScore = score;
137
+ bestSpace = i;
138
+ }
139
+ }
140
+ }
141
+
142
+ if (bestSpace === -1) {
143
+ const tex = await createTextureAtlasTexture(device, packed, textureSize);
144
+ cpuTextureAtlases.push({
145
+ texture: tex,
146
+ textureRegions: atlasRegionMap,
147
+ width: tex.width,
148
+ height: tex.height,
149
+ });
150
+
151
+ atlasRegionMap = new Map<string, TextureRegion>();
152
+ packed.length = 0;
153
+
154
+ spaces.length = 0;
155
+ spaces.push({
156
+ x: 0,
157
+ y: 0,
158
+ width: textureSize,
159
+ height: textureSize,
160
+ });
161
+ bestSpace = 0;
162
+ }
163
+
164
+ const space = spaces[bestSpace];
165
+
166
+ // Pack the image
167
+ packed.push(<PackedTexture>{
168
+ texture: await textureToBitmap(
169
+ device,
170
+ texture,
171
+ texture.width,
172
+ texture.height,
173
+ ),
174
+ x: space.x,
175
+ y: space.y,
176
+ width: texture.width,
177
+ height: texture.height,
178
+ });
179
+
180
+ texture.destroy();
181
+
182
+ // Split remaining space into two new spaces
183
+ spaces.splice(bestSpace, 1);
184
+
185
+ if (space.width - texture.width > 0) {
186
+ spaces.push({
187
+ x: space.x + texture.width,
188
+ y: space.y,
189
+ width: space.width - texture.width,
190
+ height: texture.height,
191
+ });
192
+ }
193
+
194
+ if (space.height - texture.height > 0) {
195
+ spaces.push({
196
+ x: space.x,
197
+ y: space.y + texture.height,
198
+ width: space.width,
199
+ height: space.height - texture.height,
200
+ });
201
+ }
202
+
203
+ // Create atlas coords
204
+ atlasRegionMap.set(id, {
205
+ uvOffset: {
206
+ x: space.x / textureSize,
207
+ y: space.y / textureSize,
208
+ },
209
+ uvScale: {
210
+ width: originalSize.width / textureSize,
211
+ height: originalSize.height / textureSize,
212
+ },
213
+ uvScaleCropped: {
214
+ width: texture.width / textureSize,
215
+ height: texture.height / textureSize,
216
+ },
217
+ cropOffset: offset,
218
+ originalSize,
219
+ });
220
+ }
221
+ const tex = await createTextureAtlasTexture(device, packed, textureSize);
222
+
223
+ cpuTextureAtlases.push({
224
+ texture: tex,
225
+ textureRegions: atlasRegionMap,
226
+ width: tex.width,
227
+ height: tex.height,
228
+ });
229
+
230
+ return cpuTextureAtlases;
231
+ }
232
+
233
+ async function createTextureAtlasTexture(
234
+ device: GPUDevice,
235
+ packed: PackedTexture[],
236
+ atlasSize: number,
237
+ ) {
238
+ const encoder: GPUCommandEncoder = device.createCommandEncoder();
239
+ const atlasTexture: GPUTexture = device.createTexture({
240
+ label: "Texture Atlas Texture Holder",
241
+ size: [atlasSize, atlasSize, 1],
242
+ format: "rgba8unorm",
243
+ usage:
244
+ GPUTextureUsage.TEXTURE_BINDING |
245
+ GPUTextureUsage.COPY_DST |
246
+ GPUTextureUsage.COPY_SRC |
247
+ GPUTextureUsage.RENDER_ATTACHMENT,
248
+ });
249
+
250
+ for (const texture of packed) {
251
+ device.queue.copyExternalImageToTexture(
252
+ {
253
+ source: texture.texture,
254
+ },
255
+ {
256
+ texture: atlasTexture,
257
+ origin: [texture.x, texture.y, 0],
258
+ },
259
+ [texture.width, texture.height, 1],
260
+ );
261
+ }
262
+ device.queue.submit([encoder.finish()]);
263
+ const atlasBitmap: ImageBitmap = await textureToBitmap(
264
+ device,
265
+ atlasTexture,
266
+ atlasTexture.width,
267
+ atlasTexture.height,
268
+ );
269
+ atlasTexture.destroy();
270
+ return atlasBitmap;
271
+ }
272
+
273
+ /**
274
+ * Converts a WebGPU GPUTexture into an ImageBitmap.
275
+ *
276
+ * @param {GPUDevice} device - The WebGPU device used to create GPU resources.
277
+ * @param {GPUTexture} texture - The GPUTexture to convert. Must be in `rgba8unorm` format.
278
+ * @param {number} width - The width of the texture in pixels.
279
+ * @param {number} height - The height of the texture in pixels.
280
+ * @returns {Promise<ImageBitmap>} A promise that resolves to an ImageBitmap containing the texture's contents.
281
+ *
282
+ * @example
283
+ * const bitmap = await textureToBitmap(device, queue, myTexture, 256, 256);
284
+ * const canvas = document.createElement("canvas");
285
+ * const ctx = canvas.getContext("2d");
286
+ * ctx.drawImage(bitmap, 0, 0);
287
+ */
288
+ async function textureToBitmap(
289
+ device: GPUDevice,
290
+ texture: GPUTexture,
291
+ width: number,
292
+ height: number,
293
+ ): Promise<ImageBitmap> {
294
+ const bytesPerPixel = 4;
295
+ const bytesPerRow = Math.ceil((width * bytesPerPixel) / 256) * 256;
296
+ const bufferSize = bytesPerRow * height;
297
+
298
+ const readBuffer = device.createBuffer({
299
+ size: bufferSize,
300
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
301
+ });
302
+
303
+ const commandEncoder = device.createCommandEncoder();
304
+ commandEncoder.copyTextureToBuffer(
305
+ { texture: texture },
306
+ {
307
+ buffer: readBuffer,
308
+ bytesPerRow: bytesPerRow,
309
+ rowsPerImage: height,
310
+ },
311
+ {
312
+ width: width,
313
+ height: height,
314
+ depthOrArrayLayers: 1,
315
+ },
316
+ );
317
+
318
+ const commands = commandEncoder.finish();
319
+ device.queue.submit([commands]);
320
+
321
+ await readBuffer.mapAsync(GPUMapMode.READ);
322
+ const arrayBuffer = readBuffer.getMappedRange();
323
+ const data = new Uint8ClampedArray(arrayBuffer);
324
+
325
+ const imageData = new Uint8ClampedArray(width * height * 4);
326
+ for (let y = 0; y < height; y++) {
327
+ const rowStart = y * bytesPerRow;
328
+ const rowEnd = rowStart + width * 4;
329
+ imageData.set(data.subarray(rowStart, rowEnd), y * width * 4);
330
+ }
331
+
332
+ const image = new ImageData(imageData, width, height);
333
+ const bitmap = await createImageBitmap(image);
334
+
335
+ readBuffer.unmap();
336
+ return bitmap;
337
+ }
338
+
339
+ type PackedTexture = {
340
+ texture: ImageBitmap;
341
+ x: number;
342
+ y: number;
343
+ width: number;
344
+ height: number;
345
+ };
346
+
347
+ type Rectangle = {
348
+ x: number;
349
+ y: number;
350
+ width: number;
351
+ height: number;
352
+ };
@@ -0,0 +1,5 @@
1
+ export function assert(condition: any, message: string): asserts condition {
2
+ if (!condition) {
3
+ throw new Error(message);
4
+ }
5
+ }
@@ -0,0 +1,110 @@
1
+ import {
2
+ makeBindGroupLayoutDescriptors,
3
+ makeShaderDataDefinitions,
4
+ } from "webgpu-utils";
5
+ import type { ShaderDescriptor } from "../shaders/ShaderDescriptor";
6
+ import { assert } from "./assert";
7
+
8
+ // convenience functions to wrap verbose webgpu apis - not part of public api
9
+
10
+ export async function initGpu(
11
+ canvas: HTMLCanvasElement,
12
+ onUncapturedError?: (e: GPUUncapturedErrorEvent) => void,
13
+ ) {
14
+ const adapter = await navigator.gpu.requestAdapter();
15
+ if (!adapter) {
16
+ throw new Error("WebGPU not supported");
17
+ }
18
+
19
+ const device = await adapter.requestDevice();
20
+ device.lost.then((info) => {
21
+ console.error("GPU Device lost", info);
22
+ });
23
+ if (onUncapturedError) {
24
+ device.onuncapturederror = onUncapturedError;
25
+ }
26
+
27
+ const context = canvas.getContext("webgpu");
28
+
29
+ assert(device, "WebGPU not supported");
30
+ assert(context, "WebGPU not supported");
31
+
32
+ const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
33
+
34
+ context.configure({
35
+ device,
36
+ format: presentationFormat,
37
+ });
38
+
39
+ return {
40
+ device,
41
+ context,
42
+ presentationFormat,
43
+ };
44
+ }
45
+
46
+ export function getGpuPipelineDescriptor(
47
+ shaderDescriptor: ShaderDescriptor,
48
+ module: GPUShaderModule,
49
+ presentationFormat: GPUTextureFormat,
50
+ blend?: GPUBlendState,
51
+ ): Omit<GPURenderPipelineDescriptor, "layout"> {
52
+ const pipelineDescriptor: Omit<GPURenderPipelineDescriptor, "layout"> = {
53
+ label: `${shaderDescriptor.label} pipeline`,
54
+ vertex: {
55
+ module,
56
+ entryPoint: shaderDescriptor.vertexEntrypoint,
57
+ },
58
+ fragment: {
59
+ module,
60
+ entryPoint: shaderDescriptor.fragmentEntrypoint,
61
+ targets: [
62
+ {
63
+ format: presentationFormat,
64
+ blend,
65
+ },
66
+ ],
67
+ },
68
+ primitive: {
69
+ topology: "triangle-strip",
70
+ },
71
+ };
72
+
73
+ return pipelineDescriptor;
74
+ }
75
+
76
+ export function setVertexInstanceBufferLayout(
77
+ pipeline: Omit<GPURenderPipelineDescriptor, "layout">,
78
+ bufferLayout: GPUVertexBufferLayout,
79
+ ): Omit<GPURenderPipelineDescriptor, "layout"> {
80
+ pipeline.vertex.buffers = [bufferLayout];
81
+ return pipeline;
82
+ }
83
+
84
+ export function attachVertexInstanceBuffer(
85
+ renderPass: GPURenderPassEncoder,
86
+ instanceBuffer: GPUBuffer,
87
+ ) {
88
+ renderPass.setVertexBuffer(0, instanceBuffer);
89
+ }
90
+
91
+ export function createGpuPipeline(
92
+ device: GPUDevice,
93
+ shaderDescriptor: ShaderDescriptor,
94
+ pipelineDescriptor: Omit<GPURenderPipelineDescriptor, "layout">,
95
+ ): GPURenderPipeline {
96
+ const defs = makeShaderDataDefinitions(shaderDescriptor.code);
97
+ const descriptors = makeBindGroupLayoutDescriptors(defs, pipelineDescriptor);
98
+
99
+ return device.createRenderPipeline({
100
+ ...pipelineDescriptor,
101
+ layout: device.createPipelineLayout({
102
+ bindGroupLayouts: descriptors.map((d, i) =>
103
+ device.createBindGroupLayout({
104
+ label: `${shaderDescriptor.label} bind group layout ${i}`,
105
+ ...d,
106
+ }),
107
+ ),
108
+ }),
109
+ });
110
+ }
@@ -0,0 +1,14 @@
1
+ const warnings: Map<string, boolean> = new Map<string, boolean>();
2
+ /**
3
+ * Useful for warning in a function run every frame if you only want to warn once
4
+ *
5
+ * @param key a unique key to tag the warning
6
+ * @param msg message to console.warn
7
+ */
8
+ export function warnOnce(key: string, msg?: string) {
9
+ if (warnings.has(key)) {
10
+ return;
11
+ }
12
+ warnings.set(key, true);
13
+ console.warn(msg ?? key);
14
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./assert";
2
+ export * from "./pool";
@@ -0,0 +1,42 @@
1
+ /**
2
+ * A simple pool for creating and reusing objects to avoid allocation between frames
3
+ *
4
+ * @example
5
+ *
6
+ * const pool = new Pool(() => new SomeObject(), 10);
7
+ *
8
+ * function animate() {
9
+ * const obj = pool.get();
10
+ * console.log(obj);
11
+ * pool.free();
12
+ * requestAnimationFrame(animate);
13
+ * }
14
+ *
15
+ * requestAnimationFrame(animate);
16
+ */
17
+ export class Pool<T> {
18
+ #items: T[] = [];
19
+ #create: () => T;
20
+ #index = 0;
21
+
22
+ constructor(create: () => T, initialSize = 0) {
23
+ this.#create = create;
24
+ if (initialSize > 0) {
25
+ this.#items = Array.from({ length: initialSize })
26
+ .fill(null)
27
+ .map(() => this.#create());
28
+ }
29
+ }
30
+
31
+ get() {
32
+ if (this.#index >= this.#items.length) {
33
+ this.#items.push(this.#create());
34
+ }
35
+
36
+ return this.#items[this.#index++];
37
+ }
38
+
39
+ free() {
40
+ this.#index = 0;
41
+ }
42
+ }