@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,624 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Crowd`: local avoidance for many agents on the XZ plane by ORCA (the RVO2 method). Each tick,
|
|
3
|
+
* every agent picks the velocity nearest its preferred one that keeps it clear of its neighbours
|
|
4
|
+
* (and of the obstacles of an `ObstacleSet`, as static lines) for `timeHorizon` seconds, then
|
|
5
|
+
* moves by it. Neighbours come from a hashed uniform grid. Attached to a `NavMesh`, agents walk
|
|
6
|
+
* corridors to targets (`setTarget`, searched through a `PathQueue` or synchronously), their
|
|
7
|
+
* preferred velocity steers along the pulled string, and after each move they are clamped onto
|
|
8
|
+
* the mesh with `y` from its height. Everything is allocated at creation (and at `attach`) for
|
|
9
|
+
* `maxAgents`; `update` allocates nothing.
|
|
10
|
+
*/
|
|
11
|
+
import { createCorridor } from './corridor.js';
|
|
12
|
+
import { createNavPath3, findMeshPath } from './mesh/mesh-path.js';
|
|
13
|
+
import { arrive } from './steer.js';
|
|
14
|
+
const EPS = 0.00001;
|
|
15
|
+
function det(ax, ay, bx, by) {
|
|
16
|
+
return ax * by - ay * bx;
|
|
17
|
+
}
|
|
18
|
+
/** Lines are `dirX, dirY, pointX, pointY`; the result of a solve lands in `resX`, `resY`. */
|
|
19
|
+
let resX = 0;
|
|
20
|
+
let resY = 0;
|
|
21
|
+
function linearProgram1(lines, lineNo, radius, optX, optY, dirOpt) {
|
|
22
|
+
const dx = lines[lineNo * 4];
|
|
23
|
+
const dy = lines[lineNo * 4 + 1];
|
|
24
|
+
const px = lines[lineNo * 4 + 2];
|
|
25
|
+
const py = lines[lineNo * 4 + 3];
|
|
26
|
+
const dot = px * dx + py * dy;
|
|
27
|
+
const disc = dot * dot + radius * radius - (px * px + py * py);
|
|
28
|
+
if (disc < 0)
|
|
29
|
+
return false;
|
|
30
|
+
const sq = Math.sqrt(disc);
|
|
31
|
+
let tLeft = -dot - sq;
|
|
32
|
+
let tRight = -dot + sq;
|
|
33
|
+
for (let i = 0; i < lineNo; i++) {
|
|
34
|
+
const idx = lines[i * 4];
|
|
35
|
+
const idy = lines[i * 4 + 1];
|
|
36
|
+
const denominator = det(dx, dy, idx, idy);
|
|
37
|
+
const numerator = det(idx, idy, px - lines[i * 4 + 2], py - lines[i * 4 + 3]);
|
|
38
|
+
if (Math.abs(denominator) <= EPS) {
|
|
39
|
+
if (numerator < 0)
|
|
40
|
+
return false;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const t = numerator / denominator;
|
|
44
|
+
if (denominator >= 0) {
|
|
45
|
+
if (t < tRight)
|
|
46
|
+
tRight = t;
|
|
47
|
+
}
|
|
48
|
+
else if (t > tLeft)
|
|
49
|
+
tLeft = t;
|
|
50
|
+
if (tLeft > tRight)
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
let t;
|
|
54
|
+
if (dirOpt) {
|
|
55
|
+
t = optX * dx + optY * dy > 0 ? tRight : tLeft;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
t = dx * (optX - px) + dy * (optY - py);
|
|
59
|
+
if (t < tLeft)
|
|
60
|
+
t = tLeft;
|
|
61
|
+
else if (t > tRight)
|
|
62
|
+
t = tRight;
|
|
63
|
+
}
|
|
64
|
+
resX = px + t * dx;
|
|
65
|
+
resY = py + t * dy;
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
function linearProgram2(lines, count, radius, optX, optY, dirOpt) {
|
|
69
|
+
if (dirOpt) {
|
|
70
|
+
resX = optX * radius;
|
|
71
|
+
resY = optY * radius;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const l2 = optX * optX + optY * optY;
|
|
75
|
+
if (l2 > radius * radius) {
|
|
76
|
+
const s = radius / Math.sqrt(l2);
|
|
77
|
+
resX = optX * s;
|
|
78
|
+
resY = optY * s;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
resX = optX;
|
|
82
|
+
resY = optY;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (let i = 0; i < count; i++) {
|
|
86
|
+
const dx = lines[i * 4];
|
|
87
|
+
const dy = lines[i * 4 + 1];
|
|
88
|
+
if (det(dx, dy, lines[i * 4 + 2] - resX, lines[i * 4 + 3] - resY) > 0) {
|
|
89
|
+
const tx = resX;
|
|
90
|
+
const ty = resY;
|
|
91
|
+
if (!linearProgram1(lines, i, radius, optX, optY, dirOpt)) {
|
|
92
|
+
resX = tx;
|
|
93
|
+
resY = ty;
|
|
94
|
+
return i;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return count;
|
|
99
|
+
}
|
|
100
|
+
function linearProgram3(lines, count, beginLine, radius, proj) {
|
|
101
|
+
let distance = 0;
|
|
102
|
+
for (let i = beginLine; i < count; i++) {
|
|
103
|
+
const idx = lines[i * 4];
|
|
104
|
+
const idy = lines[i * 4 + 1];
|
|
105
|
+
const ipx = lines[i * 4 + 2];
|
|
106
|
+
const ipy = lines[i * 4 + 3];
|
|
107
|
+
if (det(idx, idy, ipx - resX, ipy - resY) <= distance)
|
|
108
|
+
continue;
|
|
109
|
+
let np = 0;
|
|
110
|
+
for (let j = 0; j < i; j++) {
|
|
111
|
+
const jdx = lines[j * 4];
|
|
112
|
+
const jdy = lines[j * 4 + 1];
|
|
113
|
+
const jpx = lines[j * 4 + 2];
|
|
114
|
+
const jpy = lines[j * 4 + 3];
|
|
115
|
+
const denominator = det(idx, idy, jdx, jdy);
|
|
116
|
+
let px;
|
|
117
|
+
let py;
|
|
118
|
+
if (Math.abs(denominator) <= EPS) {
|
|
119
|
+
if (idx * jdx + idy * jdy > 0)
|
|
120
|
+
continue;
|
|
121
|
+
px = 0.5 * (ipx + jpx);
|
|
122
|
+
py = 0.5 * (ipy + jpy);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const t = det(jdx, jdy, ipx - jpx, ipy - jpy) / denominator;
|
|
126
|
+
px = ipx + t * idx;
|
|
127
|
+
py = ipy + t * idy;
|
|
128
|
+
}
|
|
129
|
+
let ddx = jdx - idx;
|
|
130
|
+
let ddy = jdy - idy;
|
|
131
|
+
const len = Math.sqrt(ddx * ddx + ddy * ddy);
|
|
132
|
+
if (len > 0) {
|
|
133
|
+
ddx /= len;
|
|
134
|
+
ddy /= len;
|
|
135
|
+
}
|
|
136
|
+
proj[np * 4] = ddx;
|
|
137
|
+
proj[np * 4 + 1] = ddy;
|
|
138
|
+
proj[np * 4 + 2] = px;
|
|
139
|
+
proj[np * 4 + 3] = py;
|
|
140
|
+
np++;
|
|
141
|
+
}
|
|
142
|
+
const tx = resX;
|
|
143
|
+
const ty = resY;
|
|
144
|
+
if (linearProgram2(proj, np, radius, -idy, idx, true) < np) {
|
|
145
|
+
resX = tx;
|
|
146
|
+
resY = ty;
|
|
147
|
+
}
|
|
148
|
+
distance = det(idx, idy, ipx - resX, ipy - resY);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** A crowd with room for `maxAgents`. */
|
|
152
|
+
export function createCrowd(opts) {
|
|
153
|
+
const maxAgents = Math.max(1, opts.maxAgents);
|
|
154
|
+
const maxNeighbors = Math.max(1, opts.maxNeighbors ?? 10);
|
|
155
|
+
const timeHorizon = opts.timeHorizon ?? 2;
|
|
156
|
+
const neighborDist = opts.neighborDist ?? 4;
|
|
157
|
+
const agents = [];
|
|
158
|
+
for (let i = 0; i < maxAgents; i++) {
|
|
159
|
+
agents.push({
|
|
160
|
+
active: false,
|
|
161
|
+
x: 0,
|
|
162
|
+
z: 0,
|
|
163
|
+
vx: 0,
|
|
164
|
+
vz: 0,
|
|
165
|
+
radius: 0.5,
|
|
166
|
+
maxSpeed: 0,
|
|
167
|
+
prefX: 0,
|
|
168
|
+
prefZ: 0,
|
|
169
|
+
y: 0,
|
|
170
|
+
poly: -1,
|
|
171
|
+
corridor: null,
|
|
172
|
+
targetReached: false,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
// Mesh attachment state, per agent.
|
|
176
|
+
let mesh = null;
|
|
177
|
+
let queue = null;
|
|
178
|
+
let arriveRadius = -1;
|
|
179
|
+
let slowRadius = 1;
|
|
180
|
+
let replans = 0;
|
|
181
|
+
const paths = [];
|
|
182
|
+
const tickets = new Int32Array(maxAgents);
|
|
183
|
+
const hasTarget = new Uint8Array(maxAgents);
|
|
184
|
+
const targetX = new Float64Array(maxAgents);
|
|
185
|
+
const targetY = new Float64Array(maxAgents);
|
|
186
|
+
const targetZ = new Float64Array(maxAgents);
|
|
187
|
+
const agentPoint = { x: 0, y: 0, z: 0 };
|
|
188
|
+
const corner = { x: 0, y: 0, z: 0 };
|
|
189
|
+
const self2 = { x: 0, z: 0 };
|
|
190
|
+
const corner2 = { x: 0, z: 0 };
|
|
191
|
+
const pref2 = { x: 0, z: 0 };
|
|
192
|
+
let obstacleSet = null;
|
|
193
|
+
// Hashed uniform grid, rebuilt every update by counting sort.
|
|
194
|
+
let tableSize = 1;
|
|
195
|
+
while (tableSize < maxAgents * 2)
|
|
196
|
+
tableSize *= 2;
|
|
197
|
+
const cellStart = new Int32Array(tableSize + 1);
|
|
198
|
+
const cellFill = new Int32Array(tableSize);
|
|
199
|
+
const cellItems = new Int32Array(maxAgents);
|
|
200
|
+
const cellOf = new Int32Array(maxAgents);
|
|
201
|
+
const neighIdx = new Int32Array(maxNeighbors);
|
|
202
|
+
const neighD2 = new Float64Array(maxNeighbors);
|
|
203
|
+
// Room for the neighbours plus as many obstacle lines (nearest obstacles, up to maxNeighbors).
|
|
204
|
+
const lines = new Float64Array(maxNeighbors * 8);
|
|
205
|
+
const proj = new Float64Array(maxNeighbors * 8);
|
|
206
|
+
const newVx = new Float64Array(maxAgents);
|
|
207
|
+
const newVz = new Float64Array(maxAgents);
|
|
208
|
+
const invCell = 1 / neighborDist;
|
|
209
|
+
const neighborDist2 = neighborDist * neighborDist;
|
|
210
|
+
const hash = (cx, cz) => ((cx * 73856093) ^ (cz * 19349663)) & (tableSize - 1);
|
|
211
|
+
/**
|
|
212
|
+
* Adds the ORCA half-plane for agent `a` against a disc at `(ox, oz)` moving `(ovx, ovz)` of
|
|
213
|
+
* radius `or`, `a` taking `share` of the needed velocity change (0.5 between agents, 1 against
|
|
214
|
+
* something static). Returns the next line slot.
|
|
215
|
+
*/
|
|
216
|
+
const addLine = (a, nl, dt, ox, oz, ovx, ovz, or, share) => {
|
|
217
|
+
const invTimeHorizon = 1 / timeHorizon;
|
|
218
|
+
const rpx = ox - a.x;
|
|
219
|
+
const rpy = oz - a.z;
|
|
220
|
+
const rvx = a.vx - ovx;
|
|
221
|
+
const rvy = a.vz - ovz;
|
|
222
|
+
const distSq = rpx * rpx + rpy * rpy;
|
|
223
|
+
const cr = a.radius + or;
|
|
224
|
+
const crSq = cr * cr;
|
|
225
|
+
let dx;
|
|
226
|
+
let dy;
|
|
227
|
+
let ux;
|
|
228
|
+
let uy;
|
|
229
|
+
if (distSq > crSq) {
|
|
230
|
+
// No collision yet: the velocity obstacle is a truncated cone.
|
|
231
|
+
const wx = rvx - invTimeHorizon * rpx;
|
|
232
|
+
const wy = rvy - invTimeHorizon * rpy;
|
|
233
|
+
const wLenSq = wx * wx + wy * wy;
|
|
234
|
+
const dot1 = wx * rpx + wy * rpy;
|
|
235
|
+
if (dot1 < 0 && dot1 * dot1 > crSq * wLenSq) {
|
|
236
|
+
// Project on the cut-off circle.
|
|
237
|
+
const wLen = Math.sqrt(wLenSq);
|
|
238
|
+
const uwx = wx / wLen;
|
|
239
|
+
const uwy = wy / wLen;
|
|
240
|
+
dx = uwy;
|
|
241
|
+
dy = -uwx;
|
|
242
|
+
const s = cr * invTimeHorizon - wLen;
|
|
243
|
+
ux = s * uwx;
|
|
244
|
+
uy = s * uwy;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
// Project on a leg.
|
|
248
|
+
const leg = Math.sqrt(distSq - crSq);
|
|
249
|
+
if (det(rpx, rpy, wx, wy) > 0) {
|
|
250
|
+
dx = (rpx * leg - rpy * cr) / distSq;
|
|
251
|
+
dy = (rpx * cr + rpy * leg) / distSq;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
dx = -(rpx * leg + rpy * cr) / distSq;
|
|
255
|
+
dy = -(-rpx * cr + rpy * leg) / distSq;
|
|
256
|
+
}
|
|
257
|
+
const dot2 = rvx * dx + rvy * dy;
|
|
258
|
+
ux = dot2 * dx - rvx;
|
|
259
|
+
uy = dot2 * dy - rvy;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
// Already overlapping: separate within this time step.
|
|
264
|
+
const invDt = 1 / dt;
|
|
265
|
+
const wx = rvx - invDt * rpx;
|
|
266
|
+
const wy = rvy - invDt * rpy;
|
|
267
|
+
const wLen = Math.sqrt(wx * wx + wy * wy);
|
|
268
|
+
let uwx;
|
|
269
|
+
let uwy;
|
|
270
|
+
if (wLen > 0) {
|
|
271
|
+
uwx = wx / wLen;
|
|
272
|
+
uwy = wy / wLen;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// Coincident and still: push along a fixed direction.
|
|
276
|
+
uwx = 1;
|
|
277
|
+
uwy = 0;
|
|
278
|
+
}
|
|
279
|
+
dx = uwy;
|
|
280
|
+
dy = -uwx;
|
|
281
|
+
const s = cr * invDt - wLen;
|
|
282
|
+
ux = s * uwx;
|
|
283
|
+
uy = s * uwy;
|
|
284
|
+
}
|
|
285
|
+
lines[nl * 4] = dx;
|
|
286
|
+
lines[nl * 4 + 1] = dy;
|
|
287
|
+
lines[nl * 4 + 2] = a.vx + share * ux;
|
|
288
|
+
lines[nl * 4 + 3] = a.vz + share * uy;
|
|
289
|
+
return nl + 1;
|
|
290
|
+
};
|
|
291
|
+
/** Lines for the obstacles within `neighborDist` of `a` (a box through its nearest point). */
|
|
292
|
+
const addObstacleLines = (a, nl, dt) => {
|
|
293
|
+
if (!obstacleSet)
|
|
294
|
+
return nl;
|
|
295
|
+
const list = obstacleSet.obstacles;
|
|
296
|
+
const limit = nl + maxNeighbors;
|
|
297
|
+
for (let k = 0; k < list.length && nl < limit; k++) {
|
|
298
|
+
const o = list[k];
|
|
299
|
+
if (!o.active)
|
|
300
|
+
continue;
|
|
301
|
+
const ddx = o.x - a.x;
|
|
302
|
+
const ddz = o.z - a.z;
|
|
303
|
+
const reach = neighborDist + o.radius;
|
|
304
|
+
if (ddx * ddx + ddz * ddz > reach * reach)
|
|
305
|
+
continue;
|
|
306
|
+
if (o.kind === 'disc') {
|
|
307
|
+
nl = addLine(a, nl, dt, o.x, o.z, 0, 0, o.radius, 1);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
// The box's nearest point to the agent, as a zero-radius static disc.
|
|
311
|
+
const c = Math.cos(o.yaw);
|
|
312
|
+
const s = Math.sin(o.yaw);
|
|
313
|
+
const lx = ddx * c + ddz * s;
|
|
314
|
+
const lz = -ddx * s + ddz * c;
|
|
315
|
+
const hw = o.w * 0.5;
|
|
316
|
+
const hd = o.d * 0.5;
|
|
317
|
+
const qx = Math.max(-hw, Math.min(hw, lx));
|
|
318
|
+
const qz = Math.max(-hd, Math.min(hd, lz));
|
|
319
|
+
// Inside the box: push out through the nearest face instead.
|
|
320
|
+
let px;
|
|
321
|
+
let pz;
|
|
322
|
+
if (qx === lx && qz === lz) {
|
|
323
|
+
const ex = hw - Math.abs(lx);
|
|
324
|
+
const ez = hd - Math.abs(lz);
|
|
325
|
+
px = ex < ez ? (lx < 0 ? -hw : hw) : lx;
|
|
326
|
+
pz = ex < ez ? lz : lz < 0 ? -hd : hd;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
px = qx;
|
|
330
|
+
pz = qz;
|
|
331
|
+
}
|
|
332
|
+
const wx = o.x + px * c - pz * s;
|
|
333
|
+
const wz = o.z + px * s + pz * c;
|
|
334
|
+
nl = addLine(a, nl, dt, wx, wz, 0, 0, 0, 1);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return nl;
|
|
338
|
+
};
|
|
339
|
+
const computeNewVelocity = (i, dt, nn) => {
|
|
340
|
+
const a = agents[i];
|
|
341
|
+
let nl = 0;
|
|
342
|
+
for (let k = 0; k < nn; k++) {
|
|
343
|
+
const o = agents[neighIdx[k]];
|
|
344
|
+
nl = addLine(a, nl, dt, o.x, o.z, o.vx, o.vz, o.radius, 0.5);
|
|
345
|
+
}
|
|
346
|
+
nl = addObstacleLines(a, nl, dt);
|
|
347
|
+
const fail = linearProgram2(lines, nl, a.maxSpeed, a.prefX, a.prefZ, false);
|
|
348
|
+
if (fail < nl)
|
|
349
|
+
linearProgram3(lines, nl, fail, a.maxSpeed, proj);
|
|
350
|
+
newVx[i] = resX;
|
|
351
|
+
newVz[i] = resY;
|
|
352
|
+
};
|
|
353
|
+
/** Starts (or restarts) the search for agent `i`'s target. */
|
|
354
|
+
const plan = (i) => {
|
|
355
|
+
if (!mesh)
|
|
356
|
+
return;
|
|
357
|
+
const a = agents[i];
|
|
358
|
+
const path = paths[i];
|
|
359
|
+
replans++;
|
|
360
|
+
a.corridor.clear();
|
|
361
|
+
agentPoint.x = a.x;
|
|
362
|
+
agentPoint.y = a.y;
|
|
363
|
+
agentPoint.z = a.z;
|
|
364
|
+
corner.x = targetX[i];
|
|
365
|
+
corner.y = targetY[i];
|
|
366
|
+
corner.z = targetZ[i];
|
|
367
|
+
if (queue) {
|
|
368
|
+
if (tickets[i] > 0)
|
|
369
|
+
queue.cancel(tickets[i]);
|
|
370
|
+
tickets[i] = queue.request(agentPoint, corner, path);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (findMeshPath(mesh, agentPoint, corner, path))
|
|
374
|
+
a.corridor.set(path);
|
|
375
|
+
};
|
|
376
|
+
/** Steers attached agent `i` along its corridor: the preferred velocity for this tick. */
|
|
377
|
+
const steerAgent = (i) => {
|
|
378
|
+
if (!mesh)
|
|
379
|
+
return;
|
|
380
|
+
const a = agents[i];
|
|
381
|
+
if (hasTarget[i] === 0)
|
|
382
|
+
return;
|
|
383
|
+
const cor = a.corridor;
|
|
384
|
+
const reach = arriveRadius >= 0 ? arriveRadius : a.radius;
|
|
385
|
+
const tdx = targetX[i] - a.x;
|
|
386
|
+
const tdz = targetZ[i] - a.z;
|
|
387
|
+
if (tdx * tdx + tdz * tdz <= reach * reach) {
|
|
388
|
+
a.targetReached = true;
|
|
389
|
+
a.prefX = 0;
|
|
390
|
+
a.prefZ = 0;
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if (queue && tickets[i] > 0) {
|
|
394
|
+
const st = queue.status(tickets[i]);
|
|
395
|
+
if (st === 'pending') {
|
|
396
|
+
a.prefX = 0;
|
|
397
|
+
a.prefZ = 0;
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
tickets[i] = 0;
|
|
401
|
+
if (st === 'done')
|
|
402
|
+
cor.set(paths[i]);
|
|
403
|
+
}
|
|
404
|
+
if (cor.count === 0) {
|
|
405
|
+
a.prefX = 0;
|
|
406
|
+
a.prefZ = 0;
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (!cor.valid(mesh)) {
|
|
410
|
+
plan(i);
|
|
411
|
+
a.prefX = 0;
|
|
412
|
+
a.prefZ = 0;
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
cor.advance(a.x, a.z, corner);
|
|
416
|
+
self2.x = a.x;
|
|
417
|
+
self2.z = a.z;
|
|
418
|
+
corner2.x = corner.x;
|
|
419
|
+
corner2.z = corner.z;
|
|
420
|
+
const last = cor.path.length <= 2;
|
|
421
|
+
arrive(self2, corner2, a.maxSpeed, last ? slowRadius : 0, pref2);
|
|
422
|
+
a.prefX = pref2.x;
|
|
423
|
+
a.prefZ = pref2.z;
|
|
424
|
+
};
|
|
425
|
+
/** Keeps attached agent `i` on the mesh after a move and reads its height. */
|
|
426
|
+
const clamp = (i) => {
|
|
427
|
+
if (!mesh)
|
|
428
|
+
return;
|
|
429
|
+
const a = agents[i];
|
|
430
|
+
let p = a.poly;
|
|
431
|
+
if (p < 0 || !mesh.containsXZ(p, a.x, a.z)) {
|
|
432
|
+
// Try the corridor's next polygons first, then the neighbourhood.
|
|
433
|
+
const cor = a.corridor;
|
|
434
|
+
p = -1;
|
|
435
|
+
const look = Math.min(cor.count, 4);
|
|
436
|
+
for (let k = 0; k < look; k++) {
|
|
437
|
+
const q = cor.polys[cor.offset + k];
|
|
438
|
+
if (mesh.containsXZ(q, a.x, a.z)) {
|
|
439
|
+
p = q;
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (p < 0) {
|
|
444
|
+
p = mesh.findNearestPoly(a.x, a.y, a.z, agentPoint, a.radius * 4 + 1);
|
|
445
|
+
if (p >= 0) {
|
|
446
|
+
a.x = agentPoint.x;
|
|
447
|
+
a.z = agentPoint.z;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
a.poly = p;
|
|
452
|
+
if (p >= 0)
|
|
453
|
+
a.y = mesh.polyHeight(p, a.x, a.z);
|
|
454
|
+
};
|
|
455
|
+
const update = (dt) => {
|
|
456
|
+
if (dt <= 0)
|
|
457
|
+
return;
|
|
458
|
+
// Bin the agents.
|
|
459
|
+
cellStart.fill(0);
|
|
460
|
+
for (let i = 0; i < maxAgents; i++) {
|
|
461
|
+
const a = agents[i];
|
|
462
|
+
if (!a.active)
|
|
463
|
+
continue;
|
|
464
|
+
const c = hash(Math.floor(a.x * invCell), Math.floor(a.z * invCell));
|
|
465
|
+
cellOf[i] = c;
|
|
466
|
+
cellStart[c + 1]++;
|
|
467
|
+
}
|
|
468
|
+
for (let c = 0; c < tableSize; c++)
|
|
469
|
+
cellStart[c + 1] += cellStart[c];
|
|
470
|
+
cellFill.fill(0);
|
|
471
|
+
for (let i = 0; i < maxAgents; i++) {
|
|
472
|
+
if (!agents[i].active)
|
|
473
|
+
continue;
|
|
474
|
+
const c = cellOf[i];
|
|
475
|
+
cellItems[cellStart[c] + cellFill[c]++] = i;
|
|
476
|
+
}
|
|
477
|
+
// Choose velocities from the current state, then apply them all at once.
|
|
478
|
+
for (let i = 0; i < maxAgents; i++) {
|
|
479
|
+
const a = agents[i];
|
|
480
|
+
if (!a.active)
|
|
481
|
+
continue;
|
|
482
|
+
if (mesh)
|
|
483
|
+
steerAgent(i);
|
|
484
|
+
let nn = 0;
|
|
485
|
+
const cx = Math.floor(a.x * invCell);
|
|
486
|
+
const cz = Math.floor(a.z * invCell);
|
|
487
|
+
for (let oz = -1; oz <= 1; oz++) {
|
|
488
|
+
for (let ox = -1; ox <= 1; ox++) {
|
|
489
|
+
const c = hash(cx + ox, cz + oz);
|
|
490
|
+
const end = cellStart[c + 1];
|
|
491
|
+
for (let k = cellStart[c]; k < end; k++) {
|
|
492
|
+
const j = cellItems[k];
|
|
493
|
+
if (j === i)
|
|
494
|
+
continue;
|
|
495
|
+
const o = agents[j];
|
|
496
|
+
// A hash bucket may hold far cells too: the distance test sorts it out.
|
|
497
|
+
const ddx = o.x - a.x;
|
|
498
|
+
const ddz = o.z - a.z;
|
|
499
|
+
const d2 = ddx * ddx + ddz * ddz;
|
|
500
|
+
if (d2 > neighborDist2)
|
|
501
|
+
continue;
|
|
502
|
+
if (nn === maxNeighbors && d2 >= neighD2[nn - 1])
|
|
503
|
+
continue;
|
|
504
|
+
// Sorted insertion, nearest first.
|
|
505
|
+
let at = nn < maxNeighbors ? nn : maxNeighbors - 1;
|
|
506
|
+
while (at > 0 && neighD2[at - 1] > d2) {
|
|
507
|
+
neighD2[at] = neighD2[at - 1];
|
|
508
|
+
neighIdx[at] = neighIdx[at - 1];
|
|
509
|
+
at--;
|
|
510
|
+
}
|
|
511
|
+
neighD2[at] = d2;
|
|
512
|
+
neighIdx[at] = j;
|
|
513
|
+
if (nn < maxNeighbors)
|
|
514
|
+
nn++;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
computeNewVelocity(i, dt, nn);
|
|
519
|
+
}
|
|
520
|
+
for (let i = 0; i < maxAgents; i++) {
|
|
521
|
+
const a = agents[i];
|
|
522
|
+
if (!a.active)
|
|
523
|
+
continue;
|
|
524
|
+
a.vx = newVx[i];
|
|
525
|
+
a.vz = newVz[i];
|
|
526
|
+
a.x += a.vx * dt;
|
|
527
|
+
a.z += a.vz * dt;
|
|
528
|
+
if (mesh)
|
|
529
|
+
clamp(i);
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
return {
|
|
533
|
+
agents,
|
|
534
|
+
add(o) {
|
|
535
|
+
for (let i = 0; i < maxAgents; i++) {
|
|
536
|
+
const a = agents[i];
|
|
537
|
+
if (a.active)
|
|
538
|
+
continue;
|
|
539
|
+
a.active = true;
|
|
540
|
+
a.x = o.x;
|
|
541
|
+
a.z = o.z;
|
|
542
|
+
a.vx = 0;
|
|
543
|
+
a.vz = 0;
|
|
544
|
+
a.radius = o.radius;
|
|
545
|
+
a.maxSpeed = o.maxSpeed;
|
|
546
|
+
a.prefX = o.prefVelocity?.x ?? 0;
|
|
547
|
+
a.prefZ = o.prefVelocity?.z ?? 0;
|
|
548
|
+
a.y = 0;
|
|
549
|
+
a.poly = -1;
|
|
550
|
+
a.targetReached = false;
|
|
551
|
+
hasTarget[i] = 0;
|
|
552
|
+
if (tickets[i] > 0 && queue)
|
|
553
|
+
queue.cancel(tickets[i]);
|
|
554
|
+
tickets[i] = 0;
|
|
555
|
+
a.corridor?.clear();
|
|
556
|
+
if (mesh)
|
|
557
|
+
clamp(i);
|
|
558
|
+
return i;
|
|
559
|
+
}
|
|
560
|
+
return -1;
|
|
561
|
+
},
|
|
562
|
+
remove(index) {
|
|
563
|
+
const a = agents[index];
|
|
564
|
+
if (!a)
|
|
565
|
+
return;
|
|
566
|
+
a.active = false;
|
|
567
|
+
if (tickets[index] > 0 && queue)
|
|
568
|
+
queue.cancel(tickets[index]);
|
|
569
|
+
tickets[index] = 0;
|
|
570
|
+
},
|
|
571
|
+
setPrefVelocity(index, x, z) {
|
|
572
|
+
const a = agents[index];
|
|
573
|
+
if (!a)
|
|
574
|
+
return;
|
|
575
|
+
a.prefX = x;
|
|
576
|
+
a.prefZ = z;
|
|
577
|
+
},
|
|
578
|
+
setPosition(index, x, z) {
|
|
579
|
+
const a = agents[index];
|
|
580
|
+
if (!a)
|
|
581
|
+
return;
|
|
582
|
+
a.x = x;
|
|
583
|
+
a.z = z;
|
|
584
|
+
a.poly = -1;
|
|
585
|
+
if (mesh && a.active)
|
|
586
|
+
clamp(index);
|
|
587
|
+
},
|
|
588
|
+
update,
|
|
589
|
+
attach(m, o) {
|
|
590
|
+
mesh = m;
|
|
591
|
+
queue = o?.queue ?? null;
|
|
592
|
+
arriveRadius = o?.arriveRadius ?? -1;
|
|
593
|
+
slowRadius = o?.slowRadius ?? 1;
|
|
594
|
+
const maxWaypoints = o?.maxWaypoints ?? 64;
|
|
595
|
+
for (let i = 0; i < maxAgents; i++) {
|
|
596
|
+
const a = agents[i];
|
|
597
|
+
a.corridor = createCorridor(m, maxWaypoints);
|
|
598
|
+
paths[i] = createNavPath3(maxWaypoints);
|
|
599
|
+
tickets[i] = 0;
|
|
600
|
+
hasTarget[i] = 0;
|
|
601
|
+
a.poly = -1;
|
|
602
|
+
if (a.active)
|
|
603
|
+
clamp(i);
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
setTarget(index, x, y, z) {
|
|
607
|
+
const a = agents[index];
|
|
608
|
+
if (!a || !mesh || !a.active)
|
|
609
|
+
return;
|
|
610
|
+
hasTarget[index] = 1;
|
|
611
|
+
targetX[index] = x;
|
|
612
|
+
targetY[index] = y;
|
|
613
|
+
targetZ[index] = z;
|
|
614
|
+
a.targetReached = false;
|
|
615
|
+
plan(index);
|
|
616
|
+
},
|
|
617
|
+
obstacles(set) {
|
|
618
|
+
obstacleSet = set;
|
|
619
|
+
},
|
|
620
|
+
get replans() {
|
|
621
|
+
return replans;
|
|
622
|
+
},
|
|
623
|
+
};
|
|
624
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A flow field: one Dijkstra from a set of goal cells gives every cell its distance and the
|
|
3
|
+
* direction to step, so any number of agents share one build. Arrays are sized to the grid once;
|
|
4
|
+
* the goals are kept, so `update()` recomputes in place after the grid or the goals move.
|
|
5
|
+
*/
|
|
6
|
+
import type { NavCell, NavGrid, NavPoint } from './grid.js';
|
|
7
|
+
/**
|
|
8
|
+
* A flow direction with the cost of the step it points along: what `findPath` charges for the
|
|
9
|
+
* same move (`(1 | √2) × cost(dest)` plus the edge cost). 0 at a goal, `Infinity` off the field
|
|
10
|
+
* (an unwalkable, unreachable or out-of-grid cell).
|
|
11
|
+
*/
|
|
12
|
+
export interface FlowDirection extends NavPoint {
|
|
13
|
+
cost: number;
|
|
14
|
+
}
|
|
15
|
+
export interface FlowFieldOptions {
|
|
16
|
+
/** Goal cells (row-major indices) to build from at once; the field is built immediately. */
|
|
17
|
+
goals?: ArrayLike<number>;
|
|
18
|
+
}
|
|
19
|
+
export interface FlowField {
|
|
20
|
+
readonly grid: NavGrid;
|
|
21
|
+
/** `grid.version` at the last build, or -1 before the first; stale when the grid moved on. */
|
|
22
|
+
readonly version: number;
|
|
23
|
+
/** True when the grid was edited (or touched) since the last build; `update()` clears it. */
|
|
24
|
+
readonly stale: boolean;
|
|
25
|
+
/** The goal indices of the last build (`goalCount` of them; sized to the grid). */
|
|
26
|
+
readonly goals: Int32Array;
|
|
27
|
+
readonly goalCount: number;
|
|
28
|
+
/** Cost-weighted distance to the nearest goal per cell (row-major); `Infinity` unreachable. */
|
|
29
|
+
readonly distances: Float32Array;
|
|
30
|
+
/**
|
|
31
|
+
* Unit direction per cell (`x, z` pairs, row-major) towards the cheapest neighbour; zero at
|
|
32
|
+
* a goal, an unwalkable cell or an unreachable one. Only the grid's neighbourhood is used, so
|
|
33
|
+
* a 4-neighbour grid never gives a diagonal.
|
|
34
|
+
*/
|
|
35
|
+
readonly directions: Float32Array;
|
|
36
|
+
/**
|
|
37
|
+
* Per cell, the cost of the step `directions` points along (`findPath`'s charge for it): 0 at
|
|
38
|
+
* a goal, `Infinity` where the direction is zero. Summed along a walk it equals `distances`.
|
|
39
|
+
*/
|
|
40
|
+
readonly stepCosts: Float32Array;
|
|
41
|
+
/** Dijkstra from `goals` (cells; unwalkable or out-of-grid ones are skipped). */
|
|
42
|
+
build(goals: ArrayLike<Readonly<NavCell>>): void;
|
|
43
|
+
/** Dijkstra from `goals` given as row-major indices (unwalkable or out-of-grid are skipped). */
|
|
44
|
+
setGoals(goals: ArrayLike<number>): void;
|
|
45
|
+
/** Recomputes from the kept goals, in place: after a grid edit, or to clear `stale`. */
|
|
46
|
+
update(): void;
|
|
47
|
+
/**
|
|
48
|
+
* The step direction at a cell into `out` (zero outside the grid). An `out` with a `cost`
|
|
49
|
+
* field (`FlowDirection`) also receives the step's cost (`Infinity` off the field).
|
|
50
|
+
*/
|
|
51
|
+
direction<T extends NavPoint>(cx: number, cy: number, out: T): T;
|
|
52
|
+
/** The step direction under a world point into `out`; a `FlowDirection` gets the step cost too. */
|
|
53
|
+
directionAt<T extends NavPoint>(worldX: number, worldZ: number, out: T): T;
|
|
54
|
+
/** Cost-weighted distance from a cell to the nearest goal (`Infinity` when unreachable). */
|
|
55
|
+
distance(cx: number, cy: number): number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A flow field over `grid`: unbuilt (every distance `Infinity`, `version` -1) until
|
|
59
|
+
* `build(goals)` or `setGoals(goals)`, or built at once from `opts.goals`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function createFlowField(grid: NavGrid, opts?: FlowFieldOptions): FlowField;
|