@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,115 @@
1
+ /**
2
+ * Transforms: position, rotation and scale, with an optional parent, cached as a 3×4 world
3
+ * matrix. The renderer copies that matrix straight into the instance buffer
4
+ * (`frame.sprite(material, transform)` / `frame.mesh(mesh, material, transform)`).
5
+ *
6
+ * Conventions:
7
+ * - The world matrix is **3×4, row-major**: 12 floats `[r0 | tx, r1 | ty, r2 | tz]`, so
8
+ * `world = (dot(row0, p), dot(row1, p), dot(row2, p))` with `p = (x, y, z, 1)`. The fourth
9
+ * row of an affine matrix is always `(0, 0, 0, 1)` and is not stored.
10
+ * - The local matrix is `T · R · S` (scale, then rotate, then translate); a child's world
11
+ * matrix is `parent.world · local`.
12
+ * - Rotation is a unit quaternion `(x, y, z, w)`. The 2D case is a rotation about +Z:
13
+ * `rotation = a` (radians) gives the same matrix as `DrawParams.rotation`, clockwise on
14
+ * screen when y points down. A pure Z rotation is built from `Math.cos/sin(a)` directly, so
15
+ * it matches the `DrawParams` path exactly.
16
+ * - 2D: keep `z = 0`, rotate about Z only, and `scale.z = 1`.
17
+ *
18
+ * Setters mark the transform dirty; `world` recomputes lazily, at most once per change (or
19
+ * per parent change). Nothing allocates after construction.
20
+ */
21
+ /** Floats in a 3×4 world matrix. */
22
+ export declare const MATRIX3X4_FLOATS = 12;
23
+ /**
24
+ * Write the 3×4 row-major matrix of a 2D draw (`DrawParams` x, y, w, h, rotation) at
25
+ * `out[o..o+12)`. This is the instance matrix `frame.sprite(material, params)` builds: the
26
+ * built-in quad spans -0.5..0.5, so `w, h` are its size. No allocation.
27
+ */
28
+ export declare function writeMatrix2d(out: Float32Array, o: number, x: number, y: number, w: number, h: number, rotation: number): void;
29
+ /**
30
+ * `out = a · b` for 3×4 affine matrices (implicit last row `0 0 0 1`). `out` may alias
31
+ * neither input. No allocation.
32
+ */
33
+ export declare function multiplyMatrix3x4(out: Float32Array, a: ArrayLike<number>, b: ArrayLike<number>): void;
34
+ /** Read-only view of a vector a transform owns. */
35
+ export interface ReadonlyVec3 {
36
+ readonly x: number;
37
+ readonly y: number;
38
+ readonly z: number;
39
+ }
40
+ export interface ReadonlyQuat extends ReadonlyVec3 {
41
+ readonly w: number;
42
+ }
43
+ export declare class Transform {
44
+ private readonly _position;
45
+ private readonly _rotation;
46
+ private readonly _scale;
47
+ /** Angle about Z when the rotation was set as one (exact cos/sin path), else NaN. */
48
+ private angleZ;
49
+ private _parent;
50
+ private readonly local;
51
+ private readonly _world;
52
+ private localDirty;
53
+ private worldDirty;
54
+ /** Bumps whenever `world` is recomputed; children compare it to their cached value. */
55
+ private worldVersion;
56
+ private parentVersion;
57
+ /** Setter calls on this transform (ws/audio-4); `changed` adds the ancestors'. */
58
+ private _changed;
59
+ constructor(opts?: {
60
+ x?: number;
61
+ y?: number;
62
+ z?: number;
63
+ rotation?: number;
64
+ scaleX?: number;
65
+ scaleY?: number;
66
+ scaleZ?: number;
67
+ parent?: Transform | null;
68
+ });
69
+ get position(): ReadonlyVec3;
70
+ /**
71
+ * A monotonic counter bumped by every setter on this transform or an ancestor (ws/audio-4),
72
+ * so a reader can skip `world` when nothing moved (`Voice.follow` does). It does not say
73
+ * whether `world` is stale; the dirty flags still do that.
74
+ */
75
+ get changed(): number;
76
+ get quaternion(): ReadonlyQuat;
77
+ get scale(): ReadonlyVec3;
78
+ setPosition(x: number, y: number, z?: number): this;
79
+ /**
80
+ * Set the local scale. One argument scales all three axes (`setScale(2)` is `2, 2, 2`, so a
81
+ * 3D node keeps its shape; a flat 2D quad has no depth, so it draws the same). Two arguments
82
+ * are the 2D form: `z` stays 1. Three set each axis.
83
+ */
84
+ setScale(s: number): this;
85
+ setScale(x: number, y: number, z?: number): this;
86
+ /**
87
+ * The 2D rotation: radians about +Z (clockwise on screen with y down, like
88
+ * `DrawParams.rotation`). Reading it after `setQuaternion` returns the quaternion's angle
89
+ * about Z, which is only meaningful for a pure Z rotation.
90
+ */
91
+ get rotation(): number;
92
+ set rotation(radians: number);
93
+ /** Set a 3D rotation as a quaternion (normalised here). */
94
+ setQuaternion(x: number, y: number, z: number, w: number): this;
95
+ /** Rotation from an axis (need not be unit length) and an angle in radians. */
96
+ setAxisAngle(ax: number, ay: number, az: number, radians: number): this;
97
+ /**
98
+ * Set the local matrix from a 3×4 row-major matrix at `m[o..o+12)` (an animation socket, a
99
+ * node world matrix). The 12 floats are copied as they are, so `world` is exact; `position`,
100
+ * `quaternion` and `scale` are decomposed from it (translation column, column lengths, the
101
+ * rotation of the normalised columns; a mirrored matrix carries the sign on `scale.z`), so a
102
+ * later setter rebuilds the nearest `T · R · S`. No allocation.
103
+ */
104
+ setMatrix(m: ArrayLike<number>, o?: number): this;
105
+ get parent(): Transform | null;
106
+ set parent(p: Transform | null);
107
+ /** Local matrix (3×4 row-major), recomputed if a setter ran since the last read. */
108
+ get localMatrix(): Float32Array;
109
+ /**
110
+ * World matrix (3×4 row-major): the parent's world times the local matrix. Cached; it
111
+ * recomputes only after a setter on this transform or a change anywhere up the chain.
112
+ */
113
+ get world(): Float32Array;
114
+ private updateLocal;
115
+ }
@@ -0,0 +1,318 @@
1
+ /**
2
+ * Transforms: position, rotation and scale, with an optional parent, cached as a 3×4 world
3
+ * matrix. The renderer copies that matrix straight into the instance buffer
4
+ * (`frame.sprite(material, transform)` / `frame.mesh(mesh, material, transform)`).
5
+ *
6
+ * Conventions:
7
+ * - The world matrix is **3×4, row-major**: 12 floats `[r0 | tx, r1 | ty, r2 | tz]`, so
8
+ * `world = (dot(row0, p), dot(row1, p), dot(row2, p))` with `p = (x, y, z, 1)`. The fourth
9
+ * row of an affine matrix is always `(0, 0, 0, 1)` and is not stored.
10
+ * - The local matrix is `T · R · S` (scale, then rotate, then translate); a child's world
11
+ * matrix is `parent.world · local`.
12
+ * - Rotation is a unit quaternion `(x, y, z, w)`. The 2D case is a rotation about +Z:
13
+ * `rotation = a` (radians) gives the same matrix as `DrawParams.rotation`, clockwise on
14
+ * screen when y points down. A pure Z rotation is built from `Math.cos/sin(a)` directly, so
15
+ * it matches the `DrawParams` path exactly.
16
+ * - 2D: keep `z = 0`, rotate about Z only, and `scale.z = 1`.
17
+ *
18
+ * Setters mark the transform dirty; `world` recomputes lazily, at most once per change (or
19
+ * per parent change). Nothing allocates after construction.
20
+ */
21
+ /** Floats in a 3×4 world matrix. */
22
+ export const MATRIX3X4_FLOATS = 12;
23
+ /**
24
+ * Write the 3×4 row-major matrix of a 2D draw (`DrawParams` x, y, w, h, rotation) at
25
+ * `out[o..o+12)`. This is the instance matrix `frame.sprite(material, params)` builds: the
26
+ * built-in quad spans -0.5..0.5, so `w, h` are its size. No allocation.
27
+ */
28
+ export function writeMatrix2d(out, o, x, y, w, h, rotation) {
29
+ const c = rotation === 0 ? 1 : Math.cos(rotation);
30
+ const s = rotation === 0 ? 0 : Math.sin(rotation);
31
+ out[o] = c * w;
32
+ out[o + 1] = -s * h;
33
+ out[o + 2] = 0;
34
+ out[o + 3] = x;
35
+ out[o + 4] = s * w;
36
+ out[o + 5] = c * h;
37
+ out[o + 6] = 0;
38
+ out[o + 7] = y;
39
+ out[o + 8] = 0;
40
+ out[o + 9] = 0;
41
+ out[o + 10] = 1;
42
+ out[o + 11] = 0;
43
+ }
44
+ /**
45
+ * `out = a · b` for 3×4 affine matrices (implicit last row `0 0 0 1`). `out` may alias
46
+ * neither input. No allocation.
47
+ */
48
+ export function multiplyMatrix3x4(out, a, b) {
49
+ for (let r = 0; r < 3; r++) {
50
+ const a0 = a[r * 4];
51
+ const a1 = a[r * 4 + 1];
52
+ const a2 = a[r * 4 + 2];
53
+ const a3 = a[r * 4 + 3];
54
+ out[r * 4] = a0 * b[0] + a1 * b[4] + a2 * b[8];
55
+ out[r * 4 + 1] = a0 * b[1] + a1 * b[5] + a2 * b[9];
56
+ out[r * 4 + 2] = a0 * b[2] + a1 * b[6] + a2 * b[10];
57
+ out[r * 4 + 3] = a0 * b[3] + a1 * b[7] + a2 * b[11] + a3;
58
+ }
59
+ }
60
+ export class Transform {
61
+ _position = { x: 0, y: 0, z: 0 };
62
+ _rotation = { x: 0, y: 0, z: 0, w: 1 };
63
+ _scale = { x: 1, y: 1, z: 1 };
64
+ /** Angle about Z when the rotation was set as one (exact cos/sin path), else NaN. */
65
+ angleZ = 0;
66
+ _parent = null;
67
+ local = new Float32Array(MATRIX3X4_FLOATS);
68
+ _world = new Float32Array(MATRIX3X4_FLOATS);
69
+ localDirty = true;
70
+ worldDirty = true;
71
+ /** Bumps whenever `world` is recomputed; children compare it to their cached value. */
72
+ worldVersion = 0;
73
+ parentVersion = -1;
74
+ /** Setter calls on this transform (ws/audio-4); `changed` adds the ancestors'. */
75
+ _changed = 0;
76
+ constructor(opts) {
77
+ if (opts) {
78
+ this.setPosition(opts.x ?? 0, opts.y ?? 0, opts.z ?? 0);
79
+ if (opts.rotation)
80
+ this.rotation = opts.rotation;
81
+ this.setScale(opts.scaleX ?? 1, opts.scaleY ?? 1, opts.scaleZ ?? 1);
82
+ if (opts.parent)
83
+ this.parent = opts.parent;
84
+ }
85
+ }
86
+ get position() {
87
+ return this._position;
88
+ }
89
+ /**
90
+ * A monotonic counter bumped by every setter on this transform or an ancestor (ws/audio-4),
91
+ * so a reader can skip `world` when nothing moved (`Voice.follow` does). It does not say
92
+ * whether `world` is stale; the dirty flags still do that.
93
+ */
94
+ get changed() {
95
+ return this._changed + (this._parent ? this._parent.changed : 0);
96
+ }
97
+ get quaternion() {
98
+ return this._rotation;
99
+ }
100
+ get scale() {
101
+ return this._scale;
102
+ }
103
+ setPosition(x, y, z = 0) {
104
+ const p = this._position;
105
+ p.x = x;
106
+ p.y = y;
107
+ p.z = z;
108
+ this._changed++;
109
+ this.localDirty = true;
110
+ return this;
111
+ }
112
+ setScale(x, y, z) {
113
+ const s = this._scale;
114
+ s.x = x;
115
+ s.y = y ?? x;
116
+ s.z = z ?? (y === undefined ? x : 1);
117
+ this._changed++;
118
+ this.localDirty = true;
119
+ return this;
120
+ }
121
+ /**
122
+ * The 2D rotation: radians about +Z (clockwise on screen with y down, like
123
+ * `DrawParams.rotation`). Reading it after `setQuaternion` returns the quaternion's angle
124
+ * about Z, which is only meaningful for a pure Z rotation.
125
+ */
126
+ get rotation() {
127
+ if (!Number.isNaN(this.angleZ))
128
+ return this.angleZ;
129
+ const q = this._rotation;
130
+ return 2 * Math.atan2(q.z, q.w);
131
+ }
132
+ set rotation(radians) {
133
+ this.angleZ = radians;
134
+ const q = this._rotation;
135
+ q.x = 0;
136
+ q.y = 0;
137
+ q.z = Math.sin(radians / 2);
138
+ q.w = Math.cos(radians / 2);
139
+ this._changed++;
140
+ this.localDirty = true;
141
+ }
142
+ /** Set a 3D rotation as a quaternion (normalised here). */
143
+ setQuaternion(x, y, z, w) {
144
+ const len = Math.hypot(x, y, z, w) || 1;
145
+ const q = this._rotation;
146
+ q.x = x / len;
147
+ q.y = y / len;
148
+ q.z = z / len;
149
+ q.w = w / len;
150
+ this.angleZ = Number.NaN;
151
+ this._changed++;
152
+ this.localDirty = true;
153
+ return this;
154
+ }
155
+ /** Rotation from an axis (need not be unit length) and an angle in radians. */
156
+ setAxisAngle(ax, ay, az, radians) {
157
+ const len = Math.hypot(ax, ay, az) || 1;
158
+ const s = Math.sin(radians / 2) / len;
159
+ return this.setQuaternion(ax * s, ay * s, az * s, Math.cos(radians / 2));
160
+ }
161
+ /**
162
+ * Set the local matrix from a 3×4 row-major matrix at `m[o..o+12)` (an animation socket, a
163
+ * node world matrix). The 12 floats are copied as they are, so `world` is exact; `position`,
164
+ * `quaternion` and `scale` are decomposed from it (translation column, column lengths, the
165
+ * rotation of the normalised columns; a mirrored matrix carries the sign on `scale.z`), so a
166
+ * later setter rebuilds the nearest `T · R · S`. No allocation.
167
+ */
168
+ setMatrix(m, o = 0) {
169
+ const l = this.local;
170
+ for (let i = 0; i < MATRIX3X4_FLOATS; i++)
171
+ l[i] = m[o + i];
172
+ const p = this._position;
173
+ p.x = l[3];
174
+ p.y = l[7];
175
+ p.z = l[11];
176
+ const s = this._scale;
177
+ let sx = Math.hypot(l[0], l[4], l[8]);
178
+ let sy = Math.hypot(l[1], l[5], l[9]);
179
+ let sz = Math.hypot(l[2], l[6], l[10]);
180
+ const det = l[0] * (l[5] * l[10] - l[6] * l[9]) -
181
+ l[1] * (l[4] * l[10] - l[6] * l[8]) +
182
+ l[2] * (l[4] * l[9] - l[5] * l[8]);
183
+ if (det < 0)
184
+ sz = -sz;
185
+ s.x = sx;
186
+ s.y = sy;
187
+ s.z = sz;
188
+ sx = sx || 1;
189
+ sy = sy || 1;
190
+ sz = sz || 1;
191
+ // Rotation matrix columns (unit), row-major: r[row][col].
192
+ const r00 = l[0] / sx;
193
+ const r01 = l[1] / sy;
194
+ const r02 = l[2] / sz;
195
+ const r10 = l[4] / sx;
196
+ const r11 = l[5] / sy;
197
+ const r12 = l[6] / sz;
198
+ const r20 = l[8] / sx;
199
+ const r21 = l[9] / sy;
200
+ const r22 = l[10] / sz;
201
+ const q = this._rotation;
202
+ const trace = r00 + r11 + r22;
203
+ if (trace > 0) {
204
+ const w = Math.sqrt(trace + 1) * 0.5;
205
+ const k = 0.25 / w;
206
+ q.x = (r21 - r12) * k;
207
+ q.y = (r02 - r20) * k;
208
+ q.z = (r10 - r01) * k;
209
+ q.w = w;
210
+ }
211
+ else if (r00 > r11 && r00 > r22) {
212
+ const x = Math.sqrt(1 + r00 - r11 - r22) * 0.5;
213
+ const k = 0.25 / x;
214
+ q.x = x;
215
+ q.y = (r01 + r10) * k;
216
+ q.z = (r02 + r20) * k;
217
+ q.w = (r21 - r12) * k;
218
+ }
219
+ else if (r11 > r22) {
220
+ const y = Math.sqrt(1 + r11 - r00 - r22) * 0.5;
221
+ const k = 0.25 / y;
222
+ q.x = (r01 + r10) * k;
223
+ q.y = y;
224
+ q.z = (r12 + r21) * k;
225
+ q.w = (r02 - r20) * k;
226
+ }
227
+ else {
228
+ const z = Math.sqrt(1 + r22 - r00 - r11) * 0.5;
229
+ const k = 0.25 / z;
230
+ q.x = (r02 + r20) * k;
231
+ q.y = (r12 + r21) * k;
232
+ q.z = z;
233
+ q.w = (r10 - r01) * k;
234
+ }
235
+ this.angleZ = Number.NaN;
236
+ this._changed++;
237
+ this.localDirty = false;
238
+ this.worldDirty = true;
239
+ return this;
240
+ }
241
+ get parent() {
242
+ return this._parent;
243
+ }
244
+ set parent(p) {
245
+ for (let q = p; q; q = q._parent) {
246
+ if (q === this)
247
+ throw new Error('Transform: parent cycle');
248
+ }
249
+ this._parent = p;
250
+ this.parentVersion = -1;
251
+ this._changed++;
252
+ this.worldDirty = true;
253
+ }
254
+ /** Local matrix (3×4 row-major), recomputed if a setter ran since the last read. */
255
+ get localMatrix() {
256
+ if (this.localDirty)
257
+ this.updateLocal();
258
+ return this.local;
259
+ }
260
+ /**
261
+ * World matrix (3×4 row-major): the parent's world times the local matrix. Cached; it
262
+ * recomputes only after a setter on this transform or a change anywhere up the chain.
263
+ */
264
+ get world() {
265
+ const p = this._parent;
266
+ if (p) {
267
+ const pw = p.world;
268
+ if (this.localDirty || this.worldDirty || p.worldVersion !== this.parentVersion) {
269
+ multiplyMatrix3x4(this._world, pw, this.localMatrix);
270
+ this.parentVersion = p.worldVersion;
271
+ this.worldDirty = false;
272
+ this.worldVersion++;
273
+ }
274
+ }
275
+ else if (this.localDirty || this.worldDirty) {
276
+ this._world.set(this.localMatrix);
277
+ this.worldDirty = false;
278
+ this.worldVersion++;
279
+ }
280
+ return this._world;
281
+ }
282
+ updateLocal() {
283
+ const m = this.local;
284
+ const s = this._scale;
285
+ const p = this._position;
286
+ if (!Number.isNaN(this.angleZ)) {
287
+ writeMatrix2d(m, 0, p.x, p.y, s.x, s.y, this.angleZ);
288
+ m[10] = s.z;
289
+ m[11] = p.z;
290
+ }
291
+ else {
292
+ const { x, y, z, w } = this._rotation;
293
+ const xx = x * x;
294
+ const yy = y * y;
295
+ const zz = z * z;
296
+ const xy = x * y;
297
+ const xz = x * z;
298
+ const yz = y * z;
299
+ const wx = w * x;
300
+ const wy = w * y;
301
+ const wz = w * z;
302
+ m[0] = (1 - 2 * (yy + zz)) * s.x;
303
+ m[1] = 2 * (xy - wz) * s.y;
304
+ m[2] = 2 * (xz + wy) * s.z;
305
+ m[3] = p.x;
306
+ m[4] = 2 * (xy + wz) * s.x;
307
+ m[5] = (1 - 2 * (xx + zz)) * s.y;
308
+ m[6] = 2 * (yz - wx) * s.z;
309
+ m[7] = p.y;
310
+ m[8] = 2 * (xz - wy) * s.x;
311
+ m[9] = 2 * (yz + wx) * s.y;
312
+ m[10] = (1 - 2 * (xx + yy)) * s.z;
313
+ m[11] = p.z;
314
+ }
315
+ this.localDirty = false;
316
+ this.worldDirty = true;
317
+ }
318
+ }
@@ -0,0 +1,131 @@
1
+ import { type VertexLayout } from './mesh.js';
2
+ /**
3
+ * Create a shader module and surface compile errors with file/line context. Compilation is
4
+ * async in the browser; errors are logged as soon as they are known.
5
+ */
6
+ export declare function createShaderModule(device: GPUDevice, code: string, label: string): GPUShaderModule;
7
+ /**
8
+ * Per-frame engine bindings for every material and drawable, in `@group(0)`:
9
+ *
10
+ * - `@binding(0) globals`: `logicalSize`, `targetSize` (scene target px), `time`, `dt`.
11
+ * - `@binding(1) camera` (the camera block): `view`, `proj`, `view_proj` (world → clip),
12
+ * `camera_pos` (world eye position, w = 1), `viewport` (target px: x, y, w, h),
13
+ * `view_index` (`camera.viewIndex`: 0, or the eye index of an XR view), `inv_view_proj`
14
+ * (clip → world, the inverse of `view_proj`; `camera.invViewProj` on the CPU side),
15
+ * `prev_view_proj` and `prev_view` (last frame's unjittered `view_proj` and `view`) and
16
+ * `jitter` (clip-space dx, dy; the pixel offset x, y).
17
+ */
18
+ export declare const WGSL_GLOBALS = "\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";
19
+ /**
20
+ * The Lambert BRDF for `wgslLightLoop`: `N·L` clamped at 0, the reflected fraction of a light's
21
+ * colour before the albedo (the light's colour × this is what `engine_lambert` returns per light).
22
+ */
23
+ export declare const WGSL_LAMBERT_BRDF = "vec3f(max(dot(normal, l), 0.0))";
24
+ /**
25
+ * Generate the engine light loop as a WGSL function `name(world_pos: vec3f, normal: vec3f,
26
+ * layer_mask: u32${params}) -> vec3f`: the sum over the lights whose `layers` share a bit with
27
+ * `layer_mask` of the light's colour × its attenuation × `brdf`. The sun (× `engine_shadow`),
28
+ * the `(1 - d/radius)²` point falloff and the spot cone (`engine_spot_cone` × the same falloff)
29
+ * are the loop's; the BRDF is the material's.
30
+ *
31
+ * WGSL has no function pointers, so the material supplies `brdf` as a WGSL expression that the
32
+ * loop body inlines once per light kind. In it, `l` is the unit direction from the surface to
33
+ * the light, `normal` and `world_pos` are the function's parameters and `params` (`', v: vec3f,
34
+ * f0: vec3f'` and so on; leading comma) adds whatever else it needs to the signature. The
35
+ * expression must be finite for any `l` (it is multiplied by 0 for lights that do not reach).
36
+ * `WGSL_LIGHTS` instantiates it as `engine_light_accum` with `WGSL_LAMBERT_BRDF`; `WGSL_PBR` as
37
+ * `engine_pbr_accum` with `engine_brdf(...)`. Generate rather than copy: the loop then changes
38
+ * in one place when the block gains a light kind.
39
+ */
40
+ export declare function wgslLightLoop(name: string, brdf: string, params?: string): string;
41
+ /**
42
+ * The lighting block, `@group(0) @binding(2)` (see `Lights` / `lights.ts`), in every material
43
+ * and drawable prelude: `lights.ambient`, `lights.point_count`, `lights.sun_dir` (the way
44
+ * the light travels), `lights.sun_color`, `lights.points[i]` (`position`, `radius`, `color`),
45
+ * `lights.sun_view_proj` (world → sun clip), `lights.shadow_params` (bias, map texel size,
46
+ * enabled, pad), `lights.fog` (rgb, density), `lights.fog_range` (near, far, pad, pad),
47
+ * `lights.spot_count`, `lights.sun_layers` (the sun's layer mask), `lights.point_layers`
48
+ * (`array<vec4u, 4>`: the mask of point `i` is `point_layers[i >> 2u][i & 3u]`) and
49
+ * `lights.spots[i]` (`position`, `radius`, `direction`, `cos_outer`, `color`, `cos_inner`,
50
+ * `layers`). The sun's shadow map (`texture_depth_2d`) and its comparison sampler sit at
51
+ * `@binding(3)` and `@binding(4)`; with no shadow pass a 1×1 depth texture is bound there.
52
+ *
53
+ * Helpers a game may call or ignore: `engine_point_lights(normal, world_pos)` sums the point
54
+ * lights' diffuse (Lambert × a smooth falloff that reaches zero at `radius`), all layers;
55
+ * `engine_spot_cone(cos_theta, cos_outer, cos_inner)` is a spot's cone factor;
56
+ * `engine_instance_layers(flags)` is the instance's layer bits from `VSOut.flags`;
57
+ * `engine_light_accum(world_pos, normal, layer_mask)` sums the sun (× `engine_shadow`), point
58
+ * and spot Lambert terms of every light whose `layers` share a bit with `layer_mask`;
59
+ * `engine_shadow(world_pos)` is the sun's visibility, 0..1 (3×3 PCF over the shadow map; 1
60
+ * outside the map or when there is no shadow pass); `engine_fog(color, world_pos)` blends
61
+ * `color` toward the fog colour by the distance to the camera (linear over `fog_range` when
62
+ * `far > near`, else exponential past `near`; identity when density is 0);
63
+ * `engine_lambert(normal, world_pos)` is ambient + `engine_light_accum` over every layer, so
64
+ * with the default block it returns `vec3f(1.0)` and `albedo * engine_lambert(...)` is unlit;
65
+ * `engine_lambert_layers(normal, world_pos, layer_mask)` is the same against the instance's
66
+ * layers (`engine_instance_layers(in.flags)`), so masked lights skip it.
67
+ *
68
+ * `engine_light_accum` is `wgslLightLoop('engine_light_accum', WGSL_LAMBERT_BRDF)`: the one
69
+ * light loop, generated with a Lambert BRDF; `WGSL_PBR` generates the same loop with its GGX BRDF.
70
+ */
71
+ export declare const WGSL_LIGHTS: string;
72
+ /** Hash / value-noise / fbm helpers available to every material and fullscreen pass. */
73
+ export declare const WGSL_NOISE = "\nfn engine_hash21(p: vec2f) -> f32 {\n var p3 = fract(vec3f(p.x, p.y, p.x) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\nfn engine_hash22(p: vec2f) -> vec2f {\n var p3 = fract(vec3f(p.x, p.y, p.x) * vec3f(0.1031, 0.1030, 0.0973));\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\nfn engine_noise(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n let a = engine_hash21(i);\n let b = engine_hash21(i + vec2f(1.0, 0.0));\n let c = engine_hash21(i + vec2f(0.0, 1.0));\n let d = engine_hash21(i + vec2f(1.0, 1.0));\n return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);\n}\nfn engine_fbm(p: vec2f, octaves: i32) -> f32 {\n var v = 0.0;\n var amp = 0.5;\n var q = p;\n for (var i = 0; i < octaves; i++) {\n v += amp * engine_noise(q);\n q = q * 2.03 + vec2f(17.1, 9.2);\n amp *= 0.5;\n }\n return v;\n}\nfn engine_luma(c: vec3f) -> f32 {\n return dot(c, vec3f(0.2126, 0.7152, 0.0722));\n}\n";
74
+ /** The `SkinPalette` binding inside the material's group: `@group(1) @binding(16)`. */
75
+ export declare const SKIN_PALETTE_BINDING = 16;
76
+ /**
77
+ * GPU skinning, emitted by `materialPrelude` for a layout with `skinned: true` (after
78
+ * `VertexIn`, which it reads). The palette is the material's storage buffer slot 0
79
+ * (`SkinPalette.buffer` passed as `buffers: [palette.buffer]`): a header (`joints` per
80
+ * instance, `instances`, `history`) and `rows`, three `vec4f` rows per joint (row-major 3×4, the layout
81
+ * `anim`'s `skinMatrices` writes), instance after instance. `engine_skin(v, position, normal)`
82
+ * sums the four weighted joint matrices of the vertex (`v.joints`, `v.weights`) for the
83
+ * instance's palette slot `u32(v.params.w)` and applies them to an object-space position and
84
+ * normal, before the instance matrix. A weight of 0 skips the fetch.
85
+ */
86
+ export declare const WGSL_SKIN = "struct EngineSkinPalette {\n joints: u32,\n instances: u32,\n history: u32,\n _pad1: u32,\n rows: array<vec4f>,\n};\n@group(1) @binding(16) var<storage, read> engine_skin_palette: EngineSkinPalette;\nstruct EngineSkinned {\n position: vec3f,\n normal: vec3f,\n};\nfn engine_skin(v: VertexIn, position: vec3f, normal: vec3f) -> EngineSkinned {\n let base = u32(v.params.w) * engine_skin_palette.joints * 3u;\n let p = vec4f(position, 1.0);\n var skinned: EngineSkinned;\n skinned.position = vec3f(0.0);\n skinned.normal = vec3f(0.0);\n for (var k = 0u; k < 4u; k++) {\n let w = v.weights[k];\n if (w == 0.0) { continue; }\n let r = base + v.joints[k] * 3u;\n let r0 = engine_skin_palette.rows[r];\n let r1 = engine_skin_palette.rows[r + 1u];\n let r2 = engine_skin_palette.rows[r + 2u];\n skinned.position += w * vec3f(dot(r0, p), dot(r1, p), dot(r2, p));\n skinned.normal += w * vec3f(dot(r0.xyz, normal), dot(r1.xyz, normal), dot(r2.xyz, normal));\n }\n return skinned;\n}\n// The previous frame's skinned position from the palette's history block (SkinPalette\n// with history), w = 1; w = 0 when the palette keeps none (velocity reads zero).\nfn engine_skin_previous(v: VertexIn, position: vec3f) -> vec4f {\n if (engine_skin_palette.history == 0u) { return vec4f(0.0); }\n let base = (engine_skin_palette.instances + u32(v.params.w)) * engine_skin_palette.joints * 3u;\n let p = vec4f(position, 1.0);\n var out = vec3f(0.0);\n for (var k = 0u; k < 4u; k++) {\n let w = v.weights[k];\n if (w == 0.0) { continue; }\n let r = base + v.joints[k] * 3u;\n out += w * vec3f(dot(engine_skin_palette.rows[r], p), dot(engine_skin_palette.rows[r + 1u], p), dot(engine_skin_palette.rows[r + 2u], p));\n }\n return vec4f(out, 1.0);\n}";
87
+ /**
88
+ * What a material prelude is generated for beyond the vertex layout (ws/render-4): the aux
89
+ * attachments of the target it draws into (`roughMetal`, `velocity`: `FragOut` gains
90
+ * `rough_metal` / `velocity` and `engine_write_aux` fills them) and `prevLane`, a third vertex
91
+ * buffer carrying each instance's previous 3×4 matrix (`InstanceList` with `velocity`), read
92
+ * by `engine_previous_world_position`. Every flag off is the plain prelude.
93
+ */
94
+ export interface PreludeVariant {
95
+ roughMetal?: boolean;
96
+ velocity?: boolean;
97
+ prevLane?: boolean;
98
+ }
99
+ /** The plain variant: what every material compiled with before aux targets. */
100
+ export declare const PLAIN_VARIANT: PreludeVariant;
101
+ /**
102
+ * Three vertex locations in 10..15 the layout's attributes leave free, for the previous-matrix
103
+ * lane (`prevLane`), as `[p0, p1, p2]`.
104
+ */
105
+ export declare function prevLaneLocations(layout: VertexLayout): [number, number, number];
106
+ /** The previous-matrix vertex buffer layout (slot 2) for `layout`: 48 bytes per instance. */
107
+ export declare function prevLaneBufferLayout(layout: VertexLayout): GPUVertexBufferLayout;
108
+ /**
109
+ * Prelude prepended to every material, generated per vertex layout (and `PreludeVariant`).
110
+ * Declares `VertexIn` (the layout's vertex fields plus the 28-float instance: 3×4 world matrix
111
+ * rows `m0..m2`, `uvRect`, `tint`, `params`, `misc` = emissive, flags, size.xy), the default
112
+ * vertex entry `vs_main`, the `VSOut` varyings (`flags` is the instance's flag bits: bit 0 set
113
+ * means `receiveShadow: false`, bits 1..23 are its layers; `tangent` the world-space file
114
+ * tangent, w = 0 without one; `uv1` the second uv set, `uv` without one) and the `FragOut` MRT
115
+ * struct.
116
+ *
117
+ * Helpers: `engine_local_position(v)` / `engine_local_normal(v)` / `engine_local_tangent(v)`
118
+ * (object space; skinned for a `skinned` layout), `engine_world_position(v)`,
119
+ * `engine_previous_world_position(v)` (last frame's, `vec4f`, w = 0 when unknown),
120
+ * `engine_vertex(v)`, `engine_velocity(in)` (screen-space uv motion since last frame, zero
121
+ * without a velocity target) and `engine_write_aux(&o, rough_metal, velocity)` (fills the
122
+ * target's aux outputs, a no-op without them); the lighting block and `engine_lambert` /
123
+ * `engine_point_lights` from `WGSL_LIGHTS`; `WGSL_SKIN` (`engine_skin`, the palette binding)
124
+ * for a skinned layout only. The text for the 2D and 3D layouts does not change with skinning
125
+ * (E-008).
126
+ */
127
+ export declare function materialPrelude(layout: VertexLayout, variant?: PreludeVariant): string;
128
+ /** The material prelude for the 2D vertex layout (what every 2D material compiles with). */
129
+ export declare const WGSL_MATERIAL_PRELUDE: string;
130
+ /** Prelude for fullscreen passes: `vs_fullscreen` emits one triangle covering the target. */
131
+ export declare const WGSL_FULLSCREEN_PRELUDE = "\n\nfn engine_hash21(p: vec2f) -> f32 {\n var p3 = fract(vec3f(p.x, p.y, p.x) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\nfn engine_hash22(p: vec2f) -> vec2f {\n var p3 = fract(vec3f(p.x, p.y, p.x) * vec3f(0.1031, 0.1030, 0.0973));\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\nfn engine_noise(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n let a = engine_hash21(i);\n let b = engine_hash21(i + vec2f(1.0, 0.0));\n let c = engine_hash21(i + vec2f(0.0, 1.0));\n let d = engine_hash21(i + vec2f(1.0, 1.0));\n return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);\n}\nfn engine_fbm(p: vec2f, octaves: i32) -> f32 {\n var v = 0.0;\n var amp = 0.5;\n var q = p;\n for (var i = 0; i < octaves; i++) {\n v += amp * engine_noise(q);\n q = q * 2.03 + vec2f(17.1, 9.2);\n amp *= 0.5;\n }\n return v;\n}\nfn engine_luma(c: vec3f) -> f32 {\n return dot(c, vec3f(0.2126, 0.7152, 0.0722));\n}\n\nstruct FullscreenIn {\n @builtin(position) pos: vec4f,\n @location(0) uv: vec2f,\n};\n@vertex fn vs_fullscreen(@builtin(vertex_index) i: u32) -> FullscreenIn {\n let p = vec2f(f32((i << 1u) & 2u), f32(i & 2u));\n var o: FullscreenIn;\n o.pos = vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n o.uv = vec2f(p.x, 1.0 - p.y);\n return o;\n}\n";