@thunderclap-engine/engine 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/CHANGELOG.md +390 -0
  2. package/LICENSE +21 -0
  3. package/README.md +333 -2
  4. package/dist/analytics/analytics.d.ts +80 -0
  5. package/dist/analytics/analytics.js +129 -0
  6. package/dist/analytics/index.d.ts +1 -0
  7. package/dist/analytics/index.js +1 -0
  8. package/dist/anim/aim.d.ts +43 -0
  9. package/dist/anim/aim.js +157 -0
  10. package/dist/anim/clip.d.ts +98 -0
  11. package/dist/anim/clip.js +282 -0
  12. package/dist/anim/compress.d.ts +65 -0
  13. package/dist/anim/compress.js +339 -0
  14. package/dist/anim/foot-ik.d.ts +74 -0
  15. package/dist/anim/foot-ik.js +241 -0
  16. package/dist/anim/graph.d.ts +153 -0
  17. package/dist/anim/graph.js +532 -0
  18. package/dist/anim/ik.d.ts +105 -0
  19. package/dist/anim/ik.js +435 -0
  20. package/dist/anim/index.d.ts +36 -0
  21. package/dist/anim/index.js +21 -0
  22. package/dist/anim/match.d.ts +66 -0
  23. package/dist/anim/match.js +153 -0
  24. package/dist/anim/mixer.d.ts +113 -0
  25. package/dist/anim/mixer.js +314 -0
  26. package/dist/anim/morph.d.ts +41 -0
  27. package/dist/anim/morph.js +94 -0
  28. package/dist/anim/pose.d.ts +74 -0
  29. package/dist/anim/pose.js +254 -0
  30. package/dist/anim/quat.d.ts +44 -0
  31. package/dist/anim/quat.js +187 -0
  32. package/dist/anim/retarget.d.ts +97 -0
  33. package/dist/anim/retarget.js +366 -0
  34. package/dist/anim/root-motion.d.ts +44 -0
  35. package/dist/anim/root-motion.js +224 -0
  36. package/dist/anim/skin-pose.d.ts +39 -0
  37. package/dist/anim/skin-pose.js +53 -0
  38. package/dist/anim/socket.d.ts +47 -0
  39. package/dist/anim/socket.js +84 -0
  40. package/dist/anim/spring-chain.d.ts +73 -0
  41. package/dist/anim/spring-chain.js +294 -0
  42. package/dist/assets/atlas.d.ts +90 -0
  43. package/dist/assets/atlas.js +212 -0
  44. package/dist/assets/baked.d.ts +33 -0
  45. package/dist/assets/baked.js +38 -0
  46. package/dist/assets/bundle.d.ts +88 -0
  47. package/dist/assets/bundle.js +464 -0
  48. package/dist/assets/cache.d.ts +56 -0
  49. package/dist/assets/cache.js +123 -0
  50. package/dist/assets/gltf-load.d.ts +252 -0
  51. package/dist/assets/gltf-load.js +661 -0
  52. package/dist/assets/gltf-skin.d.ts +36 -0
  53. package/dist/assets/gltf-skin.js +109 -0
  54. package/dist/assets/gltf.d.ts +706 -0
  55. package/dist/assets/gltf.js +1376 -0
  56. package/dist/assets/index.d.ts +20 -0
  57. package/dist/assets/index.js +10 -0
  58. package/dist/assets/ktx2.d.ts +71 -0
  59. package/dist/assets/ktx2.js +213 -0
  60. package/dist/assets/manifest.d.ts +79 -0
  61. package/dist/assets/manifest.js +7 -0
  62. package/dist/assets/meshopt.d.ts +23 -0
  63. package/dist/assets/meshopt.js +403 -0
  64. package/dist/audio/audio.d.ts +733 -0
  65. package/dist/audio/audio.js +2013 -0
  66. package/dist/audio/dsp.d.ts +61 -0
  67. package/dist/audio/dsp.js +159 -0
  68. package/dist/audio/duck.d.ts +44 -0
  69. package/dist/audio/duck.js +101 -0
  70. package/dist/audio/envelope.d.ts +53 -0
  71. package/dist/audio/envelope.js +106 -0
  72. package/dist/audio/index.d.ts +13 -0
  73. package/dist/audio/index.js +14 -0
  74. package/dist/audio/music.d.ts +113 -0
  75. package/dist/audio/music.js +548 -0
  76. package/dist/audio/occlusion.d.ts +55 -0
  77. package/dist/audio/occlusion.js +61 -0
  78. package/dist/audio/persist.d.ts +23 -0
  79. package/dist/audio/persist.js +27 -0
  80. package/dist/audio/recipes.d.ts +55 -0
  81. package/dist/audio/recipes.js +227 -0
  82. package/dist/audio/send.d.ts +41 -0
  83. package/dist/audio/send.js +118 -0
  84. package/dist/audio/sprites.d.ts +59 -0
  85. package/dist/audio/sprites.js +43 -0
  86. package/dist/audio/synth.d.ts +103 -0
  87. package/dist/audio/synth.js +197 -0
  88. package/dist/audio/variations.d.ts +25 -0
  89. package/dist/audio/variations.js +55 -0
  90. package/dist/audio/zones.d.ts +100 -0
  91. package/dist/audio/zones.js +167 -0
  92. package/dist/core/detached-surface.d.ts +44 -0
  93. package/dist/core/detached-surface.js +104 -0
  94. package/dist/core/events.d.ts +24 -0
  95. package/dist/core/events.js +43 -0
  96. package/dist/core/game.d.ts +409 -0
  97. package/dist/core/game.js +530 -0
  98. package/dist/core/hash.d.ts +24 -0
  99. package/dist/core/hash.js +49 -0
  100. package/dist/core/index.d.ts +17 -0
  101. package/dist/core/index.js +9 -0
  102. package/dist/core/loop.d.ts +113 -0
  103. package/dist/core/loop.js +185 -0
  104. package/dist/core/math.d.ts +58 -0
  105. package/dist/core/math.js +210 -0
  106. package/dist/core/noise.d.ts +40 -0
  107. package/dist/core/noise.js +247 -0
  108. package/dist/core/pool.d.ts +42 -0
  109. package/dist/core/pool.js +85 -0
  110. package/dist/core/random.d.ts +61 -0
  111. package/dist/core/random.js +199 -0
  112. package/dist/core/scene.d.ts +79 -0
  113. package/dist/core/scene.js +195 -0
  114. package/dist/core/timer.d.ts +66 -0
  115. package/dist/core/timer.js +286 -0
  116. package/dist/fx/billboard-wgsl.d.ts +29 -0
  117. package/dist/fx/billboard-wgsl.js +158 -0
  118. package/dist/fx/billboard.d.ts +249 -0
  119. package/dist/fx/billboard.js +702 -0
  120. package/dist/fx/debug-draw.d.ts +127 -0
  121. package/dist/fx/debug-draw.js +523 -0
  122. package/dist/fx/debug-wgsl.d.ts +7 -0
  123. package/dist/fx/debug-wgsl.js +32 -0
  124. package/dist/fx/decals-wgsl.d.ts +15 -0
  125. package/dist/fx/decals-wgsl.js +173 -0
  126. package/dist/fx/decals.d.ts +216 -0
  127. package/dist/fx/decals.js +607 -0
  128. package/dist/fx/effect.d.ts +129 -0
  129. package/dist/fx/effect.js +349 -0
  130. package/dist/fx/effects/hit-spark.json +48 -0
  131. package/dist/fx/effects/index.d.ts +8 -0
  132. package/dist/fx/effects/index.js +9 -0
  133. package/dist/fx/effects/magic-aura.json +47 -0
  134. package/dist/fx/effects/smoke-puff.json +34 -0
  135. package/dist/fx/emit-surface.d.ts +40 -0
  136. package/dist/fx/emit-surface.js +124 -0
  137. package/dist/fx/flicker.d.ts +30 -0
  138. package/dist/fx/flicker.js +42 -0
  139. package/dist/fx/index.d.ts +31 -0
  140. package/dist/fx/index.js +20 -0
  141. package/dist/fx/particles-wgsl.d.ts +57 -0
  142. package/dist/fx/particles-wgsl.js +828 -0
  143. package/dist/fx/particles.d.ts +566 -0
  144. package/dist/fx/particles.js +1533 -0
  145. package/dist/fx/random.d.ts +15 -0
  146. package/dist/fx/random.js +20 -0
  147. package/dist/fx/sky-wgsl.d.ts +23 -0
  148. package/dist/fx/sky-wgsl.js +127 -0
  149. package/dist/fx/sky.d.ts +96 -0
  150. package/dist/fx/sky.js +175 -0
  151. package/dist/fx/text-atlas.d.ts +143 -0
  152. package/dist/fx/text-atlas.js +327 -0
  153. package/dist/fx/trail-wgsl.d.ts +11 -0
  154. package/dist/fx/trail-wgsl.js +42 -0
  155. package/dist/fx/trail.d.ts +194 -0
  156. package/dist/fx/trail.js +555 -0
  157. package/dist/fx/water-wgsl.d.ts +34 -0
  158. package/dist/fx/water-wgsl.js +197 -0
  159. package/dist/fx/water.d.ts +176 -0
  160. package/dist/fx/water.js +371 -0
  161. package/dist/geom/collide/bvh.d.ts +151 -0
  162. package/dist/geom/collide/bvh.js +493 -0
  163. package/dist/geom/collide/debug.d.ts +14 -0
  164. package/dist/geom/collide/debug.js +74 -0
  165. package/dist/geom/collide/grid.d.ts +26 -0
  166. package/dist/geom/collide/grid.js +91 -0
  167. package/dist/geom/collide/index.d.ts +8 -0
  168. package/dist/geom/collide/index.js +8 -0
  169. package/dist/geom/collide/queries.d.ts +70 -0
  170. package/dist/geom/collide/queries.js +583 -0
  171. package/dist/geom/collide/serialize.d.ts +14 -0
  172. package/dist/geom/collide/serialize.js +145 -0
  173. package/dist/geom/collide/shapes.d.ts +161 -0
  174. package/dist/geom/collide/shapes.js +686 -0
  175. package/dist/geom/collide/slide.d.ts +66 -0
  176. package/dist/geom/collide/slide.js +375 -0
  177. package/dist/geom/collide/tile-slide.d.ts +88 -0
  178. package/dist/geom/collide/tile-slide.js +255 -0
  179. package/dist/geom/geometry.d.ts +95 -0
  180. package/dist/geom/geometry.js +322 -0
  181. package/dist/geom/heightfield.d.ts +72 -0
  182. package/dist/geom/heightfield.js +295 -0
  183. package/dist/geom/hull.d.ts +27 -0
  184. package/dist/geom/hull.js +279 -0
  185. package/dist/geom/index.d.ts +35 -0
  186. package/dist/geom/index.js +23 -0
  187. package/dist/geom/iso.d.ts +74 -0
  188. package/dist/geom/iso.js +89 -0
  189. package/dist/geom/lod.d.ts +29 -0
  190. package/dist/geom/lod.js +27 -0
  191. package/dist/geom/ops.d.ts +47 -0
  192. package/dist/geom/ops.js +285 -0
  193. package/dist/geom/primitives.d.ts +97 -0
  194. package/dist/geom/primitives.js +359 -0
  195. package/dist/geom/shapes.d.ts +43 -0
  196. package/dist/geom/shapes.js +88 -0
  197. package/dist/geom/simplify.d.ts +38 -0
  198. package/dist/geom/simplify.js +519 -0
  199. package/dist/geom/split.d.ts +37 -0
  200. package/dist/geom/split.js +413 -0
  201. package/dist/geom/sweep.d.ts +83 -0
  202. package/dist/geom/sweep.js +534 -0
  203. package/dist/geom/tangents.d.ts +16 -0
  204. package/dist/geom/tangents.js +124 -0
  205. package/dist/geom/triangulate.d.ts +19 -0
  206. package/dist/geom/triangulate.js +147 -0
  207. package/dist/host/default.d.ts +10 -0
  208. package/dist/host/default.js +10 -0
  209. package/dist/host/index.d.ts +4 -0
  210. package/dist/host/index.js +3 -0
  211. package/dist/host/types.d.ts +144 -0
  212. package/dist/host/types.js +1 -0
  213. package/dist/host/web-links.d.ts +38 -0
  214. package/dist/host/web-links.js +110 -0
  215. package/dist/host/web.d.ts +30 -0
  216. package/dist/host/web.js +216 -0
  217. package/dist/host/xr.d.ts +24 -0
  218. package/dist/host/xr.js +59 -0
  219. package/dist/i18n/i18n.d.ts +59 -0
  220. package/dist/i18n/i18n.js +241 -0
  221. package/dist/i18n/index.d.ts +3 -0
  222. package/dist/i18n/index.js +3 -0
  223. package/dist/i18n/message.d.ts +72 -0
  224. package/dist/i18n/message.js +369 -0
  225. package/dist/i18n/negotiate.d.ts +17 -0
  226. package/dist/i18n/negotiate.js +58 -0
  227. package/dist/index.d.ts +7 -0
  228. package/dist/index.js +1 -0
  229. package/dist/input/bindings.d.ts +31 -0
  230. package/dist/input/bindings.js +141 -0
  231. package/dist/input/clock.d.ts +44 -0
  232. package/dist/input/clock.js +49 -0
  233. package/dist/input/follow.d.ts +133 -0
  234. package/dist/input/follow.js +218 -0
  235. package/dist/input/gestures.d.ts +281 -0
  236. package/dist/input/gestures.js +662 -0
  237. package/dist/input/glyphs.d.ts +35 -0
  238. package/dist/input/glyphs.js +216 -0
  239. package/dist/input/gyro.d.ts +85 -0
  240. package/dist/input/gyro.js +140 -0
  241. package/dist/input/index.d.ts +19 -0
  242. package/dist/input/index.js +16 -0
  243. package/dist/input/input.d.ts +543 -0
  244. package/dist/input/input.js +1492 -0
  245. package/dist/input/look.d.ts +327 -0
  246. package/dist/input/look.js +681 -0
  247. package/dist/input/magnify.d.ts +177 -0
  248. package/dist/input/magnify.js +131 -0
  249. package/dist/input/pointer-dispatch.d.ts +138 -0
  250. package/dist/input/pointer-dispatch.js +180 -0
  251. package/dist/input/pointer-router.d.ts +204 -0
  252. package/dist/input/pointer-router.js +533 -0
  253. package/dist/input/pointer-sources.d.ts +164 -0
  254. package/dist/input/pointer-sources.js +306 -0
  255. package/dist/input/rays.d.ts +138 -0
  256. package/dist/input/rays.js +615 -0
  257. package/dist/input/record.d.ts +209 -0
  258. package/dist/input/record.js +601 -0
  259. package/dist/input/touch-zones.d.ts +147 -0
  260. package/dist/input/touch-zones.js +300 -0
  261. package/dist/input/types.d.ts +158 -0
  262. package/dist/input/types.js +1 -0
  263. package/dist/input/xr-source.d.ts +53 -0
  264. package/dist/input/xr-source.js +164 -0
  265. package/dist/nav/astar.d.ts +45 -0
  266. package/dist/nav/astar.js +182 -0
  267. package/dist/nav/corridor.d.ts +40 -0
  268. package/dist/nav/corridor.js +95 -0
  269. package/dist/nav/crowd.d.ts +94 -0
  270. package/dist/nav/crowd.js +624 -0
  271. package/dist/nav/flow.d.ts +61 -0
  272. package/dist/nav/flow.js +193 -0
  273. package/dist/nav/grid.d.ts +108 -0
  274. package/dist/nav/grid.js +210 -0
  275. package/dist/nav/heap.d.ts +22 -0
  276. package/dist/nav/heap.js +92 -0
  277. package/dist/nav/index.d.ts +37 -0
  278. package/dist/nav/index.js +19 -0
  279. package/dist/nav/mesh/areas.d.ts +44 -0
  280. package/dist/nav/mesh/areas.js +98 -0
  281. package/dist/nav/mesh/bake-options.d.ts +33 -0
  282. package/dist/nav/mesh/bake-options.js +76 -0
  283. package/dist/nav/mesh/contour.d.ts +22 -0
  284. package/dist/nav/mesh/contour.js +323 -0
  285. package/dist/nav/mesh/flow3.d.ts +35 -0
  286. package/dist/nav/mesh/flow3.js +229 -0
  287. package/dist/nav/mesh/links.d.ts +38 -0
  288. package/dist/nav/mesh/links.js +72 -0
  289. package/dist/nav/mesh/mesh-path.d.ts +152 -0
  290. package/dist/nav/mesh/mesh-path.js +643 -0
  291. package/dist/nav/mesh/mesh-reach.d.ts +78 -0
  292. package/dist/nav/mesh/mesh-reach.js +450 -0
  293. package/dist/nav/mesh/navmesh.d.ts +117 -0
  294. package/dist/nav/mesh/navmesh.js +647 -0
  295. package/dist/nav/mesh/polymesh.d.ts +24 -0
  296. package/dist/nav/mesh/polymesh.js +384 -0
  297. package/dist/nav/mesh/regions.d.ts +12 -0
  298. package/dist/nav/mesh/regions.js +367 -0
  299. package/dist/nav/mesh/serialize.d.ts +13 -0
  300. package/dist/nav/mesh/serialize.js +197 -0
  301. package/dist/nav/mesh/voxelize.d.ts +111 -0
  302. package/dist/nav/mesh/voxelize.js +552 -0
  303. package/dist/nav/obstacles.d.ts +75 -0
  304. package/dist/nav/obstacles.js +294 -0
  305. package/dist/nav/path.d.ts +59 -0
  306. package/dist/nav/path.js +177 -0
  307. package/dist/nav/query-queue.d.ts +46 -0
  308. package/dist/nav/query-queue.js +308 -0
  309. package/dist/nav/reach.d.ts +53 -0
  310. package/dist/nav/reach.js +148 -0
  311. package/dist/nav/steer.d.ts +36 -0
  312. package/dist/nav/steer.js +78 -0
  313. package/dist/platform/boot.d.ts +28 -0
  314. package/dist/platform/boot.js +43 -0
  315. package/dist/platform/device-mode.d.ts +40 -0
  316. package/dist/platform/device-mode.js +104 -0
  317. package/dist/platform/device.d.ts +31 -0
  318. package/dist/platform/device.js +91 -0
  319. package/dist/platform/environment.d.ts +42 -0
  320. package/dist/platform/environment.js +82 -0
  321. package/dist/platform/gpu.d.ts +40 -0
  322. package/dist/platform/gpu.js +57 -0
  323. package/dist/platform/index.d.ts +18 -0
  324. package/dist/platform/index.js +10 -0
  325. package/dist/platform/letterbox.d.ts +43 -0
  326. package/dist/platform/letterbox.js +57 -0
  327. package/dist/platform/links.d.ts +20 -0
  328. package/dist/platform/links.js +43 -0
  329. package/dist/platform/screens.d.ts +36 -0
  330. package/dist/platform/screens.js +138 -0
  331. package/dist/platform/surface.d.ts +72 -0
  332. package/dist/platform/surface.js +157 -0
  333. package/dist/platform/xr-fake.d.ts +168 -0
  334. package/dist/platform/xr-fake.js +434 -0
  335. package/dist/platform/xr-surface.d.ts +120 -0
  336. package/dist/platform/xr-surface.js +214 -0
  337. package/dist/platform/xr-types.d.ts +262 -0
  338. package/dist/post/ao.d.ts +12 -0
  339. package/dist/post/ao.js +136 -0
  340. package/dist/post/blend.d.ts +27 -0
  341. package/dist/post/blend.js +129 -0
  342. package/dist/post/depth-pass.d.ts +43 -0
  343. package/dist/post/depth-pass.js +118 -0
  344. package/dist/post/dof.d.ts +1 -0
  345. package/dist/post/dof.js +66 -0
  346. package/dist/post/exposure.d.ts +80 -0
  347. package/dist/post/exposure.js +322 -0
  348. package/dist/post/index.d.ts +12 -0
  349. package/dist/post/index.js +11 -0
  350. package/dist/post/lens-dirt.d.ts +13 -0
  351. package/dist/post/lens-dirt.js +91 -0
  352. package/dist/post/lut.d.ts +19 -0
  353. package/dist/post/lut.js +50 -0
  354. package/dist/post/motion-blur.d.ts +9 -0
  355. package/dist/post/motion-blur.js +78 -0
  356. package/dist/post/post-stack.d.ts +302 -0
  357. package/dist/post/post-stack.js +1137 -0
  358. package/dist/post/settings.d.ts +485 -0
  359. package/dist/post/settings.js +416 -0
  360. package/dist/post/shaders.d.ts +25 -0
  361. package/dist/post/shaders.js +410 -0
  362. package/dist/post/ssr.d.ts +16 -0
  363. package/dist/post/ssr.js +155 -0
  364. package/dist/post/taa.d.ts +74 -0
  365. package/dist/post/taa.js +235 -0
  366. package/dist/post/white-balance.d.ts +25 -0
  367. package/dist/post/white-balance.js +98 -0
  368. package/dist/render/bindings.d.ts +98 -0
  369. package/dist/render/bindings.js +281 -0
  370. package/dist/render/blend.d.ts +13 -0
  371. package/dist/render/blend.js +26 -0
  372. package/dist/render/camera-2d.d.ts +72 -0
  373. package/dist/render/camera-2d.js +92 -0
  374. package/dist/render/camera.d.ts +302 -0
  375. package/dist/render/camera.js +671 -0
  376. package/dist/render/color.d.ts +16 -0
  377. package/dist/render/color.js +41 -0
  378. package/dist/render/compressed.d.ts +104 -0
  379. package/dist/render/compressed.js +248 -0
  380. package/dist/render/diagnostics.d.ts +15 -0
  381. package/dist/render/diagnostics.js +43 -0
  382. package/dist/render/dynamic-resolution.d.ts +70 -0
  383. package/dist/render/dynamic-resolution.js +126 -0
  384. package/dist/render/fake-gpu.d.ts +204 -0
  385. package/dist/render/fake-gpu.js +426 -0
  386. package/dist/render/flipbook.d.ts +56 -0
  387. package/dist/render/flipbook.js +87 -0
  388. package/dist/render/frame.d.ts +278 -0
  389. package/dist/render/frame.js +174 -0
  390. package/dist/render/fullscreen.d.ts +54 -0
  391. package/dist/render/fullscreen.js +91 -0
  392. package/dist/render/gpu-timer.d.ts +73 -0
  393. package/dist/render/gpu-timer.js +186 -0
  394. package/dist/render/index.d.ts +53 -0
  395. package/dist/render/index.js +29 -0
  396. package/dist/render/instance-list.d.ts +185 -0
  397. package/dist/render/instance-list.js +547 -0
  398. package/dist/render/lights.d.ts +181 -0
  399. package/dist/render/lights.js +233 -0
  400. package/dist/render/lod.d.ts +54 -0
  401. package/dist/render/lod.js +52 -0
  402. package/dist/render/material.d.ts +165 -0
  403. package/dist/render/material.js +292 -0
  404. package/dist/render/mesh.d.ts +284 -0
  405. package/dist/render/mesh.js +472 -0
  406. package/dist/render/mipmap.d.ts +16 -0
  407. package/dist/render/mipmap.js +121 -0
  408. package/dist/render/parallax.d.ts +50 -0
  409. package/dist/render/parallax.js +47 -0
  410. package/dist/render/pbr-wgsl.d.ts +31 -0
  411. package/dist/render/pbr-wgsl.js +119 -0
  412. package/dist/render/ping-pong.d.ts +42 -0
  413. package/dist/render/ping-pong.js +74 -0
  414. package/dist/render/renderer.d.ts +741 -0
  415. package/dist/render/renderer.js +2486 -0
  416. package/dist/render/scene-pipelines.d.ts +44 -0
  417. package/dist/render/scene-pipelines.js +92 -0
  418. package/dist/render/scene-target.d.ts +170 -0
  419. package/dist/render/scene-target.js +450 -0
  420. package/dist/render/shadow.d.ts +74 -0
  421. package/dist/render/shadow.js +208 -0
  422. package/dist/render/skin.d.ts +112 -0
  423. package/dist/render/skin.js +240 -0
  424. package/dist/render/snapshot.d.ts +36 -0
  425. package/dist/render/snapshot.js +34 -0
  426. package/dist/render/standard.d.ts +162 -0
  427. package/dist/render/standard.js +263 -0
  428. package/dist/render/texture.d.ts +142 -0
  429. package/dist/render/texture.js +228 -0
  430. package/dist/render/tile-layer.d.ts +110 -0
  431. package/dist/render/tile-layer.js +304 -0
  432. package/dist/render/transform.d.ts +115 -0
  433. package/dist/render/transform.js +318 -0
  434. package/dist/render/wgsl.d.ts +131 -0
  435. package/dist/render/wgsl.js +528 -0
  436. package/dist/save/codec.d.ts +49 -0
  437. package/dist/save/codec.js +169 -0
  438. package/dist/save/index.d.ts +8 -0
  439. package/dist/save/index.js +8 -0
  440. package/dist/save/journal.d.ts +24 -0
  441. package/dist/save/journal.js +102 -0
  442. package/dist/save/migrate.d.ts +15 -0
  443. package/dist/save/migrate.js +37 -0
  444. package/dist/save/schema.d.ts +72 -0
  445. package/dist/save/schema.js +154 -0
  446. package/dist/save/settings.d.ts +28 -0
  447. package/dist/save/settings.js +59 -0
  448. package/dist/save/slots.d.ts +56 -0
  449. package/dist/save/slots.js +200 -0
  450. package/dist/save/storage.d.ts +35 -0
  451. package/dist/save/storage.js +62 -0
  452. package/dist/save/store.d.ts +114 -0
  453. package/dist/save/store.js +269 -0
  454. package/dist/testing/fake-host.d.ts +103 -0
  455. package/dist/testing/fake-host.js +163 -0
  456. package/dist/testing/fixed-clock.d.ts +25 -0
  457. package/dist/testing/fixed-clock.js +30 -0
  458. package/dist/testing/index.d.ts +4 -0
  459. package/dist/testing/index.js +5 -0
  460. package/dist/testing/test-game.d.ts +76 -0
  461. package/dist/testing/test-game.js +92 -0
  462. package/dist/tween/ease.d.ts +77 -0
  463. package/dist/tween/ease.js +192 -0
  464. package/dist/tween/index.d.ts +8 -0
  465. package/dist/tween/index.js +7 -0
  466. package/dist/tween/timeline.d.ts +78 -0
  467. package/dist/tween/timeline.js +269 -0
  468. package/dist/tween/tween.d.ts +168 -0
  469. package/dist/tween/tween.js +320 -0
  470. package/dist/ui/anchor.d.ts +206 -0
  471. package/dist/ui/anchor.js +307 -0
  472. package/dist/ui/caption.d.ts +122 -0
  473. package/dist/ui/caption.js +286 -0
  474. package/dist/ui/cursor.d.ts +105 -0
  475. package/dist/ui/cursor.js +261 -0
  476. package/dist/ui/dom.d.ts +30 -0
  477. package/dist/ui/dom.js +92 -0
  478. package/dist/ui/floats.d.ts +86 -0
  479. package/dist/ui/floats.js +260 -0
  480. package/dist/ui/hud.d.ts +198 -0
  481. package/dist/ui/hud.js +431 -0
  482. package/dist/ui/index.d.ts +37 -0
  483. package/dist/ui/index.js +34 -0
  484. package/dist/ui/inventory-card.d.ts +52 -0
  485. package/dist/ui/inventory-card.js +173 -0
  486. package/dist/ui/inventory-context.d.ts +29 -0
  487. package/dist/ui/inventory-context.js +125 -0
  488. package/dist/ui/inventory-drag.d.ts +63 -0
  489. package/dist/ui/inventory-drag.js +394 -0
  490. package/dist/ui/inventory-grid.d.ts +66 -0
  491. package/dist/ui/inventory-grid.js +625 -0
  492. package/dist/ui/inventory-radial.d.ts +39 -0
  493. package/dist/ui/inventory-radial.js +168 -0
  494. package/dist/ui/inventory.d.ts +128 -0
  495. package/dist/ui/inventory.js +154 -0
  496. package/dist/ui/layout.d.ts +356 -0
  497. package/dist/ui/layout.js +856 -0
  498. package/dist/ui/link.d.ts +64 -0
  499. package/dist/ui/link.js +155 -0
  500. package/dist/ui/loading.d.ts +40 -0
  501. package/dist/ui/loading.js +157 -0
  502. package/dist/ui/loupe.d.ts +74 -0
  503. package/dist/ui/loupe.js +164 -0
  504. package/dist/ui/menu-nav.d.ts +33 -0
  505. package/dist/ui/menu-nav.js +28 -0
  506. package/dist/ui/minimap-canvas.d.ts +145 -0
  507. package/dist/ui/minimap-canvas.js +460 -0
  508. package/dist/ui/notify.d.ts +40 -0
  509. package/dist/ui/notify.js +141 -0
  510. package/dist/ui/orb.d.ts +53 -0
  511. package/dist/ui/orb.js +304 -0
  512. package/dist/ui/overlay.d.ts +213 -0
  513. package/dist/ui/overlay.js +394 -0
  514. package/dist/ui/padnav.d.ts +53 -0
  515. package/dist/ui/padnav.js +146 -0
  516. package/dist/ui/perf.d.ts +130 -0
  517. package/dist/ui/perf.js +329 -0
  518. package/dist/ui/rotate-card.d.ts +54 -0
  519. package/dist/ui/rotate-card.js +97 -0
  520. package/dist/ui/stack.d.ts +128 -0
  521. package/dist/ui/stack.js +312 -0
  522. package/dist/ui/styles.d.ts +13 -0
  523. package/dist/ui/styles.js +200 -0
  524. package/dist/ui/text-scale.d.ts +67 -0
  525. package/dist/ui/text-scale.js +102 -0
  526. package/dist/ui/theme.d.ts +70 -0
  527. package/dist/ui/theme.js +98 -0
  528. package/dist/ui/toast.d.ts +23 -0
  529. package/dist/ui/toast.js +46 -0
  530. package/dist/ui/tooltip.d.ts +89 -0
  531. package/dist/ui/tooltip.js +333 -0
  532. package/dist/ui/widgets-2.d.ts +134 -0
  533. package/dist/ui/widgets-2.js +399 -0
  534. package/dist/ui/widgets-3.d.ts +91 -0
  535. package/dist/ui/widgets-3.js +212 -0
  536. package/dist/ui/widgets.d.ts +34 -0
  537. package/dist/ui/widgets.js +50 -0
  538. package/dist/ui/world-panel/index.d.ts +5 -0
  539. package/dist/ui/world-panel/index.js +5 -0
  540. package/dist/ui/world-panel/layout.d.ts +38 -0
  541. package/dist/ui/world-panel/layout.js +68 -0
  542. package/dist/ui/world-panel/paint.d.ts +96 -0
  543. package/dist/ui/world-panel/paint.js +136 -0
  544. package/dist/ui/world-panel/panel.d.ts +235 -0
  545. package/dist/ui/world-panel/panel.js +762 -0
  546. package/dist/ui/world-panel/wgsl.d.ts +10 -0
  547. package/dist/ui/world-panel/wgsl.js +52 -0
  548. package/dist/ui/world-panel/widgets.d.ts +207 -0
  549. package/dist/ui/world-panel/widgets.js +569 -0
  550. package/dist/voxel/chunks.d.ts +77 -0
  551. package/dist/voxel/chunks.js +149 -0
  552. package/dist/voxel/grid.d.ts +84 -0
  553. package/dist/voxel/grid.js +223 -0
  554. package/dist/voxel/index.d.ts +22 -0
  555. package/dist/voxel/index.js +7 -0
  556. package/dist/voxel/mesher-worker.d.ts +14 -0
  557. package/dist/voxel/mesher-worker.js +47 -0
  558. package/dist/voxel/mesher.d.ts +73 -0
  559. package/dist/voxel/mesher.js +306 -0
  560. package/dist/voxel/ray.d.ts +32 -0
  561. package/dist/voxel/ray.js +73 -0
  562. package/dist/voxel/wgsl.d.ts +16 -0
  563. package/dist/voxel/wgsl.js +28 -0
  564. package/dist/voxel/worker-client.d.ts +79 -0
  565. package/dist/voxel/worker-client.js +122 -0
  566. package/package.json +177 -3
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Flipbook (ws/ergo-2d): frame timing over a list of texture sub-rectangles. Pure: no GPU, no
3
+ * allocation in `update`. A 2D game keeps one per animated sprite, calls `update(dt)` each tick
4
+ * and hands `uv` to its `DrawParams.uv`.
5
+ */
6
+ /**
7
+ * The `UvRect`s of a grid atlas's cells, row-major from the top left (`cols × rows` cells); with
8
+ * `indices`, only those cells in that order. Throws when `inset` is set without `width` and
9
+ * `height`. Allocates: call it at load time.
10
+ */
11
+ export function atlasFrames(atlas, indices) {
12
+ const { cols, rows } = atlas;
13
+ const inset = atlas.inset ?? 0;
14
+ let du = 0;
15
+ let dv = 0;
16
+ if (inset !== 0) {
17
+ const { width, height } = atlas;
18
+ if (!(width > 0) || !(height > 0)) {
19
+ throw new Error('atlasFrames: inset needs the atlas width and height in texels');
20
+ }
21
+ du = inset / width;
22
+ dv = inset / height;
23
+ }
24
+ const n = indices ? indices.length : cols * rows;
25
+ const out = [];
26
+ for (let k = 0; k < n; k++) {
27
+ const i = indices ? indices[k] : k;
28
+ const c = i % cols;
29
+ const r = Math.floor(i / cols);
30
+ out.push([c / cols + du, r / rows + dv, (c + 1) / cols - du, (r + 1) / rows - dv]);
31
+ }
32
+ return out;
33
+ }
34
+ /** Make a `Flipbook` over `frames` at `fps`. */
35
+ export function createFlipbook(opts) {
36
+ if (opts.frames.length === 0)
37
+ throw new Error('createFlipbook: no frames');
38
+ let frames = opts.frames;
39
+ let time = 0;
40
+ let index = 0;
41
+ let done = false;
42
+ const book = {
43
+ fps: opts.fps ?? 12,
44
+ loop: opts.loop ?? true,
45
+ get frames() {
46
+ return frames;
47
+ },
48
+ get uv() {
49
+ return frames[index];
50
+ },
51
+ get frame() {
52
+ return index;
53
+ },
54
+ get done() {
55
+ return done;
56
+ },
57
+ update(dt) {
58
+ if (done || !(book.fps > 0))
59
+ return;
60
+ time += dt;
61
+ const total = frames.length / book.fps;
62
+ if (book.loop) {
63
+ if (time >= total)
64
+ time -= total * Math.floor(time / total);
65
+ }
66
+ else if (time >= total) {
67
+ time = total;
68
+ done = true;
69
+ }
70
+ index = Math.min(frames.length - 1, Math.floor(time * book.fps));
71
+ },
72
+ reset() {
73
+ time = 0;
74
+ index = 0;
75
+ done = false;
76
+ },
77
+ play(next) {
78
+ if (next) {
79
+ if (next.length === 0)
80
+ throw new Error('Flipbook.play: no frames');
81
+ frames = next;
82
+ }
83
+ book.reset();
84
+ },
85
+ };
86
+ return book;
87
+ }
@@ -0,0 +1,278 @@
1
+ import type { Camera } from './camera.js';
2
+ import type { InstanceList } from './instance-list.js';
3
+ import { Lights } from './lights.js';
4
+ import { type MeshLod } from './lod.js';
5
+ import type { Material } from './material.js';
6
+ import type { Mesh, MeshBounds, MeshRange } from './mesh.js';
7
+ import type { SceneTarget } from './scene-target.js';
8
+ import { Transform } from './transform.js';
9
+ /**
10
+ * Floats per instance in `InstanceBatch.params`: the instance format after its 3×4 matrix
11
+ * (`INSTANCE_FLOATS` − 12): `uvRect` (4), `tint` (4), `params` (4), `emissive`, `flags`,
12
+ * `size.x`, `size.y`. `writeInstanceParams` fills one from an `InstanceParams`.
13
+ */
14
+ export declare const INSTANCE_PARAM_FLOATS = 16;
15
+ /**
16
+ * Many instances of one mesh and material submitted at once (`frame.meshes`): `count` 3×4
17
+ * row-major world matrices in `matrices` (12 floats each, `Transform.world`'s layout) and,
18
+ * optionally, their `INSTANCE_PARAM_FLOATS` of params each in `params` (null or absent: the
19
+ * defaults, white tint, full uv, the mesh's shadow flags, size from the matrix columns). The
20
+ * renderer copies both straight into its instance upload. `bounds`, when given, is one
21
+ * world-space sphere for the whole batch: the camera culls the batch with one test and never
22
+ * per instance; without it each instance is culled by `mesh.bounds` through its matrix. The
23
+ * batch is one sort key (its `order`, then its first instance's depth) and one draw. An
24
+ * `InstanceList` is one.
25
+ */
26
+ export interface InstanceBatch {
27
+ /** Instances to draw (the first `count` of `matrices` / `params`). */
28
+ count: number;
29
+ /** `count` × 12 floats (at least). */
30
+ matrices: Float32Array;
31
+ /** `count` × `INSTANCE_PARAM_FLOATS` floats, or null for the defaults. */
32
+ params?: Float32Array | null;
33
+ /** One world-space sphere for the batch, or null to cull per instance. */
34
+ bounds?: MeshBounds | null;
35
+ /** Layer mask of every instance, matched against `camera.layers`. Default 1. */
36
+ layerBits?: number;
37
+ /** Sort key, as `InstanceParams.order`. Default 0. */
38
+ order?: number;
39
+ /** Draw into the sun's shadow map; default: the mesh is not in `VERTEX_LAYOUT_2D`. */
40
+ castShadow?: boolean;
41
+ /**
42
+ * Each instance's previous-frame matrix (`count` × 12 floats, index for index with
43
+ * `matrices`), or null (ws/render-7). Drawn into a target with a velocity attachment by a
44
+ * material with `aux`, the batch then writes per-instance motion through the renderer's
45
+ * shared previous-matrix lane; without it the instances report camera motion only. A LOD
46
+ * `InstanceList` made with `velocity` carries its own.
47
+ */
48
+ prevMatrices?: Float32Array | null;
49
+ }
50
+ /**
51
+ * Write the `INSTANCE_PARAM_FLOATS` of one instance (its fields after the matrix) at float
52
+ * `o` of `dst` from `p`, with `sizeX`, `sizeY` as its `size` (`VSOut.size`: a transform's
53
+ * scale.xy). Same defaults as `frame.mesh`: uv 0,0,1,1, white tint, zero params and emissive,
54
+ * `packInstanceFlags(receiveShadow, layers)`.
55
+ */
56
+ export declare function writeInstanceParams(dst: Float32Array, o: number, p: InstanceParams, sizeX?: number, sizeY?: number): void;
57
+ /**
58
+ * Index into `InstanceParams.params` of the skin palette slot (`params.w`): the convention
59
+ * `engine_skin` reads and the skin harness and glTF skins write. A constant, not a layout change.
60
+ */
61
+ export declare const SKIN_PARAM = 3;
62
+ /**
63
+ * Per-draw instance fields other than placement. A draw placed by a `Transform` takes these;
64
+ * `DrawParams` adds the 2D placement (x, y, w, h, rotation). Reuse the object across frames.
65
+ */
66
+ export interface InstanceParams {
67
+ /** Linear RGBA multiplier (HDR allowed). Default white. */
68
+ tint?: ArrayLike<number>;
69
+ /** Sub-rectangle of the texture: u0, v0, u1, v1. Default 0,0,1,1. */
70
+ uv?: ArrayLike<number>;
71
+ /**
72
+ * Free per-instance vec4 for custom materials (`in.params`). Convention: a skinned draw names
73
+ * its `SkinPalette` slot in `params[SKIN_PARAM]` (`params.w`, read as `u32` by `engine_skin`);
74
+ * the other three stay the material's.
75
+ */
76
+ params?: ArrayLike<number>;
77
+ /** Emissive strength (`in.emissive`); the built-in sprite writes colour × this to bloom. */
78
+ emissive?: number;
79
+ /**
80
+ * Draw this instance into the sun's shadow map when `frame.lights.sun.shadow` is set and the
81
+ * material is opaque. Default: true for meshes in a 3D vertex layout, false for 2D sprites
82
+ * and quads (`VERTEX_LAYOUT_2D`), so a 2D scene never renders a shadow pass.
83
+ */
84
+ castShadow?: boolean;
85
+ /**
86
+ * Set false to mark the instance as not receiving the sun's shadow: instance flag bit 0
87
+ * (`in.flags & 1u`) is set and a material may skip `engine_shadow` for it. The engine's
88
+ * `engine_lambert` does not read the flag. Default true (flag bit clear).
89
+ */
90
+ receiveShadow?: boolean;
91
+ /**
92
+ * This draw's own uniform block (f32s, copied at call time) for a material created with
93
+ * `perDrawUniforms`. Lets many instances share one material, each with its own uniforms.
94
+ */
95
+ uniforms?: ArrayLike<number>;
96
+ /**
97
+ * Layer membership mask (u32). The draw is skipped when `layers & camera.layers` is 0.
98
+ * Default 1. A camera without `layers` sees every layer. Its low `INSTANCE_LAYER_BITS` also
99
+ * ride the instance flags (bits 1..23), so a light whose `layers` share no bit skips it.
100
+ */
101
+ layers?: number;
102
+ /**
103
+ * Sort key. Draws render by `order`, then submission order, so leaving it at the default 0
104
+ * keeps plain submission order. With depth on it is still the first key (see the renderer).
105
+ */
106
+ order?: number;
107
+ /**
108
+ * Draw only the indices `[first, first + count)` of the mesh (ws/render-4): a sub-mesh of a
109
+ * file, one of `mesh.ranges`. Instances batch per (mesh, material, range). Indexed meshes
110
+ * only; ignored by `frame.meshes` batches and lists.
111
+ */
112
+ range?: MeshRange;
113
+ }
114
+ /** Parameters for one instanced draw. Reuse the object across frames to avoid garbage. */
115
+ export interface DrawParams extends InstanceParams {
116
+ /** Position (logical px). For the built-in quad this is the centre. */
117
+ x: number;
118
+ y: number;
119
+ /** Scale. For the quad: size in logical px. Default 1. */
120
+ w?: number;
121
+ h?: number;
122
+ /** Radians, clockwise on screen (y is down). */
123
+ rotation?: number;
124
+ }
125
+ /**
126
+ * Something that draws itself inside the scene pass (particles, custom pipelines).
127
+ * `prepare` runs once per frame before the scene pass (compute work, uploads);
128
+ * `draw` runs in draw order inside the scene pass, which has the colour targets of
129
+ * `renderer.sceneTargets(blend, frame.auxKey)` (HDR colour, HDR emissive, then the target's aux
130
+ * attachments) and `@group(0)` = engine globals.
131
+ * When the camera asks for depth the pass also has a depth attachment
132
+ * (`frame.depthFormat`), and the drawable's pipeline must declare a matching `depthStencil`.
133
+ *
134
+ * Depth hook (ws/render-hooks): a drawable with `readsDepth` set makes the renderer split the
135
+ * view's scene pass at the opaque/blended boundary when the camera has `depthTest`: the opaque
136
+ * draws end their pass, the depth attachment is copied into the target's `depthCopy`, every
137
+ * hooked drawable's `afterOpaque(encoder, view)` runs (the same encoder, between the passes),
138
+ * and the blended draws follow in a second pass that loads everything. `readsDepth` is the
139
+ * flag; a drawable may set it without an `afterOpaque` (it then reads `view.target.depthCopy`
140
+ * itself in `draw`). Without `depthTest` (`ortho2d`), or on a target whose depth cannot be
141
+ * copied, nothing splits and `afterOpaque` never fires; the drawable keeps its fallback.
142
+ */
143
+ export interface Drawable {
144
+ prepare?(encoder: GPUCommandEncoder, frame: Frame): void;
145
+ draw(pass: GPURenderPassEncoder, frame: Frame): void;
146
+ /** Ask for this frame's opaque depth before `draw` (see above). Default off. */
147
+ readsDepth?: boolean;
148
+ /** Runs between the opaque and blended passes of each view that split for this drawable. */
149
+ afterOpaque?(encoder: GPUCommandEncoder, view: ViewInfo): void;
150
+ }
151
+ /**
152
+ * What `Drawable.afterOpaque` gets: the view's camera and target, the sampleable copy of the
153
+ * opaque depth (`depthCopy`, `frame.depthFormat`, the whole target; `depthView` is its `'2d'`
154
+ * view) and the viewport the view draws into (target px). Valid until the view's blended pass
155
+ * ends; the copy is overwritten by the next view that splits into the same target.
156
+ */
157
+ export interface ViewInfo {
158
+ camera: Camera;
159
+ target: SceneTarget;
160
+ depthCopy: GPUTexture;
161
+ depthView: GPUTextureView;
162
+ viewport: {
163
+ x: number;
164
+ y: number;
165
+ width: number;
166
+ height: number;
167
+ };
168
+ }
169
+ /** Hooks the renderer exposes to Frame (kept internal). */
170
+ export interface FrameSink {
171
+ /**
172
+ * `t` places the draw when given; otherwise `p` is a `DrawParams`. `bounds` is the mesh-space
173
+ * sphere the draw is frustum-culled by (through its instance matrix), or null for a draw that
174
+ * is never culled (sprites). `lod` is the chain the renderer picks `mesh` from per view
175
+ * (`frame.mesh` with a `MeshLod`; `mesh` is then its first level).
176
+ */
177
+ pushInstance(material: Material, mesh: Mesh, t: Transform | null, p: DrawParams | InstanceParams, bounds: MeshBounds | null, lod?: MeshLod | null): void;
178
+ /**
179
+ * A batch of `mesh` with `material` (`frame.meshes` / `frame.list`); `bounds` is the mesh's
180
+ * sphere for per-instance culling when the batch gives none. `list` is the retained list
181
+ * the batch is, if any (its instances live in its own buffer). `lod` is the chain each
182
+ * instance picks its level from per view (ws/render-6; `mesh` is then its first level).
183
+ */
184
+ pushBatch(material: Material, mesh: Mesh, batch: InstanceBatch, bounds: MeshBounds | null, list: InstanceList | null, lod?: MeshLod | null): void;
185
+ pushDrawable(d: Drawable, order: number, layers: number): void;
186
+ pushPrePass(fn: (encoder: GPUCommandEncoder) => void): void;
187
+ readonly defaultSprite: Material;
188
+ readonly quad: Mesh;
189
+ }
190
+ /**
191
+ * Per-frame draw recorder. Obtained from `renderer.beginFrame()`; the same object is reused
192
+ * every frame. Draws render sorted by `order` (default 0), then call order; consecutive draws
193
+ * with the same material, mesh and uniforms merge into one instanced draw call. `meshes` draws
194
+ * a typed-array batch and `list` a retained `InstanceList`, each as one unit.
195
+ */
196
+ export declare class Frame {
197
+ private readonly sink;
198
+ readonly logicalWidth: number;
199
+ readonly logicalHeight: number;
200
+ /** Seconds since renderer start (or whatever the caller passed to beginFrame). */
201
+ time: number;
202
+ /** Seconds since last frame. */
203
+ dt: number;
204
+ /** Linear clear colour for the HDR colour target. */
205
+ readonly clearColor: GPUColorDict;
206
+ /**
207
+ * Depth attachment format of this frame's scene pass, or null when the camera has no depth
208
+ * (the 2D path). Set by the renderer before `prepare`/`draw` run.
209
+ */
210
+ depthFormat: GPUTextureFormat | null;
211
+ /**
212
+ * Aux key (`SceneTarget.auxKey`: bit 0 rough-metal, bit 1 velocity) of the target this view's
213
+ * scene pass draws into; 0 for a plain target. Set by the renderer with `depthFormat`. A
214
+ * drawable keys its pipelines on it and builds them with `renderer.sceneTargets(blend,
215
+ * frame.auxKey)` (ws/render-10).
216
+ */
217
+ auxKey: number;
218
+ /**
219
+ * The frame's lights, uploaded as `EngineLights` (`@group(0) @binding(2)`) with every view.
220
+ * Defaults to an unlit block (ambient 1, no sun, no points), so materials that read it draw
221
+ * their albedo unchanged until the game sets it. Mutate it or assign another `Lights`; the
222
+ * object persists across frames (it is not reset by `beginFrame`).
223
+ */
224
+ lights: Lights;
225
+ constructor(sink: FrameSink, logicalWidth: number, logicalHeight: number);
226
+ clear(r: number, g: number, b: number, a?: number): void;
227
+ /**
228
+ * Draw a quad with `material` (default: built-in white sprite), placed by `DrawParams`
229
+ * (x, y = centre, w, h = size, rotation) or by a `Transform` (the quad spans -0.5..0.5 in
230
+ * its local space, so the transform's scale is the size).
231
+ */
232
+ sprite(material: Material | null, p: DrawParams): void;
233
+ sprite(material: Material | null, t: Transform, p?: InstanceParams): void;
234
+ /**
235
+ * Draw `mesh` with `material`, placed by `DrawParams` (x, y, w, h, rotation) or a `Transform`.
236
+ * The draw carries `mesh.bounds` through its instance matrix, so a camera with `cull` on
237
+ * skips it when the sphere is outside the frustum (sprites are never culled).
238
+ *
239
+ * Given a `MeshLod` (ws/render-5), each view picks one of its `meshes` for the instance from
240
+ * the projected height of its sphere (`meshes[0].bounds`) against `thresholdsPx`, times
241
+ * `camera.lodBias`, with `renderer.lodHysteresis` keyed on the `Transform` (or the
242
+ * `DrawParams` object), so pass a stable one; instances of a level sort together and draw
243
+ * as one instanced call per (level, material). `renderer.stats.lodCounts[i]` counts them.
244
+ *
245
+ * Placed by a `Transform` with an `aux` material into a velocity target (ws/render-8), the
246
+ * draw writes the object's own motion: the renderer keeps the transform's world matrix per
247
+ * view and passes last view's as the previous one (zero motion on its first view).
248
+ */
249
+ mesh(mesh: Mesh | MeshLod, material: Material, p: DrawParams): void;
250
+ mesh(mesh: Mesh | MeshLod, material: Material, t: Transform, p?: InstanceParams): void;
251
+ /**
252
+ * Draw `batch.count` instances of `mesh` with `material` from typed arrays (`InstanceBatch`):
253
+ * the bulk path for many things that change every frame. One sort key and one draw call;
254
+ * culled as one sphere when `batch.bounds` is given, else per instance by `mesh.bounds`.
255
+ * Throws when `matrices` or `params` are too short for `count`.
256
+ *
257
+ * Given a `MeshLod` (ws/render-6), each instance picks its level per view as `frame.mesh`
258
+ * does (the sphere of `meshes[0].bounds` through its matrix, the level memory kept per view
259
+ * and instance index) and the batch draws one instanced call per non-empty level.
260
+ */
261
+ meshes(mesh: Mesh | MeshLod, material: Material, batch: InstanceBatch): void;
262
+ /**
263
+ * Draw a retained `InstanceList` (`renderer.createInstanceList`): its instances live in their
264
+ * own GPU buffer, uploaded only where `set` / `remove` changed them since the last frame.
265
+ * Culled as one sphere (`list.bounds`), one draw call. A list made with a `MeshLod`
266
+ * (ws/render-6) picks a level per instance and view, and its instances are copied into the
267
+ * frame's upload bucketed by level (one draw per non-empty level) instead of drawn from its
268
+ * own buffer.
269
+ */
270
+ list(list: InstanceList): void;
271
+ /**
272
+ * Insert a custom drawable (e.g. a particle system) at this point in the draw order, with
273
+ * sort key `order` (default 0) and layer mask `layers` (default 1).
274
+ */
275
+ drawable(d: Drawable, order?: number, layers?: number): void;
276
+ /** Run `fn` before the scene pass (offscreen passes, compute). Pass a stable function. */
277
+ prePass(fn: (encoder: GPUCommandEncoder) => void): void;
278
+ }
@@ -0,0 +1,174 @@
1
+ import { Lights, packInstanceFlags } from './lights.js';
2
+ import { isMeshLod } from './lod.js';
3
+ import { Transform } from './transform.js';
4
+ /**
5
+ * Floats per instance in `InstanceBatch.params`: the instance format after its 3×4 matrix
6
+ * (`INSTANCE_FLOATS` − 12): `uvRect` (4), `tint` (4), `params` (4), `emissive`, `flags`,
7
+ * `size.x`, `size.y`. `writeInstanceParams` fills one from an `InstanceParams`.
8
+ */
9
+ export const INSTANCE_PARAM_FLOATS = 16;
10
+ /**
11
+ * Write the `INSTANCE_PARAM_FLOATS` of one instance (its fields after the matrix) at float
12
+ * `o` of `dst` from `p`, with `sizeX`, `sizeY` as its `size` (`VSOut.size`: a transform's
13
+ * scale.xy). Same defaults as `frame.mesh`: uv 0,0,1,1, white tint, zero params and emissive,
14
+ * `packInstanceFlags(receiveShadow, layers)`.
15
+ */
16
+ export function writeInstanceParams(dst, o, p, sizeX = 1, sizeY = 1) {
17
+ const uv = p.uv;
18
+ dst[o++] = uv ? uv[0] : 0;
19
+ dst[o++] = uv ? uv[1] : 0;
20
+ dst[o++] = uv ? uv[2] : 1;
21
+ dst[o++] = uv ? uv[3] : 1;
22
+ const t = p.tint;
23
+ dst[o++] = t ? t[0] : 1;
24
+ dst[o++] = t ? t[1] : 1;
25
+ dst[o++] = t ? t[2] : 1;
26
+ dst[o++] = t ? (t[3] ?? 1) : 1;
27
+ const q = p.params;
28
+ dst[o++] = q ? q[0] : 0;
29
+ dst[o++] = q ? (q[1] ?? 0) : 0;
30
+ dst[o++] = q ? (q[2] ?? 0) : 0;
31
+ dst[o++] = q ? (q[3] ?? 0) : 0;
32
+ dst[o++] = p.emissive ?? 0;
33
+ dst[o++] = packInstanceFlags(p.receiveShadow !== false, p.layers ?? 1);
34
+ dst[o++] = sizeX;
35
+ dst[o] = sizeY;
36
+ }
37
+ /**
38
+ * Index into `InstanceParams.params` of the skin palette slot (`params.w`): the convention
39
+ * `engine_skin` reads and the skin harness and glTF skins write. A constant, not a layout change.
40
+ */
41
+ export const SKIN_PARAM = 3;
42
+ const NO_PARAMS = Object.freeze({});
43
+ /**
44
+ * Per-frame draw recorder. Obtained from `renderer.beginFrame()`; the same object is reused
45
+ * every frame. Draws render sorted by `order` (default 0), then call order; consecutive draws
46
+ * with the same material, mesh and uniforms merge into one instanced draw call. `meshes` draws
47
+ * a typed-array batch and `list` a retained `InstanceList`, each as one unit.
48
+ */
49
+ export class Frame {
50
+ sink;
51
+ logicalWidth;
52
+ logicalHeight;
53
+ /** Seconds since renderer start (or whatever the caller passed to beginFrame). */
54
+ time = 0;
55
+ /** Seconds since last frame. */
56
+ dt = 0;
57
+ /** Linear clear colour for the HDR colour target. */
58
+ clearColor = { r: 0, g: 0, b: 0, a: 1 };
59
+ /**
60
+ * Depth attachment format of this frame's scene pass, or null when the camera has no depth
61
+ * (the 2D path). Set by the renderer before `prepare`/`draw` run.
62
+ */
63
+ depthFormat = null;
64
+ /**
65
+ * Aux key (`SceneTarget.auxKey`: bit 0 rough-metal, bit 1 velocity) of the target this view's
66
+ * scene pass draws into; 0 for a plain target. Set by the renderer with `depthFormat`. A
67
+ * drawable keys its pipelines on it and builds them with `renderer.sceneTargets(blend,
68
+ * frame.auxKey)` (ws/render-10).
69
+ */
70
+ auxKey = 0;
71
+ /**
72
+ * The frame's lights, uploaded as `EngineLights` (`@group(0) @binding(2)`) with every view.
73
+ * Defaults to an unlit block (ambient 1, no sun, no points), so materials that read it draw
74
+ * their albedo unchanged until the game sets it. Mutate it or assign another `Lights`; the
75
+ * object persists across frames (it is not reset by `beginFrame`).
76
+ */
77
+ lights = new Lights();
78
+ constructor(sink, logicalWidth, logicalHeight) {
79
+ this.sink = sink;
80
+ this.logicalWidth = logicalWidth;
81
+ this.logicalHeight = logicalHeight;
82
+ }
83
+ clear(r, g, b, a = 1) {
84
+ const c = this.clearColor;
85
+ c.r = r;
86
+ c.g = g;
87
+ c.b = b;
88
+ c.a = a;
89
+ }
90
+ sprite(material, a, b) {
91
+ const m = material ?? this.sink.defaultSprite;
92
+ const q = this.sink.quad;
93
+ if (a instanceof Transform)
94
+ this.sink.pushInstance(m, q, a, b ?? NO_PARAMS, null);
95
+ else
96
+ this.sink.pushInstance(m, q, null, a, null);
97
+ }
98
+ mesh(mesh, material, a, b) {
99
+ let lod = null;
100
+ let m;
101
+ if (isMeshLod(mesh)) {
102
+ lod = mesh;
103
+ const first = mesh.meshes[0];
104
+ if (!first)
105
+ throw new Error('frame.mesh: MeshLod has no meshes');
106
+ m = first;
107
+ }
108
+ else {
109
+ m = mesh;
110
+ }
111
+ const bounds = m.bounds;
112
+ if (a instanceof Transform)
113
+ this.sink.pushInstance(material, m, a, b ?? NO_PARAMS, bounds, lod);
114
+ else
115
+ this.sink.pushInstance(material, m, null, a, bounds, lod);
116
+ }
117
+ /**
118
+ * Draw `batch.count` instances of `mesh` with `material` from typed arrays (`InstanceBatch`):
119
+ * the bulk path for many things that change every frame. One sort key and one draw call;
120
+ * culled as one sphere when `batch.bounds` is given, else per instance by `mesh.bounds`.
121
+ * Throws when `matrices` or `params` are too short for `count`.
122
+ *
123
+ * Given a `MeshLod` (ws/render-6), each instance picks its level per view as `frame.mesh`
124
+ * does (the sphere of `meshes[0].bounds` through its matrix, the level memory kept per view
125
+ * and instance index) and the batch draws one instanced call per non-empty level.
126
+ */
127
+ meshes(mesh, material, batch) {
128
+ if (batch.count <= 0)
129
+ return;
130
+ let lod = null;
131
+ let m;
132
+ if (isMeshLod(mesh)) {
133
+ lod = mesh;
134
+ const first = mesh.meshes[0];
135
+ if (!first)
136
+ throw new Error('frame.meshes: MeshLod has no meshes');
137
+ m = first;
138
+ }
139
+ else {
140
+ m = mesh;
141
+ }
142
+ if (batch.matrices.length < batch.count * 12) {
143
+ throw new Error(`frame.meshes: matrices holds ${batch.matrices.length} floats for ${batch.count} instances`);
144
+ }
145
+ if (batch.params && batch.params.length < batch.count * INSTANCE_PARAM_FLOATS) {
146
+ throw new Error(`frame.meshes: params holds ${batch.params.length} floats for ${batch.count} instances`);
147
+ }
148
+ this.sink.pushBatch(material, m, batch, m.bounds, null, lod);
149
+ }
150
+ /**
151
+ * Draw a retained `InstanceList` (`renderer.createInstanceList`): its instances live in their
152
+ * own GPU buffer, uploaded only where `set` / `remove` changed them since the last frame.
153
+ * Culled as one sphere (`list.bounds`), one draw call. A list made with a `MeshLod`
154
+ * (ws/render-6) picks a level per instance and view, and its instances are copied into the
155
+ * frame's upload bucketed by level (one draw per non-empty level) instead of drawn from its
156
+ * own buffer.
157
+ */
158
+ list(list) {
159
+ if (list.count <= 0)
160
+ return;
161
+ this.sink.pushBatch(list.material, list.mesh, list, null, list, list.lod);
162
+ }
163
+ /**
164
+ * Insert a custom drawable (e.g. a particle system) at this point in the draw order, with
165
+ * sort key `order` (default 0) and layer mask `layers` (default 1).
166
+ */
167
+ drawable(d, order = 0, layers = 1) {
168
+ this.sink.pushDrawable(d, order, layers);
169
+ }
170
+ /** Run `fn` before the scene pass (offscreen passes, compute). Pass a stable function. */
171
+ prePass(fn) {
172
+ this.sink.pushPrePass(fn);
173
+ }
174
+ }
@@ -0,0 +1,54 @@
1
+ import { type BindingDesc, BindingSet } from './bindings.js';
2
+ import { type RenderBlendMode } from './blend.js';
3
+ import type { TextureLike } from './texture.js';
4
+ export interface FullscreenPassDesc extends BindingDesc {
5
+ label: string;
6
+ /**
7
+ * WGSL appended after the fullscreen prelude. Must define
8
+ * `@fragment fn fs_main(in: FullscreenIn) -> @location(0) vec4f` (or a struct for MRT).
9
+ * Bindings live in `@group(0)` following the convention in `bindings.ts`.
10
+ */
11
+ wgsl: string;
12
+ /** Colour target formats. */
13
+ targets: GPUTextureFormat[];
14
+ blend?: RenderBlendMode | GPUBlendState;
15
+ fragmentEntry?: string;
16
+ }
17
+ export interface FullscreenEncodeOptions {
18
+ /** Clear colour; omit to clear to transparent black, `null` to load existing contents. */
19
+ clear?: GPUColor | null;
20
+ /** Use an explicit bind group (see `createBindGroup`) instead of the managed one. */
21
+ bindGroup?: GPUBindGroup;
22
+ blendConstant?: GPUColor;
23
+ /** Timestamp writes for this pass (see `GpuTimer.pass`). */
24
+ timestampWrites?: GPURenderPassTimestampWrites;
25
+ /**
26
+ * Draw into this part of `target` only (texture px): viewport and scissor. Pair it with
27
+ * `clear: null`, since a clear covers the whole attachment (ws/xr-post: one eye of a layer).
28
+ */
29
+ viewport?: {
30
+ x: number;
31
+ y: number;
32
+ width: number;
33
+ height: number;
34
+ };
35
+ }
36
+ /**
37
+ * A fragment shader run over a whole render target. Used by the post stack, procedural
38
+ * texture generation and game passes (e.g. a fluid sim into a render target).
39
+ */
40
+ export declare class FullscreenPass {
41
+ readonly label: string;
42
+ readonly pipeline: GPURenderPipeline;
43
+ readonly bindings: BindingSet | null;
44
+ private readonly colorAttachment;
45
+ private readonly passDesc;
46
+ constructor(device: GPUDevice, desc: FullscreenPassDesc, sampler: GPUSampler, defaultView: GPUTextureView);
47
+ setUniforms(data: BufferSource, byteOffset?: number): void;
48
+ setTexture(slot: number, tex: TextureLike | GPUTextureView): void;
49
+ /** Create a bind group for a fixed set of input views. Cache the result (e.g. per resize). */
50
+ createBindGroup(views: readonly GPUTextureView[]): GPUBindGroup;
51
+ /** Record the pass into `encoder`, drawing into `target` (single colour attachment). */
52
+ encode(encoder: GPUCommandEncoder, target: GPUTextureView, opts?: FullscreenEncodeOptions): void;
53
+ destroy(): void;
54
+ }
@@ -0,0 +1,91 @@
1
+ import { BindingSet, hasBindings } from './bindings.js';
2
+ import { blendState } from './blend.js';
3
+ import { createShaderModule, WGSL_FULLSCREEN_PRELUDE } from './wgsl.js';
4
+ /**
5
+ * A fragment shader run over a whole render target. Used by the post stack, procedural
6
+ * texture generation and game passes (e.g. a fluid sim into a render target).
7
+ */
8
+ export class FullscreenPass {
9
+ label;
10
+ pipeline;
11
+ bindings;
12
+ colorAttachment;
13
+ passDesc;
14
+ constructor(device, desc, sampler, defaultView) {
15
+ this.label = desc.label;
16
+ this.bindings = hasBindings(desc)
17
+ ? new BindingSet(device, { ...desc, visibility: GPUShaderStage.FRAGMENT }, sampler, defaultView, `pass:${desc.label}`)
18
+ : null;
19
+ const code = `${WGSL_FULLSCREEN_PRELUDE}\n// ---- pass: ${desc.label} ----\n${desc.wgsl}`;
20
+ const module = createShaderModule(device, code, `pass:${desc.label}`);
21
+ const blend = typeof desc.blend === 'string' || desc.blend === undefined
22
+ ? blendState(desc.blend ?? 'opaque')
23
+ : desc.blend;
24
+ this.pipeline = device.createRenderPipeline({
25
+ label: `pass:${desc.label}`,
26
+ layout: device.createPipelineLayout({
27
+ bindGroupLayouts: this.bindings ? [this.bindings.layout] : [],
28
+ }),
29
+ vertex: { module, entryPoint: 'vs_fullscreen' },
30
+ fragment: {
31
+ module,
32
+ entryPoint: desc.fragmentEntry ?? 'fs_main',
33
+ targets: desc.targets.map((format) => ({ format, blend })),
34
+ },
35
+ primitive: { topology: 'triangle-list' },
36
+ });
37
+ this.colorAttachment = {
38
+ view: defaultView,
39
+ loadOp: 'clear',
40
+ storeOp: 'store',
41
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
42
+ };
43
+ this.passDesc = { label: `pass:${desc.label}`, colorAttachments: [this.colorAttachment] };
44
+ }
45
+ setUniforms(data, byteOffset = 0) {
46
+ if (!this.bindings)
47
+ throw new Error(`pass ${this.label}: no uniforms declared`);
48
+ this.bindings.setUniforms(data, byteOffset);
49
+ }
50
+ setTexture(slot, tex) {
51
+ if (!this.bindings)
52
+ throw new Error(`pass ${this.label}: no textures declared`);
53
+ this.bindings.setTexture(slot, tex);
54
+ }
55
+ /** Create a bind group for a fixed set of input views. Cache the result (e.g. per resize). */
56
+ createBindGroup(views) {
57
+ if (!this.bindings)
58
+ throw new Error(`pass ${this.label}: no bindings declared`);
59
+ return this.bindings.createGroup(views);
60
+ }
61
+ /** Record the pass into `encoder`, drawing into `target` (single colour attachment). */
62
+ encode(encoder, target, opts = {}) {
63
+ const ca = this.colorAttachment;
64
+ ca.view = target;
65
+ if (opts.clear === null) {
66
+ ca.loadOp = 'load';
67
+ }
68
+ else {
69
+ ca.loadOp = 'clear';
70
+ ca.clearValue = opts.clear ?? { r: 0, g: 0, b: 0, a: 0 };
71
+ }
72
+ this.passDesc.timestampWrites = opts.timestampWrites;
73
+ const pass = encoder.beginRenderPass(this.passDesc);
74
+ pass.setPipeline(this.pipeline);
75
+ const vp = opts.viewport;
76
+ if (vp) {
77
+ pass.setViewport(vp.x, vp.y, vp.width, vp.height, 0, 1);
78
+ pass.setScissorRect(vp.x, vp.y, vp.width, vp.height);
79
+ }
80
+ const group = opts.bindGroup ?? this.bindings?.bindGroup;
81
+ if (group)
82
+ pass.setBindGroup(0, group);
83
+ if (opts.blendConstant)
84
+ pass.setBlendConstant(opts.blendConstant);
85
+ pass.draw(3);
86
+ pass.end();
87
+ }
88
+ destroy() {
89
+ this.bindings?.destroy();
90
+ }
91
+ }