@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,97 @@
1
+ /**
2
+ * Primitive builders, all in `VERTEX_LAYOUT_3D`, centred on the origin, y up, with outward
3
+ * normals and counter-clockwise triangles seen from outside. Each takes `{ color?, uvScale? }`
4
+ * (`GeometryOptions`) plus its own sizes and segment counts; every size defaults to a unit
5
+ * extent, so a `Transform`'s scale is the object's size in world units.
6
+ *
7
+ * Normals: `box`, `plane` and cylinder caps are flat (a vertex per face corner); `sphere`,
8
+ * `icosphere`, `capsule`, `torus` and cylinder sides are smooth (the analytic surface normal).
9
+ */
10
+ import { type Geometry, type GeometryOptions } from './geometry.js';
11
+ type Vec3Opt = number | [number, number, number];
12
+ type Vec2Opt = number | [number, number];
13
+ export interface BoxOptions extends GeometryOptions {
14
+ /** Extent on each axis (one number for a cube). Default 1. */
15
+ size?: Vec3Opt;
16
+ /** Subdivisions per axis (x, y, z). Default 1: 24 vertices, 12 triangles. */
17
+ segments?: Vec3Opt;
18
+ }
19
+ /** An axis-aligned box centred on the origin, flat normals, each face uv 0..1 (v = 0 at the top). */
20
+ export declare function box(opts?: BoxOptions): Geometry;
21
+ export interface PlaneOptions extends GeometryOptions {
22
+ /** Extent along x and z (one number for a square). Default 1. */
23
+ size?: Vec2Opt;
24
+ /** Subdivisions along x and z. Default 1. */
25
+ segments?: Vec2Opt;
26
+ }
27
+ /**
28
+ * A flat grid in the xz plane at y = 0 facing +y, centred on the origin; u runs along +x and
29
+ * v along +z, 0..1 across the plane.
30
+ */
31
+ export declare function plane(opts?: PlaneOptions): Geometry;
32
+ export interface SphereOptions extends GeometryOptions {
33
+ /** Default 0.5 (a unit diameter). */
34
+ radius?: number;
35
+ /** Segments around (≥ 3) and from pole to pole (≥ 2). Default `[32, 16]`. */
36
+ segments?: Vec2Opt;
37
+ }
38
+ /**
39
+ * A UV sphere: rings of latitude from the bottom pole to the top, smooth normals, u around
40
+ * (0 at +z, increasing towards +x), v = 0 at the top pole and 1 at the bottom.
41
+ */
42
+ export declare function sphere(opts?: SphereOptions): Geometry;
43
+ export interface IcosphereOptions extends GeometryOptions {
44
+ /** Default 0.5. */
45
+ radius?: number;
46
+ /** Subdivision passes (each splits every triangle in four). Default 2: 162 vertices, 320 triangles. */
47
+ subdivisions?: number;
48
+ }
49
+ /**
50
+ * A sphere from a subdivided icosahedron: evenly sized triangles, welded vertices, smooth
51
+ * normals. uv is the spherical mapping of the normal (u = atan2 around y, v from the top), with
52
+ * a seam at -x; prefer `sphere` when the texture matters.
53
+ */
54
+ export declare function icosphere(opts?: IcosphereOptions): Geometry;
55
+ export interface CapsuleOptions extends GeometryOptions {
56
+ /** Default 0.25. */
57
+ radius?: number;
58
+ /** Total height, caps included, along y; at most `2 × radius` gives a sphere. Default 1. */
59
+ height?: number;
60
+ /** Segments around (≥ 3) and rings per hemisphere (≥ 1). Default `[16, 8]`. */
61
+ segments?: Vec2Opt;
62
+ }
63
+ /**
64
+ * A capsule along y centred on the origin: two hemispheres joined by a cylinder, smooth normals,
65
+ * u around (0 at +z), v = 0 at the top and 1 at the bottom.
66
+ */
67
+ export declare function capsule(opts?: CapsuleOptions): Geometry;
68
+ export interface CylinderOptions extends GeometryOptions {
69
+ /** Radius, or `[top, bottom]` for a taper (0 at one end makes a cone). Default 0.5. */
70
+ radius?: Vec2Opt;
71
+ /** Height along y. Default 1. */
72
+ height?: number;
73
+ /** Segments around (≥ 3) and along the height (≥ 1). Default `[24, 1]`. */
74
+ segments?: Vec2Opt;
75
+ /** Close the ends with flat discs. Default true. */
76
+ caps?: boolean;
77
+ }
78
+ /**
79
+ * A cylinder (or cone, or truncated cone) along y centred on the origin. The side has smooth
80
+ * normals that lean with the taper, u around (0 at +z) and v = 0 at the top; each cap is a flat
81
+ * disc with its own vertices, uv the disc in 0..1.
82
+ */
83
+ export declare function cylinder(opts?: CylinderOptions): Geometry;
84
+ export interface TorusOptions extends GeometryOptions {
85
+ /** Distance from the centre to the middle of the tube. Default 0.5. */
86
+ radius?: number;
87
+ /** Radius of the tube. Default 0.2. */
88
+ tube?: number;
89
+ /** Segments around the tube's section (≥ 3) and around the ring (≥ 3). Default `[12, 24]`. */
90
+ segments?: Vec2Opt;
91
+ }
92
+ /**
93
+ * A torus in the xz plane around y, centred on the origin, smooth normals; u runs around the
94
+ * ring, v around the tube's section.
95
+ */
96
+ export declare function torus(opts?: TorusOptions): Geometry;
97
+ export {};
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Primitive builders, all in `VERTEX_LAYOUT_3D`, centred on the origin, y up, with outward
3
+ * normals and counter-clockwise triangles seen from outside. Each takes `{ color?, uvScale? }`
4
+ * (`GeometryOptions`) plus its own sizes and segment counts; every size defaults to a unit
5
+ * extent, so a `Transform`'s scale is the object's size in world units.
6
+ *
7
+ * Normals: `box`, `plane` and cylinder caps are flat (a vertex per face corner); `sphere`,
8
+ * `icosphere`, `capsule`, `torus` and cylinder sides are smooth (the analytic surface normal).
9
+ */
10
+ import { GeometryWriter } from './geometry.js';
11
+ const TAU = Math.PI * 2;
12
+ function v3(v, d) {
13
+ if (v === undefined)
14
+ return [d, d, d];
15
+ return typeof v === 'number' ? [v, v, v] : [v[0], v[1], v[2]];
16
+ }
17
+ function v2(v, d0, d1) {
18
+ if (v === undefined)
19
+ return [d0, d1];
20
+ return typeof v === 'number' ? [v, v] : [v[0], v[1]];
21
+ }
22
+ function atLeast(name, value, min) {
23
+ const n = Math.floor(value);
24
+ if (!(n >= min))
25
+ throw new Error(`geom: ${name} segments must be at least ${min}, got ${value}`);
26
+ return n;
27
+ }
28
+ /**
29
+ * Stitch two rings of `cols + 1` vertices (indices `a + i` and `b + i`, `b` the later ring along
30
+ * the surface) with quads, or triangles where one ring is a pole (every vertex at one point).
31
+ * The rings are ordered so that a vertex moves along the ring with `i` and across it from `a`
32
+ * to `b` in a right-handed sense with the outward normal.
33
+ */
34
+ function stitch(w, cols, a, b, poleA = false, poleB = false) {
35
+ for (let i = 0; i < cols; i++) {
36
+ if (poleA)
37
+ w.tri(a + i, b + i + 1, b + i);
38
+ else if (poleB)
39
+ w.tri(a + i, a + i + 1, b + i + 1);
40
+ else
41
+ w.quad(a + i, a + i + 1, b + i + 1, b + i);
42
+ }
43
+ }
44
+ /** Face table: normal axis and sign, then the axes that run right and up across the face. */
45
+ // biome-ignore format: table
46
+ const BOX_FACES = [
47
+ // nAxis, nSign, rAxis, rSign, uAxis, uSign (r × u = n)
48
+ [2, 1, 0, 1, 1, 1], // +z
49
+ [2, -1, 0, -1, 1, 1], // -z
50
+ [0, 1, 2, -1, 1, 1], // +x
51
+ [0, -1, 2, 1, 1, 1], // -x
52
+ [1, 1, 0, 1, 2, -1], // +y
53
+ [1, -1, 0, 1, 2, 1], // -y
54
+ ];
55
+ /** An axis-aligned box centred on the origin, flat normals, each face uv 0..1 (v = 0 at the top). */
56
+ export function box(opts = {}) {
57
+ const size = v3(opts.size, 1);
58
+ const seg = v3(opts.segments, 1).map((n, k) => atLeast('xyz'[k], n, 1));
59
+ let vCount = 0;
60
+ let iCount = 0;
61
+ for (const f of BOX_FACES) {
62
+ const sr = seg[f[2]];
63
+ const su = seg[f[4]];
64
+ vCount += (sr + 1) * (su + 1);
65
+ iCount += sr * su * 6;
66
+ }
67
+ const w = new GeometryWriter(vCount, iCount, opts);
68
+ const p = [0, 0, 0];
69
+ for (const [nAxis, nSign, rAxis, rSign, uAxis, uSign] of BOX_FACES) {
70
+ const sr = seg[rAxis];
71
+ const su = seg[uAxis];
72
+ const base = w.count;
73
+ for (let j = 0; j <= su; j++) {
74
+ for (let i = 0; i <= sr; i++) {
75
+ p[nAxis] = nSign * 0.5 * size[nAxis];
76
+ p[rAxis] = rSign * (i / sr - 0.5) * size[rAxis];
77
+ p[uAxis] = uSign * (j / su - 0.5) * size[uAxis];
78
+ const nx = nAxis === 0 ? nSign : 0;
79
+ const ny = nAxis === 1 ? nSign : 0;
80
+ const nz = nAxis === 2 ? nSign : 0;
81
+ w.vertex(p[0], p[1], p[2], nx, ny, nz, i / sr, 1 - j / su);
82
+ }
83
+ }
84
+ for (let j = 0; j < su; j++) {
85
+ const row = base + j * (sr + 1);
86
+ stitch(w, sr, row, row + sr + 1);
87
+ }
88
+ }
89
+ return w.finish();
90
+ }
91
+ /**
92
+ * A flat grid in the xz plane at y = 0 facing +y, centred on the origin; u runs along +x and
93
+ * v along +z, 0..1 across the plane.
94
+ */
95
+ export function plane(opts = {}) {
96
+ const [sx, sz] = v2(opts.size, 1, 1);
97
+ const [nx, nz] = v2(opts.segments, 1, 1);
98
+ const cx = atLeast('x', nx, 1);
99
+ const cz = atLeast('z', nz, 1);
100
+ const w = new GeometryWriter((cx + 1) * (cz + 1), cx * cz * 6, opts);
101
+ for (let j = 0; j <= cz; j++) {
102
+ for (let i = 0; i <= cx; i++) {
103
+ w.vertex((i / cx - 0.5) * sx, 0, (j / cz - 0.5) * sz, 0, 1, 0, i / cx, j / cz);
104
+ }
105
+ }
106
+ for (let j = 0; j < cz; j++) {
107
+ for (let i = 0; i < cx; i++) {
108
+ const a = j * (cx + 1) + i;
109
+ // (i, j) → (i, j+1) → (i+1, j+1) → (i+1, j): +z then +x, so the normal comes out +y.
110
+ w.quad(a, a + cx + 1, a + cx + 2, a + 1);
111
+ }
112
+ }
113
+ return w.finish();
114
+ }
115
+ /**
116
+ * A UV sphere: rings of latitude from the bottom pole to the top, smooth normals, u around
117
+ * (0 at +z, increasing towards +x), v = 0 at the top pole and 1 at the bottom.
118
+ */
119
+ export function sphere(opts = {}) {
120
+ const r = opts.radius ?? 0.5;
121
+ const [ws, hs] = v2(opts.segments, 32, 16);
122
+ const cols = atLeast('width', ws, 3);
123
+ const rows = atLeast('height', hs, 2);
124
+ const w = new GeometryWriter((cols + 1) * (rows + 1), cols * (rows - 1) * 6, opts);
125
+ for (let j = 0; j <= rows; j++) {
126
+ const lat = -Math.PI / 2 + (j / rows) * Math.PI;
127
+ const cl = j === 0 || j === rows ? 0 : Math.cos(lat);
128
+ const sl = Math.sin(lat);
129
+ for (let i = 0; i <= cols; i++) {
130
+ const phi = (i / cols) * TAU;
131
+ const nx = cl * Math.sin(phi);
132
+ const nz = cl * Math.cos(phi);
133
+ w.vertex(r * nx, r * sl, r * nz, nx, sl, nz, i / cols, 1 - j / rows);
134
+ }
135
+ }
136
+ for (let j = 0; j < rows; j++) {
137
+ const a = j * (cols + 1);
138
+ stitch(w, cols, a, a + cols + 1, j === 0, j === rows - 1);
139
+ }
140
+ return w.finish();
141
+ }
142
+ const ICO_T = (1 + Math.sqrt(5)) / 2;
143
+ // biome-ignore format: table
144
+ const ICO_VERTS = [
145
+ -1, ICO_T, 0, 1, ICO_T, 0, -1, -ICO_T, 0, 1, -ICO_T, 0,
146
+ 0, -1, ICO_T, 0, 1, ICO_T, 0, -1, -ICO_T, 0, 1, -ICO_T,
147
+ ICO_T, 0, -1, ICO_T, 0, 1, -ICO_T, 0, -1, -ICO_T, 0, 1,
148
+ ];
149
+ // biome-ignore format: table
150
+ const ICO_TRIS = [
151
+ 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
152
+ 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
153
+ 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
154
+ 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1,
155
+ ];
156
+ /**
157
+ * A sphere from a subdivided icosahedron: evenly sized triangles, welded vertices, smooth
158
+ * normals. uv is the spherical mapping of the normal (u = atan2 around y, v from the top), with
159
+ * a seam at -x; prefer `sphere` when the texture matters.
160
+ */
161
+ export function icosphere(opts = {}) {
162
+ const r = opts.radius ?? 0.5;
163
+ const n = atLeast('subdivision', opts.subdivisions ?? 2, 0);
164
+ const pow = 4 ** n;
165
+ const vCount = 10 * pow + 2;
166
+ const tCount = 20 * pow;
167
+ // Unit positions, welded through a midpoint cache keyed by the edge's vertex pair.
168
+ const pos = new Float64Array(vCount * 3);
169
+ let pc = 0;
170
+ for (let i = 0; i < ICO_VERTS.length; i += 3) {
171
+ const l = Math.hypot(ICO_VERTS[i], ICO_VERTS[i + 1], ICO_VERTS[i + 2]);
172
+ pos[pc++] = ICO_VERTS[i] / l;
173
+ pos[pc++] = ICO_VERTS[i + 1] / l;
174
+ pos[pc++] = ICO_VERTS[i + 2] / l;
175
+ }
176
+ let tris = Uint32Array.from(ICO_TRIS);
177
+ const cache = new Map();
178
+ const midpoint = (a, b) => {
179
+ const key = a < b ? a * vCount + b : b * vCount + a;
180
+ const hit = cache.get(key);
181
+ if (hit !== undefined)
182
+ return hit;
183
+ let x = pos[a * 3] + pos[b * 3];
184
+ let y = pos[a * 3 + 1] + pos[b * 3 + 1];
185
+ let z = pos[a * 3 + 2] + pos[b * 3 + 2];
186
+ const l = Math.hypot(x, y, z);
187
+ x /= l;
188
+ y /= l;
189
+ z /= l;
190
+ const idx = pc / 3;
191
+ pos[pc++] = x;
192
+ pos[pc++] = y;
193
+ pos[pc++] = z;
194
+ cache.set(key, idx);
195
+ return idx;
196
+ };
197
+ for (let s = 0; s < n; s++) {
198
+ const next = new Uint32Array(tris.length * 4);
199
+ let o = 0;
200
+ for (let t = 0; t < tris.length; t += 3) {
201
+ const a = tris[t];
202
+ const b = tris[t + 1];
203
+ const c = tris[t + 2];
204
+ const ab = midpoint(a, b);
205
+ const bc = midpoint(b, c);
206
+ const ca = midpoint(c, a);
207
+ next.set([a, ab, ca, b, bc, ab, c, ca, bc, ab, bc, ca], o);
208
+ o += 12;
209
+ }
210
+ tris = next;
211
+ }
212
+ const w = new GeometryWriter(vCount, tCount * 3, opts);
213
+ for (let i = 0; i < vCount; i++) {
214
+ const x = pos[i * 3];
215
+ const y = pos[i * 3 + 1];
216
+ const z = pos[i * 3 + 2];
217
+ const u = 0.5 + Math.atan2(z, x) / TAU;
218
+ const v = Math.acos(Math.max(-1, Math.min(1, y))) / Math.PI;
219
+ w.vertex(r * x, r * y, r * z, x, y, z, u, v);
220
+ }
221
+ for (let t = 0; t < tris.length; t += 3)
222
+ w.tri(tris[t], tris[t + 1], tris[t + 2]);
223
+ return w.finish();
224
+ }
225
+ /**
226
+ * A capsule along y centred on the origin: two hemispheres joined by a cylinder, smooth normals,
227
+ * u around (0 at +z), v = 0 at the top and 1 at the bottom.
228
+ */
229
+ export function capsule(opts = {}) {
230
+ const r = opts.radius ?? 0.25;
231
+ const height = opts.height ?? 1;
232
+ const half = Math.max(0, height / 2 - r);
233
+ const [rs, cs] = v2(opts.segments, 16, 8);
234
+ const cols = atLeast('radial', rs, 3);
235
+ const rings = atLeast('ring', cs, 1);
236
+ const rowCount = 2 * (rings + 1);
237
+ const total = 2 * (half + r);
238
+ const w = new GeometryWriter((cols + 1) * rowCount, cols * (3 + 3 + (rowCount - 3) * 6), opts);
239
+ for (let row = 0; row < rowCount; row++) {
240
+ // Rows 0..rings: the bottom hemisphere (latitude -90°..0°); rings+1..: the top (0°..90°).
241
+ const top = row > rings;
242
+ const k = top ? row - rings - 1 : row;
243
+ const lat = top ? (k / rings) * (Math.PI / 2) : -Math.PI / 2 + (k / rings) * (Math.PI / 2);
244
+ const pole = row === 0 || row === rowCount - 1;
245
+ const cl = pole ? 0 : Math.cos(lat);
246
+ const sl = Math.sin(lat);
247
+ const y0 = top ? half : -half;
248
+ for (let i = 0; i <= cols; i++) {
249
+ const phi = (i / cols) * TAU;
250
+ const nx = cl * Math.sin(phi);
251
+ const nz = cl * Math.cos(phi);
252
+ const y = y0 + r * sl;
253
+ w.vertex(r * nx, y, r * nz, nx, sl, nz, i / cols, 0.5 - y / total);
254
+ }
255
+ }
256
+ for (let row = 0; row < rowCount - 1; row++) {
257
+ const a = row * (cols + 1);
258
+ stitch(w, cols, a, a + cols + 1, row === 0, row === rowCount - 2);
259
+ }
260
+ return w.finish();
261
+ }
262
+ /**
263
+ * A cylinder (or cone, or truncated cone) along y centred on the origin. The side has smooth
264
+ * normals that lean with the taper, u around (0 at +z) and v = 0 at the top; each cap is a flat
265
+ * disc with its own vertices, uv the disc in 0..1.
266
+ */
267
+ export function cylinder(opts = {}) {
268
+ const [rt, rb] = v2(opts.radius, 0.5, 0.5);
269
+ const height = opts.height ?? 1;
270
+ const [rs, hs] = v2(opts.segments, 24, 1);
271
+ const cols = atLeast('radial', rs, 3);
272
+ const rows = atLeast('height', hs, 1);
273
+ const caps = opts.caps ?? true;
274
+ const capTop = caps && rt > 0;
275
+ const capBottom = caps && rb > 0;
276
+ const poleTop = rt === 0;
277
+ const poleBottom = rb === 0;
278
+ let iCount = cols * rows * 6;
279
+ if (poleTop)
280
+ iCount -= cols * 3;
281
+ if (poleBottom)
282
+ iCount -= cols * 3;
283
+ const capV = (capTop ? 1 : 0) + (capBottom ? 1 : 0);
284
+ const w = new GeometryWriter((cols + 1) * (rows + 1) + capV * (cols + 2), iCount + capV * cols * 3, opts);
285
+ // Side normal: perpendicular to the slanted side, (1, slope, 1) scaled, then unit.
286
+ const slope = (rb - rt) / height;
287
+ const nl = Math.hypot(1, slope);
288
+ for (let j = 0; j <= rows; j++) {
289
+ const t = j / rows;
290
+ const y = (t - 0.5) * height;
291
+ const rad = rb + (rt - rb) * t;
292
+ for (let i = 0; i <= cols; i++) {
293
+ const phi = (i / cols) * TAU;
294
+ const sx = Math.sin(phi);
295
+ const cz = Math.cos(phi);
296
+ w.vertex(rad * sx, y, rad * cz, sx / nl, slope / nl, cz / nl, i / cols, 1 - t);
297
+ }
298
+ }
299
+ for (let j = 0; j < rows; j++) {
300
+ const a = j * (cols + 1);
301
+ stitch(w, cols, a, a + cols + 1, poleBottom && j === 0, poleTop && j === rows - 1);
302
+ }
303
+ if (capTop)
304
+ disc(w, cols, rt, height / 2, 1);
305
+ if (capBottom)
306
+ disc(w, cols, rb, -height / 2, -1);
307
+ return w.finish();
308
+ }
309
+ /** A flat disc of `cols` triangles at height `y`, facing `ny` (±1). */
310
+ function disc(w, cols, radius, y, ny) {
311
+ const centre = w.vertex(0, y, 0, 0, ny, 0, 0.5, 0.5);
312
+ const ring = w.count;
313
+ for (let i = 0; i <= cols; i++) {
314
+ const phi = (i / cols) * TAU;
315
+ const sx = Math.sin(phi);
316
+ const cz = Math.cos(phi);
317
+ w.vertex(radius * sx, y, radius * cz, 0, ny, 0, 0.5 + 0.5 * sx, 0.5 - 0.5 * cz * ny);
318
+ }
319
+ for (let i = 0; i < cols; i++) {
320
+ if (ny > 0)
321
+ w.tri(centre, ring + i, ring + i + 1);
322
+ else
323
+ w.tri(centre, ring + i + 1, ring + i);
324
+ }
325
+ }
326
+ /**
327
+ * A torus in the xz plane around y, centred on the origin, smooth normals; u runs around the
328
+ * ring, v around the tube's section.
329
+ */
330
+ export function torus(opts = {}) {
331
+ const R = opts.radius ?? 0.5;
332
+ const r = opts.tube ?? 0.2;
333
+ const [rs, ts] = v2(opts.segments, 12, 24);
334
+ const radial = atLeast('radial', rs, 3);
335
+ const tubular = atLeast('tubular', ts, 3);
336
+ const w = new GeometryWriter((tubular + 1) * (radial + 1), tubular * radial * 6, opts);
337
+ for (let i = 0; i <= tubular; i++) {
338
+ const phi = (i / tubular) * TAU;
339
+ const cp = Math.cos(phi);
340
+ const sp = Math.sin(phi);
341
+ for (let j = 0; j <= radial; j++) {
342
+ const theta = (j / radial) * TAU;
343
+ const ct = Math.cos(theta);
344
+ const st = Math.sin(theta);
345
+ const nx = ct * cp;
346
+ const ny = st;
347
+ const nz = ct * sp;
348
+ w.vertex(R * cp + r * nx, r * ny, R * sp + r * nz, nx, ny, nz, i / tubular, j / radial);
349
+ }
350
+ }
351
+ for (let i = 0; i < tubular; i++) {
352
+ for (let j = 0; j < radial; j++) {
353
+ const a = i * (radial + 1) + j;
354
+ // (i, j) → (i, j+1) → (i+1, j+1) → (i+1, j): around the section, then around the ring.
355
+ w.quad(a, a + 1, a + radial + 2, a + radial + 1);
356
+ }
357
+ }
358
+ return w.finish();
359
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Level-building shapes assembled from the sweeps and primitives: `stairs` and `arch`. Both are
3
+ * centred on the origin (their axis-aligned box's centre) like every builder; `recenter` and
4
+ * `transformGeometry` move them.
5
+ */
6
+ import { type Geometry, type GeometryOptions } from './geometry.js';
7
+ export interface StairsOptions extends GeometryOptions {
8
+ /** Number of steps (≥ 1). Default 4. */
9
+ steps?: number;
10
+ /** Extent along x. Default 1. */
11
+ width?: number;
12
+ /** Height of each step. Default 0.25. */
13
+ rise?: number;
14
+ /** Depth of each step along z. Default 0.3. */
15
+ run?: number;
16
+ /** Close the two sides (the solid's x faces). Default true; `false` leaves them open. */
17
+ sides?: boolean;
18
+ }
19
+ /**
20
+ * A solid flight of stairs climbing along +z: `steps` steps of `rise` by `run`, `width` wide,
21
+ * flat normals, the underside and back closed (a block with a sawtooth top). The sides are the
22
+ * extrusion's caps, so `sides: false` leaves them open. Centred on the origin.
23
+ */
24
+ export declare function stairs(opts?: StairsOptions): Geometry;
25
+ export interface ArchOptions extends GeometryOptions {
26
+ /** Outer extent along x. Default 1. */
27
+ width?: number;
28
+ /** Outer extent along y, at least `thickness + width / 2`. Default 1. */
29
+ height?: number;
30
+ /** Extent along z. Default 0.25. */
31
+ depth?: number;
32
+ /** Wall thickness around the opening (less than `width / 2`). Default 0.15. */
33
+ thickness?: number;
34
+ /** Straight segments in the semicircle (≥ 2). Default 16. */
35
+ segments?: number;
36
+ }
37
+ /**
38
+ * A rectangular wall of `width` × `height` × `depth` pierced by a round-topped opening:
39
+ * two legs (`box`) under a lintel whose underside is a semicircle of radius
40
+ * `width / 2 - thickness` (an `extrude` of the lintel's outline). Flat normals; a height of
41
+ * exactly `thickness + width / 2` has no legs. Centred on the origin.
42
+ */
43
+ export declare function arch(opts?: ArchOptions): Geometry;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Level-building shapes assembled from the sweeps and primitives: `stairs` and `arch`. Both are
3
+ * centred on the origin (their axis-aligned box's centre) like every builder; `recenter` and
4
+ * `transformGeometry` move them.
5
+ */
6
+ import { mergeGeometry, transformGeometry } from './geometry.js';
7
+ import { recenter } from './ops.js';
8
+ import { box } from './primitives.js';
9
+ import { extrude } from './sweep.js';
10
+ /** Profile x → world +z, profile y → y, extrusion z → world -x (a rotation about y, det +1). */
11
+ // biome-ignore format: matrix
12
+ const PROFILE_TO_Z = [
13
+ 0, 0, -1, 0,
14
+ 0, 1, 0, 0,
15
+ 1, 0, 0, 0,
16
+ ];
17
+ /**
18
+ * A solid flight of stairs climbing along +z: `steps` steps of `rise` by `run`, `width` wide,
19
+ * flat normals, the underside and back closed (a block with a sawtooth top). The sides are the
20
+ * extrusion's caps, so `sides: false` leaves them open. Centred on the origin.
21
+ */
22
+ export function stairs(opts = {}) {
23
+ const steps = Math.floor(opts.steps ?? 4);
24
+ if (!(steps >= 1))
25
+ throw new Error(`geom: stairs steps must be at least 1, got ${steps}`);
26
+ const width = opts.width ?? 1;
27
+ const rise = opts.rise ?? 0.25;
28
+ const run = opts.run ?? 0.3;
29
+ // Counter-clockwise in (run, height): along the bottom, up the back, then down the steps.
30
+ const profile = [0, 0, steps * run, 0, steps * run, steps * rise];
31
+ for (let k = steps; k >= 1; k--) {
32
+ profile.push((k - 1) * run, k * rise);
33
+ if (k > 1)
34
+ profile.push((k - 1) * run, (k - 1) * rise);
35
+ }
36
+ const g = extrude(profile, {
37
+ depth: width,
38
+ caps: opts.sides ?? true,
39
+ color: opts.color,
40
+ uvScale: opts.uvScale,
41
+ });
42
+ return recenter(transformGeometry(g, PROFILE_TO_Z));
43
+ }
44
+ /**
45
+ * A rectangular wall of `width` × `height` × `depth` pierced by a round-topped opening:
46
+ * two legs (`box`) under a lintel whose underside is a semicircle of radius
47
+ * `width / 2 - thickness` (an `extrude` of the lintel's outline). Flat normals; a height of
48
+ * exactly `thickness + width / 2` has no legs. Centred on the origin.
49
+ */
50
+ export function arch(opts = {}) {
51
+ const width = opts.width ?? 1;
52
+ const height = opts.height ?? 1;
53
+ const depth = opts.depth ?? 0.25;
54
+ const thickness = opts.thickness ?? 0.15;
55
+ const segments = Math.floor(opts.segments ?? 16);
56
+ if (!(segments >= 2))
57
+ throw new Error(`geom: arch segments must be at least 2, got ${segments}`);
58
+ const ri = width / 2 - thickness;
59
+ if (!(ri > 0))
60
+ throw new Error(`geom: arch thickness ${thickness} must be under width / 2`);
61
+ const spring = height - thickness - ri;
62
+ if (spring < -1e-9) {
63
+ throw new Error(`geom: arch height ${height} must be at least thickness + width / 2`);
64
+ }
65
+ const hw = width / 2;
66
+ // Lintel outline, counter-clockwise in (x, y): across the top, down the outside, in along the
67
+ // springing line, over the inner semicircle, out to the far leg, back up.
68
+ const outline = [-hw, height, -hw, spring, -ri, spring];
69
+ for (let k = 1; k < segments; k++) {
70
+ const a = Math.PI - (k / segments) * Math.PI;
71
+ outline.push(ri * Math.cos(a), spring + ri * Math.sin(a));
72
+ }
73
+ outline.push(ri, spring, hw, spring, hw, height);
74
+ const common = { color: opts.color, uvScale: opts.uvScale };
75
+ const lintel = extrude(outline, { depth, ...common });
76
+ if (spring <= 1e-9)
77
+ return recenter(lintel);
78
+ const leg = (x) => {
79
+ const g = box({ size: [thickness, spring, depth], ...common });
80
+ // biome-ignore format: matrix
81
+ return transformGeometry(g, [
82
+ 1, 0, 0, x,
83
+ 0, 1, 0, spring / 2,
84
+ 0, 0, 1, 0,
85
+ ]);
86
+ };
87
+ return recenter(mergeGeometry(lintel, leg(-hw + thickness / 2), leg(hw - thickness / 2)));
88
+ }
@@ -0,0 +1,38 @@
1
+ import { type Geometry } from './geometry.js';
2
+ export interface SimplifyOptions {
3
+ /** Keep this fraction of the triangles (0..1). Default 0.5. Ignored under `targetTriangles`. */
4
+ targetRatio?: number;
5
+ /** Keep at most this many triangles. */
6
+ targetTriangles?: number;
7
+ /** Never move a vertex on an open border (an edge with one triangle). Default false. */
8
+ preserveBorders?: boolean;
9
+ /**
10
+ * Never move a position whose vertices disagree (a uv seam or a hard normal edge), so islands
11
+ * and creases keep their outline. Default false.
12
+ */
13
+ preserveUvSeams?: boolean;
14
+ /**
15
+ * Stop before any collapse whose error (the square root of its quadric cost, world units:
16
+ * at least the farthest the moved position lies from one of its original planes) exceeds this.
17
+ * Default unlimited: the target alone decides.
18
+ */
19
+ errorLimit?: number;
20
+ }
21
+ export interface SimplifyResult {
22
+ geometry: Geometry;
23
+ /** The largest collapse error made (world units, see `errorLimit`); 0 when nothing collapsed. */
24
+ error: number;
25
+ }
26
+ /**
27
+ * Simplify `g` by quadric-error edge collapse to `targetTriangles` (or `targetRatio` of its
28
+ * triangles), stopping early at `errorLimit`. Returns a new geometry in `g`'s layout (welded, its
29
+ * indices 16-bit when they fit) and the largest error made. `g` is untouched. Takes
30
+ * `VERTEX_LAYOUT_3D` or `VERTEX_LAYOUT_3D_TANGENT`.
31
+ */
32
+ export declare function simplifyGeometry(g: Geometry, opts?: SimplifyOptions): SimplifyResult;
33
+ /**
34
+ * A level-of-detail chain: level 0 is `g` itself, level `i` is `simplifyGeometry(g, { ...opts,
35
+ * targetRatio: ratios[i - 1] })` (each from the full mesh, so errors do not compound). Ratios are
36
+ * fractions of `g`'s triangles, typically decreasing (`[0.5, 0.25, 0.1]`).
37
+ */
38
+ export declare function createLodChain(g: Geometry, ratios: readonly number[], opts?: Omit<SimplifyOptions, 'targetRatio' | 'targetTriangles'>): Geometry[];