@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.
- package/CHANGELOG.md +390 -0
- package/LICENSE +21 -0
- package/README.md +333 -2
- package/dist/analytics/analytics.d.ts +80 -0
- package/dist/analytics/analytics.js +129 -0
- package/dist/analytics/index.d.ts +1 -0
- package/dist/analytics/index.js +1 -0
- package/dist/anim/aim.d.ts +43 -0
- package/dist/anim/aim.js +157 -0
- package/dist/anim/clip.d.ts +98 -0
- package/dist/anim/clip.js +282 -0
- package/dist/anim/compress.d.ts +65 -0
- package/dist/anim/compress.js +339 -0
- package/dist/anim/foot-ik.d.ts +74 -0
- package/dist/anim/foot-ik.js +241 -0
- package/dist/anim/graph.d.ts +153 -0
- package/dist/anim/graph.js +532 -0
- package/dist/anim/ik.d.ts +105 -0
- package/dist/anim/ik.js +435 -0
- package/dist/anim/index.d.ts +36 -0
- package/dist/anim/index.js +21 -0
- package/dist/anim/match.d.ts +66 -0
- package/dist/anim/match.js +153 -0
- package/dist/anim/mixer.d.ts +113 -0
- package/dist/anim/mixer.js +314 -0
- package/dist/anim/morph.d.ts +41 -0
- package/dist/anim/morph.js +94 -0
- package/dist/anim/pose.d.ts +74 -0
- package/dist/anim/pose.js +254 -0
- package/dist/anim/quat.d.ts +44 -0
- package/dist/anim/quat.js +187 -0
- package/dist/anim/retarget.d.ts +97 -0
- package/dist/anim/retarget.js +366 -0
- package/dist/anim/root-motion.d.ts +44 -0
- package/dist/anim/root-motion.js +224 -0
- package/dist/anim/skin-pose.d.ts +39 -0
- package/dist/anim/skin-pose.js +53 -0
- package/dist/anim/socket.d.ts +47 -0
- package/dist/anim/socket.js +84 -0
- package/dist/anim/spring-chain.d.ts +73 -0
- package/dist/anim/spring-chain.js +294 -0
- package/dist/assets/atlas.d.ts +90 -0
- package/dist/assets/atlas.js +212 -0
- package/dist/assets/baked.d.ts +33 -0
- package/dist/assets/baked.js +38 -0
- package/dist/assets/bundle.d.ts +88 -0
- package/dist/assets/bundle.js +464 -0
- package/dist/assets/cache.d.ts +56 -0
- package/dist/assets/cache.js +123 -0
- package/dist/assets/gltf-load.d.ts +252 -0
- package/dist/assets/gltf-load.js +661 -0
- package/dist/assets/gltf-skin.d.ts +36 -0
- package/dist/assets/gltf-skin.js +109 -0
- package/dist/assets/gltf.d.ts +706 -0
- package/dist/assets/gltf.js +1376 -0
- package/dist/assets/index.d.ts +20 -0
- package/dist/assets/index.js +10 -0
- package/dist/assets/ktx2.d.ts +71 -0
- package/dist/assets/ktx2.js +213 -0
- package/dist/assets/manifest.d.ts +79 -0
- package/dist/assets/manifest.js +7 -0
- package/dist/assets/meshopt.d.ts +23 -0
- package/dist/assets/meshopt.js +403 -0
- package/dist/audio/audio.d.ts +733 -0
- package/dist/audio/audio.js +2013 -0
- package/dist/audio/dsp.d.ts +61 -0
- package/dist/audio/dsp.js +159 -0
- package/dist/audio/duck.d.ts +44 -0
- package/dist/audio/duck.js +101 -0
- package/dist/audio/envelope.d.ts +53 -0
- package/dist/audio/envelope.js +106 -0
- package/dist/audio/index.d.ts +13 -0
- package/dist/audio/index.js +14 -0
- package/dist/audio/music.d.ts +113 -0
- package/dist/audio/music.js +548 -0
- package/dist/audio/occlusion.d.ts +55 -0
- package/dist/audio/occlusion.js +61 -0
- package/dist/audio/persist.d.ts +23 -0
- package/dist/audio/persist.js +27 -0
- package/dist/audio/recipes.d.ts +55 -0
- package/dist/audio/recipes.js +227 -0
- package/dist/audio/send.d.ts +41 -0
- package/dist/audio/send.js +118 -0
- package/dist/audio/sprites.d.ts +59 -0
- package/dist/audio/sprites.js +43 -0
- package/dist/audio/synth.d.ts +103 -0
- package/dist/audio/synth.js +197 -0
- package/dist/audio/variations.d.ts +25 -0
- package/dist/audio/variations.js +55 -0
- package/dist/audio/zones.d.ts +100 -0
- package/dist/audio/zones.js +167 -0
- package/dist/core/detached-surface.d.ts +44 -0
- package/dist/core/detached-surface.js +104 -0
- package/dist/core/events.d.ts +24 -0
- package/dist/core/events.js +43 -0
- package/dist/core/game.d.ts +409 -0
- package/dist/core/game.js +530 -0
- package/dist/core/hash.d.ts +24 -0
- package/dist/core/hash.js +49 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.js +9 -0
- package/dist/core/loop.d.ts +113 -0
- package/dist/core/loop.js +185 -0
- package/dist/core/math.d.ts +58 -0
- package/dist/core/math.js +210 -0
- package/dist/core/noise.d.ts +40 -0
- package/dist/core/noise.js +247 -0
- package/dist/core/pool.d.ts +42 -0
- package/dist/core/pool.js +85 -0
- package/dist/core/random.d.ts +61 -0
- package/dist/core/random.js +199 -0
- package/dist/core/scene.d.ts +79 -0
- package/dist/core/scene.js +195 -0
- package/dist/core/timer.d.ts +66 -0
- package/dist/core/timer.js +286 -0
- package/dist/fx/billboard-wgsl.d.ts +29 -0
- package/dist/fx/billboard-wgsl.js +158 -0
- package/dist/fx/billboard.d.ts +249 -0
- package/dist/fx/billboard.js +702 -0
- package/dist/fx/debug-draw.d.ts +127 -0
- package/dist/fx/debug-draw.js +523 -0
- package/dist/fx/debug-wgsl.d.ts +7 -0
- package/dist/fx/debug-wgsl.js +32 -0
- package/dist/fx/decals-wgsl.d.ts +15 -0
- package/dist/fx/decals-wgsl.js +173 -0
- package/dist/fx/decals.d.ts +216 -0
- package/dist/fx/decals.js +607 -0
- package/dist/fx/effect.d.ts +129 -0
- package/dist/fx/effect.js +349 -0
- package/dist/fx/effects/hit-spark.json +48 -0
- package/dist/fx/effects/index.d.ts +8 -0
- package/dist/fx/effects/index.js +9 -0
- package/dist/fx/effects/magic-aura.json +47 -0
- package/dist/fx/effects/smoke-puff.json +34 -0
- package/dist/fx/emit-surface.d.ts +40 -0
- package/dist/fx/emit-surface.js +124 -0
- package/dist/fx/flicker.d.ts +30 -0
- package/dist/fx/flicker.js +42 -0
- package/dist/fx/index.d.ts +31 -0
- package/dist/fx/index.js +20 -0
- package/dist/fx/particles-wgsl.d.ts +57 -0
- package/dist/fx/particles-wgsl.js +828 -0
- package/dist/fx/particles.d.ts +566 -0
- package/dist/fx/particles.js +1533 -0
- package/dist/fx/random.d.ts +15 -0
- package/dist/fx/random.js +20 -0
- package/dist/fx/sky-wgsl.d.ts +23 -0
- package/dist/fx/sky-wgsl.js +127 -0
- package/dist/fx/sky.d.ts +96 -0
- package/dist/fx/sky.js +175 -0
- package/dist/fx/text-atlas.d.ts +143 -0
- package/dist/fx/text-atlas.js +327 -0
- package/dist/fx/trail-wgsl.d.ts +11 -0
- package/dist/fx/trail-wgsl.js +42 -0
- package/dist/fx/trail.d.ts +194 -0
- package/dist/fx/trail.js +555 -0
- package/dist/fx/water-wgsl.d.ts +34 -0
- package/dist/fx/water-wgsl.js +197 -0
- package/dist/fx/water.d.ts +176 -0
- package/dist/fx/water.js +371 -0
- package/dist/geom/collide/bvh.d.ts +151 -0
- package/dist/geom/collide/bvh.js +493 -0
- package/dist/geom/collide/debug.d.ts +14 -0
- package/dist/geom/collide/debug.js +74 -0
- package/dist/geom/collide/grid.d.ts +26 -0
- package/dist/geom/collide/grid.js +91 -0
- package/dist/geom/collide/index.d.ts +8 -0
- package/dist/geom/collide/index.js +8 -0
- package/dist/geom/collide/queries.d.ts +70 -0
- package/dist/geom/collide/queries.js +583 -0
- package/dist/geom/collide/serialize.d.ts +14 -0
- package/dist/geom/collide/serialize.js +145 -0
- package/dist/geom/collide/shapes.d.ts +161 -0
- package/dist/geom/collide/shapes.js +686 -0
- package/dist/geom/collide/slide.d.ts +66 -0
- package/dist/geom/collide/slide.js +375 -0
- package/dist/geom/collide/tile-slide.d.ts +88 -0
- package/dist/geom/collide/tile-slide.js +255 -0
- package/dist/geom/geometry.d.ts +95 -0
- package/dist/geom/geometry.js +322 -0
- package/dist/geom/heightfield.d.ts +72 -0
- package/dist/geom/heightfield.js +295 -0
- package/dist/geom/hull.d.ts +27 -0
- package/dist/geom/hull.js +279 -0
- package/dist/geom/index.d.ts +35 -0
- package/dist/geom/index.js +23 -0
- package/dist/geom/iso.d.ts +74 -0
- package/dist/geom/iso.js +89 -0
- package/dist/geom/lod.d.ts +29 -0
- package/dist/geom/lod.js +27 -0
- package/dist/geom/ops.d.ts +47 -0
- package/dist/geom/ops.js +285 -0
- package/dist/geom/primitives.d.ts +97 -0
- package/dist/geom/primitives.js +359 -0
- package/dist/geom/shapes.d.ts +43 -0
- package/dist/geom/shapes.js +88 -0
- package/dist/geom/simplify.d.ts +38 -0
- package/dist/geom/simplify.js +519 -0
- package/dist/geom/split.d.ts +37 -0
- package/dist/geom/split.js +413 -0
- package/dist/geom/sweep.d.ts +83 -0
- package/dist/geom/sweep.js +534 -0
- package/dist/geom/tangents.d.ts +16 -0
- package/dist/geom/tangents.js +124 -0
- package/dist/geom/triangulate.d.ts +19 -0
- package/dist/geom/triangulate.js +147 -0
- package/dist/host/default.d.ts +10 -0
- package/dist/host/default.js +10 -0
- package/dist/host/index.d.ts +4 -0
- package/dist/host/index.js +3 -0
- package/dist/host/types.d.ts +144 -0
- package/dist/host/types.js +1 -0
- package/dist/host/web-links.d.ts +38 -0
- package/dist/host/web-links.js +110 -0
- package/dist/host/web.d.ts +30 -0
- package/dist/host/web.js +216 -0
- package/dist/host/xr.d.ts +24 -0
- package/dist/host/xr.js +59 -0
- package/dist/i18n/i18n.d.ts +59 -0
- package/dist/i18n/i18n.js +241 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/message.d.ts +72 -0
- package/dist/i18n/message.js +369 -0
- package/dist/i18n/negotiate.d.ts +17 -0
- package/dist/i18n/negotiate.js +58 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -0
- package/dist/input/bindings.d.ts +31 -0
- package/dist/input/bindings.js +141 -0
- package/dist/input/clock.d.ts +44 -0
- package/dist/input/clock.js +49 -0
- package/dist/input/follow.d.ts +133 -0
- package/dist/input/follow.js +218 -0
- package/dist/input/gestures.d.ts +281 -0
- package/dist/input/gestures.js +662 -0
- package/dist/input/glyphs.d.ts +35 -0
- package/dist/input/glyphs.js +216 -0
- package/dist/input/gyro.d.ts +85 -0
- package/dist/input/gyro.js +140 -0
- package/dist/input/index.d.ts +19 -0
- package/dist/input/index.js +16 -0
- package/dist/input/input.d.ts +543 -0
- package/dist/input/input.js +1492 -0
- package/dist/input/look.d.ts +327 -0
- package/dist/input/look.js +681 -0
- package/dist/input/magnify.d.ts +177 -0
- package/dist/input/magnify.js +131 -0
- package/dist/input/pointer-dispatch.d.ts +138 -0
- package/dist/input/pointer-dispatch.js +180 -0
- package/dist/input/pointer-router.d.ts +204 -0
- package/dist/input/pointer-router.js +533 -0
- package/dist/input/pointer-sources.d.ts +164 -0
- package/dist/input/pointer-sources.js +306 -0
- package/dist/input/rays.d.ts +138 -0
- package/dist/input/rays.js +615 -0
- package/dist/input/record.d.ts +209 -0
- package/dist/input/record.js +601 -0
- package/dist/input/touch-zones.d.ts +147 -0
- package/dist/input/touch-zones.js +300 -0
- package/dist/input/types.d.ts +158 -0
- package/dist/input/types.js +1 -0
- package/dist/input/xr-source.d.ts +53 -0
- package/dist/input/xr-source.js +164 -0
- package/dist/nav/astar.d.ts +45 -0
- package/dist/nav/astar.js +182 -0
- package/dist/nav/corridor.d.ts +40 -0
- package/dist/nav/corridor.js +95 -0
- package/dist/nav/crowd.d.ts +94 -0
- package/dist/nav/crowd.js +624 -0
- package/dist/nav/flow.d.ts +61 -0
- package/dist/nav/flow.js +193 -0
- package/dist/nav/grid.d.ts +108 -0
- package/dist/nav/grid.js +210 -0
- package/dist/nav/heap.d.ts +22 -0
- package/dist/nav/heap.js +92 -0
- package/dist/nav/index.d.ts +37 -0
- package/dist/nav/index.js +19 -0
- package/dist/nav/mesh/areas.d.ts +44 -0
- package/dist/nav/mesh/areas.js +98 -0
- package/dist/nav/mesh/bake-options.d.ts +33 -0
- package/dist/nav/mesh/bake-options.js +76 -0
- package/dist/nav/mesh/contour.d.ts +22 -0
- package/dist/nav/mesh/contour.js +323 -0
- package/dist/nav/mesh/flow3.d.ts +35 -0
- package/dist/nav/mesh/flow3.js +229 -0
- package/dist/nav/mesh/links.d.ts +38 -0
- package/dist/nav/mesh/links.js +72 -0
- package/dist/nav/mesh/mesh-path.d.ts +152 -0
- package/dist/nav/mesh/mesh-path.js +643 -0
- package/dist/nav/mesh/mesh-reach.d.ts +78 -0
- package/dist/nav/mesh/mesh-reach.js +450 -0
- package/dist/nav/mesh/navmesh.d.ts +117 -0
- package/dist/nav/mesh/navmesh.js +647 -0
- package/dist/nav/mesh/polymesh.d.ts +24 -0
- package/dist/nav/mesh/polymesh.js +384 -0
- package/dist/nav/mesh/regions.d.ts +12 -0
- package/dist/nav/mesh/regions.js +367 -0
- package/dist/nav/mesh/serialize.d.ts +13 -0
- package/dist/nav/mesh/serialize.js +197 -0
- package/dist/nav/mesh/voxelize.d.ts +111 -0
- package/dist/nav/mesh/voxelize.js +552 -0
- package/dist/nav/obstacles.d.ts +75 -0
- package/dist/nav/obstacles.js +294 -0
- package/dist/nav/path.d.ts +59 -0
- package/dist/nav/path.js +177 -0
- package/dist/nav/query-queue.d.ts +46 -0
- package/dist/nav/query-queue.js +308 -0
- package/dist/nav/reach.d.ts +53 -0
- package/dist/nav/reach.js +148 -0
- package/dist/nav/steer.d.ts +36 -0
- package/dist/nav/steer.js +78 -0
- package/dist/platform/boot.d.ts +28 -0
- package/dist/platform/boot.js +43 -0
- package/dist/platform/device-mode.d.ts +40 -0
- package/dist/platform/device-mode.js +104 -0
- package/dist/platform/device.d.ts +31 -0
- package/dist/platform/device.js +91 -0
- package/dist/platform/environment.d.ts +42 -0
- package/dist/platform/environment.js +82 -0
- package/dist/platform/gpu.d.ts +40 -0
- package/dist/platform/gpu.js +57 -0
- package/dist/platform/index.d.ts +18 -0
- package/dist/platform/index.js +10 -0
- package/dist/platform/letterbox.d.ts +43 -0
- package/dist/platform/letterbox.js +57 -0
- package/dist/platform/links.d.ts +20 -0
- package/dist/platform/links.js +43 -0
- package/dist/platform/screens.d.ts +36 -0
- package/dist/platform/screens.js +138 -0
- package/dist/platform/surface.d.ts +72 -0
- package/dist/platform/surface.js +157 -0
- package/dist/platform/xr-fake.d.ts +168 -0
- package/dist/platform/xr-fake.js +434 -0
- package/dist/platform/xr-surface.d.ts +120 -0
- package/dist/platform/xr-surface.js +214 -0
- package/dist/platform/xr-types.d.ts +262 -0
- package/dist/post/ao.d.ts +12 -0
- package/dist/post/ao.js +136 -0
- package/dist/post/blend.d.ts +27 -0
- package/dist/post/blend.js +129 -0
- package/dist/post/depth-pass.d.ts +43 -0
- package/dist/post/depth-pass.js +118 -0
- package/dist/post/dof.d.ts +1 -0
- package/dist/post/dof.js +66 -0
- package/dist/post/exposure.d.ts +80 -0
- package/dist/post/exposure.js +322 -0
- package/dist/post/index.d.ts +12 -0
- package/dist/post/index.js +11 -0
- package/dist/post/lens-dirt.d.ts +13 -0
- package/dist/post/lens-dirt.js +91 -0
- package/dist/post/lut.d.ts +19 -0
- package/dist/post/lut.js +50 -0
- package/dist/post/motion-blur.d.ts +9 -0
- package/dist/post/motion-blur.js +78 -0
- package/dist/post/post-stack.d.ts +302 -0
- package/dist/post/post-stack.js +1137 -0
- package/dist/post/settings.d.ts +485 -0
- package/dist/post/settings.js +416 -0
- package/dist/post/shaders.d.ts +25 -0
- package/dist/post/shaders.js +410 -0
- package/dist/post/ssr.d.ts +16 -0
- package/dist/post/ssr.js +155 -0
- package/dist/post/taa.d.ts +74 -0
- package/dist/post/taa.js +235 -0
- package/dist/post/white-balance.d.ts +25 -0
- package/dist/post/white-balance.js +98 -0
- package/dist/render/bindings.d.ts +98 -0
- package/dist/render/bindings.js +281 -0
- package/dist/render/blend.d.ts +13 -0
- package/dist/render/blend.js +26 -0
- package/dist/render/camera-2d.d.ts +72 -0
- package/dist/render/camera-2d.js +92 -0
- package/dist/render/camera.d.ts +302 -0
- package/dist/render/camera.js +671 -0
- package/dist/render/color.d.ts +16 -0
- package/dist/render/color.js +41 -0
- package/dist/render/compressed.d.ts +104 -0
- package/dist/render/compressed.js +248 -0
- package/dist/render/diagnostics.d.ts +15 -0
- package/dist/render/diagnostics.js +43 -0
- package/dist/render/dynamic-resolution.d.ts +70 -0
- package/dist/render/dynamic-resolution.js +126 -0
- package/dist/render/fake-gpu.d.ts +204 -0
- package/dist/render/fake-gpu.js +426 -0
- package/dist/render/flipbook.d.ts +56 -0
- package/dist/render/flipbook.js +87 -0
- package/dist/render/frame.d.ts +278 -0
- package/dist/render/frame.js +174 -0
- package/dist/render/fullscreen.d.ts +54 -0
- package/dist/render/fullscreen.js +91 -0
- package/dist/render/gpu-timer.d.ts +73 -0
- package/dist/render/gpu-timer.js +186 -0
- package/dist/render/index.d.ts +53 -0
- package/dist/render/index.js +29 -0
- package/dist/render/instance-list.d.ts +185 -0
- package/dist/render/instance-list.js +547 -0
- package/dist/render/lights.d.ts +181 -0
- package/dist/render/lights.js +233 -0
- package/dist/render/lod.d.ts +54 -0
- package/dist/render/lod.js +52 -0
- package/dist/render/material.d.ts +165 -0
- package/dist/render/material.js +292 -0
- package/dist/render/mesh.d.ts +284 -0
- package/dist/render/mesh.js +472 -0
- package/dist/render/mipmap.d.ts +16 -0
- package/dist/render/mipmap.js +121 -0
- package/dist/render/parallax.d.ts +50 -0
- package/dist/render/parallax.js +47 -0
- package/dist/render/pbr-wgsl.d.ts +31 -0
- package/dist/render/pbr-wgsl.js +119 -0
- package/dist/render/ping-pong.d.ts +42 -0
- package/dist/render/ping-pong.js +74 -0
- package/dist/render/renderer.d.ts +741 -0
- package/dist/render/renderer.js +2486 -0
- package/dist/render/scene-pipelines.d.ts +44 -0
- package/dist/render/scene-pipelines.js +92 -0
- package/dist/render/scene-target.d.ts +170 -0
- package/dist/render/scene-target.js +450 -0
- package/dist/render/shadow.d.ts +74 -0
- package/dist/render/shadow.js +208 -0
- package/dist/render/skin.d.ts +112 -0
- package/dist/render/skin.js +240 -0
- package/dist/render/snapshot.d.ts +36 -0
- package/dist/render/snapshot.js +34 -0
- package/dist/render/standard.d.ts +162 -0
- package/dist/render/standard.js +263 -0
- package/dist/render/texture.d.ts +142 -0
- package/dist/render/texture.js +228 -0
- package/dist/render/tile-layer.d.ts +110 -0
- package/dist/render/tile-layer.js +304 -0
- package/dist/render/transform.d.ts +115 -0
- package/dist/render/transform.js +318 -0
- package/dist/render/wgsl.d.ts +131 -0
- package/dist/render/wgsl.js +528 -0
- package/dist/save/codec.d.ts +49 -0
- package/dist/save/codec.js +169 -0
- package/dist/save/index.d.ts +8 -0
- package/dist/save/index.js +8 -0
- package/dist/save/journal.d.ts +24 -0
- package/dist/save/journal.js +102 -0
- package/dist/save/migrate.d.ts +15 -0
- package/dist/save/migrate.js +37 -0
- package/dist/save/schema.d.ts +72 -0
- package/dist/save/schema.js +154 -0
- package/dist/save/settings.d.ts +28 -0
- package/dist/save/settings.js +59 -0
- package/dist/save/slots.d.ts +56 -0
- package/dist/save/slots.js +200 -0
- package/dist/save/storage.d.ts +35 -0
- package/dist/save/storage.js +62 -0
- package/dist/save/store.d.ts +114 -0
- package/dist/save/store.js +269 -0
- package/dist/testing/fake-host.d.ts +103 -0
- package/dist/testing/fake-host.js +163 -0
- package/dist/testing/fixed-clock.d.ts +25 -0
- package/dist/testing/fixed-clock.js +30 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/test-game.d.ts +76 -0
- package/dist/testing/test-game.js +92 -0
- package/dist/tween/ease.d.ts +77 -0
- package/dist/tween/ease.js +192 -0
- package/dist/tween/index.d.ts +8 -0
- package/dist/tween/index.js +7 -0
- package/dist/tween/timeline.d.ts +78 -0
- package/dist/tween/timeline.js +269 -0
- package/dist/tween/tween.d.ts +168 -0
- package/dist/tween/tween.js +320 -0
- package/dist/ui/anchor.d.ts +206 -0
- package/dist/ui/anchor.js +307 -0
- package/dist/ui/caption.d.ts +122 -0
- package/dist/ui/caption.js +286 -0
- package/dist/ui/cursor.d.ts +105 -0
- package/dist/ui/cursor.js +261 -0
- package/dist/ui/dom.d.ts +30 -0
- package/dist/ui/dom.js +92 -0
- package/dist/ui/floats.d.ts +86 -0
- package/dist/ui/floats.js +260 -0
- package/dist/ui/hud.d.ts +198 -0
- package/dist/ui/hud.js +431 -0
- package/dist/ui/index.d.ts +37 -0
- package/dist/ui/index.js +34 -0
- package/dist/ui/inventory-card.d.ts +52 -0
- package/dist/ui/inventory-card.js +173 -0
- package/dist/ui/inventory-context.d.ts +29 -0
- package/dist/ui/inventory-context.js +125 -0
- package/dist/ui/inventory-drag.d.ts +63 -0
- package/dist/ui/inventory-drag.js +394 -0
- package/dist/ui/inventory-grid.d.ts +66 -0
- package/dist/ui/inventory-grid.js +625 -0
- package/dist/ui/inventory-radial.d.ts +39 -0
- package/dist/ui/inventory-radial.js +168 -0
- package/dist/ui/inventory.d.ts +128 -0
- package/dist/ui/inventory.js +154 -0
- package/dist/ui/layout.d.ts +356 -0
- package/dist/ui/layout.js +856 -0
- package/dist/ui/link.d.ts +64 -0
- package/dist/ui/link.js +155 -0
- package/dist/ui/loading.d.ts +40 -0
- package/dist/ui/loading.js +157 -0
- package/dist/ui/loupe.d.ts +74 -0
- package/dist/ui/loupe.js +164 -0
- package/dist/ui/menu-nav.d.ts +33 -0
- package/dist/ui/menu-nav.js +28 -0
- package/dist/ui/minimap-canvas.d.ts +145 -0
- package/dist/ui/minimap-canvas.js +460 -0
- package/dist/ui/notify.d.ts +40 -0
- package/dist/ui/notify.js +141 -0
- package/dist/ui/orb.d.ts +53 -0
- package/dist/ui/orb.js +304 -0
- package/dist/ui/overlay.d.ts +213 -0
- package/dist/ui/overlay.js +394 -0
- package/dist/ui/padnav.d.ts +53 -0
- package/dist/ui/padnav.js +146 -0
- package/dist/ui/perf.d.ts +130 -0
- package/dist/ui/perf.js +329 -0
- package/dist/ui/rotate-card.d.ts +54 -0
- package/dist/ui/rotate-card.js +97 -0
- package/dist/ui/stack.d.ts +128 -0
- package/dist/ui/stack.js +312 -0
- package/dist/ui/styles.d.ts +13 -0
- package/dist/ui/styles.js +200 -0
- package/dist/ui/text-scale.d.ts +67 -0
- package/dist/ui/text-scale.js +102 -0
- package/dist/ui/theme.d.ts +70 -0
- package/dist/ui/theme.js +98 -0
- package/dist/ui/toast.d.ts +23 -0
- package/dist/ui/toast.js +46 -0
- package/dist/ui/tooltip.d.ts +89 -0
- package/dist/ui/tooltip.js +333 -0
- package/dist/ui/widgets-2.d.ts +134 -0
- package/dist/ui/widgets-2.js +399 -0
- package/dist/ui/widgets-3.d.ts +91 -0
- package/dist/ui/widgets-3.js +212 -0
- package/dist/ui/widgets.d.ts +34 -0
- package/dist/ui/widgets.js +50 -0
- package/dist/ui/world-panel/index.d.ts +5 -0
- package/dist/ui/world-panel/index.js +5 -0
- package/dist/ui/world-panel/layout.d.ts +38 -0
- package/dist/ui/world-panel/layout.js +68 -0
- package/dist/ui/world-panel/paint.d.ts +96 -0
- package/dist/ui/world-panel/paint.js +136 -0
- package/dist/ui/world-panel/panel.d.ts +235 -0
- package/dist/ui/world-panel/panel.js +762 -0
- package/dist/ui/world-panel/wgsl.d.ts +10 -0
- package/dist/ui/world-panel/wgsl.js +52 -0
- package/dist/ui/world-panel/widgets.d.ts +207 -0
- package/dist/ui/world-panel/widgets.js +569 -0
- package/dist/voxel/chunks.d.ts +77 -0
- package/dist/voxel/chunks.js +149 -0
- package/dist/voxel/grid.d.ts +84 -0
- package/dist/voxel/grid.js +223 -0
- package/dist/voxel/index.d.ts +22 -0
- package/dist/voxel/index.js +7 -0
- package/dist/voxel/mesher-worker.d.ts +14 -0
- package/dist/voxel/mesher-worker.js +47 -0
- package/dist/voxel/mesher.d.ts +73 -0
- package/dist/voxel/mesher.js +306 -0
- package/dist/voxel/ray.d.ts +32 -0
- package/dist/voxel/ray.js +73 -0
- package/dist/voxel/wgsl.d.ts +16 -0
- package/dist/voxel/wgsl.js +28 -0
- package/dist/voxel/worker-client.d.ts +79 -0
- package/dist/voxel/worker-client.js +122 -0
- package/package.json +177 -3
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { NEIGHBOUR_X, NEIGHBOUR_Y, stepCost } from './grid.js';
|
|
2
|
+
import { CellHeap } from './heap.js';
|
|
3
|
+
import { clearPath3, MeshSearch } from './mesh/mesh-path.js';
|
|
4
|
+
import { NavMesh } from './mesh/navmesh.js';
|
|
5
|
+
import { reservePath, smoothPath } from './path.js';
|
|
6
|
+
const SQRT2 = Math.SQRT2;
|
|
7
|
+
function heuristic(x, y, tx, ty, diagonal) {
|
|
8
|
+
const dx = x > tx ? x - tx : tx - x;
|
|
9
|
+
const dy = y > ty ? y - ty : ty - y;
|
|
10
|
+
if (!diagonal)
|
|
11
|
+
return dx + dy;
|
|
12
|
+
return dx > dy ? dx + (SQRT2 - 1) * dy : dy + (SQRT2 - 1) * dx;
|
|
13
|
+
}
|
|
14
|
+
/** `findPath`'s A*, resumable: identical expansion order, so identical paths. */
|
|
15
|
+
class GridSearch {
|
|
16
|
+
grid;
|
|
17
|
+
state = 'idle';
|
|
18
|
+
version = -1;
|
|
19
|
+
g;
|
|
20
|
+
f;
|
|
21
|
+
parent;
|
|
22
|
+
seen;
|
|
23
|
+
closed;
|
|
24
|
+
heap;
|
|
25
|
+
stamp = 0;
|
|
26
|
+
goal = -1;
|
|
27
|
+
tx = 0;
|
|
28
|
+
ty = 0;
|
|
29
|
+
diagonal = true;
|
|
30
|
+
weight = 1;
|
|
31
|
+
maxExpand = 0;
|
|
32
|
+
maxCost = Number.POSITIVE_INFINITY;
|
|
33
|
+
expanded = 0;
|
|
34
|
+
constructor(grid) {
|
|
35
|
+
this.grid = grid;
|
|
36
|
+
const n = grid.size;
|
|
37
|
+
this.g = new Float64Array(n);
|
|
38
|
+
this.f = new Float64Array(n);
|
|
39
|
+
this.parent = new Int32Array(n);
|
|
40
|
+
this.seen = new Uint32Array(n);
|
|
41
|
+
this.closed = new Uint32Array(n);
|
|
42
|
+
this.heap = new CellHeap(n, this.f);
|
|
43
|
+
}
|
|
44
|
+
begin(from, to, opts) {
|
|
45
|
+
const grid = this.grid;
|
|
46
|
+
this.version = grid.version;
|
|
47
|
+
this.state = 'failed';
|
|
48
|
+
this.expanded = 0;
|
|
49
|
+
if (!grid.isWalkable(from.x, from.y) || !grid.isWalkable(to.x, to.y))
|
|
50
|
+
return false;
|
|
51
|
+
this.diagonal = opts?.diagonal ?? grid.neighbours === 8;
|
|
52
|
+
this.maxExpand = opts?.maxExpand ?? grid.size;
|
|
53
|
+
this.maxCost = opts?.maxCost ?? Infinity;
|
|
54
|
+
this.weight = opts?.heuristicWeight ?? 1;
|
|
55
|
+
this.stamp = (this.stamp + 1) >>> 0 || 1;
|
|
56
|
+
this.heap.clear();
|
|
57
|
+
const width = grid.width;
|
|
58
|
+
this.tx = to.x;
|
|
59
|
+
this.ty = to.y;
|
|
60
|
+
const start = from.y * width + from.x;
|
|
61
|
+
this.goal = to.y * width + to.x;
|
|
62
|
+
this.g[start] = 0;
|
|
63
|
+
this.f[start] = this.weight * heuristic(from.x, from.y, to.x, to.y, this.diagonal);
|
|
64
|
+
this.parent[start] = -1;
|
|
65
|
+
this.seen[start] = this.stamp;
|
|
66
|
+
this.heap.pushOrDecrease(start);
|
|
67
|
+
this.state = 'running';
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
step(maxPops) {
|
|
71
|
+
if (this.state !== 'running')
|
|
72
|
+
return 0;
|
|
73
|
+
const { grid, g, f, parent, seen, closed, heap, stamp, goal, tx, ty, diagonal, weight } = this;
|
|
74
|
+
const maxCost = this.maxCost;
|
|
75
|
+
const width = grid.width;
|
|
76
|
+
const dirs = diagonal ? 8 : 4;
|
|
77
|
+
let pops = 0;
|
|
78
|
+
while (pops < maxPops) {
|
|
79
|
+
if (heap.size === 0) {
|
|
80
|
+
this.state = 'failed';
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
const cur = heap.pop();
|
|
84
|
+
pops++;
|
|
85
|
+
if (cur === goal) {
|
|
86
|
+
this.state = 'found';
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
if (++this.expanded > this.maxExpand) {
|
|
90
|
+
this.state = 'failed';
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
closed[cur] = stamp;
|
|
94
|
+
const cx = cur % width;
|
|
95
|
+
const cy = (cur - cx) / width;
|
|
96
|
+
const gc = g[cur];
|
|
97
|
+
for (let d = 0; d < dirs; d++) {
|
|
98
|
+
const step = stepCost(grid, cur, cx, cy, d);
|
|
99
|
+
if (step === Infinity)
|
|
100
|
+
continue;
|
|
101
|
+
const nx = cx + NEIGHBOUR_X[d];
|
|
102
|
+
const ny = cy + NEIGHBOUR_Y[d];
|
|
103
|
+
const ni = ny * width + nx;
|
|
104
|
+
if (closed[ni] === stamp)
|
|
105
|
+
continue;
|
|
106
|
+
const ng = gc + step;
|
|
107
|
+
if (ng > maxCost)
|
|
108
|
+
continue;
|
|
109
|
+
if (seen[ni] === stamp && ng >= g[ni])
|
|
110
|
+
continue;
|
|
111
|
+
seen[ni] = stamp;
|
|
112
|
+
g[ni] = ng;
|
|
113
|
+
f[ni] = ng + weight * heuristic(nx, ny, tx, ty, diagonal);
|
|
114
|
+
parent[ni] = cur;
|
|
115
|
+
heap.pushOrDecrease(ni);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return pops;
|
|
119
|
+
}
|
|
120
|
+
finish(out) {
|
|
121
|
+
out.length = 0;
|
|
122
|
+
out.cursor = 0;
|
|
123
|
+
out.version = this.version;
|
|
124
|
+
if (this.state !== 'found')
|
|
125
|
+
return false;
|
|
126
|
+
const { grid, parent, goal } = this;
|
|
127
|
+
const width = grid.width;
|
|
128
|
+
let count = 0;
|
|
129
|
+
for (let i = goal; i >= 0; i = parent[i])
|
|
130
|
+
count++;
|
|
131
|
+
reservePath(out, count);
|
|
132
|
+
const p = out.points;
|
|
133
|
+
const cs = grid.cellSize;
|
|
134
|
+
const ox = grid.origin.x;
|
|
135
|
+
const oz = grid.origin.z;
|
|
136
|
+
let k = count - 1;
|
|
137
|
+
for (let i = goal; i >= 0; i = parent[i], k--) {
|
|
138
|
+
const x = i % width;
|
|
139
|
+
const y = (i - x) / width;
|
|
140
|
+
p[k * 2] = ox + (x + 0.5) * cs;
|
|
141
|
+
p[k * 2 + 1] = oz + (y + 0.5) * cs;
|
|
142
|
+
}
|
|
143
|
+
out.length = count;
|
|
144
|
+
this.state = 'idle';
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** A queue of path searches over a mesh or a grid, sliced across `update()` calls. */
|
|
149
|
+
export function createPathQueue(target, opts) {
|
|
150
|
+
const max = Math.max(1, opts.maxQueries);
|
|
151
|
+
const budget = Math.max(1, opts.iterationsPerUpdate ?? 256);
|
|
152
|
+
const mesh = target instanceof NavMesh ? target : null;
|
|
153
|
+
const grid = mesh ? null : target;
|
|
154
|
+
const meshSearch = mesh ? new MeshSearch(mesh) : null;
|
|
155
|
+
const gridSearch = grid ? new GridSearch(grid) : null;
|
|
156
|
+
// A ring of tickets in request order; finished tickets keep their state until their slot is reused.
|
|
157
|
+
const ring = [];
|
|
158
|
+
for (let i = 0; i < max; i++) {
|
|
159
|
+
ring.push({
|
|
160
|
+
id: 0,
|
|
161
|
+
state: 'none',
|
|
162
|
+
fx: 0,
|
|
163
|
+
fy: 0,
|
|
164
|
+
fz: 0,
|
|
165
|
+
tx: 0,
|
|
166
|
+
ty: 0,
|
|
167
|
+
tz: 0,
|
|
168
|
+
out: null,
|
|
169
|
+
opts: undefined,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
let head = 0; // the oldest pending ticket's slot
|
|
173
|
+
let tail = 0; // the next free slot
|
|
174
|
+
let pending = 0;
|
|
175
|
+
/** Slots taken, cancelled ones included until the ring reaches them. */
|
|
176
|
+
let occupied = 0;
|
|
177
|
+
let finished = 0;
|
|
178
|
+
let nextId = 1;
|
|
179
|
+
/** The ticket id the in-flight search belongs to, 0 when none. */
|
|
180
|
+
let inFlight = 0;
|
|
181
|
+
const from3 = { x: 0, y: 0, z: 0 };
|
|
182
|
+
const to3 = { x: 0, y: 0, z: 0 };
|
|
183
|
+
const fromCell = { x: 0, y: 0 };
|
|
184
|
+
const toCell = { x: 0, y: 0 };
|
|
185
|
+
const find = (ticket) => {
|
|
186
|
+
if (ticket <= 0)
|
|
187
|
+
return undefined;
|
|
188
|
+
for (let i = 0; i < max; i++) {
|
|
189
|
+
const t = ring[i];
|
|
190
|
+
if (t.id === ticket)
|
|
191
|
+
return t;
|
|
192
|
+
}
|
|
193
|
+
return undefined;
|
|
194
|
+
};
|
|
195
|
+
const begin = (t) => {
|
|
196
|
+
inFlight = t.id;
|
|
197
|
+
if (meshSearch) {
|
|
198
|
+
from3.x = t.fx;
|
|
199
|
+
from3.y = t.fy;
|
|
200
|
+
from3.z = t.fz;
|
|
201
|
+
to3.x = t.tx;
|
|
202
|
+
to3.y = t.ty;
|
|
203
|
+
to3.z = t.tz;
|
|
204
|
+
return meshSearch.begin(from3, to3, t.opts);
|
|
205
|
+
}
|
|
206
|
+
fromCell.x = t.fx;
|
|
207
|
+
fromCell.y = t.fy;
|
|
208
|
+
toCell.x = t.tx;
|
|
209
|
+
toCell.y = t.ty;
|
|
210
|
+
return gridSearch.begin(fromCell, toCell, t.opts);
|
|
211
|
+
};
|
|
212
|
+
const queue = {
|
|
213
|
+
get pending() {
|
|
214
|
+
return pending;
|
|
215
|
+
},
|
|
216
|
+
get finished() {
|
|
217
|
+
return finished;
|
|
218
|
+
},
|
|
219
|
+
onDone: null,
|
|
220
|
+
request(from, to, out, reqOpts) {
|
|
221
|
+
if (occupied >= max)
|
|
222
|
+
return -1;
|
|
223
|
+
const t = ring[tail];
|
|
224
|
+
tail = tail + 1 === max ? 0 : tail + 1;
|
|
225
|
+
t.id = nextId++;
|
|
226
|
+
t.state = 'pending';
|
|
227
|
+
t.fx = from.x;
|
|
228
|
+
t.fy = from.y;
|
|
229
|
+
t.fz = 'z' in from ? from.z : 0;
|
|
230
|
+
t.tx = to.x;
|
|
231
|
+
t.ty = to.y;
|
|
232
|
+
t.tz = 'z' in to ? to.z : 0;
|
|
233
|
+
t.out = out;
|
|
234
|
+
t.opts = reqOpts;
|
|
235
|
+
pending++;
|
|
236
|
+
occupied++;
|
|
237
|
+
return t.id;
|
|
238
|
+
},
|
|
239
|
+
update() {
|
|
240
|
+
let left = budget;
|
|
241
|
+
while (left > 0 && occupied > 0) {
|
|
242
|
+
const t = ring[head];
|
|
243
|
+
if (t.state !== 'pending') {
|
|
244
|
+
// Cancelled: skip the slot.
|
|
245
|
+
head = head + 1 === max ? 0 : head + 1;
|
|
246
|
+
occupied--;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
const search = meshSearch ?? gridSearch;
|
|
250
|
+
let ok;
|
|
251
|
+
if (inFlight !== t.id || search.version !== target.version) {
|
|
252
|
+
ok = begin(t);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
ok = true;
|
|
256
|
+
}
|
|
257
|
+
if (ok && search.state === 'running') {
|
|
258
|
+
left -= search.step(left);
|
|
259
|
+
if (search.state === 'running')
|
|
260
|
+
break; // budget spent; resume next update
|
|
261
|
+
}
|
|
262
|
+
const done = search.state === 'found' &&
|
|
263
|
+
(meshSearch
|
|
264
|
+
? meshSearch.finish(t.out)
|
|
265
|
+
: gridSearch.finish(t.out));
|
|
266
|
+
if (done && gridSearch && t.opts?.smooth)
|
|
267
|
+
smoothPath(grid, t.out);
|
|
268
|
+
if (!done && t.out) {
|
|
269
|
+
if (meshSearch)
|
|
270
|
+
clearPath3(t.out);
|
|
271
|
+
else {
|
|
272
|
+
t.out.length = 0;
|
|
273
|
+
t.out.cursor = 0;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
search.state = 'idle';
|
|
277
|
+
inFlight = 0;
|
|
278
|
+
t.state = done ? 'done' : 'failed';
|
|
279
|
+
head = head + 1 === max ? 0 : head + 1;
|
|
280
|
+
pending--;
|
|
281
|
+
occupied--;
|
|
282
|
+
finished++;
|
|
283
|
+
const out = t.out;
|
|
284
|
+
t.out = null;
|
|
285
|
+
t.opts = undefined;
|
|
286
|
+
queue.onDone?.(t.id, done, out);
|
|
287
|
+
}
|
|
288
|
+
return budget - left;
|
|
289
|
+
},
|
|
290
|
+
status(ticket) {
|
|
291
|
+
const t = find(ticket);
|
|
292
|
+
return t ? t.state : 'none';
|
|
293
|
+
},
|
|
294
|
+
cancel(ticket) {
|
|
295
|
+
const t = find(ticket);
|
|
296
|
+
if (t?.state !== 'pending')
|
|
297
|
+
return false;
|
|
298
|
+
t.state = 'none';
|
|
299
|
+
t.out = null;
|
|
300
|
+
t.opts = undefined;
|
|
301
|
+
pending--;
|
|
302
|
+
if (inFlight === ticket)
|
|
303
|
+
inFlight = 0;
|
|
304
|
+
return true;
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
return queue;
|
|
308
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded reachability: Dijkstra from one or more start cells that stops at a cost budget and
|
|
3
|
+
* keeps every parent, so a turn-based or tile game asks "where can this unit move" and "by which
|
|
4
|
+
* path" from one query. The result lives in a `Reach` sized to the grid once and reused.
|
|
5
|
+
*/
|
|
6
|
+
import type { NavGrid } from './grid.js';
|
|
7
|
+
import { type MeshReach, type MeshReachOptions } from './mesh/mesh-reach.js';
|
|
8
|
+
import { NavMesh, type NavPoint3 } from './mesh/navmesh.js';
|
|
9
|
+
import { type NavPath } from './path.js';
|
|
10
|
+
export interface Reach {
|
|
11
|
+
readonly grid: NavGrid;
|
|
12
|
+
/** Cells reached by the last query (the starts included). */
|
|
13
|
+
readonly count: number;
|
|
14
|
+
/** The reached cells' row-major indices, in order of increasing distance; `count` are valid. */
|
|
15
|
+
readonly cells: Int32Array;
|
|
16
|
+
/** Cost-weighted distance from the nearest start per grid cell; `Infinity` when not reached. */
|
|
17
|
+
readonly distances: Float32Array;
|
|
18
|
+
/** The cell each reached cell was entered from; -1 at a start or an unreached cell. */
|
|
19
|
+
readonly parents: Int32Array;
|
|
20
|
+
/** The budget of the last query. */
|
|
21
|
+
readonly budget: number;
|
|
22
|
+
/** `grid.version` at the last query, or -1 before the first. */
|
|
23
|
+
readonly version: number;
|
|
24
|
+
/** True when the grid was edited since the last query. */
|
|
25
|
+
readonly stale: boolean;
|
|
26
|
+
/** True when the cell was reached within the budget (a start counts). */
|
|
27
|
+
has(index: number): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Walks the parents from the nearest start to `index` into `path` (world cell centres, like
|
|
30
|
+
* `findPath`; `cursor` 0, `version` stamped). False, with an empty path, when not reached.
|
|
31
|
+
*/
|
|
32
|
+
pathTo(index: number, path: NavPath): boolean;
|
|
33
|
+
/** Calls `fn` for every reached cell, nearest first. */
|
|
34
|
+
forEach(fn: (index: number, distance: number) => void): void;
|
|
35
|
+
}
|
|
36
|
+
/** A reusable reachability result sized to `grid`; pass it to `reachable` as `out`. */
|
|
37
|
+
export declare function createReach(grid: NavGrid): Reach;
|
|
38
|
+
/**
|
|
39
|
+
* Grid form: Dijkstra from `start` (a row-major index, or several) over the grid's neighbourhood with its
|
|
40
|
+
* edge costs, stopping at `budget` (inclusive: a cell whose cost equals the budget is reached).
|
|
41
|
+
* Writes into `out`, or into one `Reach` kept per grid when omitted, and returns it; nothing
|
|
42
|
+
* allocates after the first query on a grid. Unwalkable or out-of-grid starts are skipped. The
|
|
43
|
+
* cells in `out.cells` come nearest first, so the heap order doubles as a frontier order.
|
|
44
|
+
*/
|
|
45
|
+
export declare function reachable(grid: NavGrid, start: number | ArrayLike<number>, budget: number, out?: Reach): Reach;
|
|
46
|
+
/**
|
|
47
|
+
* Mesh form (ws/nav-5): the polygons whose centre is within path cost `opts.budget` of `from`
|
|
48
|
+
* (snapped onto the mesh), with their cost to reach, priced as `findMeshPath` prices a route
|
|
49
|
+
* (areas, links) and stopping at the budget or `opts.maxPolys`. Writes into `out`
|
|
50
|
+
* (`createMeshReach`) or one `MeshReach` kept per mesh; allocation-free after the first query.
|
|
51
|
+
* `reachableOutline` draws its boundary.
|
|
52
|
+
*/
|
|
53
|
+
export declare function reachable(mesh: NavMesh, from: Readonly<NavPoint3>, opts: MeshReachOptions, out?: MeshReach): MeshReach;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { NEIGHBOUR_X, NEIGHBOUR_Y, stepCost } from './grid.js';
|
|
2
|
+
import { CellHeap } from './heap.js';
|
|
3
|
+
import { reachableMesh } from './mesh/mesh-reach.js';
|
|
4
|
+
import { NavMesh } from './mesh/navmesh.js';
|
|
5
|
+
import { reservePath } from './path.js';
|
|
6
|
+
class ReachImpl {
|
|
7
|
+
grid;
|
|
8
|
+
cells;
|
|
9
|
+
distances;
|
|
10
|
+
parents;
|
|
11
|
+
count = 0;
|
|
12
|
+
budget = 0;
|
|
13
|
+
version = -1;
|
|
14
|
+
heap;
|
|
15
|
+
constructor(grid) {
|
|
16
|
+
this.grid = grid;
|
|
17
|
+
const n = grid.size;
|
|
18
|
+
this.cells = new Int32Array(n);
|
|
19
|
+
this.distances = new Float32Array(n).fill(Infinity);
|
|
20
|
+
this.parents = new Int32Array(n).fill(-1);
|
|
21
|
+
this.heap = new CellHeap(n, this.distances);
|
|
22
|
+
}
|
|
23
|
+
get stale() {
|
|
24
|
+
return this.version !== this.grid.version;
|
|
25
|
+
}
|
|
26
|
+
has(index) {
|
|
27
|
+
return index >= 0 && index < this.grid.size && this.distances[index] < Infinity;
|
|
28
|
+
}
|
|
29
|
+
pathTo(index, path) {
|
|
30
|
+
path.length = 0;
|
|
31
|
+
path.cursor = 0;
|
|
32
|
+
path.version = this.version;
|
|
33
|
+
if (!this.has(index))
|
|
34
|
+
return false;
|
|
35
|
+
const parents = this.parents;
|
|
36
|
+
let count = 0;
|
|
37
|
+
for (let i = index; i >= 0; i = parents[i])
|
|
38
|
+
count++;
|
|
39
|
+
reservePath(path, count);
|
|
40
|
+
const grid = this.grid;
|
|
41
|
+
const width = grid.width;
|
|
42
|
+
const cs = grid.cellSize;
|
|
43
|
+
const ox = grid.origin.x;
|
|
44
|
+
const oz = grid.origin.z;
|
|
45
|
+
const p = path.points;
|
|
46
|
+
let k = count - 1;
|
|
47
|
+
for (let i = index; i >= 0; i = parents[i], k--) {
|
|
48
|
+
const x = i % width;
|
|
49
|
+
const y = (i - x) / width;
|
|
50
|
+
p[k * 2] = ox + (x + 0.5) * cs;
|
|
51
|
+
p[k * 2 + 1] = oz + (y + 0.5) * cs;
|
|
52
|
+
}
|
|
53
|
+
path.length = count;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
forEach(fn) {
|
|
57
|
+
for (let i = 0; i < this.count; i++) {
|
|
58
|
+
const c = this.cells[i];
|
|
59
|
+
fn(c, this.distances[c]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Forgets the last query's cells only (the untouched rest is still `Infinity` / -1). */
|
|
63
|
+
reset() {
|
|
64
|
+
for (let i = 0; i < this.count; i++) {
|
|
65
|
+
const c = this.cells[i];
|
|
66
|
+
this.distances[c] = Infinity;
|
|
67
|
+
this.parents[c] = -1;
|
|
68
|
+
}
|
|
69
|
+
this.count = 0;
|
|
70
|
+
this.heap.clear();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** A reusable reachability result sized to `grid`; pass it to `reachable` as `out`. */
|
|
74
|
+
export function createReach(grid) {
|
|
75
|
+
return new ReachImpl(grid);
|
|
76
|
+
}
|
|
77
|
+
const reachFor = new WeakMap();
|
|
78
|
+
function seed(r, gi) {
|
|
79
|
+
if (!(gi >= 0 && gi < r.grid.size) || r.grid.costs[gi] <= 0 || r.distances[gi] === 0)
|
|
80
|
+
return;
|
|
81
|
+
r.distances[gi] = 0;
|
|
82
|
+
r.parents[gi] = -1;
|
|
83
|
+
r.heap.pushOrDecrease(gi);
|
|
84
|
+
}
|
|
85
|
+
export function reachable(target, start, budget, out) {
|
|
86
|
+
if (target instanceof NavMesh) {
|
|
87
|
+
return reachableMesh(target, start, budget, out);
|
|
88
|
+
}
|
|
89
|
+
return reachableGrid(target, start, budget, out);
|
|
90
|
+
}
|
|
91
|
+
function reachableGrid(grid, start, budget, out) {
|
|
92
|
+
let r;
|
|
93
|
+
if (out) {
|
|
94
|
+
if (out.grid !== grid)
|
|
95
|
+
throw new Error('nav: reach belongs to another grid');
|
|
96
|
+
r = out;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
const cached = reachFor.get(grid);
|
|
100
|
+
if (cached) {
|
|
101
|
+
r = cached;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
r = new ReachImpl(grid);
|
|
105
|
+
reachFor.set(grid, r);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
r.reset();
|
|
109
|
+
r.budget = budget;
|
|
110
|
+
r.version = grid.version;
|
|
111
|
+
const width = grid.width;
|
|
112
|
+
const dist = r.distances;
|
|
113
|
+
const parents = r.parents;
|
|
114
|
+
const cells = r.cells;
|
|
115
|
+
const heap = r.heap;
|
|
116
|
+
const dirs = grid.neighbours;
|
|
117
|
+
if (typeof start === 'number') {
|
|
118
|
+
seed(r, start);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
for (let i = 0; i < start.length; i++)
|
|
122
|
+
seed(r, start[i]);
|
|
123
|
+
}
|
|
124
|
+
let count = 0;
|
|
125
|
+
while (heap.size > 0) {
|
|
126
|
+
const cur = heap.pop();
|
|
127
|
+
cells[count++] = cur;
|
|
128
|
+
const cx = cur % width;
|
|
129
|
+
const cy = (cur - cx) / width;
|
|
130
|
+
const dc = dist[cur];
|
|
131
|
+
for (let d = 0; d < dirs; d++) {
|
|
132
|
+
const step = stepCost(grid, cur, cx, cy, d);
|
|
133
|
+
if (step === Infinity)
|
|
134
|
+
continue;
|
|
135
|
+
const nd = dc + step;
|
|
136
|
+
if (nd > budget)
|
|
137
|
+
continue;
|
|
138
|
+
const ni = (cy + NEIGHBOUR_Y[d]) * width + cx + NEIGHBOUR_X[d];
|
|
139
|
+
if (nd >= dist[ni])
|
|
140
|
+
continue;
|
|
141
|
+
dist[ni] = nd;
|
|
142
|
+
parents[ni] = cur;
|
|
143
|
+
heap.pushOrDecrease(ni);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
r.count = count;
|
|
147
|
+
return r;
|
|
148
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local steering on the XZ plane: small vector helpers an agent combines with a path or flow
|
|
3
|
+
* direction each tick. Every function writes `out` and returns it; nothing allocates.
|
|
4
|
+
*/
|
|
5
|
+
import type { NavPoint } from './grid.js';
|
|
6
|
+
/** A circular obstacle on the XZ plane. */
|
|
7
|
+
export interface Disc {
|
|
8
|
+
x: number;
|
|
9
|
+
z: number;
|
|
10
|
+
radius: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Pushes `self` away from every neighbour closer than `radius`: the sum over them of the unit
|
|
14
|
+
* vector away, weighted `(radius - d) / radius`, so a touching neighbour weighs 1 and one at the
|
|
15
|
+
* edge weighs 0. Zero when none is near; a neighbour exactly at `self` is skipped. Scale the
|
|
16
|
+
* result by a speed to make it a velocity.
|
|
17
|
+
*/
|
|
18
|
+
export declare function separate(self: Readonly<NavPoint>, neighbours: ArrayLike<Readonly<NavPoint>>, radius: number, out: NavPoint): NavPoint;
|
|
19
|
+
/**
|
|
20
|
+
* The velocity that reaches `target`: `speed` outside `slowRadius`, scaled down linearly inside
|
|
21
|
+
* it, zero at the target. `slowRadius` 0 never slows.
|
|
22
|
+
*/
|
|
23
|
+
export declare function arrive(self: Readonly<NavPoint>, target: Readonly<NavPoint>, speed: number, slowRadius: number, out: NavPoint): NavPoint;
|
|
24
|
+
/**
|
|
25
|
+
* `velocity` bent around `disc`: when the disc lies ahead within one second of travel and the
|
|
26
|
+
* course passes closer than its radius, a sideways push away from the centre is added, sized by
|
|
27
|
+
* how deep the course cuts in (full speed at a head-on hit, nothing at a graze). Otherwise `out`
|
|
28
|
+
* is `velocity`. A disc behind, or a zero velocity, leaves it alone. `out` may be `velocity`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function avoidDisc(self: Readonly<NavPoint>, velocity: Readonly<NavPoint>, disc: Readonly<Disc>, out: NavPoint): NavPoint;
|
|
31
|
+
/** The three helpers as one namespace: `steer.separate`, `steer.arrive`, `steer.avoidDisc`. */
|
|
32
|
+
export declare const steer: {
|
|
33
|
+
readonly separate: typeof separate;
|
|
34
|
+
readonly arrive: typeof arrive;
|
|
35
|
+
readonly avoidDisc: typeof avoidDisc;
|
|
36
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pushes `self` away from every neighbour closer than `radius`: the sum over them of the unit
|
|
3
|
+
* vector away, weighted `(radius - d) / radius`, so a touching neighbour weighs 1 and one at the
|
|
4
|
+
* edge weighs 0. Zero when none is near; a neighbour exactly at `self` is skipped. Scale the
|
|
5
|
+
* result by a speed to make it a velocity.
|
|
6
|
+
*/
|
|
7
|
+
export function separate(self, neighbours, radius, out) {
|
|
8
|
+
let x = 0;
|
|
9
|
+
let z = 0;
|
|
10
|
+
const r2 = radius * radius;
|
|
11
|
+
for (let i = 0; i < neighbours.length; i++) {
|
|
12
|
+
const n = neighbours[i];
|
|
13
|
+
const dx = self.x - n.x;
|
|
14
|
+
const dz = self.z - n.z;
|
|
15
|
+
const d2 = dx * dx + dz * dz;
|
|
16
|
+
if (d2 >= r2 || d2 === 0)
|
|
17
|
+
continue;
|
|
18
|
+
const d = Math.sqrt(d2);
|
|
19
|
+
const w = (radius - d) / radius / d;
|
|
20
|
+
x += dx * w;
|
|
21
|
+
z += dz * w;
|
|
22
|
+
}
|
|
23
|
+
out.x = x;
|
|
24
|
+
out.z = z;
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The velocity that reaches `target`: `speed` outside `slowRadius`, scaled down linearly inside
|
|
29
|
+
* it, zero at the target. `slowRadius` 0 never slows.
|
|
30
|
+
*/
|
|
31
|
+
export function arrive(self, target, speed, slowRadius, out) {
|
|
32
|
+
const dx = target.x - self.x;
|
|
33
|
+
const dz = target.z - self.z;
|
|
34
|
+
const d = Math.sqrt(dx * dx + dz * dz);
|
|
35
|
+
if (d === 0) {
|
|
36
|
+
out.x = 0;
|
|
37
|
+
out.z = 0;
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
const s = slowRadius > 0 && d < slowRadius ? (speed * d) / slowRadius : speed;
|
|
41
|
+
out.x = (dx / d) * s;
|
|
42
|
+
out.z = (dz / d) * s;
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* `velocity` bent around `disc`: when the disc lies ahead within one second of travel and the
|
|
47
|
+
* course passes closer than its radius, a sideways push away from the centre is added, sized by
|
|
48
|
+
* how deep the course cuts in (full speed at a head-on hit, nothing at a graze). Otherwise `out`
|
|
49
|
+
* is `velocity`. A disc behind, or a zero velocity, leaves it alone. `out` may be `velocity`.
|
|
50
|
+
*/
|
|
51
|
+
export function avoidDisc(self, velocity, disc, out) {
|
|
52
|
+
const vx = velocity.x;
|
|
53
|
+
const vz = velocity.z;
|
|
54
|
+
const speed = Math.sqrt(vx * vx + vz * vz);
|
|
55
|
+
out.x = vx;
|
|
56
|
+
out.z = vz;
|
|
57
|
+
if (speed === 0)
|
|
58
|
+
return out;
|
|
59
|
+
const dx = disc.x - self.x;
|
|
60
|
+
const dz = disc.z - self.z;
|
|
61
|
+
// Distance along the course (world units) and the signed distance beside it, measured along
|
|
62
|
+
// the perpendicular `perp = (vz, -vx) / speed`.
|
|
63
|
+
const along = (dx * vx + dz * vz) / speed;
|
|
64
|
+
if (along <= 0 || along > speed + disc.radius)
|
|
65
|
+
return out;
|
|
66
|
+
const side = (dx * vz - dz * vx) / speed;
|
|
67
|
+
const miss = Math.abs(side);
|
|
68
|
+
if (miss >= disc.radius)
|
|
69
|
+
return out;
|
|
70
|
+
const push = (speed * (disc.radius - miss)) / disc.radius;
|
|
71
|
+
// Push along `perp` away from the centre (a centre dead ahead goes to +perp).
|
|
72
|
+
const sign = side > 0 ? -1 : 1;
|
|
73
|
+
out.x = vx + (vz / speed) * push * sign;
|
|
74
|
+
out.z = vz + (-vx / speed) * push * sign;
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
/** The three helpers as one namespace: `steer.separate`, `steer.arrive`, `steer.avoidDisc`. */
|
|
78
|
+
export const steer = { separate, arrive, avoidDisc };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type GpuContext, type GpuFailureReason } from './gpu.js';
|
|
2
|
+
import { type Surface, type SurfaceOptions } from './surface.js';
|
|
3
|
+
export interface BootOptions extends SurfaceOptions {
|
|
4
|
+
/** Shown as the eyebrow on fatal screens (the game's name). */
|
|
5
|
+
title?: string;
|
|
6
|
+
/** Called after the device-lost screen is shown (stop loops here). */
|
|
7
|
+
onDeviceLost?: (info: GPUDeviceLostInfo) => void;
|
|
8
|
+
/** Dev aid: pretend WebGPU is missing to preview the unsupported screen. */
|
|
9
|
+
forceUnsupported?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export type BootResult = {
|
|
12
|
+
ok: true;
|
|
13
|
+
surface: Surface;
|
|
14
|
+
gpu: GpuContext;
|
|
15
|
+
/**
|
|
16
|
+
* Run `fn` after the device-lost screen is shown, to halt whatever was built after boot
|
|
17
|
+
* (loop, audio, timers). Returns unsubscribe.
|
|
18
|
+
*/
|
|
19
|
+
onDeviceLost(fn: (info: GPUDeviceLostInfo) => void): () => void;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
reason: GpuFailureReason | 'forced';
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Mount a letterboxed canvas in `root` and bring up WebGPU. On failure the canvas is removed
|
|
26
|
+
* and the styled unsupported screen is shown; on device loss the reload screen is shown.
|
|
27
|
+
*/
|
|
28
|
+
export declare function boot(root: HTMLElement, opts?: BootOptions): Promise<BootResult>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { initGpu } from './gpu.js';
|
|
2
|
+
import { showDeviceLostScreen, showUnsupportedScreen } from './screens.js';
|
|
3
|
+
import { mountSurface } from './surface.js';
|
|
4
|
+
/**
|
|
5
|
+
* Mount a letterboxed canvas in `root` and bring up WebGPU. On failure the canvas is removed
|
|
6
|
+
* and the styled unsupported screen is shown; on device loss the reload screen is shown.
|
|
7
|
+
*/
|
|
8
|
+
export async function boot(root, opts = {}) {
|
|
9
|
+
if (opts.forceUnsupported) {
|
|
10
|
+
showUnsupportedScreen(root, { title: opts.title });
|
|
11
|
+
return { ok: false, reason: 'forced' };
|
|
12
|
+
}
|
|
13
|
+
const surface = mountSurface(root, opts);
|
|
14
|
+
const lostListeners = new Set();
|
|
15
|
+
const res = await initGpu(surface.canvas, {
|
|
16
|
+
onLost: (info) => {
|
|
17
|
+
showDeviceLostScreen(root, { title: opts.title, detail: info.message || undefined });
|
|
18
|
+
opts.onDeviceLost?.(info);
|
|
19
|
+
for (const fn of [...lostListeners]) {
|
|
20
|
+
try {
|
|
21
|
+
fn(info);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error('[boot] device-lost handler failed', err);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
surface.destroy();
|
|
31
|
+
showUnsupportedScreen(root, { title: opts.title, detail: res.detail ?? res.reason });
|
|
32
|
+
return { ok: false, reason: res.reason };
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
ok: true,
|
|
36
|
+
surface,
|
|
37
|
+
gpu: res.gpu,
|
|
38
|
+
onDeviceLost(fn) {
|
|
39
|
+
lostListeners.add(fn);
|
|
40
|
+
return () => lostListeners.delete(fn);
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|