@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,615 @@
1
+ export function createRay() {
2
+ return { origin: [0, 0, 0], dir: [0, 0, 1] };
3
+ }
4
+ export function createHit(target) {
5
+ return { point: [0, 0, 0], normal: null, distance: 0, target };
6
+ }
7
+ /** `out = ray.origin + t * ray.dir`. */
8
+ export function rayAt(ray, t, out) {
9
+ out[0] = ray.origin[0] + ray.dir[0] * t;
10
+ out[1] = ray.origin[1] + ray.dir[1] * t;
11
+ out[2] = ray.origin[2] + ray.dir[2] * t;
12
+ return out;
13
+ }
14
+ const near = { x: 0, y: 0, z: 0 };
15
+ const far = { x: 0, y: 0, z: 0 };
16
+ /**
17
+ * The ray through screen point (`sx`, `sy`) (the camera's screen units): from the near plane
18
+ * (`screenToWorld(…, 0)`) towards the far one (`…, 1`; depth 0.5 when the far plane is at
19
+ * infinity). For `Camera.ortho2d` the origin is the world point on the near plane
20
+ * (z = -ORTHO2D_HALF_DEPTH) and `dir` is +z, into the screen.
21
+ * Returns false (and leaves `out` alone) when the camera gives no usable ray.
22
+ */
23
+ export function screenRay(camera, sx, sy, out) {
24
+ camera.screenToWorld(sx, sy, 0, near);
25
+ camera.screenToWorld(sx, sy, 1, far);
26
+ if (!Number.isFinite(far.x) || !Number.isFinite(far.y) || !Number.isFinite(far.z)) {
27
+ camera.screenToWorld(sx, sy, 0.5, far);
28
+ }
29
+ const dx = far.x - near.x;
30
+ const dy = far.y - near.y;
31
+ const dz = far.z - near.z;
32
+ const len = Math.hypot(dx, dy, dz);
33
+ if (!(len > 0) || !Number.isFinite(len) || !Number.isFinite(near.x + near.y + near.z)) {
34
+ return false;
35
+ }
36
+ const o = out.origin;
37
+ const d = out.dir;
38
+ o[0] = near.x;
39
+ o[1] = near.y;
40
+ o[2] = near.z;
41
+ d[0] = dx / len;
42
+ d[1] = dy / len;
43
+ d[2] = dz / len;
44
+ return true;
45
+ }
46
+ const EPS = 1e-9;
47
+ /**
48
+ * Hits a plane: the plane z = `plane` when it is a number (a 2D game's world, default 0), or
49
+ * any `RayPlane` (a floor at y = 0 is `{ normal: [0, 1, 0] }`). The hit point is where the ray
50
+ * crosses it, so through `Camera.ortho2d` the z-plane hit is the world point under the pointer.
51
+ * Rays parallel to the plane or pointing away from it miss. The hit's normal is the plane's,
52
+ * unit length, turned to face the ray. `target` is what every hit carries (default `null`).
53
+ */
54
+ export function planeTester(plane = 0, target = null) {
55
+ const hit = createHit(target);
56
+ const normal = [0, 0, 0];
57
+ if (typeof plane === 'number') {
58
+ const z = plane;
59
+ return (ray) => {
60
+ const dz = ray.dir[2];
61
+ if (Math.abs(dz) < EPS)
62
+ return null;
63
+ const t = (z - ray.origin[2]) / dz;
64
+ if (t < 0)
65
+ return null;
66
+ rayAt(ray, t, hit.point);
67
+ hit.point[2] = z;
68
+ normal[2] = dz > 0 ? -1 : 1;
69
+ hit.normal = normal;
70
+ hit.distance = t;
71
+ hit.target = target;
72
+ return hit;
73
+ };
74
+ }
75
+ return (ray) => {
76
+ const n = plane.normal;
77
+ const len = Math.hypot(n[0], n[1], n[2]);
78
+ if (!(len > 0))
79
+ return null;
80
+ const nx = n[0] / len;
81
+ const ny = n[1] / len;
82
+ const nz = n[2] / len;
83
+ const d = (plane.offset ?? 0) / len;
84
+ const dn = ray.dir[0] * nx + ray.dir[1] * ny + ray.dir[2] * nz;
85
+ if (Math.abs(dn) < EPS)
86
+ return null;
87
+ const t = (d - (ray.origin[0] * nx + ray.origin[1] * ny + ray.origin[2] * nz)) / dn;
88
+ if (t < 0)
89
+ return null;
90
+ rayAt(ray, t, hit.point);
91
+ const s = dn > 0 ? -1 : 1;
92
+ normal[0] = nx * s;
93
+ normal[1] = ny * s;
94
+ normal[2] = nz * s;
95
+ hit.normal = normal;
96
+ hit.distance = t;
97
+ hit.target = target;
98
+ return hit;
99
+ };
100
+ }
101
+ /**
102
+ * Hits the nearest of `boxes` (read on every call, so the game may edit the array and its
103
+ * boxes). A ray that starts inside a box hits it at distance 0 with no normal. Equal distances
104
+ * go to the earlier box. Flat boxes (`min[i] === max[i]`) work, so 2D quads at z = 0 can be
105
+ * picked through `Camera.ortho2d`.
106
+ */
107
+ export function aabbTester(boxes) {
108
+ const hit = createHit(undefined);
109
+ const normal = [0, 0, 0];
110
+ return (ray) => {
111
+ let best = Infinity;
112
+ let bestBox = null;
113
+ let bestAxis = -1;
114
+ let bestSign = 0;
115
+ for (let b = 0; b < boxes.length; b++) {
116
+ const box = boxes[b];
117
+ let tmin = -Infinity;
118
+ let tmax = Infinity;
119
+ let axis = -1;
120
+ let sign = 0;
121
+ let miss = false;
122
+ for (let i = 0; i < 3; i++) {
123
+ const o = ray.origin[i];
124
+ const d = ray.dir[i];
125
+ const lo = box.min[i];
126
+ const hi = box.max[i];
127
+ if (Math.abs(d) < EPS) {
128
+ if (o < lo || o > hi) {
129
+ miss = true;
130
+ break;
131
+ }
132
+ continue;
133
+ }
134
+ let t1 = (lo - o) / d;
135
+ let t2 = (hi - o) / d;
136
+ // Entering through the `lo` face means travelling +axis: the face normal is -axis.
137
+ let s = -1;
138
+ if (t1 > t2) {
139
+ const tt = t1;
140
+ t1 = t2;
141
+ t2 = tt;
142
+ s = 1;
143
+ }
144
+ if (t1 > tmin) {
145
+ tmin = t1;
146
+ axis = i;
147
+ sign = s;
148
+ }
149
+ if (t2 < tmax)
150
+ tmax = t2;
151
+ if (tmin > tmax) {
152
+ miss = true;
153
+ break;
154
+ }
155
+ }
156
+ if (miss || tmax < 0)
157
+ continue;
158
+ const inside = tmin < 0;
159
+ const t = inside ? 0 : tmin;
160
+ if (t < best) {
161
+ best = t;
162
+ bestBox = box;
163
+ bestAxis = inside ? -1 : axis;
164
+ bestSign = sign;
165
+ }
166
+ }
167
+ if (!bestBox)
168
+ return null;
169
+ rayAt(ray, best, hit.point);
170
+ hit.distance = best;
171
+ hit.target = bestBox.target;
172
+ if (bestAxis < 0) {
173
+ hit.normal = null;
174
+ }
175
+ else {
176
+ normal[0] = 0;
177
+ normal[1] = 0;
178
+ normal[2] = 0;
179
+ normal[bestAxis] = bestSign;
180
+ hit.normal = normal;
181
+ }
182
+ return hit;
183
+ };
184
+ }
185
+ /** Floats per vertex and the position's float offset in `VERTEX_LAYOUT_3D` (x, y, z first). */
186
+ const DEFAULT_STRIDE = 12;
187
+ const DEFAULT_OFFSET = 0;
188
+ /**
189
+ * Inverts the 3×3 part of a 3×4 world matrix into `out` (9 floats, row-major). Returns false
190
+ * (leaving `out` alone) when the matrix is singular (a zero scale).
191
+ */
192
+ function invert3x3(m, out) {
193
+ const a = m[0];
194
+ const b = m[1];
195
+ const c = m[2];
196
+ const d = m[4];
197
+ const e = m[5];
198
+ const f = m[6];
199
+ const g = m[8];
200
+ const h = m[9];
201
+ const i = m[10];
202
+ const A = e * i - f * h;
203
+ const B = -(d * i - f * g);
204
+ const C = d * h - e * g;
205
+ const det = a * A + b * B + c * C;
206
+ if (!(Math.abs(det) > 1e-20) || !Number.isFinite(det))
207
+ return false;
208
+ const inv = 1 / det;
209
+ out[0] = A * inv;
210
+ out[1] = -(b * i - c * h) * inv;
211
+ out[2] = (b * f - c * e) * inv;
212
+ out[3] = B * inv;
213
+ out[4] = (a * i - c * g) * inv;
214
+ out[5] = -(a * f - c * d) * inv;
215
+ out[6] = C * inv;
216
+ out[7] = -(a * h - b * g) * inv;
217
+ out[8] = (a * e - b * d) * inv;
218
+ return true;
219
+ }
220
+ /**
221
+ * `out` = `ray` in the object space of a 3×4 world matrix whose 3×3 inverse is `inv`, with
222
+ * `out.dir` normalised. Returns the world units per object-space unit along the ray (an
223
+ * object-space distance times it is the world distance), or 0 when the direction collapses.
224
+ */
225
+ function localRay(ray, m, inv, out) {
226
+ const ox = ray.origin[0] - m[3];
227
+ const oy = ray.origin[1] - m[7];
228
+ const oz = ray.origin[2] - m[11];
229
+ const o = out.origin;
230
+ o[0] = inv[0] * ox + inv[1] * oy + inv[2] * oz;
231
+ o[1] = inv[3] * ox + inv[4] * oy + inv[5] * oz;
232
+ o[2] = inv[6] * ox + inv[7] * oy + inv[8] * oz;
233
+ const dx = ray.dir[0];
234
+ const dy = ray.dir[1];
235
+ const dz = ray.dir[2];
236
+ const lx = inv[0] * dx + inv[1] * dy + inv[2] * dz;
237
+ const ly = inv[3] * dx + inv[4] * dy + inv[5] * dz;
238
+ const lz = inv[6] * dx + inv[7] * dy + inv[8] * dz;
239
+ const len = Math.hypot(lx, ly, lz);
240
+ if (!(len > 0) || !Number.isFinite(len))
241
+ return 0;
242
+ const d = out.dir;
243
+ d[0] = lx / len;
244
+ d[1] = ly / len;
245
+ d[2] = lz / len;
246
+ return 1 / len;
247
+ }
248
+ /**
249
+ * Object-space normal `n` to a unit world normal through the inverse transpose of the 3×3 part
250
+ * (`inv` is the inverse): correct under non-uniform scale. Writes `out`.
251
+ */
252
+ function worldNormal(n, inv, out) {
253
+ const x = inv[0] * n[0] + inv[3] * n[1] + inv[6] * n[2];
254
+ const y = inv[1] * n[0] + inv[4] * n[1] + inv[7] * n[2];
255
+ const z = inv[2] * n[0] + inv[5] * n[1] + inv[8] * n[2];
256
+ const len = Math.hypot(x, y, z);
257
+ if (len > 0) {
258
+ out[0] = x / len;
259
+ out[1] = y / len;
260
+ out[2] = z / len;
261
+ }
262
+ else {
263
+ out[0] = n[0];
264
+ out[1] = n[1];
265
+ out[2] = n[2];
266
+ }
267
+ return out;
268
+ }
269
+ const transformInv = new Float32Array(9);
270
+ /**
271
+ * `outRay` = `ray` in the object space of `worldMatrix3x4` (12 floats, row-major, as
272
+ * `Transform.world`): the 3×3 is inverted (non-uniform scale is fine), the translation
273
+ * removed, and `outRay.dir` normalised. Returns the world units per object-space unit along
274
+ * the ray, so a distance found in object space times the result is the world distance. Returns
275
+ * 0 (and leaves `outRay` alone) when the matrix is singular. No allocation.
276
+ */
277
+ export function transformRayInto(ray, worldMatrix3x4, outRay) {
278
+ if (!invert3x3(worldMatrix3x4, transformInv))
279
+ return 0;
280
+ return localRay(ray, worldMatrix3x4, transformInv, outRay);
281
+ }
282
+ /**
283
+ * Möller–Trumbore: the distance along `ray` to triangle `a, b, c` (counter-clockwise seen from
284
+ * the front), or -1 for a miss. With `cullBack` a triangle whose back faces the ray misses.
285
+ * `out`, when given, receives the unit triangle normal turned to face the ray. No allocation.
286
+ */
287
+ export function rayTriangle(ray, a, b, c, cullBack, out) {
288
+ const e1x = b[0] - a[0];
289
+ const e1y = b[1] - a[1];
290
+ const e1z = b[2] - a[2];
291
+ const e2x = c[0] - a[0];
292
+ const e2y = c[1] - a[1];
293
+ const e2z = c[2] - a[2];
294
+ const dx = ray.dir[0];
295
+ const dy = ray.dir[1];
296
+ const dz = ray.dir[2];
297
+ // p = dir × e2
298
+ const px = dy * e2z - dz * e2y;
299
+ const py = dz * e2x - dx * e2z;
300
+ const pz = dx * e2y - dy * e2x;
301
+ const det = e1x * px + e1y * py + e1z * pz;
302
+ if (cullBack ? det < EPS : Math.abs(det) < EPS)
303
+ return -1;
304
+ const invDet = 1 / det;
305
+ const tx = ray.origin[0] - a[0];
306
+ const ty = ray.origin[1] - a[1];
307
+ const tz = ray.origin[2] - a[2];
308
+ const u = (tx * px + ty * py + tz * pz) * invDet;
309
+ if (u < 0 || u > 1)
310
+ return -1;
311
+ // q = t × e1
312
+ const qx = ty * e1z - tz * e1y;
313
+ const qy = tz * e1x - tx * e1z;
314
+ const qz = tx * e1y - ty * e1x;
315
+ const v = (dx * qx + dy * qy + dz * qz) * invDet;
316
+ if (v < 0 || u + v > 1)
317
+ return -1;
318
+ const t = (e2x * qx + e2y * qy + e2z * qz) * invDet;
319
+ if (t < 0)
320
+ return -1;
321
+ if (out) {
322
+ let nx = e1y * e2z - e1z * e2y;
323
+ let ny = e1z * e2x - e1x * e2z;
324
+ let nz = e1x * e2y - e1y * e2x;
325
+ if (nx * dx + ny * dy + nz * dz > 0) {
326
+ nx = -nx;
327
+ ny = -ny;
328
+ nz = -nz;
329
+ }
330
+ const len = Math.hypot(nx, ny, nz);
331
+ out[0] = nx / len;
332
+ out[1] = ny / len;
333
+ out[2] = nz / len;
334
+ }
335
+ return t;
336
+ }
337
+ /**
338
+ * The entry distance of `ray` (unit `dir`) into a sphere, or -1 for a miss. A ray starting
339
+ * inside returns 0.
340
+ */
341
+ function raySphere(ray, cx, cy, cz, r) {
342
+ const ox = ray.origin[0] - cx;
343
+ const oy = ray.origin[1] - cy;
344
+ const oz = ray.origin[2] - cz;
345
+ const b = ox * ray.dir[0] + oy * ray.dir[1] + oz * ray.dir[2];
346
+ const c = ox * ox + oy * oy + oz * oz - r * r;
347
+ const disc = b * b - c;
348
+ if (disc < 0)
349
+ return -1;
350
+ const s = Math.sqrt(disc);
351
+ const t0 = -b - s;
352
+ if (t0 >= 0)
353
+ return t0;
354
+ return -b + s >= 0 ? 0 : -1;
355
+ }
356
+ /**
357
+ * Hits `bounds` (an object-space sphere, read each call) placed by `transform` (read each call).
358
+ * The hit carries `point` and `normal` in world space and `distance` in world units, under any
359
+ * rotation and non-uniform scale (an ellipsoid). A ray that starts inside hits at distance 0
360
+ * with `normal: null`. Zero allocations per call.
361
+ */
362
+ export function sphereTester(transform, bounds, target = null) {
363
+ const hit = createHit(target);
364
+ const normal = [0, 0, 0];
365
+ const local = [0, 0, 0];
366
+ const inv = new Float32Array(9);
367
+ const lray = createRay();
368
+ return (ray) => {
369
+ const m = transform.world;
370
+ if (!invert3x3(m, inv))
371
+ return null;
372
+ const scale = localRay(ray, m, inv, lray);
373
+ if (scale === 0)
374
+ return null;
375
+ const c = bounds.center;
376
+ const t = raySphere(lray, c[0], c[1], c[2], bounds.radius);
377
+ if (t < 0)
378
+ return null;
379
+ const dist = t * scale;
380
+ rayAt(ray, dist, hit.point);
381
+ hit.distance = dist;
382
+ hit.target = target;
383
+ if (t === 0) {
384
+ hit.normal = null;
385
+ }
386
+ else {
387
+ rayAt(lray, t, local);
388
+ local[0] -= c[0];
389
+ local[1] -= c[1];
390
+ local[2] -= c[2];
391
+ hit.normal = worldNormal(local, inv, normal);
392
+ }
393
+ return hit;
394
+ };
395
+ }
396
+ /**
397
+ * Entry distance of `ray` (unit `dir`) into the object-space box `[-h, h]` per axis, or -1.
398
+ * `faceOut` receives the entering face as `[axis, sign]`; axis -1 when the ray started inside,
399
+ * in which case the distance is 0.
400
+ */
401
+ function rayBox(ray, h, faceOut) {
402
+ let tmin = -Infinity;
403
+ let tmax = Infinity;
404
+ let axis = -1;
405
+ let sign = 0;
406
+ for (let i = 0; i < 3; i++) {
407
+ const o = ray.origin[i];
408
+ const d = ray.dir[i];
409
+ const e = h[i];
410
+ if (Math.abs(d) < EPS) {
411
+ if (o < -e || o > e)
412
+ return -1;
413
+ continue;
414
+ }
415
+ let t1 = (-e - o) / d;
416
+ let t2 = (e - o) / d;
417
+ let s = -1;
418
+ if (t1 > t2) {
419
+ const tt = t1;
420
+ t1 = t2;
421
+ t2 = tt;
422
+ s = 1;
423
+ }
424
+ if (t1 > tmin) {
425
+ tmin = t1;
426
+ axis = i;
427
+ sign = s;
428
+ }
429
+ if (t2 < tmax)
430
+ tmax = t2;
431
+ if (tmin > tmax)
432
+ return -1;
433
+ }
434
+ if (tmax < 0)
435
+ return -1;
436
+ if (tmin < 0) {
437
+ faceOut[0] = -1;
438
+ faceOut[1] = 0;
439
+ return 0;
440
+ }
441
+ faceOut[0] = axis;
442
+ faceOut[1] = sign;
443
+ return tmin;
444
+ }
445
+ /**
446
+ * Hits an oriented box: the object-space box `[-halfExtents, +halfExtents]` placed by
447
+ * `transform` (both read each call). The hit's `normal` is the entering face's, in world space;
448
+ * `distance` is in world units. A ray that starts inside hits at distance 0 with `normal: null`.
449
+ * Zero allocations per call.
450
+ */
451
+ export function obbTester(transform, halfExtents, target = null) {
452
+ const hit = createHit(target);
453
+ const normal = [0, 0, 0];
454
+ const local = [0, 0, 0];
455
+ const face = [-1, 0];
456
+ const inv = new Float32Array(9);
457
+ const lray = createRay();
458
+ return (ray) => {
459
+ const m = transform.world;
460
+ if (!invert3x3(m, inv))
461
+ return null;
462
+ const scale = localRay(ray, m, inv, lray);
463
+ if (scale === 0)
464
+ return null;
465
+ const t = rayBox(lray, halfExtents, face);
466
+ if (t < 0)
467
+ return null;
468
+ const dist = t * scale;
469
+ rayAt(ray, dist, hit.point);
470
+ hit.distance = dist;
471
+ hit.target = target;
472
+ if (face[0] < 0) {
473
+ hit.normal = null;
474
+ }
475
+ else {
476
+ local[0] = 0;
477
+ local[1] = 0;
478
+ local[2] = 0;
479
+ local[face[0]] = face[1];
480
+ hit.normal = worldNormal(local, inv, normal);
481
+ }
482
+ return hit;
483
+ };
484
+ }
485
+ /** Vertices with a full x, y, z in an interleaved buffer. */
486
+ function vertexCount(positions, stride, offset) {
487
+ const room = positions.length - offset - 3;
488
+ return room < 0 ? 0 : Math.floor(room / stride) + 1;
489
+ }
490
+ /** The bounding sphere of the positions in an interleaved buffer (centre of the AABB). */
491
+ function boundsOf(positions, stride, offset) {
492
+ const bounds = { center: [0, 0, 0], radius: 0 };
493
+ const n = vertexCount(positions, stride, offset);
494
+ if (n <= 0)
495
+ return bounds;
496
+ let minX = Infinity;
497
+ let minY = Infinity;
498
+ let minZ = Infinity;
499
+ let maxX = -Infinity;
500
+ let maxY = -Infinity;
501
+ let maxZ = -Infinity;
502
+ for (let i = 0; i < n; i++) {
503
+ const p = offset + i * stride;
504
+ const x = positions[p];
505
+ const y = positions[p + 1];
506
+ const z = positions[p + 2];
507
+ if (x < minX)
508
+ minX = x;
509
+ if (x > maxX)
510
+ maxX = x;
511
+ if (y < minY)
512
+ minY = y;
513
+ if (y > maxY)
514
+ maxY = y;
515
+ if (z < minZ)
516
+ minZ = z;
517
+ if (z > maxZ)
518
+ maxZ = z;
519
+ }
520
+ const c = bounds.center;
521
+ c[0] = (minX + maxX) / 2;
522
+ c[1] = (minY + maxY) / 2;
523
+ c[2] = (minZ + maxZ) / 2;
524
+ let r2 = 0;
525
+ for (let i = 0; i < n; i++) {
526
+ const p = offset + i * stride;
527
+ const dx = positions[p] - c[0];
528
+ const dy = positions[p + 1] - c[1];
529
+ const dz = positions[p + 2] - c[2];
530
+ const d2 = dx * dx + dy * dy + dz * dz;
531
+ if (d2 > r2)
532
+ r2 = d2;
533
+ }
534
+ bounds.radius = Math.sqrt(r2);
535
+ return bounds;
536
+ }
537
+ /**
538
+ * Hits the triangles of a mesh whose positions the game keeps on the CPU: `positions` is the
539
+ * interleaved vertex buffer it uploaded (`MeshDesc.vertices`; `stride`/`offset` in floats say
540
+ * where x, y, z sit, default `VERTEX_LAYOUT_3D`), `indices` its index buffer or `null` for a
541
+ * plain triangle list. Both are read each call, so a mesh rebuilt in place is picked as drawn,
542
+ * and `transform` is read each call too. The ray is moved into object space, rejected on the
543
+ * bounds sphere first, then tested against every triangle (Möller–Trumbore); the nearest wins.
544
+ * The hit carries the world-space `point`, the triangle's unit `normal` facing the ray and
545
+ * `distance` in world units. Zero allocations per call; O(triangles) after the sphere.
546
+ */
547
+ export function meshTester(transform, positions, indices, target = null, opts = {}) {
548
+ const stride = opts.stride ?? DEFAULT_STRIDE;
549
+ const offset = opts.offset ?? DEFAULT_OFFSET;
550
+ const bounds = opts.bounds ?? boundsOf(positions, stride, offset);
551
+ const cullBack = opts.cullBack ?? false;
552
+ const hit = createHit(target);
553
+ const normal = [0, 0, 0];
554
+ const local = [0, 0, 0];
555
+ const a = [0, 0, 0];
556
+ const b = [0, 0, 0];
557
+ const c = [0, 0, 0];
558
+ const inv = new Float32Array(9);
559
+ const lray = createRay();
560
+ const corners = (tri) => {
561
+ let i0 = tri;
562
+ let i1 = tri + 1;
563
+ let i2 = tri + 2;
564
+ if (indices) {
565
+ i0 = indices[i0];
566
+ i1 = indices[i1];
567
+ i2 = indices[i2];
568
+ }
569
+ let p = offset + i0 * stride;
570
+ a[0] = positions[p];
571
+ a[1] = positions[p + 1];
572
+ a[2] = positions[p + 2];
573
+ p = offset + i1 * stride;
574
+ b[0] = positions[p];
575
+ b[1] = positions[p + 1];
576
+ b[2] = positions[p + 2];
577
+ p = offset + i2 * stride;
578
+ c[0] = positions[p];
579
+ c[1] = positions[p + 1];
580
+ c[2] = positions[p + 2];
581
+ };
582
+ return (ray) => {
583
+ const m = transform.world;
584
+ if (!invert3x3(m, inv))
585
+ return null;
586
+ const scale = localRay(ray, m, inv, lray);
587
+ if (scale === 0)
588
+ return null;
589
+ const bc = bounds.center;
590
+ if (bounds.radius !== Infinity && raySphere(lray, bc[0], bc[1], bc[2], bounds.radius) < 0) {
591
+ return null;
592
+ }
593
+ const count = indices ? indices.length : vertexCount(positions, stride, offset);
594
+ let best = Infinity;
595
+ let bestTri = -1;
596
+ for (let i = 0; i + 2 < count; i += 3) {
597
+ corners(i);
598
+ const t = rayTriangle(lray, a, b, c, cullBack, null);
599
+ if (t >= 0 && t < best) {
600
+ best = t;
601
+ bestTri = i;
602
+ }
603
+ }
604
+ if (bestTri < 0)
605
+ return null;
606
+ corners(bestTri);
607
+ rayTriangle(lray, a, b, c, cullBack, local);
608
+ const dist = best * scale;
609
+ rayAt(ray, dist, hit.point);
610
+ hit.distance = dist;
611
+ hit.target = target;
612
+ hit.normal = worldNormal(local, inv, normal);
613
+ return hit;
614
+ };
615
+ }