@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,164 @@
1
+ /// <reference path="../platform/xr-types.d.ts" preserve="true" />
2
+ /**
3
+ * XR controllers and hands as pointers (ws/xr; ARCHITECTURE "Input"). `XrPointerSource` is a
4
+ * `PointerSource` the router polls like any other: each `XRInputSource` of the session becomes
5
+ * one `PointerSample` whose ray is the source's target ray in the reference space (`x`, `y`
6
+ * NaN: there is no screen), with `xr.trigger` and `xr.squeeze` from the `xr-standard` gamepad
7
+ * (buttons 0 and 1) or, without a gamepad, from the session's select and squeeze events, and
8
+ * `xr.pinch` from the hand's index-finger tip and thumb tip when the Hand Input module reports
9
+ * joints. `select = trigger || pinch`, `secondary = squeeze`, `hand` is the handedness. Nothing in
10
+ * the router changes; `{ xr: 'trigger' | 'squeeze' | 'pinch', hand? }` bindings read these.
11
+ *
12
+ * Poses are only readable inside an `XRFrame`, so the source takes a getter for the frame that is
13
+ * running (`() => xrHost.frame`); polled outside one it reports no pointers.
14
+ */
15
+ import { createSample } from './pointer-sources.js';
16
+ /** Position of a joint pose's transform; the pose's `position` is read, not its matrix. */
17
+ function dist(a, b) {
18
+ const p = a.transform.position;
19
+ const q = b.transform.position;
20
+ return Math.hypot(p.x - q.x, p.y - q.y, p.z - q.z);
21
+ }
22
+ export class XrPointerSource {
23
+ session;
24
+ referenceSpace;
25
+ frame;
26
+ samples = new Map();
27
+ pressed = new Map();
28
+ pinching = new Map();
29
+ out = [];
30
+ pinchStart;
31
+ pinchEnd;
32
+ nextKey = 0;
33
+ listening = false;
34
+ constructor(session, referenceSpace,
35
+ /** The `XRFrame` running now, or null between frames (`() => xrHost.frame`). */
36
+ frame, opts = {}) {
37
+ this.session = session;
38
+ this.referenceSpace = referenceSpace;
39
+ this.frame = frame;
40
+ this.pinchStart = opts.pinchStart ?? 0.02;
41
+ this.pinchEnd = opts.pinchEnd ?? 0.035;
42
+ this.attach();
43
+ }
44
+ /** Listens to the session's select and squeeze events (the router calls this; idempotent). */
45
+ attach() {
46
+ if (this.listening)
47
+ return;
48
+ this.listening = true;
49
+ const s = this.session;
50
+ s.addEventListener('selectstart', this.onSelectStart);
51
+ s.addEventListener('selectend', this.onSelectEnd);
52
+ s.addEventListener('squeezestart', this.onSqueezeStart);
53
+ s.addEventListener('squeezeend', this.onSqueezeEnd);
54
+ s.addEventListener('inputsourceschange', this.onSourcesChange);
55
+ }
56
+ /** Stops listening and forgets every pointer. */
57
+ detach() {
58
+ if (!this.listening)
59
+ return;
60
+ this.listening = false;
61
+ const s = this.session;
62
+ s.removeEventListener('selectstart', this.onSelectStart);
63
+ s.removeEventListener('selectend', this.onSelectEnd);
64
+ s.removeEventListener('squeezestart', this.onSqueezeStart);
65
+ s.removeEventListener('squeezeend', this.onSqueezeEnd);
66
+ s.removeEventListener('inputsourceschange', this.onSourcesChange);
67
+ this.samples.clear();
68
+ this.pressed.clear();
69
+ this.pinching.clear();
70
+ }
71
+ poll(_camera) {
72
+ const out = this.out;
73
+ out.length = 0;
74
+ const frame = this.frame();
75
+ if (!frame)
76
+ return out;
77
+ const sources = this.session.inputSources;
78
+ for (let i = 0; i < sources.length; i++) {
79
+ const src = sources[i];
80
+ const pose = frame.getPose(src.targetRaySpace, this.referenceSpace);
81
+ if (!pose)
82
+ continue;
83
+ let s = this.samples.get(src);
84
+ if (!s) {
85
+ s = createSample(this.nextKey++, 'xr');
86
+ s.xr = { trigger: false, squeeze: false, pinch: false };
87
+ this.samples.set(src, s);
88
+ }
89
+ s.hand = src.handedness === 'left' || src.handedness === 'right' ? src.handedness : null;
90
+ const m = pose.transform.matrix;
91
+ const ray = s.ray;
92
+ ray.origin[0] = m[12];
93
+ ray.origin[1] = m[13];
94
+ ray.origin[2] = m[14];
95
+ // The target ray points down the space's -z: the negated third column, normalised.
96
+ const dx = -m[8];
97
+ const dy = -m[9];
98
+ const dz = -m[10];
99
+ const len = Math.hypot(dx, dy, dz) || 1;
100
+ ray.dir[0] = dx / len;
101
+ ray.dir[1] = dy / len;
102
+ ray.dir[2] = dz / len;
103
+ const gp = src.gamepad;
104
+ const ev = this.pressed.get(src);
105
+ const b = s.xr;
106
+ b.trigger = (gp?.buttons[0]?.pressed ?? false) || (ev?.select ?? false);
107
+ b.squeeze = (gp?.buttons[1]?.pressed ?? false) || (ev?.squeeze ?? false);
108
+ b.pinch = this.pinch(frame, src);
109
+ s.select = b.trigger || b.pinch;
110
+ s.secondary = b.squeeze;
111
+ out.push(s);
112
+ }
113
+ return out;
114
+ }
115
+ /** Index tip to thumb tip under `pinchStart` starts a pinch; over `pinchEnd` ends it. */
116
+ pinch(frame, src) {
117
+ const hand = src.hand;
118
+ const getJointPose = frame.getJointPose;
119
+ if (!hand || !getJointPose)
120
+ return false;
121
+ const index = hand.get('index-finger-tip');
122
+ const thumb = hand.get('thumb-tip');
123
+ if (!index || !thumb)
124
+ return false;
125
+ const a = getJointPose.call(frame, index, this.referenceSpace);
126
+ const b = getJointPose.call(frame, thumb, this.referenceSpace);
127
+ if (!a || !b)
128
+ return false;
129
+ const d = dist(a, b);
130
+ const was = this.pinching.get(src) ?? false;
131
+ const now = was ? d <= this.pinchEnd : d <= this.pinchStart;
132
+ if (now !== was)
133
+ this.pinching.set(src, now);
134
+ return now;
135
+ }
136
+ state(src) {
137
+ let p = this.pressed.get(src);
138
+ if (!p) {
139
+ p = { select: false, squeeze: false };
140
+ this.pressed.set(src, p);
141
+ }
142
+ return p;
143
+ }
144
+ onSelectStart = (e) => {
145
+ this.state(e.inputSource).select = true;
146
+ };
147
+ onSelectEnd = (e) => {
148
+ this.state(e.inputSource).select = false;
149
+ };
150
+ onSqueezeStart = (e) => {
151
+ this.state(e.inputSource).squeeze = true;
152
+ };
153
+ onSqueezeEnd = (e) => {
154
+ this.state(e.inputSource).squeeze = false;
155
+ };
156
+ /** A removed source's pointer ends (its key stops appearing) and its state is dropped. */
157
+ onSourcesChange = (e) => {
158
+ for (const src of e.removed) {
159
+ this.samples.delete(src);
160
+ this.pressed.delete(src);
161
+ this.pinching.delete(src);
162
+ }
163
+ };
164
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * A* over a `NavGrid` into a `NavPath`, and string pulling over the result. The open heap,
3
+ * scores and parents are allocated once per grid (the first query is the warm-up) and reused by
4
+ * every query after it.
5
+ */
6
+ import { type NavCell, type NavGrid } from './grid.js';
7
+ import { type NavPath } from './path.js';
8
+ export interface FindPathOptions {
9
+ /** Allow the eight-neighbour moves (√2 steps). Default: `grid.neighbours === 8`. */
10
+ diagonal?: boolean;
11
+ /**
12
+ * Corner cutting is never allowed: a diagonal step needs both cells beside it walkable, so a
13
+ * path never squeezes between two diagonal walls. The option exists to say so in a call.
14
+ */
15
+ cutCorners?: false;
16
+ /** Give up (return false) after expanding this many cells. Default: the whole grid. */
17
+ maxExpand?: number;
18
+ /**
19
+ * The most a path may cost (cost-weighted, inclusive). A cell beyond it is never opened, so
20
+ * an unreachable goal costs the budget's area, not the grid's. Default: no cap.
21
+ */
22
+ maxCost?: number;
23
+ /**
24
+ * Multiplies the heuristic (weighted A*): > 1 expands fewer cells and may return a path up
25
+ * to that factor longer than the best; 1 (default) is exact; 0 is Dijkstra.
26
+ */
27
+ heuristicWeight?: number;
28
+ }
29
+ /**
30
+ * Finds the cheapest walkable route from cell `from` to cell `to` and writes its cell centres,
31
+ * in world XZ, into `out` (`out.cursor` 0, `out.version` = `grid.version`). Returns false, with
32
+ * `out.length` 0, when either end is unwalkable or outside the grid, when no route exists, or
33
+ * when `maxExpand` is hit. A step costs its length (1 or √2) times the destination cell's cost;
34
+ * the octile (or Manhattan) heuristic is admissible for costs ≥ 1. `from === to` is a one-point
35
+ * path. Allocates nothing after the grid's first query, except to grow `out`.
36
+ */
37
+ export declare function findPath(grid: NavGrid, from: Readonly<NavCell>, to: Readonly<NavCell>, out: NavPath, opts?: FindPathOptions): boolean;
38
+ /**
39
+ * String pulling: drops every waypoint that a straight line of walkable cells can skip, in
40
+ * place, so a staircase of cell centres becomes a few straight legs. On a 4-neighbour grid a
41
+ * leg never leaves its row or column: only collinear waypoints are dropped, so the path keeps
42
+ * every corner and makes no diagonal cut. `path.cursor` is reset to 0. Returns the path.
43
+ * Allocation-free.
44
+ */
45
+ export declare function smoothPath(grid: NavGrid, path: NavPath): NavPath;
@@ -0,0 +1,182 @@
1
+ /**
2
+ * A* over a `NavGrid` into a `NavPath`, and string pulling over the result. The open heap,
3
+ * scores and parents are allocated once per grid (the first query is the warm-up) and reused by
4
+ * every query after it.
5
+ */
6
+ import { hasLineOfWalkable, NEIGHBOUR_X, NEIGHBOUR_Y, stepCost, } from './grid.js';
7
+ import { CellHeap } from './heap.js';
8
+ import { reservePath } from './path.js';
9
+ const SQRT2 = Math.SQRT2;
10
+ const NX = NEIGHBOUR_X;
11
+ const NY = NEIGHBOUR_Y;
12
+ const scratchFor = new WeakMap();
13
+ /** Octile distance with diagonals, Manhattan without: admissible for cell costs ≥ 1. */
14
+ function heuristic(x, y, tx, ty, diagonal) {
15
+ const dx = x > tx ? x - tx : tx - x;
16
+ const dy = y > ty ? y - ty : ty - y;
17
+ if (!diagonal)
18
+ return dx + dy;
19
+ return dx > dy ? dx + (SQRT2 - 1) * dy : dy + (SQRT2 - 1) * dx;
20
+ }
21
+ function scratch(grid) {
22
+ let s = scratchFor.get(grid);
23
+ if (!s) {
24
+ const n = grid.size;
25
+ const f = new Float64Array(n);
26
+ s = {
27
+ g: new Float64Array(n),
28
+ f,
29
+ parent: new Int32Array(n),
30
+ seen: new Uint32Array(n),
31
+ closed: new Uint32Array(n),
32
+ heap: new CellHeap(n, f),
33
+ stamp: 0,
34
+ };
35
+ scratchFor.set(grid, s);
36
+ }
37
+ return s;
38
+ }
39
+ /**
40
+ * Finds the cheapest walkable route from cell `from` to cell `to` and writes its cell centres,
41
+ * in world XZ, into `out` (`out.cursor` 0, `out.version` = `grid.version`). Returns false, with
42
+ * `out.length` 0, when either end is unwalkable or outside the grid, when no route exists, or
43
+ * when `maxExpand` is hit. A step costs its length (1 or √2) times the destination cell's cost;
44
+ * the octile (or Manhattan) heuristic is admissible for costs ≥ 1. `from === to` is a one-point
45
+ * path. Allocates nothing after the grid's first query, except to grow `out`.
46
+ */
47
+ export function findPath(grid, from, to, out, opts = {}) {
48
+ out.length = 0;
49
+ out.cursor = 0;
50
+ out.version = grid.version;
51
+ if (!grid.isWalkable(from.x, from.y) || !grid.isWalkable(to.x, to.y))
52
+ return false;
53
+ const diagonal = opts.diagonal ?? grid.neighbours === 8;
54
+ const maxExpand = opts.maxExpand ?? grid.size;
55
+ const maxCost = opts.maxCost ?? Infinity;
56
+ const weight = opts.heuristicWeight ?? 1;
57
+ const width = grid.width;
58
+ const s = scratch(grid);
59
+ const { g, f, parent, seen, closed, heap } = s;
60
+ // Stamps wrap at 2^32; a wrap to 0 would alias a stale entry, so skip 0.
61
+ s.stamp = (s.stamp + 1) >>> 0 || 1;
62
+ const stamp = s.stamp;
63
+ heap.clear();
64
+ const tx = to.x;
65
+ const ty = to.y;
66
+ const start = from.y * width + from.x;
67
+ const goal = ty * width + tx;
68
+ g[start] = 0;
69
+ f[start] = weight * heuristic(from.x, from.y, tx, ty, diagonal);
70
+ parent[start] = -1;
71
+ seen[start] = stamp;
72
+ heap.pushOrDecrease(start);
73
+ const dirs = diagonal ? 8 : 4;
74
+ let expanded = 0;
75
+ let found = false;
76
+ while (heap.size > 0) {
77
+ const cur = heap.pop();
78
+ if (cur === goal) {
79
+ found = true;
80
+ break;
81
+ }
82
+ if (++expanded > maxExpand)
83
+ break;
84
+ closed[cur] = stamp;
85
+ const cx = cur % width;
86
+ const cy = (cur - cx) / width;
87
+ const gc = g[cur];
88
+ for (let d = 0; d < dirs; d++) {
89
+ const step = stepCost(grid, cur, cx, cy, d);
90
+ if (step === Infinity)
91
+ continue;
92
+ const nx = cx + NX[d];
93
+ const ny = cy + NY[d];
94
+ const ni = ny * width + nx;
95
+ if (closed[ni] === stamp)
96
+ continue;
97
+ const ng = gc + step;
98
+ if (ng > maxCost)
99
+ continue;
100
+ if (seen[ni] === stamp && ng >= g[ni])
101
+ continue;
102
+ seen[ni] = stamp;
103
+ g[ni] = ng;
104
+ f[ni] = ng + weight * heuristic(nx, ny, tx, ty, diagonal);
105
+ parent[ni] = cur;
106
+ heap.pushOrDecrease(ni);
107
+ }
108
+ }
109
+ if (!found)
110
+ return false;
111
+ let count = 0;
112
+ for (let i = goal; i >= 0; i = parent[i])
113
+ count++;
114
+ reservePath(out, count);
115
+ const p = out.points;
116
+ const cs = grid.cellSize;
117
+ const ox = grid.origin.x;
118
+ const oz = grid.origin.z;
119
+ let k = count - 1;
120
+ for (let i = goal; i >= 0; i = parent[i], k--) {
121
+ const x = i % width;
122
+ const y = (i - x) / width;
123
+ p[k * 2] = ox + (x + 0.5) * cs;
124
+ p[k * 2 + 1] = oz + (y + 0.5) * cs;
125
+ }
126
+ out.length = count;
127
+ return true;
128
+ }
129
+ const sa = { x: 0, y: 0 };
130
+ const sb = { x: 0, y: 0 };
131
+ /**
132
+ * String pulling: drops every waypoint that a straight line of walkable cells can skip, in
133
+ * place, so a staircase of cell centres becomes a few straight legs. On a 4-neighbour grid a
134
+ * leg never leaves its row or column: only collinear waypoints are dropped, so the path keeps
135
+ * every corner and makes no diagonal cut. `path.cursor` is reset to 0. Returns the path.
136
+ * Allocation-free.
137
+ */
138
+ export function smoothPath(grid, path) {
139
+ const n = path.length;
140
+ path.cursor = 0;
141
+ if (n < 3)
142
+ return path;
143
+ const p = path.points;
144
+ let write = 1;
145
+ if (grid.neighbours === 4) {
146
+ for (let i = 1; i < n - 1; i++) {
147
+ const ax = p[i * 2] - p[write * 2 - 2];
148
+ const az = p[i * 2 + 1] - p[write * 2 - 1];
149
+ const bx = p[i * 2 + 2] - p[i * 2];
150
+ const bz = p[i * 2 + 3] - p[i * 2 + 1];
151
+ // Keep the waypoint when the run bends (the cross product of the two legs is not zero).
152
+ if (ax * bz - az * bx !== 0) {
153
+ p[write * 2] = p[i * 2];
154
+ p[write * 2 + 1] = p[i * 2 + 1];
155
+ write++;
156
+ }
157
+ }
158
+ p[write * 2] = p[n * 2 - 2];
159
+ p[write * 2 + 1] = p[n * 2 - 1];
160
+ path.length = write + 1;
161
+ return path;
162
+ }
163
+ let anchor = 0;
164
+ while (anchor < n - 1) {
165
+ grid.toCell(p[anchor * 2], p[anchor * 2 + 1], sa);
166
+ // The furthest waypoint visible from the anchor; the next one is always reachable.
167
+ let far = anchor + 1;
168
+ for (let j = n - 1; j > anchor + 1; j--) {
169
+ grid.toCell(p[j * 2], p[j * 2 + 1], sb);
170
+ if (hasLineOfWalkable(grid, sa.x, sa.y, sb.x, sb.y)) {
171
+ far = j;
172
+ break;
173
+ }
174
+ }
175
+ p[write * 2] = p[far * 2];
176
+ p[write * 2 + 1] = p[far * 2 + 1];
177
+ write++;
178
+ anchor = far;
179
+ }
180
+ path.length = write;
181
+ return path;
182
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * A corridor: the polygon list a mesh path crossed, kept beside a moving agent. `advance(x, z)`
3
+ * drops the polygons the agent has left and string-pulls the rest to the target, so each frame
4
+ * costs one funnel over what remains, never a new search. `valid(mesh)` says whether the mesh
5
+ * changed under it (a carve, an obstacle) and a replan is due. Allocated once for
6
+ * `maxWaypoints`.
7
+ */
8
+ import { type NavPath3 } from './mesh/mesh-path.js';
9
+ import type { NavMesh, NavPoint3 } from './mesh/navmesh.js';
10
+ export interface Corridor {
11
+ /** The remaining polygons, `offset .. offset + count` into `polys`. */
12
+ readonly polys: Int32Array;
13
+ readonly offset: number;
14
+ readonly count: number;
15
+ /** The target the corridor leads to (the path's last point). */
16
+ readonly target: NavPoint3;
17
+ /** The mesh version the corridor was set from. */
18
+ readonly version: number;
19
+ /** The pulled string from the last `advance`: the agent, every corner, the target. */
20
+ readonly path: NavPath3;
21
+ /** Takes a path (its `polys` corridor and last point); an empty path clears the corridor. */
22
+ set(path: Readonly<NavPath3>): void;
23
+ /** Empties the corridor. */
24
+ clear(): void;
25
+ /** The polygon the agent stands in, or -1 when the corridor is empty. */
26
+ current(): number;
27
+ /**
28
+ * Moves the corridor's head to the polygon holding `(x, z)` (searching forward through the
29
+ * remaining polygons, the first few of them) and writes the next corner to steer to into
30
+ * `out`. Returns false, leaving `out` untouched, when the corridor is empty.
31
+ */
32
+ advance(x: number, z: number, out: NavPoint3): boolean;
33
+ /**
34
+ * True while the mesh is still at the corridor's version (a carve or an obstacle bumps it) and
35
+ * no remaining polygon after the agent's own is an obstacle.
36
+ */
37
+ valid(mesh: NavMesh): boolean;
38
+ }
39
+ /** A corridor over `mesh` with room for `maxWaypoints` polygons. */
40
+ export declare function createCorridor(mesh: NavMesh, maxWaypoints?: number): Corridor;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * A corridor: the polygon list a mesh path crossed, kept beside a moving agent. `advance(x, z)`
3
+ * drops the polygons the agent has left and string-pulls the rest to the target, so each frame
4
+ * costs one funnel over what remains, never a new search. `valid(mesh)` says whether the mesh
5
+ * changed under it (a carve, an obstacle) and a replan is due. Allocated once for
6
+ * `maxWaypoints`.
7
+ */
8
+ import { OBSTACLE_AREA } from './mesh/areas.js';
9
+ import { createNavPath3, pullString, reservePolys3 } from './mesh/mesh-path.js';
10
+ const from = { x: 0, y: 0, z: 0 };
11
+ /** A corridor over `mesh` with room for `maxWaypoints` polygons. */
12
+ export function createCorridor(mesh, maxWaypoints = 64) {
13
+ const polys = new Int32Array(Math.max(1, maxWaypoints));
14
+ const path = createNavPath3(Math.max(2, maxWaypoints));
15
+ let offset = 0;
16
+ let count = 0;
17
+ let version = -1;
18
+ const target = { x: 0, y: 0, z: 0 };
19
+ const corridor = {
20
+ polys,
21
+ get offset() {
22
+ return offset;
23
+ },
24
+ get count() {
25
+ return count;
26
+ },
27
+ target,
28
+ get version() {
29
+ return version;
30
+ },
31
+ path,
32
+ set(p) {
33
+ version = p.version;
34
+ offset = 0;
35
+ count = Math.min(p.polyCount, polys.length);
36
+ polys.set(p.polys.subarray(0, count));
37
+ if (p.length > 0) {
38
+ target.x = p.points[(p.length - 1) * 3];
39
+ target.y = p.points[(p.length - 1) * 3 + 1];
40
+ target.z = p.points[(p.length - 1) * 3 + 2];
41
+ }
42
+ else {
43
+ count = 0;
44
+ }
45
+ reservePolys3(path, count);
46
+ path.length = 0;
47
+ path.polyCount = 0;
48
+ },
49
+ clear() {
50
+ count = 0;
51
+ offset = 0;
52
+ path.length = 0;
53
+ },
54
+ current() {
55
+ return count > 0 ? polys[offset] : -1;
56
+ },
57
+ advance(x, z, out) {
58
+ if (count === 0)
59
+ return false;
60
+ // Drop every polygon the agent has passed: look ahead a few, take the furthest that holds it.
61
+ const look = Math.min(count, 4);
62
+ let at = -1;
63
+ for (let i = 0; i < look; i++) {
64
+ if (mesh.containsXZ(polys[offset + i], x, z))
65
+ at = i;
66
+ }
67
+ if (at > 0) {
68
+ offset += at;
69
+ count -= at;
70
+ }
71
+ from.x = x;
72
+ from.z = z;
73
+ from.y = mesh.polyHeight(polys[offset], x, z);
74
+ pullString(mesh, polys, offset, count, from, target, path);
75
+ // The first corner after the agent's own position.
76
+ const k = path.length > 1 ? 1 : 0;
77
+ out.x = path.points[k * 3];
78
+ out.y = path.points[k * 3 + 1];
79
+ out.z = path.points[k * 3 + 2];
80
+ return true;
81
+ },
82
+ valid(m) {
83
+ if (count === 0 || m.version !== version)
84
+ return false;
85
+ // The polygon the agent stands in is exempt: an obstacle stamped under it must be walked
86
+ // out of, and a replan from inside it would find the same corridor again.
87
+ for (let i = 1; i < count; i++) {
88
+ if (m.area[polys[offset + i]] === OBSTACLE_AREA)
89
+ return false;
90
+ }
91
+ return true;
92
+ },
93
+ };
94
+ return corridor;
95
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * `Crowd`: local avoidance for many agents on the XZ plane by ORCA (the RVO2 method). Each tick,
3
+ * every agent picks the velocity nearest its preferred one that keeps it clear of its neighbours
4
+ * (and of the obstacles of an `ObstacleSet`, as static lines) for `timeHorizon` seconds, then
5
+ * moves by it. Neighbours come from a hashed uniform grid. Attached to a `NavMesh`, agents walk
6
+ * corridors to targets (`setTarget`, searched through a `PathQueue` or synchronously), their
7
+ * preferred velocity steers along the pulled string, and after each move they are clamped onto
8
+ * the mesh with `y` from its height. Everything is allocated at creation (and at `attach`) for
9
+ * `maxAgents`; `update` allocates nothing.
10
+ */
11
+ import { type Corridor } from './corridor.js';
12
+ import type { NavMesh } from './mesh/navmesh.js';
13
+ import type { ObstacleSet } from './obstacles.js';
14
+ import type { PathQueue } from './query-queue.js';
15
+ export interface CrowdOptions {
16
+ maxAgents: number;
17
+ /** Neighbours considered per agent, nearest first. Default 10. */
18
+ maxNeighbors?: number;
19
+ /** Seconds ahead an agent keeps clear of the others. Default 2. */
20
+ timeHorizon?: number;
21
+ /** Agents farther apart than this ignore each other (grid cell size). Default 4. */
22
+ neighborDist?: number;
23
+ }
24
+ export interface CrowdAgentOptions {
25
+ x: number;
26
+ z: number;
27
+ radius: number;
28
+ maxSpeed: number;
29
+ /** Where it wants to go, world units per second. Default still. */
30
+ prefVelocity?: {
31
+ x: number;
32
+ z: number;
33
+ };
34
+ }
35
+ export interface CrowdAgent {
36
+ /** False for an empty slot. */
37
+ active: boolean;
38
+ x: number;
39
+ z: number;
40
+ /** The velocity the last `update` chose. */
41
+ vx: number;
42
+ vz: number;
43
+ radius: number;
44
+ maxSpeed: number;
45
+ prefX: number;
46
+ prefZ: number;
47
+ /** On a mesh: the surface height under the agent (0 otherwise). */
48
+ y: number;
49
+ /** On a mesh: the polygon the agent stands in, -1 off the mesh or unattached. */
50
+ poly: number;
51
+ /** On a mesh: the corridor to the agent's target (null unattached). */
52
+ corridor: Corridor | null;
53
+ /** True once the agent came within `arriveRadius` of its target; false when no target. */
54
+ targetReached: boolean;
55
+ }
56
+ export interface CrowdAttachOptions {
57
+ /** Searches go through this queue when given, else `findMeshPath` runs inside `setTarget`. */
58
+ queue?: PathQueue;
59
+ /** Corridor capacity per agent. Default 64. */
60
+ maxWaypoints?: number;
61
+ /** An agent this close to its target has reached it. Default: its radius. */
62
+ arriveRadius?: number;
63
+ /** `steer.arrive` slows an agent inside this distance of its target. Default 1. */
64
+ slowRadius?: number;
65
+ }
66
+ export interface Crowd {
67
+ /** One slot per index up to `maxAgents`; check `active`. The array and its objects never change identity. */
68
+ readonly agents: readonly CrowdAgent[];
69
+ /** Adds an agent and returns its index, or -1 when the crowd is full. */
70
+ add(agent: CrowdAgentOptions): number;
71
+ remove(index: number): void;
72
+ setPrefVelocity(index: number, x: number, z: number): void;
73
+ setPosition(index: number, x: number, z: number): void;
74
+ /** Chooses every agent's velocity, then moves them by `dt` seconds. */
75
+ update(dt: number): void;
76
+ /**
77
+ * Keeps the agents on `mesh`: every agent gets a corridor, `setTarget` plans through it, and
78
+ * each `update` steers along it and clamps positions (and `y`) onto the mesh. Allocates per
79
+ * agent; call once at setup.
80
+ */
81
+ attach(mesh: NavMesh, opts?: CrowdAttachOptions): void;
82
+ /**
83
+ * Sends an attached agent to `(x, y, z)`: through the queue when attached with one (the agent
84
+ * waits until its path arrives), else by a synchronous search. A corridor that becomes invalid
85
+ * (the mesh version changed) replans the same way. `targetReached` resets to false.
86
+ */
87
+ setTarget(index: number, x: number, y: number, z: number): void;
88
+ /** Keeps agents clear of the set's obstacles (discs and boxes as static ORCA lines); null detaches. */
89
+ obstacles(set: ObstacleSet | null): void;
90
+ /** Corridor replans since creation (a changed mesh under a corridor, or a target set). */
91
+ readonly replans: number;
92
+ }
93
+ /** A crowd with room for `maxAgents`. */
94
+ export declare function createCrowd(opts: CrowdOptions): Crowd;