@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,681 @@
1
+ import { Emitter } from '../core/events.js';
2
+ import { resolveClock } from './clock.js';
3
+ import { shapeStick } from './input.js';
4
+ import { createPointerDispatcher, POINTER_PRIORITY, } from './pointer-dispatch.js';
5
+ /** Longest gap between two ticks the stick integrates over, seconds. */
6
+ const MAX_DT = 0.1;
7
+ /** Zoom units per second the right stick reports at full deflection (`zoom.pad: 'rightStickY'`). */
8
+ export const PAD_ZOOM_PER_S = 4;
9
+ /** Standard-mapping shoulder buttons: left zooms out, right zooms in. */
10
+ const SHOULDER_OUT = 4;
11
+ const SHOULDER_IN = 5;
12
+ function defaultGamepads() {
13
+ try {
14
+ return typeof navigator !== 'undefined' && navigator.getGamepads ? navigator.getGamepads() : [];
15
+ }
16
+ catch {
17
+ return [];
18
+ }
19
+ }
20
+ /**
21
+ * First- and third-person look and move. Each tick it reports `look` (yaw and pitch deltas in
22
+ * radians) and `move` (x, y in -1..1) from whichever device the player uses: pointer-locked mouse,
23
+ * a two-zone touch layout (a virtual move stick in one half, look drags anywhere else), the pad's
24
+ * sticks and the move keys. Link it with `input.setLook(look)` so it shares `blocked()`, attaches
25
+ * with `Input.attach` and advances in `Input.update()`.
26
+ *
27
+ * Signs: `look.dx` > 0 turns right, `look.dy` > 0 looks up (`invertY` flips it); `move.x` > 0 is
28
+ * right, `move.y` > 0 is forward. `zoom` > 0 is closer (wheel up, fingers apart). No allocation
29
+ * per tick.
30
+ */
31
+ export class Look {
32
+ /** This tick's look delta, radians. */
33
+ look = { dx: 0, dy: 0 };
34
+ /** This tick's move, each axis -1..1, length at most 1. */
35
+ move = { x: 0, y: 0 };
36
+ /**
37
+ * This tick's zoom: wheel notches, pinch distance over `stepPx`, or stick units; positive is
38
+ * closer. `Follow` reads it when linked.
39
+ */
40
+ zoom = 0;
41
+ /** The touch move stick (client CSS px). */
42
+ stick = { active: false, originX: 0, originY: 0, x: 0, y: 0 };
43
+ /** True while the attached element holds the pointer lock. */
44
+ locked = false;
45
+ blocked;
46
+ /** Raw key state the move keys are read from; `Input.setLook` installs its own. */
47
+ keyHeld = null;
48
+ sensitivity;
49
+ padSensitivity;
50
+ invertY;
51
+ moveZone;
52
+ deadzone;
53
+ radius;
54
+ touchSensitivity;
55
+ padDeadzone;
56
+ keys;
57
+ zoomWheel;
58
+ zoomPinch;
59
+ zoomPad;
60
+ zoomStepPx;
61
+ /** Gyro aim added to the look each tick (`LookOptions.gyro`), or null. */
62
+ gyro;
63
+ /** `onTap` thresholds. */
64
+ tapMaxMove;
65
+ tapMaxMs;
66
+ /**
67
+ * Client → game-space mapping for `onTap` coordinates; `Input.setLook` and
68
+ * `Input.setPointerTransform` keep it in step with the input's. `null`: the dispatcher's units.
69
+ */
70
+ pointerTransform = null;
71
+ tapFns = [];
72
+ /** The pointer that may still tap, or null. */
73
+ tapId = null;
74
+ tapDevice = 'mouse';
75
+ tapAt = 0;
76
+ tapLastX = 0;
77
+ tapLastY = 0;
78
+ tapTravel = 0;
79
+ gyroOut = { dx: 0, dy: 0 };
80
+ stickOut = [0, 0];
81
+ stickOpts = { deadzone: 0, shape: 'scaledRadial' };
82
+ pad;
83
+ getGamepads;
84
+ now;
85
+ /** The clock (`LookOptions.clock`, or one wrapping `now`, or the wall clock). */
86
+ clock;
87
+ events = new Emitter();
88
+ lastTime = Number.NaN;
89
+ mouseX = 0;
90
+ mouseY = 0;
91
+ touchX = 0;
92
+ touchY = 0;
93
+ moveId = null;
94
+ lookId = null;
95
+ lookLastX = 0;
96
+ lookLastY = 0;
97
+ pinchId = null;
98
+ pinchX = 0;
99
+ pinchY = 0;
100
+ pinchDist = 0;
101
+ zoomAcc = 0;
102
+ target = null;
103
+ detachFn = null;
104
+ lockOnFirstClick;
105
+ modeValue;
106
+ warnedLockOnFirstClick = false;
107
+ /** The orbit drag in progress (client CSS px), or NaN when none. */
108
+ orbitX = Number.NaN;
109
+ orbitY = Number.NaN;
110
+ /**
111
+ * True once a linked `Input` feeds the orbit drag through its own pointer feed (so the drag is
112
+ * recorded and replayed); the DOM listener here then leaves mouse and pen alone. Set by
113
+ * `Input.setLook`.
114
+ */
115
+ orbitFromInput = false;
116
+ /**
117
+ * The linked `Input`'s pads for this tick (ws/input-9), read instead of the default
118
+ * `navigator.getGamepads()` so a playback's recorded pads turn the look. Ignored when
119
+ * `LookOptions.getGamepads` was given. Set by `Input.setLook`.
120
+ */
121
+ padsFromInput = null;
122
+ /** True when `LookOptions.getGamepads` was given: it wins over `padsFromInput`. */
123
+ ownPads;
124
+ constructor(opts = {}) {
125
+ this.sensitivity = opts.sensitivity ?? 0.0025;
126
+ this.padSensitivity = opts.padSensitivity ?? 3;
127
+ this.invertY = opts.invertY ?? false;
128
+ this.moveZone = opts.touch?.moveZone ?? 'left';
129
+ this.deadzone = opts.touch?.deadzone ?? 0.12;
130
+ this.radius = opts.touch?.radius ?? 56;
131
+ this.touchSensitivity = opts.touch?.sensitivity;
132
+ this.padDeadzone = opts.padDeadzone ?? 0.15;
133
+ this.pad = opts.pad;
134
+ this.keys = opts.keys ?? {};
135
+ this.zoomWheel = opts.zoom?.wheel ?? true;
136
+ this.zoomPinch = opts.zoom?.pinch ?? true;
137
+ this.zoomPad = opts.zoom?.pad ?? 'none';
138
+ this.zoomStepPx = opts.zoom?.stepPx ?? 100;
139
+ this.getGamepads = opts.getGamepads ?? defaultGamepads;
140
+ this.ownPads = opts.getGamepads !== undefined;
141
+ this.blocked = opts.blocked ?? (() => false);
142
+ const c = resolveClock(opts.clock, opts.now);
143
+ this.clock = c.clock;
144
+ this.now = c.now;
145
+ this.lockOnFirstClick = opts.lockOnFirstClick ?? false;
146
+ this.modeValue = opts.mode ?? 'locked';
147
+ this.gyro = opts.gyro ?? null;
148
+ this.tapMaxMove = opts.tap?.maxMove ?? 10;
149
+ this.tapMaxMs = opts.tap?.maxMs ?? 450;
150
+ }
151
+ /**
152
+ * Call `fn` on a tap (ws/input-5): a primary-button press and release that travels at most
153
+ * `tap.maxMove` px within `tap.maxMs`, on a pointer the look took (an orbit-mode mouse or pen,
154
+ * a look-drag touch) or, in locked mode, on any pointer over the attached element except the
155
+ * move-stick touch. A second finger landing cancels it. (x, y) are in the router's units (the
156
+ * pointer transform's game space). Returns the remover.
157
+ */
158
+ onTap(fn) {
159
+ this.tapFns.push(fn);
160
+ return () => {
161
+ const i = this.tapFns.indexOf(fn);
162
+ if (i >= 0)
163
+ this.tapFns.splice(i, 1);
164
+ };
165
+ }
166
+ /** The look mode (`LookOptions.mode`); change it with `setMode`. */
167
+ get mode() {
168
+ return this.modeValue;
169
+ }
170
+ /**
171
+ * Switch between pointer-locked and orbit look at runtime. Into orbit the lock is released;
172
+ * into locked a drag in progress ends (the game asks for the lock from its next click).
173
+ */
174
+ setMode(mode) {
175
+ if (mode === this.modeValue)
176
+ return;
177
+ this.modeValue = mode;
178
+ if (mode === 'orbit')
179
+ this.release();
180
+ else
181
+ this.orbitUp();
182
+ }
183
+ /** True when the look takes mouse and pen pointers for itself (orbit mode), so gestures must not. */
184
+ claimsPointer(device) {
185
+ return this.modeValue === 'orbit' && device !== 'touch';
186
+ }
187
+ /** True while an orbit drag is in progress. */
188
+ get orbiting() {
189
+ return !Number.isNaN(this.orbitX);
190
+ }
191
+ /** Subscribe to `lockChange`. Returns the unsubscriber. */
192
+ on(type, fn) {
193
+ return this.events.on(type, fn);
194
+ }
195
+ /** Shorthand for `on('lockChange', fn)`. */
196
+ onLockChange(fn) {
197
+ return this.events.on('lockChange', fn);
198
+ }
199
+ // ---------------------------------------------------------------- tick
200
+ /** Advance one tick. `Input.update()` calls this when linked; don't call it twice. */
201
+ update() {
202
+ const t = this.now();
203
+ const dt = Number.isNaN(this.lastTime)
204
+ ? 0
205
+ : Math.min(MAX_DT, Math.max(0, (t - this.lastTime) / 1000));
206
+ this.lastTime = t;
207
+ const look = this.look;
208
+ const move = this.move;
209
+ if (this.blocked()) {
210
+ look.dx = look.dy = move.x = move.y = this.zoom = 0;
211
+ this.mouseX = this.mouseY = this.touchX = this.touchY = this.zoomAcc = 0;
212
+ // The gyro's turn while blocked is dropped, not saved up.
213
+ this.gyro?.take(this.gyroOut);
214
+ this.tapId = null;
215
+ this.voidTouches();
216
+ this.release();
217
+ return;
218
+ }
219
+ // Screen y grows downwards; look up is dy > 0. `0 - v` keeps a still pointer at +0.
220
+ const touchSens = this.touchSensitivity ?? this.sensitivity;
221
+ let dx = this.mouseX * this.sensitivity + this.touchX * touchSens;
222
+ const down = this.mouseY * this.sensitivity + this.touchY * touchSens;
223
+ let dy = this.invertY ? down : 0 - down;
224
+ this.mouseX = this.mouseY = this.touchX = this.touchY = 0;
225
+ let zoom = this.zoomAcc;
226
+ this.zoomAcc = 0;
227
+ const g = this.gyro;
228
+ if (g) {
229
+ const o = g.take(this.gyroOut);
230
+ dx += o.dx;
231
+ dy += o.dy;
232
+ }
233
+ let mx = 0;
234
+ let my = 0;
235
+ const s = this.stick;
236
+ // Sticks go through `shapeStick` (scaled radial, the same numbers as before ws/input-5).
237
+ const so = this.stickOut;
238
+ const opts = this.stickOpts;
239
+ if (s.active && this.radius > 0) {
240
+ const ox = (s.x - s.originX) / this.radius;
241
+ const oy = (s.originY - s.y) / this.radius;
242
+ opts.deadzone = this.deadzone;
243
+ shapeStick(ox, oy, so, opts);
244
+ mx = so[0];
245
+ my = so[1];
246
+ }
247
+ const p = this.padState();
248
+ if (p) {
249
+ const a = p.axes;
250
+ const lx = a[0] ?? 0;
251
+ const ly = -(a[1] ?? 0);
252
+ opts.deadzone = this.padDeadzone;
253
+ shapeStick(lx, ly, so, opts);
254
+ mx += so[0];
255
+ my += so[1];
256
+ const rx = a[2] ?? 0;
257
+ const ry = -(a[3] ?? 0);
258
+ const k = this.padSensitivity * dt;
259
+ shapeStick(rx, ry, so, opts);
260
+ dx += so[0] * k;
261
+ const zp = this.zoomPad;
262
+ if (zp === 'rightStickY') {
263
+ // The stick's vertical axis is the zoom, so the look pitches only from other devices.
264
+ zoom += so[1] * PAD_ZOOM_PER_S * dt;
265
+ }
266
+ else {
267
+ // Stick up looks up (dy > 0) unless inverted.
268
+ dy += so[1] * k * (this.invertY ? -1 : 1);
269
+ }
270
+ if (zp === 'shoulders') {
271
+ const b = p.buttons;
272
+ zoom += (b[SHOULDER_IN]?.pressed ? 1 : 0) - (b[SHOULDER_OUT]?.pressed ? 1 : 0);
273
+ }
274
+ }
275
+ const held = this.keyHeld;
276
+ if (held) {
277
+ const k = this.keys;
278
+ mx += anyHeld(held, k.right) - anyHeld(held, k.left);
279
+ my += anyHeld(held, k.forward) - anyHeld(held, k.back);
280
+ }
281
+ const len = Math.hypot(mx, my);
282
+ if (len > 1) {
283
+ mx /= len;
284
+ my /= len;
285
+ }
286
+ look.dx = dx;
287
+ look.dy = dy;
288
+ move.x = mx;
289
+ move.y = my;
290
+ this.zoom = zoom;
291
+ }
292
+ padState() {
293
+ let pads;
294
+ const linked = this.ownPads ? null : this.padsFromInput;
295
+ try {
296
+ pads = linked ? linked() : this.getGamepads();
297
+ }
298
+ catch {
299
+ return null;
300
+ }
301
+ if (this.pad !== undefined) {
302
+ const p = pads[this.pad];
303
+ return p && p.connected !== false ? p : null;
304
+ }
305
+ for (let i = 0; i < pads.length; i++) {
306
+ const p = pads[i];
307
+ if (p && p.connected !== false)
308
+ return p;
309
+ }
310
+ return null;
311
+ }
312
+ // ---------------------------------------------------------------- feed (tests, replays)
313
+ /** Pointer-locked mouse movement, CSS px (`movementX/Y`). The DOM listener feeds it only while locked. */
314
+ mouseMove(dx, dy) {
315
+ if (this.blocked())
316
+ return;
317
+ this.mouseX += dx;
318
+ this.mouseY += dy;
319
+ }
320
+ /**
321
+ * An orbit drag began at client (x, y) (mouse or pen, primary button). Nothing in locked mode.
322
+ * A linked `Input` feeds these from its own `buttonDown`, `pointerAt` and `buttonUp`.
323
+ */
324
+ orbitDown(x, y) {
325
+ if (this.modeValue !== 'orbit' || this.blocked())
326
+ return;
327
+ this.orbitX = x;
328
+ this.orbitY = y;
329
+ }
330
+ /** The orbit pointer moved to client (x, y): the delta turns the view at `sensitivity`. */
331
+ orbitMove(x, y) {
332
+ if (Number.isNaN(this.orbitX))
333
+ return;
334
+ if (!this.blocked()) {
335
+ this.mouseX += x - this.orbitX;
336
+ this.mouseY += y - this.orbitY;
337
+ }
338
+ this.orbitX = x;
339
+ this.orbitY = y;
340
+ }
341
+ /** The orbit drag ended. */
342
+ orbitUp() {
343
+ this.orbitX = this.orbitY = Number.NaN;
344
+ }
345
+ /** Zoom units (wheel notches) to add to this tick's `zoom`; positive is closer. */
346
+ wheel(units) {
347
+ if (this.blocked() || !this.zoomWheel)
348
+ return;
349
+ this.zoomAcc += units;
350
+ }
351
+ /**
352
+ * A touch went down at client (x, y); `inMoveZone` says whether it landed in the move zone. A
353
+ * touch that neither takes the stick nor starts a look drag pinches against the drag in progress
354
+ * when `zoom.pinch` is on.
355
+ */
356
+ touchDown(id, x, y, inMoveZone) {
357
+ // A touch that lands while blocked is ignored until it lifts.
358
+ if (this.blocked())
359
+ return;
360
+ if (inMoveZone && this.moveId === null) {
361
+ this.moveId = id;
362
+ const s = this.stick;
363
+ s.active = true;
364
+ s.originX = s.x = x;
365
+ s.originY = s.y = y;
366
+ }
367
+ else if (this.lookId === null) {
368
+ this.lookId = id;
369
+ this.lookLastX = x;
370
+ this.lookLastY = y;
371
+ }
372
+ else if (this.zoomPinch && this.pinchId === null) {
373
+ this.pinchId = id;
374
+ this.pinchX = x;
375
+ this.pinchY = y;
376
+ this.pinchDist = Math.hypot(x - this.lookLastX, y - this.lookLastY);
377
+ }
378
+ }
379
+ touchMove(id, x, y) {
380
+ if (id === this.moveId) {
381
+ const s = this.stick;
382
+ let ox = x - s.originX;
383
+ let oy = y - s.originY;
384
+ const d = Math.hypot(ox, oy);
385
+ if (d > this.radius && d > 0) {
386
+ ox *= this.radius / d;
387
+ oy *= this.radius / d;
388
+ }
389
+ s.x = s.originX + ox;
390
+ s.y = s.originY + oy;
391
+ }
392
+ else if (id === this.lookId) {
393
+ if (this.pinchId === null) {
394
+ this.touchX += x - this.lookLastX;
395
+ this.touchY += y - this.lookLastY;
396
+ }
397
+ this.lookLastX = x;
398
+ this.lookLastY = y;
399
+ if (this.pinchId !== null)
400
+ this.pinchMoved();
401
+ }
402
+ else if (id === this.pinchId) {
403
+ this.pinchX = x;
404
+ this.pinchY = y;
405
+ this.pinchMoved();
406
+ }
407
+ }
408
+ touchUp(id) {
409
+ if (id === this.moveId) {
410
+ this.moveId = null;
411
+ this.stick.active = false;
412
+ }
413
+ else if (id === this.lookId) {
414
+ // The pinch finger, if any, carries on as the look drag.
415
+ this.lookId = this.pinchId;
416
+ this.lookLastX = this.pinchX;
417
+ this.lookLastY = this.pinchY;
418
+ this.pinchId = null;
419
+ }
420
+ else if (id === this.pinchId) {
421
+ this.pinchId = null;
422
+ }
423
+ }
424
+ /** The distance between the look and pinch fingers changed: fingers apart is closer. */
425
+ pinchMoved() {
426
+ const d = Math.hypot(this.pinchX - this.lookLastX, this.pinchY - this.lookLastY);
427
+ if (this.zoomStepPx > 0)
428
+ this.zoomAcc += (d - this.pinchDist) / this.zoomStepPx;
429
+ this.pinchDist = d;
430
+ }
431
+ /** Drop every touch (blur, hidden tab, blocked). Fingers still down are ignored until lifted. */
432
+ cancelAll() {
433
+ this.voidTouches();
434
+ this.tapId = null;
435
+ this.orbitUp();
436
+ this.mouseX = this.mouseY = this.touchX = this.touchY = this.zoomAcc = 0;
437
+ }
438
+ voidTouches() {
439
+ this.moveId = null;
440
+ this.lookId = null;
441
+ this.pinchId = null;
442
+ this.stick.active = false;
443
+ }
444
+ // ---------------------------------------------------------------- pointer lock
445
+ /**
446
+ * Ask for the pointer lock on the attached element. Browsers grant it only inside a user
447
+ * gesture, so call this from a click or tap. Resolves with whether the lock is held; never
448
+ * rejects. False when detached, blocked or unsupported.
449
+ */
450
+ async request() {
451
+ const el = this.target;
452
+ if (!el || this.blocked() || this.modeValue === 'orbit')
453
+ return false;
454
+ const doc = el.ownerDocument;
455
+ if (doc.pointerLockElement === el)
456
+ return true;
457
+ if (typeof el.requestPointerLock !== 'function')
458
+ return false;
459
+ let settle = null;
460
+ const settled = new Promise((resolve) => {
461
+ settle = resolve;
462
+ });
463
+ const done = () => settle?.();
464
+ doc.addEventListener('pointerlockchange', done);
465
+ doc.addEventListener('pointerlockerror', done);
466
+ const timer = setTimeout(done, 1000);
467
+ try {
468
+ const r = el.requestPointerLock();
469
+ if (r && typeof r.then === 'function') {
470
+ r.then(done, done);
471
+ }
472
+ await settled;
473
+ }
474
+ catch {
475
+ // Unsupported or refused synchronously.
476
+ }
477
+ finally {
478
+ clearTimeout(timer);
479
+ doc.removeEventListener('pointerlockchange', done);
480
+ doc.removeEventListener('pointerlockerror', done);
481
+ }
482
+ this.syncLock();
483
+ return this.locked;
484
+ }
485
+ /** Give the pointer lock back, if the attached element holds it. */
486
+ release() {
487
+ const el = this.target;
488
+ if (!el)
489
+ return;
490
+ const doc = el.ownerDocument;
491
+ if (doc.pointerLockElement === el && typeof doc.exitPointerLock === 'function') {
492
+ doc.exitPointerLock();
493
+ }
494
+ }
495
+ syncLock() {
496
+ const el = this.target;
497
+ const now = el !== null && el.ownerDocument.pointerLockElement === el;
498
+ if (now === this.locked)
499
+ return;
500
+ this.locked = now;
501
+ this.events.emit('lockChange', now);
502
+ }
503
+ // ---------------------------------------------------------------- DOM
504
+ /**
505
+ * Listen on the element: touch pointers (zones, pinch), the wheel (passive), pointer-locked
506
+ * mouse movement and the lock's change and error events. `Input.setLook` calls this from
507
+ * `Input.attach`.
508
+ */
509
+ attach(target, dispatcher) {
510
+ this.detach();
511
+ this.target = target;
512
+ const doc = target.ownerDocument;
513
+ const shared = dispatcher ?? null;
514
+ const d = shared ?? createPointerDispatcher(target);
515
+ this.dispatcher = d;
516
+ const removeConsumer = d.add(this.consumer, POINTER_PRIORITY.look);
517
+ const onMouse = (e) => {
518
+ if (doc.pointerLockElement === target)
519
+ this.mouseMove(e.movementX, e.movementY);
520
+ };
521
+ const onWheel = (e) => {
522
+ // Wheel up (deltaY < 0) is closer. deltaMode 0 = px (stepPx a notch), 1 = lines (3 a
523
+ // notch), 2 = pages (1 a notch).
524
+ const units = e.deltaMode === 1
525
+ ? e.deltaY / 3
526
+ : e.deltaMode === 2
527
+ ? e.deltaY
528
+ : e.deltaY / this.zoomStepPx;
529
+ this.wheel(0 - units);
530
+ };
531
+ const onLock = () => this.syncLock();
532
+ target.addEventListener('wheel', onWheel, { passive: true });
533
+ doc.addEventListener('mousemove', onMouse);
534
+ doc.addEventListener('pointerlockchange', onLock);
535
+ doc.addEventListener('pointerlockerror', onLock);
536
+ this.syncLock();
537
+ this.detachFn = () => {
538
+ removeConsumer();
539
+ if (!shared)
540
+ d.destroy();
541
+ this.dispatcher = null;
542
+ target.removeEventListener('wheel', onWheel);
543
+ doc.removeEventListener('mousemove', onMouse);
544
+ doc.removeEventListener('pointerlockchange', onLock);
545
+ doc.removeEventListener('pointerlockerror', onLock);
546
+ };
547
+ }
548
+ /** The dispatcher the look consumes from while attached (shared or private). */
549
+ dispatcher = null;
550
+ /**
551
+ * The dispatcher consumer: touch pointers feed the zones and pinch; in orbit mode a mouse or
552
+ * pen primary button claims its pointer (so gestures and the router leave it alone) and, unless
553
+ * a linked `Input` feeds the drag, drives the orbit.
554
+ */
555
+ consumer = {
556
+ pointerDown: (p) => {
557
+ this.tapDown(p);
558
+ if (p.device !== 'touch') {
559
+ if (this.modeValue === 'orbit') {
560
+ if (this.lockOnFirstClick && !this.warnedLockOnFirstClick) {
561
+ this.warnedLockOnFirstClick = true;
562
+ console.warn('[look] lockOnFirstClick is ignored in orbit mode');
563
+ }
564
+ if (p.button === 0) {
565
+ this.dispatcher?.claim(p.id, this.consumer);
566
+ if (!this.orbitFromInput)
567
+ this.orbitDown(p.clientX, p.clientY);
568
+ }
569
+ }
570
+ else if (this.lockOnFirstClick && !this.locked)
571
+ void this.request();
572
+ return;
573
+ }
574
+ let inZone = false;
575
+ if (this.moveZone !== 'none' && this.target) {
576
+ const r = this.dispatcher ? this.dispatcher.bounds() : this.target.getBoundingClientRect();
577
+ const left = p.clientX < r.left + r.width / 2;
578
+ inZone = this.moveZone === 'left' ? left : !left;
579
+ }
580
+ this.touchDown(p.id, p.clientX, p.clientY, inZone);
581
+ // The move stick never taps.
582
+ if (p.id === this.moveId && p.id === this.tapId)
583
+ this.tapId = null;
584
+ },
585
+ pointerMove: (p) => {
586
+ if (p.id === this.tapId)
587
+ this.tapMove(p);
588
+ if (p.device === 'touch')
589
+ this.touchMove(p.id, p.clientX, p.clientY);
590
+ else if (!this.orbitFromInput && p.primary)
591
+ this.orbitMove(p.clientX, p.clientY);
592
+ },
593
+ pointerUp: (p) => {
594
+ if (p.id === this.tapId)
595
+ this.tapUp(p);
596
+ if (p.device === 'touch')
597
+ this.touchUp(p.id);
598
+ else if (!this.orbitFromInput && p.button <= 0)
599
+ this.orbitUp();
600
+ },
601
+ pointerCancel: (p) => {
602
+ if (p.id === this.tapId)
603
+ this.tapId = null;
604
+ if (p.device === 'touch')
605
+ this.touchUp(p.id);
606
+ else if (!this.orbitFromInput)
607
+ this.orbitUp();
608
+ },
609
+ cancelAll: () => this.cancelAll(),
610
+ };
611
+ /** A pointer went down: it may tap if it is the only one and the look takes it (see `onTap`). */
612
+ tapDown(p) {
613
+ if (this.tapId !== null) {
614
+ // A second pointer: neither taps.
615
+ this.tapId = null;
616
+ return;
617
+ }
618
+ if (!p.primary || p.button !== 0 || this.tapFns.length === 0 || this.blocked())
619
+ return;
620
+ this.tapId = p.id;
621
+ this.tapDevice = p.device;
622
+ // When the press happened, not when it was handled (ws/input-6).
623
+ this.tapAt = this.now() - p.age;
624
+ this.tapLastX = p.x;
625
+ this.tapLastY = p.y;
626
+ this.tapTravel = 0;
627
+ }
628
+ tapMove(p) {
629
+ this.tapTravel += Math.hypot(p.x - this.tapLastX, p.y - this.tapLastY);
630
+ this.tapLastX = p.x;
631
+ this.tapLastY = p.y;
632
+ if (this.tapTravel > this.tapMaxMove)
633
+ this.tapId = null;
634
+ }
635
+ tapUp(p) {
636
+ this.tapMove(p);
637
+ const id = this.tapId;
638
+ this.tapId = null;
639
+ const held = this.now() - p.age - this.tapAt;
640
+ if (id === null || held > this.tapMaxMs || this.blocked())
641
+ return;
642
+ let x = p.x;
643
+ let y = p.y;
644
+ const t = this.pointerTransform;
645
+ if (t) {
646
+ const m = t(p.x, p.y);
647
+ if (!m)
648
+ return;
649
+ x = m.x;
650
+ y = m.y;
651
+ }
652
+ const fns = this.tapFns;
653
+ for (let i = 0; i < fns.length; i++)
654
+ fns[i](x, y, this.tapDevice);
655
+ }
656
+ /** Stop listening, release the lock and drop every touch. */
657
+ detach() {
658
+ this.release();
659
+ this.detachFn?.();
660
+ this.detachFn = null;
661
+ this.cancelAll();
662
+ if (this.locked) {
663
+ this.locked = false;
664
+ this.events.emit('lockChange', false);
665
+ }
666
+ this.target = null;
667
+ }
668
+ }
669
+ /** 1 if any of the codes is held. */
670
+ function anyHeld(held, codes) {
671
+ if (!codes)
672
+ return 0;
673
+ for (let i = 0; i < codes.length; i++)
674
+ if (held(codes[i]))
675
+ return 1;
676
+ return 0;
677
+ }
678
+ /** `new Look(opts)`: look controls, on `opts.clock` when given (ws/input-8). */
679
+ export function createLook(opts = {}) {
680
+ return new Look(opts);
681
+ }