@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,533 @@
1
+ /**
2
+ * The pointer router: every pointing source (mouse, pen, touch, the pad cursor, XR controllers
3
+ * and hands through `XrPointerSource`) becomes a world-space ray through the active camera; the
4
+ * game's `HitTester`s say what each ray hits; the router keeps the nearest hit per pointer and
5
+ * reports `hit`, `hitEnd`, `select` and `secondary`. A game reads the hit and the `select`
6
+ * action; it never sees which device pointed.
7
+ */
8
+ import { Emitter } from '../core/events.js';
9
+ import { ScreenPointers, } from './pointer-sources.js';
10
+ import { createHit, createRay, } from './rays.js';
11
+ const XR_BUTTONS = ['trigger', 'squeeze', 'pinch'];
12
+ /**
13
+ * Routes pointers to hits. Call `update()` once per tick (an `Input` linked with
14
+ * `input.setPointers(router)` calls it from its own `update()`).
15
+ */
16
+ export class PointerRouter {
17
+ /** The built-in source for mouse, pen and touch (attached by `attach`). */
18
+ screen = new ScreenPointers();
19
+ /** Live pointers this tick (empty while blocked). Reused array. */
20
+ pointers = [];
21
+ /** The pointer that moved or pressed most recently, or `null`. */
22
+ primary = null;
23
+ blocked;
24
+ selectAction;
25
+ secondaryAction;
26
+ /**
27
+ * Typed over `unknown` targets, so the router is covariant in `T` (ws/input-12): a
28
+ * `PointerRouter<Target>` is a `PointerRouter<unknown>`, and `EngineCtx<A, S, C, unknown>`
29
+ * takes any typed ctx. `on` narrows the listeners back to `T`.
30
+ */
31
+ events = new Emitter();
32
+ cameraOpt;
33
+ testers = [];
34
+ sources = [];
35
+ tracks = [];
36
+ pool = [];
37
+ tick = 0;
38
+ isBlocked = false;
39
+ /**
40
+ * Live mutes, one entry per `mute()` call: `null` mutes every source (ones added later
41
+ * included), a list mutes those sources. A source is muted while any entry names it.
42
+ */
43
+ mutes = [];
44
+ /** Sources a mute's end just woke: their pointers held through the mute are not new presses. */
45
+ waking = [];
46
+ target = null;
47
+ best = createHit(undefined);
48
+ bestNormal = [0, 0, 0];
49
+ evHit = { pointer: null, hit: null };
50
+ evEnd = { pointer: null, hit: null };
51
+ evSelect = { pointer: null, hit: null };
52
+ evMoved = { pointer: null, hit: null };
53
+ evReleased = { pointer: null, hit: null };
54
+ constructor(opts = {}) {
55
+ this.cameraOpt = opts.camera ?? null;
56
+ this.blocked = opts.blocked ?? (() => false);
57
+ this.selectAction = opts.selectAction ?? 'select';
58
+ this.secondaryAction = opts.secondaryAction ?? 'secondary';
59
+ this.sources.push(this.screen);
60
+ for (const s of opts.sources ?? [])
61
+ this.sources.push(s);
62
+ for (const t of opts.testers ?? [])
63
+ this.testers.push(t);
64
+ }
65
+ /** The camera rays go through now. */
66
+ get camera() {
67
+ const c = this.cameraOpt;
68
+ return typeof c === 'function' ? c() : c;
69
+ }
70
+ /** Set the camera, or a getter read each tick. */
71
+ set camera(c) {
72
+ this.cameraOpt = c;
73
+ }
74
+ /** The primary pointer's hit, or `null`. */
75
+ get hit() {
76
+ return this.primary?.hit ?? null;
77
+ }
78
+ on(type, fn) {
79
+ return this.events.on(type, fn);
80
+ }
81
+ /**
82
+ * Add a hit tester; returns its remover. The nearest hit over all testers wins; equal
83
+ * distances go to the tester added first.
84
+ */
85
+ addTester(t) {
86
+ this.testers.push(t);
87
+ return () => {
88
+ const i = this.testers.indexOf(t);
89
+ if (i >= 0)
90
+ this.testers.splice(i, 1);
91
+ };
92
+ }
93
+ /** Add a pointer source (a `PadCursor`, an `XrPointerSource`); returns its remover. */
94
+ addSource(s) {
95
+ this.sources.push(s);
96
+ if (this.target)
97
+ s.attach?.(this.target);
98
+ return () => {
99
+ const i = this.sources.indexOf(s);
100
+ if (i < 0)
101
+ return;
102
+ this.sources.splice(i, 1);
103
+ s.detach?.();
104
+ };
105
+ }
106
+ /**
107
+ * Mute pointer sources (ws/input-11): a muted source is still polled, but its pointers are
108
+ * dropped before routing, so they hit nothing and fire nothing. With no argument every source
109
+ * is muted, the screen source and sources added later included. Samples marked `synthetic`
110
+ * (the pointers `Input.replayPointer` dispatches) are never muted, so a replay keeps its own
111
+ * pointers while the real ones are silenced. A pointer that holds select or secondary when
112
+ * its source is muted is released on the next tick: `hitEnd`, then `released` with `hit:
113
+ * null` (it let go over nothing, as a cancel), and `held` reads false.
114
+ *
115
+ * Returns the remover (ws/api-core): it lifts this mute only, so a game's mute and a replay's
116
+ * mute do not clear each other; a source stays muted while another mute names it. Calling it
117
+ * twice, or after `unmute()`, does nothing.
118
+ */
119
+ mute(sources) {
120
+ const entry = sources ? sources.slice() : null;
121
+ this.mutes.push(entry);
122
+ return () => {
123
+ const i = this.mutes.indexOf(entry);
124
+ if (i < 0)
125
+ return;
126
+ const before = this.mutedNow();
127
+ this.mutes.splice(i, 1);
128
+ this.wake(before);
129
+ };
130
+ }
131
+ /**
132
+ * Lift every mute, the removers' included. A button a woken pointer still holds reads up (not
133
+ * held, not pressed) until it is let go, so a press held through the mute never lands as a new
134
+ * one; its next press does.
135
+ */
136
+ unmute() {
137
+ if (this.mutes.length === 0)
138
+ return;
139
+ const before = this.mutedNow();
140
+ this.mutes.length = 0;
141
+ this.wake(before);
142
+ }
143
+ /** True while `source` is muted (by `mute()` or `mute([source])`). */
144
+ isMuted(source) {
145
+ const mutes = this.mutes;
146
+ for (let i = 0; i < mutes.length; i++) {
147
+ const m = mutes[i];
148
+ if (m === null || m.includes(source))
149
+ return true;
150
+ }
151
+ return false;
152
+ }
153
+ /** The sources muted now (current sources for a mute-all, listed ones otherwise). */
154
+ mutedNow() {
155
+ const out = [];
156
+ for (const s of this.sources)
157
+ if (this.isMuted(s))
158
+ out.push(s);
159
+ for (const m of this.mutes) {
160
+ if (m)
161
+ for (const s of m)
162
+ if (!out.includes(s))
163
+ out.push(s);
164
+ }
165
+ return out;
166
+ }
167
+ /** Mark every source of `before` that is no longer muted as just woken. */
168
+ wake(before) {
169
+ for (const s of before) {
170
+ if (!this.isMuted(s) && !this.waking.includes(s))
171
+ this.waking.push(s);
172
+ }
173
+ }
174
+ /** Client → camera screen units for the screen source (`Input.setPointers` shares the input's). */
175
+ setPointerTransform(fn) {
176
+ this.screen.setPointerTransform(fn);
177
+ }
178
+ /** Gestures whose magnify aim steers a single touch (`Input.setPointers` shares the input's). */
179
+ setGestures(g) {
180
+ this.screen.setGestures(g);
181
+ }
182
+ /** Listen on `target` (every source with an `attach`). `Input.attach` does this when linked. */
183
+ attach(target, dispatcher) {
184
+ this.detach();
185
+ this.target = target;
186
+ for (const s of this.sources)
187
+ s.attach?.(target, dispatcher);
188
+ }
189
+ detach() {
190
+ if (!this.target)
191
+ return;
192
+ this.target = null;
193
+ for (const s of this.sources)
194
+ s.detach?.();
195
+ }
196
+ // ---------------------------------------------------------------- queries
197
+ /**
198
+ * True while any pointer holds `button`. Raw: it keeps tracking while blocked (as `Input`'s
199
+ * keys do), so a press held through a block is not a new press after it.
200
+ */
201
+ held(button) {
202
+ for (const t of this.tracks)
203
+ if (button === 'select' ? t.select : t.secondary)
204
+ return true;
205
+ return false;
206
+ }
207
+ /** True when a pointer pressed `button` this tick (never while blocked). */
208
+ fired(button) {
209
+ for (const p of this.pointers) {
210
+ const t = p;
211
+ if (button === 'select' ? t.pressSelect : t.pressSecondary)
212
+ return true;
213
+ }
214
+ return false;
215
+ }
216
+ /** True while an XR pointer (in `hand`, or either) holds `button`. Raw, like `held`. */
217
+ xrHeld(button, hand) {
218
+ for (const t of this.tracks) {
219
+ if (t.xr && (!hand || t.hand === hand) && t.xr[button])
220
+ return true;
221
+ }
222
+ return false;
223
+ }
224
+ /** True when an XR pointer (in `hand`, or either) pressed `button` this tick. */
225
+ xrFired(button, hand) {
226
+ if (this.isBlocked)
227
+ return false;
228
+ for (const p of this.pointers) {
229
+ const t = p;
230
+ if (t.xr && (!hand || t.hand === hand) && t.xr[button] && !t.xrPrev[button])
231
+ return true;
232
+ }
233
+ return false;
234
+ }
235
+ // ---------------------------------------------------------------- tick
236
+ /**
237
+ * Poll every source, hit-test each pointer and report hover changes, then report presses
238
+ * (button edges; a linked `Input` reports them from its actions instead, see `selectAction`).
239
+ */
240
+ update() {
241
+ this.poll();
242
+ this.resolve(null);
243
+ }
244
+ /**
245
+ * First half of `update()`: sources, rays, hits, `hit`/`hitEnd`. `Input` calls it before
246
+ * evaluating `{ pointer }` and `{ xr }` bindings.
247
+ */
248
+ poll() {
249
+ this.tick++;
250
+ const blocked = this.blocked();
251
+ this.isBlocked = blocked;
252
+ const camera = this.camera;
253
+ for (const t of this.tracks)
254
+ t.seen = false;
255
+ for (const src of this.sources) {
256
+ const samples = src.poll(camera);
257
+ const muted = this.isMuted(src);
258
+ const woken = this.waking.includes(src);
259
+ for (let i = 0; i < samples.length; i++) {
260
+ const s = samples[i];
261
+ if (muted && !s.synthetic)
262
+ continue;
263
+ this.route(src, s, blocked, woken);
264
+ }
265
+ }
266
+ this.waking.length = 0;
267
+ // Pointers that were not reported have ended.
268
+ for (let i = 0; i < this.tracks.length; i++) {
269
+ const t = this.tracks[i];
270
+ if (t.seen)
271
+ continue;
272
+ this.endHit(t);
273
+ // A muted pointer holding a button lets go over nothing, never a stuck press.
274
+ if ((t.select || t.secondary) && this.isMuted(t.source))
275
+ this.release(t, blocked);
276
+ if (this.primary === t)
277
+ this.primary = null;
278
+ this.tracks.splice(i--, 1);
279
+ this.pool.push(t);
280
+ }
281
+ const list = this.pointers;
282
+ list.length = 0;
283
+ if (blocked) {
284
+ this.primary = null;
285
+ return;
286
+ }
287
+ let primary = null;
288
+ for (const t of this.tracks) {
289
+ list.push(t);
290
+ if (!primary || t.active > primary.active)
291
+ primary = t;
292
+ }
293
+ this.primary = primary;
294
+ }
295
+ /**
296
+ * Second half of `update()`: `select` and `secondary`. With `actions` (a linked `Input`), an
297
+ * action the bindings have fires on the primary pointer when pressed; otherwise each pointer
298
+ * whose button went down fires.
299
+ */
300
+ resolve(actions) {
301
+ if (this.pointers.length === 0)
302
+ return;
303
+ this.resolveButton('select', this.selectAction, actions);
304
+ this.resolveButton('secondary', this.secondaryAction, actions);
305
+ }
306
+ resolveButton(kind, action, actions) {
307
+ const ev = this.evSelect;
308
+ if (actions?.bound(action)) {
309
+ const p = this.primary;
310
+ if (!p || !actions.pressed(action))
311
+ return;
312
+ ev.pointer = p;
313
+ ev.hit = p.hit;
314
+ this.events.emit(kind, ev);
315
+ return;
316
+ }
317
+ for (const p of this.pointers) {
318
+ const t = p;
319
+ if (!(kind === 'select' ? t.pressSelect : t.pressSecondary))
320
+ continue;
321
+ ev.pointer = t;
322
+ ev.hit = t.hit;
323
+ this.events.emit(kind, ev);
324
+ }
325
+ }
326
+ /** End `t`'s held buttons and report `released` (over nothing) unless blocked. */
327
+ release(t, blocked) {
328
+ t.prevSelect = t.select;
329
+ t.prevSecondary = t.secondary;
330
+ t.select = false;
331
+ t.secondary = false;
332
+ t.pressSelect = false;
333
+ t.pressSecondary = false;
334
+ if (t.xr)
335
+ for (const b of XR_BUTTONS)
336
+ t.xrPrev[b] = t.xr[b] = false;
337
+ if (blocked)
338
+ return;
339
+ const ev = this.evReleased;
340
+ ev.pointer = t;
341
+ ev.hit = null;
342
+ this.events.emit('released', ev);
343
+ }
344
+ /**
345
+ * `quiet`: the source was just unmuted, so a button a new track already holds was held through
346
+ * the mute: it reads up (not held, never a press) until it is let go, as a key held through a
347
+ * detach does.
348
+ */
349
+ route(src, s, blocked, quiet) {
350
+ let t = null;
351
+ for (const c of this.tracks) {
352
+ if (c.source === src && c.key === s.key) {
353
+ t = c;
354
+ break;
355
+ }
356
+ }
357
+ const isNew = t === null;
358
+ if (!t) {
359
+ t = this.pool.pop() ?? this.newTrack();
360
+ t.source = src;
361
+ t.key = s.key;
362
+ t.maskSelect = quiet && s.select;
363
+ t.maskSecondary = quiet && s.secondary;
364
+ for (const b of XR_BUTTONS)
365
+ t.xrMask[b] = quiet && s.xr?.[b] === true;
366
+ t.hit = null;
367
+ this.tracks.push(t);
368
+ }
369
+ else {
370
+ t.prevSelect = t.select;
371
+ t.prevSecondary = t.secondary;
372
+ }
373
+ t.seen = true;
374
+ if (!s.select)
375
+ t.maskSelect = false;
376
+ if (!s.secondary)
377
+ t.maskSecondary = false;
378
+ const select = s.select && !t.maskSelect;
379
+ const secondary = s.secondary && !t.maskSecondary;
380
+ if (isNew) {
381
+ t.prevSelect = select && blocked;
382
+ t.prevSecondary = secondary && blocked;
383
+ }
384
+ const ray = t.ray;
385
+ const moved = isNew ||
386
+ s.x !== t.x ||
387
+ s.y !== t.y ||
388
+ s.ray.origin[0] !== ray.origin[0] ||
389
+ s.ray.origin[1] !== ray.origin[1] ||
390
+ s.ray.origin[2] !== ray.origin[2] ||
391
+ s.ray.dir[0] !== ray.dir[0] ||
392
+ s.ray.dir[1] !== ray.dir[1] ||
393
+ s.ray.dir[2] !== ray.dir[2];
394
+ t.device = s.device;
395
+ t.hand = s.hand;
396
+ t.x = s.x;
397
+ t.y = s.y;
398
+ for (let i = 0; i < 3; i++) {
399
+ ray.origin[i] = s.ray.origin[i];
400
+ ray.dir[i] = s.ray.dir[i];
401
+ }
402
+ if (s.xr) {
403
+ const prev = t.xr ? t.xrStore : null;
404
+ for (const b of XR_BUTTONS) {
405
+ if (!s.xr[b])
406
+ t.xrMask[b] = false;
407
+ const v = s.xr[b] && !t.xrMask[b];
408
+ t.xrPrev[b] = prev ? prev[b] : blocked && v;
409
+ t.xrStore[b] = v;
410
+ }
411
+ t.xr = t.xrStore;
412
+ }
413
+ else {
414
+ t.xr = null;
415
+ }
416
+ // While blocked buttons track (so a press held through the block is not a new press), but
417
+ // nothing is pressed and nothing is hit.
418
+ t.select = select;
419
+ t.secondary = secondary;
420
+ t.pressSelect = !blocked && select && !t.prevSelect;
421
+ t.pressSecondary = !blocked && secondary && !t.prevSecondary;
422
+ if (moved || t.pressSelect || t.pressSecondary)
423
+ t.active = this.tick;
424
+ if (blocked) {
425
+ this.endHit(t);
426
+ return;
427
+ }
428
+ this.test(t);
429
+ if (moved) {
430
+ const ev = this.evMoved;
431
+ ev.pointer = t;
432
+ ev.hit = t.hit;
433
+ this.events.emit('moved', ev);
434
+ }
435
+ if ((t.prevSelect && !select) || (t.prevSecondary && !secondary)) {
436
+ const ev = this.evReleased;
437
+ ev.pointer = t;
438
+ ev.hit = t.hit;
439
+ this.events.emit('released', ev);
440
+ }
441
+ }
442
+ /** Nearest hit for `t`'s ray; report `hitEnd`/`hit` when the target changes. */
443
+ test(t) {
444
+ const best = this.best;
445
+ let found = false;
446
+ for (const tester of this.testers) {
447
+ const h = tester(t.ray);
448
+ if (!h || (found && h.distance >= best.distance))
449
+ continue;
450
+ found = true;
451
+ copyHit(best, this.bestNormal, h);
452
+ }
453
+ const prev = t.hit;
454
+ if (!found) {
455
+ this.endHit(t);
456
+ return;
457
+ }
458
+ const changed = !prev || prev.target !== best.target;
459
+ if (changed)
460
+ this.endHit(t);
461
+ copyHit(t.store, t.storeNormal, best);
462
+ t.hit = t.store;
463
+ if (changed) {
464
+ const ev = this.evHit;
465
+ ev.pointer = t;
466
+ ev.hit = t.hit;
467
+ this.events.emit('hit', ev);
468
+ }
469
+ }
470
+ endHit(t) {
471
+ if (!t.hit)
472
+ return;
473
+ copyHit(t.ended, t.endedNormal, t.hit);
474
+ t.hit = null;
475
+ const ev = this.evEnd;
476
+ ev.pointer = t;
477
+ ev.hit = t.ended;
478
+ this.events.emit('hitEnd', ev);
479
+ }
480
+ newTrack() {
481
+ return {
482
+ source: this.screen,
483
+ key: 0,
484
+ device: 'mouse',
485
+ hand: null,
486
+ x: Number.NaN,
487
+ y: Number.NaN,
488
+ ray: createRay(),
489
+ select: false,
490
+ secondary: false,
491
+ xr: null,
492
+ hit: null,
493
+ store: createHit(undefined),
494
+ storeNormal: [0, 0, 0],
495
+ ended: createHit(undefined),
496
+ endedNormal: [0, 0, 0],
497
+ xrStore: { trigger: false, squeeze: false, pinch: false },
498
+ xrPrev: { trigger: false, squeeze: false, pinch: false },
499
+ seen: false,
500
+ prevSelect: false,
501
+ prevSecondary: false,
502
+ maskSelect: false,
503
+ maskSecondary: false,
504
+ xrMask: { trigger: false, squeeze: false, pinch: false },
505
+ pressSelect: false,
506
+ pressSecondary: false,
507
+ active: 0,
508
+ };
509
+ }
510
+ }
511
+ function copyHit(dst, normal, src) {
512
+ dst.point[0] = src.point[0];
513
+ dst.point[1] = src.point[1];
514
+ dst.point[2] = src.point[2];
515
+ dst.distance = src.distance;
516
+ dst.target = src.target;
517
+ if (src.normal) {
518
+ normal[0] = src.normal[0];
519
+ normal[1] = src.normal[1];
520
+ normal[2] = src.normal[2];
521
+ dst.normal = normal;
522
+ }
523
+ else {
524
+ dst.normal = null;
525
+ }
526
+ }
527
+ /**
528
+ * A pointer router (see `PointerRouter`). Link it to the action map with
529
+ * `input.setPointers(router)`; add `planeTester`/`aabbTester` or the game's own testers.
530
+ */
531
+ export function createPointerRouter(opts = {}) {
532
+ return new PointerRouter(opts);
533
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Pointer sources for the router (`pointer-router.ts`): the `PointerSource` seam, the screen
3
+ * source (mouse, pen, touch from DOM pointer events) and the pad cursor (a virtual pointer moved
4
+ * by a gamepad stick). XR controllers and hands are `XrPointerSource` (`xr-source.ts`),
5
+ * which `createGame({ xr })` adds.
6
+ */
7
+ import type { Gestures } from './gestures.js';
8
+ import { type PointerDispatcher } from './pointer-dispatch.js';
9
+ import { type Ray, type RayCamera } from './rays.js';
10
+ import type { GamepadLike, Hand, PointerTransform } from './types.js';
11
+ /** What made a routed pointer. */
12
+ export type PointerDevice = 'mouse' | 'touch' | 'pen' | 'gamepad' | 'xr';
13
+ /** XR button state of one controller or hand (pressed or not; the source applies thresholds). */
14
+ export interface XrButtons {
15
+ trigger: boolean;
16
+ squeeze: boolean;
17
+ pinch: boolean;
18
+ }
19
+ /**
20
+ * One pointer at one tick, as a source reports it. The source owns the object and reuses it.
21
+ */
22
+ export interface PointerSample {
23
+ /** Unique within its source and stable while the pointer lives (a pointer id, 0, a hand index). */
24
+ key: number;
25
+ device: PointerDevice;
26
+ /** The hand of an XR pointer; `null` for everything else. */
27
+ hand: Hand | null;
28
+ /** World-space ray, `dir` unit length. */
29
+ readonly ray: Ray;
30
+ /** The screen point the ray goes through (camera screen units), or `NaN` for XR pointers. */
31
+ x: number;
32
+ y: number;
33
+ /** Primary button held: mouse 0, a touch or pen contact, the pad cursor's press, XR trigger or pinch. */
34
+ select: boolean;
35
+ /** Secondary button held: mouse 2, the pad cursor's second button, XR squeeze. */
36
+ secondary: boolean;
37
+ /** XR button state; `null` for pointers that are not XR. */
38
+ xr: XrButtons | null;
39
+ /**
40
+ * A replay made this pointer (`Input.replayPointer`; ws/input-11): `PointerRouter.mute` never
41
+ * drops it. Absent or false for real pointers.
42
+ */
43
+ synthetic?: boolean;
44
+ }
45
+ /**
46
+ * Something that points. The router polls every source once per tick, before hit testing.
47
+ *
48
+ * `poll` returns this tick's live pointers. The source owns the array and the samples and reuses
49
+ * them (no allocation per tick); the router reads them before the next `poll`. A pointer whose
50
+ * `key` is missing from a poll has ended. `camera` is the router's active camera (or `null`):
51
+ * screen sources build their rays through it, world-space sources (XR) ignore it.
52
+ *
53
+ * Optional hooks: `attach`/`detach` when the router attaches to (or leaves) a pointer target.
54
+ */
55
+ export interface PointerSource {
56
+ poll(camera: RayCamera | null): readonly PointerSample[];
57
+ /** `dispatcher` is the one the linked `Input` built (ws/input-4); absent when attached alone. */
58
+ attach?(target: HTMLElement, dispatcher?: PointerDispatcher): void;
59
+ detach?(): void;
60
+ }
61
+ export declare function createSample(key: number, device: PointerDevice): PointerSample;
62
+ interface Contact {
63
+ id: number;
64
+ device: 'mouse' | 'touch' | 'pen';
65
+ /** Client CSS px (or target-relative without a transform). */
66
+ cx: number;
67
+ cy: number;
68
+ select: boolean;
69
+ secondary: boolean;
70
+ /** The select button went down since the last poll (a press shorter than a tick still counts). */
71
+ tapped: boolean;
72
+ /** The pointer ended; it is reported once more (its last position), then dropped. */
73
+ gone: boolean;
74
+ /** Ended by a cancel or a hover leaving: dropped without the last report. */
75
+ cancelled: boolean;
76
+ /** Made by a replay (`PointerRecord.synthetic`); see `PointerSample.synthetic`. */
77
+ synthetic: boolean;
78
+ sample: PointerSample;
79
+ }
80
+ /**
81
+ * Mouse, pen and touch as router pointers. Mouse and pen hover (a pointer while over the
82
+ * target); touch is a pointer only while the finger is down, plus one more tick after it lifts so
83
+ * a tap's tick still sees what it was on. Positions go through the pointer transform into the
84
+ * camera's screen units. With linked `Gestures` that have `magnify`, a single touch points at the
85
+ * gesture's aim (the snapped target's centre, else the lifted aim point) instead of the finger.
86
+ *
87
+ * Feed methods (`pointerDown`, `pointerMove`, `pointerUp`, `pointerLeave`, `pointerCancel`,
88
+ * `cancelAll`) take client coordinates and are public for tests and replays. `synthetic` on
89
+ * `pointerDown`/`pointerMove` marks a replayed pointer (see `PointerSample.synthetic`).
90
+ */
91
+ export declare class ScreenPointers implements PointerSource {
92
+ private transform;
93
+ private gestures;
94
+ private readonly contacts;
95
+ private readonly out;
96
+ private detachFn;
97
+ /**
98
+ * Hides a pointer from `poll` while it reads true: installed by `attach` with a dispatcher as
99
+ * "claimed and not `hoverWhileClaimed`", so an orbit drag or a touch-zone thumb produces no
100
+ * hits until it is released. Public so tests can stand one in.
101
+ */
102
+ claim: ((id: number) => boolean) | null;
103
+ setPointerTransform(fn: PointerTransform | null): void;
104
+ setGestures(g: Gestures | null): void;
105
+ pointerDown(id: number, x: number, y: number, device?: Contact['device'], button?: number, synthetic?: boolean): void;
106
+ pointerMove(id: number, x: number, y: number, device?: Contact['device'], synthetic?: boolean): void;
107
+ pointerUp(id: number, x: number, y: number, button?: number): void;
108
+ /** A hovering mouse or pen left the target. */
109
+ pointerLeave(id: number): void;
110
+ pointerCancel(id: number): void;
111
+ cancelAll(): void;
112
+ poll(camera: RayCamera | null): readonly PointerSample[];
113
+ /**
114
+ * Listen to pointer events on `target` (the router calls this from its `attach`). Positions are
115
+ * client px with a transform, target-relative px without one.
116
+ */
117
+ attach(target: HTMLElement, dispatcher?: PointerDispatcher): void;
118
+ private ownDispatcher;
119
+ private readonly consumer;
120
+ detach(): void;
121
+ private find;
122
+ private contact;
123
+ }
124
+ export interface PadCursorOptions {
125
+ /** Gamepad source. Default: `navigator.getGamepads()` (guarded). */
126
+ getGamepads?: () => readonly (GamepadLike | null)[];
127
+ /** Pad index; omitted = any pad (the first deflected stick wins). */
128
+ pad?: number;
129
+ /** Stick axes [x, y]. Default [0, 1] (the left stick). */
130
+ axes?: readonly [number, number];
131
+ /** Stick deflection ignored below this. Default 0.2. */
132
+ deadzone?: number;
133
+ /**
134
+ * Travel per tick at full deflection, as a fraction of the screen's shorter side. Default
135
+ * 0.012 (about 0.7 of it per second at 60 ticks).
136
+ */
137
+ speed?: number;
138
+ /** Standard-mapping button that is the cursor's `select`. Default 0 (A / Cross). */
139
+ selectButton?: number;
140
+ /** Button that is the cursor's `secondary`. Default 2 (X / Square). */
141
+ secondaryButton?: number;
142
+ }
143
+ /**
144
+ * A virtual pointer a gamepad stick moves over the camera's screen, so a pad aims like a mouse.
145
+ * It appears (at the screen centre) the first time its stick passes the deadzone or its select
146
+ * button is pressed, then stays until `hide()`. `x`, `y` are camera screen units.
147
+ */
148
+ export declare class PadCursor implements PointerSource {
149
+ x: number;
150
+ y: number;
151
+ /** True while the cursor is shown (it reports a pointer). */
152
+ active: boolean;
153
+ private readonly getGamepads;
154
+ private readonly opts;
155
+ private readonly sample;
156
+ private readonly out;
157
+ constructor(opts?: PadCursorOptions);
158
+ /** Put the cursor at a screen point and show it. */
159
+ moveTo(x: number, y: number): void;
160
+ /** Hide the cursor (for example when the mouse moves); the stick shows it again. */
161
+ hide(): void;
162
+ poll(camera: RayCamera | null): readonly PointerSample[];
163
+ }
164
+ export {};