@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,15 @@
1
+ /**
2
+ * Depth-projected box decal. The vertex shader places the unit box; the fragment shader
3
+ * reconstructs the world position under each pixel from the previous frame's depth copy
4
+ * (`inv_view_proj × (ndc, depth)`), maps it into the box, rejects what falls outside, samples
5
+ * the atlas by the local xy and fades by the local z edge, the surface's facing (its normal
6
+ * from `dpdx`/`dpdy` of the reconstructed position against the box axis) and the age.
7
+ */
8
+ export declare const WGSL_DECAL_BOX = "\nstruct EngineGlobals {\n logicalSize: vec2f,\n targetSize: vec2f,\n time: f32,\n dt: f32,\n _pad: vec2f,\n};\n@group(0) @binding(0) var<uniform> globals: EngineGlobals;\nstruct EngineCamera {\n view: mat4x4f,\n proj: mat4x4f,\n view_proj: mat4x4f,\n camera_pos: vec4f,\n viewport: vec4f,\n view_index: u32,\n _pad0: u32, _pad1: u32, _pad2: u32,\n inv_view_proj: mat4x4f,\n prev_view_proj: mat4x4f,\n prev_view: mat4x4f,\n jitter: vec4f,\n};\n@group(0) @binding(1) var<uniform> camera: EngineCamera;\n\nstruct DecalParams {\n inv_view_proj: mat4x4f,\n // normal_bias, fade_edge, offset, multiply (1 = multiply blend)\n shape: vec4f,\n // fade at age 0, fade at age 1, pad, pad\n fade: vec4f,\n};\n@group(1) @binding(0) var<uniform> decal: DecalParams;\n@group(1) @binding(1) var decal_sampler: sampler;\n@group(1) @binding(2) var decal_tex: texture_2d<f32>;\n@group(1) @binding(3) var scene_depth: texture_depth_2d;\n\nstruct DecalVertex {\n @location(0) position: vec3f,\n @location(3) m0: vec4f,\n @location(4) m1: vec4f,\n @location(5) m2: vec4f,\n @location(6) uv_rect: vec4f,\n @location(7) color: vec4f,\n @location(8) life: vec4f,\n};\n\nstruct DecalFrame {\n origin: vec3f,\n ax: vec3f,\n ay: vec3f,\n az: vec3f,\n normal: vec3f,\n};\n\n// The rows of the world \u2192 local matrix are axis_i / scale_i and -dot(axis_i, origin) / scale_i:\n// local \u2192 world is origin + sum(axis_i * scale_i * local_i).\nfn decal_frame(m0: vec4f, m1: vec4f, m2: vec4f) -> DecalFrame {\n var f: DecalFrame;\n let s0 = 1.0 / max(dot(m0.xyz, m0.xyz), 1e-12);\n let s1 = 1.0 / max(dot(m1.xyz, m1.xyz), 1e-12);\n let s2 = 1.0 / max(dot(m2.xyz, m2.xyz), 1e-12);\n f.ax = m0.xyz * s0;\n f.ay = m1.xyz * s1;\n f.az = m2.xyz * s2;\n f.origin = -(f.ax * m0.w + f.ay * m1.w + f.az * m2.w);\n f.normal = normalize(m2.xyz);\n return f;\n}\n\nstruct FragOut {\n @location(0) color: vec4f,\n @location(1) emissive: vec4f,\n};\n\nfn decal_out(c: vec4f, alpha: f32) -> FragOut {\n var o: FragOut;\n if (decal.shape.w > 0.5) {\n o.color = vec4f(mix(vec3f(1.0), c.rgb, alpha), 1.0);\n o.emissive = vec4f(1.0);\n } else {\n o.color = vec4f(c.rgb, alpha);\n o.emissive = vec4f(0.0);\n }\n return o;\n}\n\nfn decal_age_fade(life: vec4f) -> f32 {\n return mix(decal.fade.x, decal.fade.y, clamp(life.x, 0.0, 1.0));\n}\n\nstruct BoxOut {\n @builtin(position) clip: vec4f,\n @location(0) @interpolate(flat) m0: vec4f,\n @location(1) @interpolate(flat) m1: vec4f,\n @location(2) @interpolate(flat) m2: vec4f,\n @location(3) @interpolate(flat) uv_rect: vec4f,\n @location(4) @interpolate(flat) color: vec4f,\n @location(5) @interpolate(flat) life: vec4f,\n @location(6) @interpolate(flat) normal: vec3f,\n};\n\n@vertex fn vs(v: DecalVertex) -> BoxOut {\n let f = decal_frame(v.m0, v.m1, v.m2);\n let world = f.origin + f.ax * v.position.x + f.ay * v.position.y + f.az * v.position.z;\n var o: BoxOut;\n o.clip = camera.view_proj * vec4f(world, 1.0);\n o.m0 = v.m0;\n o.m1 = v.m1;\n o.m2 = v.m2;\n o.uv_rect = v.uv_rect;\n o.color = v.color;\n o.life = v.life;\n o.normal = f.normal;\n return o;\n}\n\n@fragment fn fs(in: BoxOut) -> FragOut {\n let dims = vec2i(textureDimensions(scene_depth));\n let px = clamp(vec2i(in.clip.xy), vec2i(0), dims - vec2i(1));\n let d = textureLoad(scene_depth, px, 0);\n if (d >= 1.0) { discard; }\n let vp = camera.viewport;\n let ndc = vec2f(\n (in.clip.x - vp.x) / vp.z * 2.0 - 1.0,\n 1.0 - (in.clip.y - vp.y) / vp.w * 2.0);\n let wp = decal.inv_view_proj * vec4f(ndc, d, 1.0);\n let world = wp.xyz / wp.w;\n let w4 = vec4f(world, 1.0);\n let local = vec3f(dot(in.m0, w4), dot(in.m1, w4), dot(in.m2, w4));\n if (any(abs(local) > vec3f(0.5))) { discard; }\n // Surface normal from the reconstructed position, turned towards the camera.\n let n0 = normalize(cross(dpdx(world), dpdy(world)));\n let n = select(-n0, n0, dot(n0, camera.camera_pos.xyz - world) >= 0.0);\n if (dot(n, in.normal) < decal.shape.x) { discard; }\n let uv = in.uv_rect.xy + vec2f(local.x + 0.5, 0.5 - local.y) * in.uv_rect.zw;\n let c = textureSample(decal_tex, decal_sampler, uv) * in.color;\n let edge = smoothstep(0.0, max(decal.shape.y, 1e-4), (0.5 - abs(local.z)) * 2.0);\n return decal_out(c, c.a * edge * decal_age_fade(in.life));\n}\n";
9
+ /**
10
+ * Surface quad decal: the unit quad (local xy, z = 0) placed in the decal's frame and lifted
11
+ * along its normal by `decal.shape.z`; the fragment is the atlas × colour × age fade.
12
+ */
13
+ export declare const WGSL_DECAL_QUAD = "\nstruct EngineGlobals {\n logicalSize: vec2f,\n targetSize: vec2f,\n time: f32,\n dt: f32,\n _pad: vec2f,\n};\n@group(0) @binding(0) var<uniform> globals: EngineGlobals;\nstruct EngineCamera {\n view: mat4x4f,\n proj: mat4x4f,\n view_proj: mat4x4f,\n camera_pos: vec4f,\n viewport: vec4f,\n view_index: u32,\n _pad0: u32, _pad1: u32, _pad2: u32,\n inv_view_proj: mat4x4f,\n prev_view_proj: mat4x4f,\n prev_view: mat4x4f,\n jitter: vec4f,\n};\n@group(0) @binding(1) var<uniform> camera: EngineCamera;\n\nstruct DecalParams {\n inv_view_proj: mat4x4f,\n // normal_bias, fade_edge, offset, multiply (1 = multiply blend)\n shape: vec4f,\n // fade at age 0, fade at age 1, pad, pad\n fade: vec4f,\n};\n@group(1) @binding(0) var<uniform> decal: DecalParams;\n@group(1) @binding(1) var decal_sampler: sampler;\n@group(1) @binding(2) var decal_tex: texture_2d<f32>;\n@group(1) @binding(3) var scene_depth: texture_depth_2d;\n\nstruct DecalVertex {\n @location(0) position: vec3f,\n @location(3) m0: vec4f,\n @location(4) m1: vec4f,\n @location(5) m2: vec4f,\n @location(6) uv_rect: vec4f,\n @location(7) color: vec4f,\n @location(8) life: vec4f,\n};\n\nstruct DecalFrame {\n origin: vec3f,\n ax: vec3f,\n ay: vec3f,\n az: vec3f,\n normal: vec3f,\n};\n\n// The rows of the world \u2192 local matrix are axis_i / scale_i and -dot(axis_i, origin) / scale_i:\n// local \u2192 world is origin + sum(axis_i * scale_i * local_i).\nfn decal_frame(m0: vec4f, m1: vec4f, m2: vec4f) -> DecalFrame {\n var f: DecalFrame;\n let s0 = 1.0 / max(dot(m0.xyz, m0.xyz), 1e-12);\n let s1 = 1.0 / max(dot(m1.xyz, m1.xyz), 1e-12);\n let s2 = 1.0 / max(dot(m2.xyz, m2.xyz), 1e-12);\n f.ax = m0.xyz * s0;\n f.ay = m1.xyz * s1;\n f.az = m2.xyz * s2;\n f.origin = -(f.ax * m0.w + f.ay * m1.w + f.az * m2.w);\n f.normal = normalize(m2.xyz);\n return f;\n}\n\nstruct FragOut {\n @location(0) color: vec4f,\n @location(1) emissive: vec4f,\n};\n\nfn decal_out(c: vec4f, alpha: f32) -> FragOut {\n var o: FragOut;\n if (decal.shape.w > 0.5) {\n o.color = vec4f(mix(vec3f(1.0), c.rgb, alpha), 1.0);\n o.emissive = vec4f(1.0);\n } else {\n o.color = vec4f(c.rgb, alpha);\n o.emissive = vec4f(0.0);\n }\n return o;\n}\n\nfn decal_age_fade(life: vec4f) -> f32 {\n return mix(decal.fade.x, decal.fade.y, clamp(life.x, 0.0, 1.0));\n}\n\nstruct QuadOut {\n @builtin(position) clip: vec4f,\n @location(0) uv: vec2f,\n @location(1) @interpolate(flat) color: vec4f,\n @location(2) @interpolate(flat) life: vec4f,\n};\n\n@vertex fn vs(v: DecalVertex) -> QuadOut {\n let f = decal_frame(v.m0, v.m1, v.m2);\n let world = f.origin + f.ax * v.position.x + f.ay * v.position.y + f.normal * decal.shape.z;\n var o: QuadOut;\n o.clip = camera.view_proj * vec4f(world, 1.0);\n o.uv = v.uv_rect.xy + vec2f(v.position.x + 0.5, 0.5 - v.position.y) * v.uv_rect.zw;\n o.color = v.color;\n o.life = v.life;\n return o;\n}\n\n@fragment fn fs(in: QuadOut) -> FragOut {\n let c = textureSample(decal_tex, decal_sampler, in.uv) * in.color;\n return decal_out(c, c.a * decal_age_fade(in.life));\n}\n";
14
+ /** Copies the scene depth into the decals' own `depth32float` texture (fullscreen triangle). */
15
+ export declare const WGSL_DECAL_DEPTH_COPY = "\n@group(0) @binding(0) var src: texture_depth_2d;\n@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {\n let p = vec2f(f32((i << 1u) & 2u), f32(i & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\n@fragment fn fs(@builtin(position) pos: vec4f) -> @builtin(frag_depth) f32 {\n return textureLoad(src, vec2i(pos.xy), 0);\n}\n";
@@ -0,0 +1,173 @@
1
+ import { WGSL_GLOBALS } from '../render/wgsl.js';
2
+ /**
3
+ * Shared by both decal shaders: the params block, the atlas, the depth copy and the instance
4
+ * decode. An instance carries the world → local 3×4 matrix of its unit box (rows `m0..m2`,
5
+ * each `xyz` a scaled axis and `w` the translation), its atlas rect (`u0, v0, du, dv`), its
6
+ * colour and `life` (`x` = age / lifetime, 0 when the decal lives forever). `decal_frame`
7
+ * inverts the rows back into the three world axes (scaled) and the origin, which the vertex
8
+ * shader needs to place the box or quad.
9
+ */
10
+ const DECAL_COMMON = /* wgsl */ `
11
+ struct DecalParams {
12
+ inv_view_proj: mat4x4f,
13
+ // normal_bias, fade_edge, offset, multiply (1 = multiply blend)
14
+ shape: vec4f,
15
+ // fade at age 0, fade at age 1, pad, pad
16
+ fade: vec4f,
17
+ };
18
+ @group(1) @binding(0) var<uniform> decal: DecalParams;
19
+ @group(1) @binding(1) var decal_sampler: sampler;
20
+ @group(1) @binding(2) var decal_tex: texture_2d<f32>;
21
+ @group(1) @binding(3) var scene_depth: texture_depth_2d;
22
+
23
+ struct DecalVertex {
24
+ @location(0) position: vec3f,
25
+ @location(3) m0: vec4f,
26
+ @location(4) m1: vec4f,
27
+ @location(5) m2: vec4f,
28
+ @location(6) uv_rect: vec4f,
29
+ @location(7) color: vec4f,
30
+ @location(8) life: vec4f,
31
+ };
32
+
33
+ struct DecalFrame {
34
+ origin: vec3f,
35
+ ax: vec3f,
36
+ ay: vec3f,
37
+ az: vec3f,
38
+ normal: vec3f,
39
+ };
40
+
41
+ // The rows of the world → local matrix are axis_i / scale_i and -dot(axis_i, origin) / scale_i:
42
+ // local → world is origin + sum(axis_i * scale_i * local_i).
43
+ fn decal_frame(m0: vec4f, m1: vec4f, m2: vec4f) -> DecalFrame {
44
+ var f: DecalFrame;
45
+ let s0 = 1.0 / max(dot(m0.xyz, m0.xyz), 1e-12);
46
+ let s1 = 1.0 / max(dot(m1.xyz, m1.xyz), 1e-12);
47
+ let s2 = 1.0 / max(dot(m2.xyz, m2.xyz), 1e-12);
48
+ f.ax = m0.xyz * s0;
49
+ f.ay = m1.xyz * s1;
50
+ f.az = m2.xyz * s2;
51
+ f.origin = -(f.ax * m0.w + f.ay * m1.w + f.az * m2.w);
52
+ f.normal = normalize(m2.xyz);
53
+ return f;
54
+ }
55
+
56
+ struct FragOut {
57
+ @location(0) color: vec4f,
58
+ @location(1) emissive: vec4f,
59
+ };
60
+
61
+ fn decal_out(c: vec4f, alpha: f32) -> FragOut {
62
+ var o: FragOut;
63
+ if (decal.shape.w > 0.5) {
64
+ o.color = vec4f(mix(vec3f(1.0), c.rgb, alpha), 1.0);
65
+ o.emissive = vec4f(1.0);
66
+ } else {
67
+ o.color = vec4f(c.rgb, alpha);
68
+ o.emissive = vec4f(0.0);
69
+ }
70
+ return o;
71
+ }
72
+
73
+ fn decal_age_fade(life: vec4f) -> f32 {
74
+ return mix(decal.fade.x, decal.fade.y, clamp(life.x, 0.0, 1.0));
75
+ }
76
+ `;
77
+ /**
78
+ * Depth-projected box decal. The vertex shader places the unit box; the fragment shader
79
+ * reconstructs the world position under each pixel from the previous frame's depth copy
80
+ * (`inv_view_proj × (ndc, depth)`), maps it into the box, rejects what falls outside, samples
81
+ * the atlas by the local xy and fades by the local z edge, the surface's facing (its normal
82
+ * from `dpdx`/`dpdy` of the reconstructed position against the box axis) and the age.
83
+ */
84
+ export const WGSL_DECAL_BOX = /* wgsl */ `${WGSL_GLOBALS}${DECAL_COMMON}
85
+ struct BoxOut {
86
+ @builtin(position) clip: vec4f,
87
+ @location(0) @interpolate(flat) m0: vec4f,
88
+ @location(1) @interpolate(flat) m1: vec4f,
89
+ @location(2) @interpolate(flat) m2: vec4f,
90
+ @location(3) @interpolate(flat) uv_rect: vec4f,
91
+ @location(4) @interpolate(flat) color: vec4f,
92
+ @location(5) @interpolate(flat) life: vec4f,
93
+ @location(6) @interpolate(flat) normal: vec3f,
94
+ };
95
+
96
+ @vertex fn vs(v: DecalVertex) -> BoxOut {
97
+ let f = decal_frame(v.m0, v.m1, v.m2);
98
+ let world = f.origin + f.ax * v.position.x + f.ay * v.position.y + f.az * v.position.z;
99
+ var o: BoxOut;
100
+ o.clip = camera.view_proj * vec4f(world, 1.0);
101
+ o.m0 = v.m0;
102
+ o.m1 = v.m1;
103
+ o.m2 = v.m2;
104
+ o.uv_rect = v.uv_rect;
105
+ o.color = v.color;
106
+ o.life = v.life;
107
+ o.normal = f.normal;
108
+ return o;
109
+ }
110
+
111
+ @fragment fn fs(in: BoxOut) -> FragOut {
112
+ let dims = vec2i(textureDimensions(scene_depth));
113
+ let px = clamp(vec2i(in.clip.xy), vec2i(0), dims - vec2i(1));
114
+ let d = textureLoad(scene_depth, px, 0);
115
+ if (d >= 1.0) { discard; }
116
+ let vp = camera.viewport;
117
+ let ndc = vec2f(
118
+ (in.clip.x - vp.x) / vp.z * 2.0 - 1.0,
119
+ 1.0 - (in.clip.y - vp.y) / vp.w * 2.0);
120
+ let wp = decal.inv_view_proj * vec4f(ndc, d, 1.0);
121
+ let world = wp.xyz / wp.w;
122
+ let w4 = vec4f(world, 1.0);
123
+ let local = vec3f(dot(in.m0, w4), dot(in.m1, w4), dot(in.m2, w4));
124
+ if (any(abs(local) > vec3f(0.5))) { discard; }
125
+ // Surface normal from the reconstructed position, turned towards the camera.
126
+ let n0 = normalize(cross(dpdx(world), dpdy(world)));
127
+ let n = select(-n0, n0, dot(n0, camera.camera_pos.xyz - world) >= 0.0);
128
+ if (dot(n, in.normal) < decal.shape.x) { discard; }
129
+ let uv = in.uv_rect.xy + vec2f(local.x + 0.5, 0.5 - local.y) * in.uv_rect.zw;
130
+ let c = textureSample(decal_tex, decal_sampler, uv) * in.color;
131
+ let edge = smoothstep(0.0, max(decal.shape.y, 1e-4), (0.5 - abs(local.z)) * 2.0);
132
+ return decal_out(c, c.a * edge * decal_age_fade(in.life));
133
+ }
134
+ `;
135
+ /**
136
+ * Surface quad decal: the unit quad (local xy, z = 0) placed in the decal's frame and lifted
137
+ * along its normal by `decal.shape.z`; the fragment is the atlas × colour × age fade.
138
+ */
139
+ export const WGSL_DECAL_QUAD = /* wgsl */ `${WGSL_GLOBALS}${DECAL_COMMON}
140
+ struct QuadOut {
141
+ @builtin(position) clip: vec4f,
142
+ @location(0) uv: vec2f,
143
+ @location(1) @interpolate(flat) color: vec4f,
144
+ @location(2) @interpolate(flat) life: vec4f,
145
+ };
146
+
147
+ @vertex fn vs(v: DecalVertex) -> QuadOut {
148
+ let f = decal_frame(v.m0, v.m1, v.m2);
149
+ let world = f.origin + f.ax * v.position.x + f.ay * v.position.y + f.normal * decal.shape.z;
150
+ var o: QuadOut;
151
+ o.clip = camera.view_proj * vec4f(world, 1.0);
152
+ o.uv = v.uv_rect.xy + vec2f(v.position.x + 0.5, 0.5 - v.position.y) * v.uv_rect.zw;
153
+ o.color = v.color;
154
+ o.life = v.life;
155
+ return o;
156
+ }
157
+
158
+ @fragment fn fs(in: QuadOut) -> FragOut {
159
+ let c = textureSample(decal_tex, decal_sampler, in.uv) * in.color;
160
+ return decal_out(c, c.a * decal_age_fade(in.life));
161
+ }
162
+ `;
163
+ /** Copies the scene depth into the decals' own `depth32float` texture (fullscreen triangle). */
164
+ export const WGSL_DECAL_DEPTH_COPY = /* wgsl */ `
165
+ @group(0) @binding(0) var src: texture_depth_2d;
166
+ @vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
167
+ let p = vec2f(f32((i << 1u) & 2u), f32(i & 2u));
168
+ return vec4f(p * 2.0 - 1.0, 0.0, 1.0);
169
+ }
170
+ @fragment fn fs(@builtin(position) pos: vec4f) -> @builtin(frag_depth) f32 {
171
+ return textureLoad(src, vec2i(pos.xy), 0);
172
+ }
173
+ `;
@@ -0,0 +1,216 @@
1
+ import type { Random } from '../core/random.js';
2
+ import type { Drawable, Frame, ViewInfo } from '../render/frame.js';
3
+ import type { Renderer } from '../render/renderer.js';
4
+ import type { TextureLike } from '../render/texture.js';
5
+ /**
6
+ * Floats per decal instance (6 × vec4f = 96 bytes):
7
+ *
8
+ * | floats | WGSL (`DecalVertex`) | content |
9
+ * | --- | --- | --- |
10
+ * | 0..11 | `m0..m2` @location(3..5) | world → local 3×4 matrix, row-major (unit box) |
11
+ * | 12..15 | `uv_rect` @location(6) | atlas rect: u0, v0, du, dv |
12
+ * | 16..19 | `color` @location(7) | linear RGBA multiplier |
13
+ * | 20..23 | `life` @location(8) | age / lifetime (0 when infinite), lifetime, 0, 0 |
14
+ */
15
+ export declare const DECAL_INSTANCE_FLOATS = 24;
16
+ /** Floats in the decals' params block: `inv_view_proj` (16), `shape` (4), `fade` (4). */
17
+ export declare const DECAL_PARAMS_FLOATS = 24;
18
+ /** How decals mix with what is under them. */
19
+ export type DecalBlend = 'alpha' | 'multiply' | 'additive';
20
+ /** `box` projects through the scene depth, `quad` lies on the surface, `auto` picks by camera. */
21
+ export type DecalMode = 'auto' | 'box' | 'quad';
22
+ export interface DecalsOptions {
23
+ /** Decals kept at once; the oldest is overwritten when full. Default 256. */
24
+ capacity?: number;
25
+ /** The atlas every decal samples. */
26
+ texture: TextureLike;
27
+ /** Atlas grid (`tile` indexes it row-major). Default 1×1. */
28
+ atlas?: {
29
+ columns: number;
30
+ rows: number;
31
+ };
32
+ /** Default `alpha`. */
33
+ blend?: DecalBlend;
34
+ /** Alpha over normalised age (0 → 1). Default `[1, 0]`; ignored for infinite lifetimes. */
35
+ fade?: [number, number];
36
+ /** Default lifetime, seconds. Default Infinity. */
37
+ lifetime?: number;
38
+ /** Default `auto`: `box` under a depth camera, else `quad`. */
39
+ mode?: DecalMode;
40
+ /** Quad mode: lift along the normal, world units. Default 0.01. */
41
+ offset?: number;
42
+ /** Box mode: reject surfaces whose normal's cosine against the decal's is below this. Default 0.3. */
43
+ normalBias?: number;
44
+ /** Box mode: fade over this share of the box's half depth at each end. Default 0.2. */
45
+ fadeEdge?: number;
46
+ /**
47
+ * Box mode: read this frame's opaque depth from the renderer's depth hook
48
+ * (`Drawable.readsDepth`, ws/fx-4). Default true (false for `mode: 'quad'`, which reads no
49
+ * depth). `false` is the fallback: `prepare` copies the
50
+ * scene depth before the scene pass, so the box samples the **previous frame's** depth (a
51
+ * moving surface trails by a frame). The fallback is also taken automatically when the
52
+ * renderer cannot copy its depth (an adopted XR depth without `COPY_SRC`).
53
+ */
54
+ readsDepth?: boolean;
55
+ /**
56
+ * The stream `rotation: 'random'` and `tile: 'random'` draw from (ws/fx-4). Default: a fork
57
+ * of the fx module default (`FX_DEFAULT_SEED`), named by creation order.
58
+ */
59
+ random?: Random;
60
+ }
61
+ /** One decal to place (`Decals.add`). */
62
+ export interface DecalDesc {
63
+ x: number;
64
+ y: number;
65
+ z: number;
66
+ /** Surface normal the decal faces along (need not be unit). */
67
+ nx: number;
68
+ ny: number;
69
+ nz: number;
70
+ /** Width and height (and box depth), world units. */
71
+ size: number;
72
+ /** Spin about the normal, radians, or `'random'` (drawn from `Decals.random`). Default 0. */
73
+ rotation?: number | 'random';
74
+ /** Atlas tile, row-major, or `'random'` (any tile of the atlas, from `Decals.random`). Default 0. */
75
+ tile?: number | 'random';
76
+ /** Linear RGBA multiplier. Default white. */
77
+ color?: ArrayLike<number>;
78
+ /** Seconds, overriding the system default. */
79
+ lifetime?: number;
80
+ }
81
+ /**
82
+ * Projected decals: an atlas stamped onto scenery, every live decal in one instanced draw.
83
+ * `frame.drawable(decals, order)` draws them; `update(dt)` ages them.
84
+ *
85
+ * Two implementations behind one API. **Box** (under a depth camera): each decal is a unit box
86
+ * in its own frame; the fragment shader reconstructs the world position under the pixel from a
87
+ * copy of the scene depth, rejects what is outside the box and samples the atlas by the local
88
+ * xy, so the decal wraps whatever it covers (depth test and write off). The depth is this
89
+ * frame's opaque depth, from the renderer's depth hook (`readsDepth`, `afterOpaque`), so a decal
90
+ * on a moving surface stays on it. With `readsDepth: false` (or a target whose depth cannot be
91
+ * copied) the fallback copy is taken in `prepare`, before the scene pass, and holds the
92
+ * **previous frame's** depth: a decal placed this frame appears next frame. **Quad**
93
+ * (no depth, or `mode: 'quad'`): a camera-independent quad lifted along the normal by `offset`
94
+ * (depth test on, write off).
95
+ *
96
+ * Handles are monotonic ids; `remove` marks a decal dead and the next `update` (or `prepare`)
97
+ * compacts the live ones to the front, keeping the id → slot map. Nothing allocates per frame
98
+ * when nothing died.
99
+ */
100
+ export declare class Decals implements Drawable {
101
+ readonly capacity: number;
102
+ readonly mode: DecalMode;
103
+ /** The mode the last `prepare` resolved (`auto` → by the frame's depth); null before. */
104
+ activeMode: 'box' | 'quad' | null;
105
+ /** Default lifetime for `add` (seconds). Live. */
106
+ lifetime: number;
107
+ /** Quad lift along the normal. Live. */
108
+ offset: number;
109
+ /** Box: minimum cosine between the surface and decal normals. Live. */
110
+ normalBias: number;
111
+ /** Box: share of the half depth faded at each end. Live. */
112
+ fadeEdge: number;
113
+ /** Alpha at age 0 and at the lifetime. Live. */
114
+ readonly fade: [number, number];
115
+ /** Box: take this frame's depth from the renderer's hook (see `DecalsOptions`). Live. */
116
+ readsDepth: boolean;
117
+ /** The stream `'random'` rotations and tiles draw from. Live. */
118
+ random: Random;
119
+ private readonly renderer;
120
+ private readonly device;
121
+ private readonly columns;
122
+ private readonly rows;
123
+ private readonly multiply;
124
+ private readonly data;
125
+ private readonly ages;
126
+ private readonly lives;
127
+ private readonly ids;
128
+ private readonly alive;
129
+ private readonly slotOf;
130
+ private live;
131
+ /** Slots in use, dead ones included until the next compaction. */
132
+ private used;
133
+ private dirty;
134
+ private nextId;
135
+ private readonly params;
136
+ private readonly paramsBuffer;
137
+ private readonly instanceBuffer;
138
+ private readonly box;
139
+ private readonly quad;
140
+ private readonly layout;
141
+ private readonly sampler;
142
+ private readonly texture;
143
+ private readonly dummyDepth;
144
+ private group;
145
+ private readonly boxModule;
146
+ private readonly quadModule;
147
+ private readonly pipelineLayout;
148
+ private readonly blend;
149
+ /**
150
+ * Pipelines per mode: depth format (null: none) × the view target's aux key, built on first
151
+ * use from `renderer.sceneTargets` (ws/render-10).
152
+ */
153
+ private readonly boxPipelines;
154
+ private readonly quadPipelines;
155
+ private readonly copyLayout;
156
+ private readonly copyPipeline;
157
+ private readonly copyAtt;
158
+ private readonly copyPass;
159
+ private copyTex;
160
+ private copySrc;
161
+ private copySrcGroup;
162
+ /** The box draw has a depth copy to read this frame. */
163
+ private depthReady;
164
+ /** The bind group over the fallback copy (`copyTex`). */
165
+ private copyGroup;
166
+ /** The renderer's `depthCopy` view the hook group was made for. */
167
+ private hookView;
168
+ private hookGroup;
169
+ private readonly noDepthGroup;
170
+ constructor(renderer: Renderer, opts: DecalsOptions);
171
+ /** Live decals. */
172
+ get count(): number;
173
+ /** Whether `handle` is still live. */
174
+ has(handle: number): boolean;
175
+ /**
176
+ * Place a decal at (`x`, `y`, `z`) facing along (`nx`, `ny`, `nz`), `size` wide. Returns its
177
+ * handle. When the system is full the oldest live decal is overwritten.
178
+ */
179
+ add(d: DecalDesc): number;
180
+ /** Remove a decal; false when the handle is not live. Compacted on the next `update`. */
181
+ remove(handle: number): boolean;
182
+ /** Remove every decal. */
183
+ clear(): void;
184
+ /** Age every decal by `dt` seconds, expire the ones past their lifetime and compact. */
185
+ update(dt: number): void;
186
+ /** Age of the decal at `handle`, seconds; -1 when not live. */
187
+ ageOf(handle: number): number;
188
+ /**
189
+ * Whether the box draw is waiting on the renderer's depth hook this frame: `readsDepth` on and
190
+ * the target's depth copyable. Otherwise `prepare` takes the fallback copy.
191
+ */
192
+ private get hooked();
193
+ /**
194
+ * Resolve the mode for this frame, upload the params block and the live instances. Box mode
195
+ * waits for the depth hook (`afterOpaque`), or takes the fallback copy of last frame's depth.
196
+ * Called by the renderer once per frame. No allocation.
197
+ */
198
+ prepare(encoder: GPUCommandEncoder, frame?: Frame): void;
199
+ /**
200
+ * The renderer's depth hook (`readsDepth`): bind this frame's opaque depth copy. The bind
201
+ * group is rebuilt only when the renderer's copy changes (a resize).
202
+ */
203
+ afterOpaque(_encoder: GPUCommandEncoder, view: ViewInfo): void;
204
+ /** Draw every live decal in one instanced draw (nothing in box mode until depth exists). */
205
+ draw(pass: GPURenderPassEncoder, frame?: Frame): void;
206
+ destroy(): void;
207
+ private writeInstance;
208
+ /** Move the live slots to the front, in order, and remap their handles. */
209
+ private compact;
210
+ /** Full and compact: drop slot 0 (the oldest) and shift the rest down. */
211
+ private dropOldest;
212
+ /** Copy the scene depth into our own texture; false when there is none yet. */
213
+ private copyDepth;
214
+ private makeGroup;
215
+ private pipelineFor;
216
+ }