@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,647 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `NavMesh`: convex walkable polygons with shared edges, baked from triangle soup by
|
|
3
|
+
* `bakeNavMesh`. Queries (nearest polygon, random point, raycast, height) allocate nothing after
|
|
4
|
+
* construction and write into an `out`. Polygons are wound counter-clockwise seen from above
|
|
5
|
+
* (`area2 > 0`), so for edge `e` the right portal vertex is `v[e]` and the left is `v[e + 1]`.
|
|
6
|
+
*/
|
|
7
|
+
import { markArea } from './areas.js';
|
|
8
|
+
import { resolveNavBakeOptions } from './bake-options.js';
|
|
9
|
+
import { buildContours } from './contour.js';
|
|
10
|
+
import { buildPolyMesh } from './polymesh.js';
|
|
11
|
+
import { buildRegions } from './regions.js';
|
|
12
|
+
import { buildCompactHeightfield, computeBounds, createHeightfield, erodeWalkableArea, filterLedgeSpans, filterLowHangingWalkableObstacles, filterWalkableLowHeightSpans, rasterizeSources, } from './voxelize.js';
|
|
13
|
+
/** Twice the signed XZ area of `a, b, c`; positive is counter-clockwise seen from above. */
|
|
14
|
+
export function area2(ax, az, bx, bz, cx, cz) {
|
|
15
|
+
return (bx - ax) * (cz - az) - (cx - ax) * (bz - az);
|
|
16
|
+
}
|
|
17
|
+
const GRID_MAX_DIM = 256;
|
|
18
|
+
export class NavMesh {
|
|
19
|
+
/** World `x, y, z` per vertex. */
|
|
20
|
+
verts;
|
|
21
|
+
vertCount;
|
|
22
|
+
/** `maxVertsPerPoly` vertex indices per polygon, -1 padded. */
|
|
23
|
+
polys;
|
|
24
|
+
/** Per polygon edge `e` (from vertex `e` to `e + 1`): the polygon across it, or -1. */
|
|
25
|
+
adjacency;
|
|
26
|
+
polyCount;
|
|
27
|
+
maxVertsPerPoly;
|
|
28
|
+
bounds;
|
|
29
|
+
/** The bake's cell size and height, kept for serialisation and for defaults in queries. */
|
|
30
|
+
cellSize;
|
|
31
|
+
cellHeight;
|
|
32
|
+
/** The area byte per polygon (0 default; `markArea` stamps, 255 is reserved for obstacles). */
|
|
33
|
+
area;
|
|
34
|
+
/** Bumps whenever the mesh changes (links added or removed, areas stamped, obstacles applied). */
|
|
35
|
+
version = 0;
|
|
36
|
+
/** The polygons the last `polysInBox` found (its return value says how many). */
|
|
37
|
+
polysFound;
|
|
38
|
+
foundStamp;
|
|
39
|
+
findStamp = 0;
|
|
40
|
+
/** Off-mesh links by index (holes stay `null` after removal); edit with `addOffMeshLink`. */
|
|
41
|
+
links = [];
|
|
42
|
+
/** CSR of link ends per polygon: `linkItems[linkStart[p] .. linkStart[p + 1])` are `link * 2 + end`. */
|
|
43
|
+
linkStart;
|
|
44
|
+
linkItems;
|
|
45
|
+
nextLinkId = 1;
|
|
46
|
+
/** Vertices per polygon (3..`maxVertsPerPoly`). */
|
|
47
|
+
nverts;
|
|
48
|
+
/** Per polygon XZ AABB, `minX, minZ, maxX, maxZ`. */
|
|
49
|
+
polyBox;
|
|
50
|
+
/** Cumulative polygon areas for `findRandomPoint`. */
|
|
51
|
+
cumArea;
|
|
52
|
+
gridW;
|
|
53
|
+
gridH;
|
|
54
|
+
gridCell;
|
|
55
|
+
gridStart;
|
|
56
|
+
gridItems;
|
|
57
|
+
triArea;
|
|
58
|
+
constructor(verts, vertCount, polys, polyCount, maxVertsPerPoly, cellSize, cellHeight, adjacency, area) {
|
|
59
|
+
this.verts = verts;
|
|
60
|
+
this.vertCount = vertCount;
|
|
61
|
+
this.polys = polys;
|
|
62
|
+
this.polyCount = polyCount;
|
|
63
|
+
this.maxVertsPerPoly = maxVertsPerPoly;
|
|
64
|
+
this.cellSize = cellSize;
|
|
65
|
+
this.cellHeight = cellHeight;
|
|
66
|
+
const nvp = maxVertsPerPoly;
|
|
67
|
+
this.nverts = new Uint8Array(Math.max(1, polyCount));
|
|
68
|
+
for (let p = 0; p < polyCount; p++) {
|
|
69
|
+
let n = 0;
|
|
70
|
+
while (n < nvp && polys[p * nvp + n] !== -1)
|
|
71
|
+
n++;
|
|
72
|
+
this.nverts[p] = n;
|
|
73
|
+
}
|
|
74
|
+
this.normaliseWinding();
|
|
75
|
+
this.adjacency = adjacency ?? buildAdjacency(polys, polyCount, nvp, this.nverts, vertCount);
|
|
76
|
+
this.triArea = new Float64Array(Math.max(1, nvp));
|
|
77
|
+
this.area = area ?? new Uint8Array(Math.max(1, polyCount));
|
|
78
|
+
this.polysFound = new Int32Array(Math.max(1, polyCount));
|
|
79
|
+
this.foundStamp = new Uint32Array(Math.max(1, polyCount));
|
|
80
|
+
const min = {
|
|
81
|
+
x: Number.POSITIVE_INFINITY,
|
|
82
|
+
y: Number.POSITIVE_INFINITY,
|
|
83
|
+
z: Number.POSITIVE_INFINITY,
|
|
84
|
+
};
|
|
85
|
+
const max = {
|
|
86
|
+
x: Number.NEGATIVE_INFINITY,
|
|
87
|
+
y: Number.NEGATIVE_INFINITY,
|
|
88
|
+
z: Number.NEGATIVE_INFINITY,
|
|
89
|
+
};
|
|
90
|
+
for (let i = 0; i < vertCount; i++) {
|
|
91
|
+
const x = verts[i * 3];
|
|
92
|
+
const y = verts[i * 3 + 1];
|
|
93
|
+
const z = verts[i * 3 + 2];
|
|
94
|
+
if (x < min.x)
|
|
95
|
+
min.x = x;
|
|
96
|
+
if (y < min.y)
|
|
97
|
+
min.y = y;
|
|
98
|
+
if (z < min.z)
|
|
99
|
+
min.z = z;
|
|
100
|
+
if (x > max.x)
|
|
101
|
+
max.x = x;
|
|
102
|
+
if (y > max.y)
|
|
103
|
+
max.y = y;
|
|
104
|
+
if (z > max.z)
|
|
105
|
+
max.z = z;
|
|
106
|
+
}
|
|
107
|
+
if (vertCount === 0) {
|
|
108
|
+
min.x = min.y = min.z = 0;
|
|
109
|
+
max.x = max.y = max.z = 0;
|
|
110
|
+
}
|
|
111
|
+
this.bounds = { min, max };
|
|
112
|
+
this.polyBox = new Float32Array(Math.max(1, polyCount) * 4);
|
|
113
|
+
this.cumArea = new Float64Array(Math.max(1, polyCount));
|
|
114
|
+
let acc = 0;
|
|
115
|
+
for (let p = 0; p < polyCount; p++) {
|
|
116
|
+
let bx0 = Number.POSITIVE_INFINITY;
|
|
117
|
+
let bz0 = Number.POSITIVE_INFINITY;
|
|
118
|
+
let bx1 = Number.NEGATIVE_INFINITY;
|
|
119
|
+
let bz1 = Number.NEGATIVE_INFINITY;
|
|
120
|
+
const n = this.nverts[p];
|
|
121
|
+
for (let k = 0; k < n; k++) {
|
|
122
|
+
const v = polys[p * nvp + k];
|
|
123
|
+
const x = verts[v * 3];
|
|
124
|
+
const z = verts[v * 3 + 2];
|
|
125
|
+
if (x < bx0)
|
|
126
|
+
bx0 = x;
|
|
127
|
+
if (z < bz0)
|
|
128
|
+
bz0 = z;
|
|
129
|
+
if (x > bx1)
|
|
130
|
+
bx1 = x;
|
|
131
|
+
if (z > bz1)
|
|
132
|
+
bz1 = z;
|
|
133
|
+
}
|
|
134
|
+
this.polyBox[p * 4] = bx0;
|
|
135
|
+
this.polyBox[p * 4 + 1] = bz0;
|
|
136
|
+
this.polyBox[p * 4 + 2] = bx1;
|
|
137
|
+
this.polyBox[p * 4 + 3] = bz1;
|
|
138
|
+
acc += this.polyArea(p);
|
|
139
|
+
this.cumArea[p] = acc;
|
|
140
|
+
}
|
|
141
|
+
// Uniform grid over the XZ bounds, about one polygon per cell.
|
|
142
|
+
const dim = Math.min(GRID_MAX_DIM, Math.max(1, Math.ceil(Math.sqrt(polyCount))));
|
|
143
|
+
const ex = Math.max(max.x - min.x, 1e-6);
|
|
144
|
+
const ez = Math.max(max.z - min.z, 1e-6);
|
|
145
|
+
this.gridCell = Math.max(ex, ez) / dim;
|
|
146
|
+
this.gridW = Math.max(1, Math.ceil(ex / this.gridCell));
|
|
147
|
+
this.gridH = Math.max(1, Math.ceil(ez / this.gridCell));
|
|
148
|
+
const cells = this.gridW * this.gridH;
|
|
149
|
+
this.gridStart = new Int32Array(cells + 1);
|
|
150
|
+
for (let p = 0; p < polyCount; p++) {
|
|
151
|
+
const x0 = this.gx(this.polyBox[p * 4]);
|
|
152
|
+
const z0 = this.gz(this.polyBox[p * 4 + 1]);
|
|
153
|
+
const x1 = this.gx(this.polyBox[p * 4 + 2]);
|
|
154
|
+
const z1 = this.gz(this.polyBox[p * 4 + 3]);
|
|
155
|
+
for (let z = z0; z <= z1; z++)
|
|
156
|
+
for (let x = x0; x <= x1; x++)
|
|
157
|
+
this.gridStart[x + z * this.gridW + 1]++;
|
|
158
|
+
}
|
|
159
|
+
for (let c = 0; c < cells; c++)
|
|
160
|
+
this.gridStart[c + 1] += this.gridStart[c];
|
|
161
|
+
this.gridItems = new Int32Array(Math.max(1, this.gridStart[cells]));
|
|
162
|
+
const fill = new Int32Array(cells);
|
|
163
|
+
for (let p = 0; p < polyCount; p++) {
|
|
164
|
+
const x0 = this.gx(this.polyBox[p * 4]);
|
|
165
|
+
const z0 = this.gz(this.polyBox[p * 4 + 1]);
|
|
166
|
+
const x1 = this.gx(this.polyBox[p * 4 + 2]);
|
|
167
|
+
const z1 = this.gz(this.polyBox[p * 4 + 3]);
|
|
168
|
+
for (let z = z0; z <= z1; z++) {
|
|
169
|
+
for (let x = x0; x <= x1; x++) {
|
|
170
|
+
const c = x + z * this.gridW;
|
|
171
|
+
this.gridItems[this.gridStart[c] + fill[c]++] = p;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
this.linkStart = new Int32Array(polyCount + 1);
|
|
176
|
+
this.linkItems = new Int32Array(0);
|
|
177
|
+
}
|
|
178
|
+
gx(x) {
|
|
179
|
+
const i = Math.floor((x - this.bounds.min.x) / this.gridCell);
|
|
180
|
+
return i < 0 ? 0 : i >= this.gridW ? this.gridW - 1 : i;
|
|
181
|
+
}
|
|
182
|
+
gz(z) {
|
|
183
|
+
const i = Math.floor((z - this.bounds.min.z) / this.gridCell);
|
|
184
|
+
return i < 0 ? 0 : i >= this.gridH ? this.gridH - 1 : i;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Collects every polygon whose XZ bounding box overlaps the box into `polysFound` (each
|
|
188
|
+
* once) and returns how many. Allocation-free; the next call overwrites the list.
|
|
189
|
+
*/
|
|
190
|
+
polysInBox(minX, minZ, maxX, maxZ) {
|
|
191
|
+
if (this.polyCount === 0)
|
|
192
|
+
return 0;
|
|
193
|
+
this.findStamp = (this.findStamp + 1) >>> 0;
|
|
194
|
+
if (this.findStamp === 0) {
|
|
195
|
+
this.foundStamp.fill(0);
|
|
196
|
+
this.findStamp = 1;
|
|
197
|
+
}
|
|
198
|
+
const stamp = this.findStamp;
|
|
199
|
+
const cx0 = this.gx(minX);
|
|
200
|
+
const cz0 = this.gz(minZ);
|
|
201
|
+
const cx1 = this.gx(maxX);
|
|
202
|
+
const cz1 = this.gz(maxZ);
|
|
203
|
+
let count = 0;
|
|
204
|
+
for (let cz = cz0; cz <= cz1; cz++) {
|
|
205
|
+
for (let cx = cx0; cx <= cx1; cx++) {
|
|
206
|
+
const c = cx + cz * this.gridW;
|
|
207
|
+
const end = this.gridStart[c + 1];
|
|
208
|
+
for (let i = this.gridStart[c]; i < end; i++) {
|
|
209
|
+
const p = this.gridItems[i];
|
|
210
|
+
if (this.foundStamp[p] === stamp)
|
|
211
|
+
continue;
|
|
212
|
+
this.foundStamp[p] = stamp;
|
|
213
|
+
const bx0 = this.polyBox[p * 4];
|
|
214
|
+
const bz0 = this.polyBox[p * 4 + 1];
|
|
215
|
+
const bx1 = this.polyBox[p * 4 + 2];
|
|
216
|
+
const bz1 = this.polyBox[p * 4 + 3];
|
|
217
|
+
if (bx0 > maxX || bx1 < minX || bz0 > maxZ || bz1 < minZ)
|
|
218
|
+
continue;
|
|
219
|
+
this.polysFound[count++] = p;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return count;
|
|
224
|
+
}
|
|
225
|
+
/** Reverses any clockwise polygon so every polygon is counter-clockwise seen from above. */
|
|
226
|
+
normaliseWinding() {
|
|
227
|
+
const nvp = this.maxVertsPerPoly;
|
|
228
|
+
for (let p = 0; p < this.polyCount; p++) {
|
|
229
|
+
const n = this.nverts[p];
|
|
230
|
+
let a = 0;
|
|
231
|
+
const v0 = this.polys[p * nvp];
|
|
232
|
+
for (let k = 1; k + 1 < n; k++) {
|
|
233
|
+
const v1 = this.polys[p * nvp + k];
|
|
234
|
+
const v2 = this.polys[p * nvp + k + 1];
|
|
235
|
+
a += area2(this.verts[v0 * 3], this.verts[v0 * 3 + 2], this.verts[v1 * 3], this.verts[v1 * 3 + 2], this.verts[v2 * 3], this.verts[v2 * 3 + 2]);
|
|
236
|
+
}
|
|
237
|
+
if (a < 0) {
|
|
238
|
+
for (let i = 0, j = n - 1; i < j; i++, j--) {
|
|
239
|
+
const t = this.polys[p * nvp + i];
|
|
240
|
+
this.polys[p * nvp + i] = this.polys[p * nvp + j];
|
|
241
|
+
this.polys[p * nvp + j] = t;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/** Vertices in polygon `p`. */
|
|
247
|
+
polyVertexCount(p) {
|
|
248
|
+
return this.nverts[p];
|
|
249
|
+
}
|
|
250
|
+
/** World position of vertex `k` of polygon `p`, into `out`. */
|
|
251
|
+
polyVertex(p, k, out) {
|
|
252
|
+
const v = this.polys[p * this.maxVertsPerPoly + k] * 3;
|
|
253
|
+
out.x = this.verts[v];
|
|
254
|
+
out.y = this.verts[v + 1];
|
|
255
|
+
out.z = this.verts[v + 2];
|
|
256
|
+
return out;
|
|
257
|
+
}
|
|
258
|
+
/** The polygon's vertex centroid, into `out`. */
|
|
259
|
+
polyCenter(p, out) {
|
|
260
|
+
const n = this.nverts[p];
|
|
261
|
+
const nvp = this.maxVertsPerPoly;
|
|
262
|
+
let x = 0;
|
|
263
|
+
let y = 0;
|
|
264
|
+
let z = 0;
|
|
265
|
+
for (let k = 0; k < n; k++) {
|
|
266
|
+
const v = this.polys[p * nvp + k] * 3;
|
|
267
|
+
x += this.verts[v];
|
|
268
|
+
y += this.verts[v + 1];
|
|
269
|
+
z += this.verts[v + 2];
|
|
270
|
+
}
|
|
271
|
+
out.x = x / n;
|
|
272
|
+
out.y = y / n;
|
|
273
|
+
out.z = z / n;
|
|
274
|
+
return out;
|
|
275
|
+
}
|
|
276
|
+
/** The polygon's XZ area. */
|
|
277
|
+
polyArea(p) {
|
|
278
|
+
const n = this.nverts[p];
|
|
279
|
+
const nvp = this.maxVertsPerPoly;
|
|
280
|
+
const v0 = this.polys[p * nvp] * 3;
|
|
281
|
+
let a = 0;
|
|
282
|
+
for (let k = 1; k + 1 < n; k++) {
|
|
283
|
+
const v1 = this.polys[p * nvp + k] * 3;
|
|
284
|
+
const v2 = this.polys[p * nvp + k + 1] * 3;
|
|
285
|
+
a += area2(this.verts[v0], this.verts[v0 + 2], this.verts[v1], this.verts[v1 + 2], this.verts[v2], this.verts[v2 + 2]);
|
|
286
|
+
}
|
|
287
|
+
return a * 0.5;
|
|
288
|
+
}
|
|
289
|
+
/** Whether `(x, z)` projects inside polygon `p` (edges included). */
|
|
290
|
+
containsXZ(p, x, z) {
|
|
291
|
+
const n = this.nverts[p];
|
|
292
|
+
const nvp = this.maxVertsPerPoly;
|
|
293
|
+
for (let k = 0; k < n; k++) {
|
|
294
|
+
const a = this.polys[p * nvp + k] * 3;
|
|
295
|
+
const b = this.polys[p * nvp + (k + 1 === n ? 0 : k + 1)] * 3;
|
|
296
|
+
if (area2(this.verts[a], this.verts[a + 2], this.verts[b], this.verts[b + 2], x, z) < -1e-6) {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
/** The surface height of polygon `p` at `(x, z)`, by its triangle fan (extrapolated outside). */
|
|
303
|
+
polyHeight(p, x, z) {
|
|
304
|
+
const n = this.nverts[p];
|
|
305
|
+
const nvp = this.maxVertsPerPoly;
|
|
306
|
+
const v0 = this.polys[p * nvp] * 3;
|
|
307
|
+
const ax = this.verts[v0];
|
|
308
|
+
const ay = this.verts[v0 + 1];
|
|
309
|
+
const az = this.verts[v0 + 2];
|
|
310
|
+
let best = ay;
|
|
311
|
+
const bestInside = false;
|
|
312
|
+
let bestOut = Number.POSITIVE_INFINITY;
|
|
313
|
+
for (let k = 1; k + 1 < n; k++) {
|
|
314
|
+
const v1 = this.polys[p * nvp + k] * 3;
|
|
315
|
+
const v2 = this.polys[p * nvp + k + 1] * 3;
|
|
316
|
+
const bx = this.verts[v1];
|
|
317
|
+
const by = this.verts[v1 + 1];
|
|
318
|
+
const bz = this.verts[v1 + 2];
|
|
319
|
+
const cx = this.verts[v2];
|
|
320
|
+
const cy = this.verts[v2 + 1];
|
|
321
|
+
const cz = this.verts[v2 + 2];
|
|
322
|
+
const d = area2(ax, az, bx, bz, cx, cz);
|
|
323
|
+
if (Math.abs(d) < 1e-12)
|
|
324
|
+
continue;
|
|
325
|
+
const u = area2(x, z, bx, bz, cx, cz) / d;
|
|
326
|
+
const v = area2(ax, az, x, z, cx, cz) / d;
|
|
327
|
+
const w = 1 - u - v;
|
|
328
|
+
const h = u * ay + v * by + w * cy;
|
|
329
|
+
const outside = Math.max(0, -u, -v, -w);
|
|
330
|
+
if (outside === 0)
|
|
331
|
+
return h;
|
|
332
|
+
if (!bestInside && outside < bestOut) {
|
|
333
|
+
bestOut = outside;
|
|
334
|
+
best = h;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return best;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* The polygon under or nearest to `(x, y, z)` within `radius`, or -1; the nearest point on it is
|
|
341
|
+
* written to `out` (left untouched when none).
|
|
342
|
+
*/
|
|
343
|
+
findNearestPoly(x, y, z, out, radius = Number.POSITIVE_INFINITY) {
|
|
344
|
+
let best = -1;
|
|
345
|
+
let bestD = radius * radius;
|
|
346
|
+
const whole = !Number.isFinite(radius);
|
|
347
|
+
const cx0 = whole ? 0 : this.gx(x - radius);
|
|
348
|
+
const cz0 = whole ? 0 : this.gz(z - radius);
|
|
349
|
+
const cx1 = whole ? this.gridW - 1 : this.gx(x + radius);
|
|
350
|
+
const cz1 = whole ? this.gridH - 1 : this.gz(z + radius);
|
|
351
|
+
for (let cz = cz0; cz <= cz1; cz++) {
|
|
352
|
+
for (let cx = cx0; cx <= cx1; cx++) {
|
|
353
|
+
const c = cx + cz * this.gridW;
|
|
354
|
+
const end = this.gridStart[c + 1];
|
|
355
|
+
for (let i = this.gridStart[c]; i < end; i++) {
|
|
356
|
+
const p = this.gridItems[i];
|
|
357
|
+
// Skip a polygon seen through an earlier cell: it is nearest only once anyway.
|
|
358
|
+
if (!whole) {
|
|
359
|
+
const bx0 = this.polyBox[p * 4];
|
|
360
|
+
const bz0 = this.polyBox[p * 4 + 1];
|
|
361
|
+
const bx1 = this.polyBox[p * 4 + 2];
|
|
362
|
+
const bz1 = this.polyBox[p * 4 + 3];
|
|
363
|
+
if (bx0 > x + radius || bx1 < x - radius || bz0 > z + radius || bz1 < z - radius)
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const d = this.closestPointOnPoly(p, x, y, z, scratch);
|
|
367
|
+
if (d < bestD) {
|
|
368
|
+
bestD = d;
|
|
369
|
+
best = p;
|
|
370
|
+
out.x = scratch.x;
|
|
371
|
+
out.y = scratch.y;
|
|
372
|
+
out.z = scratch.z;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return best;
|
|
378
|
+
}
|
|
379
|
+
/** The point of polygon `p` nearest `(x, y, z)` into `out`; returns the squared distance. */
|
|
380
|
+
closestPointOnPoly(p, x, y, z, out) {
|
|
381
|
+
if (this.containsXZ(p, x, z)) {
|
|
382
|
+
out.x = x;
|
|
383
|
+
out.z = z;
|
|
384
|
+
out.y = this.polyHeight(p, x, z);
|
|
385
|
+
const dy = out.y - y;
|
|
386
|
+
return dy * dy;
|
|
387
|
+
}
|
|
388
|
+
const n = this.nverts[p];
|
|
389
|
+
const nvp = this.maxVertsPerPoly;
|
|
390
|
+
let bestD = Number.POSITIVE_INFINITY;
|
|
391
|
+
for (let k = 0; k < n; k++) {
|
|
392
|
+
const a = this.polys[p * nvp + k] * 3;
|
|
393
|
+
const b = this.polys[p * nvp + (k + 1 === n ? 0 : k + 1)] * 3;
|
|
394
|
+
const ax = this.verts[a];
|
|
395
|
+
const ay = this.verts[a + 1];
|
|
396
|
+
const az = this.verts[a + 2];
|
|
397
|
+
const ex = this.verts[b] - ax;
|
|
398
|
+
const ey = this.verts[b + 1] - ay;
|
|
399
|
+
const ez = this.verts[b + 2] - az;
|
|
400
|
+
const len = ex * ex + ez * ez;
|
|
401
|
+
let t = len > 0 ? ((x - ax) * ex + (z - az) * ez) / len : 0;
|
|
402
|
+
if (t < 0)
|
|
403
|
+
t = 0;
|
|
404
|
+
else if (t > 1)
|
|
405
|
+
t = 1;
|
|
406
|
+
const px = ax + ex * t;
|
|
407
|
+
const py = ay + ey * t;
|
|
408
|
+
const pz = az + ez * t;
|
|
409
|
+
const dx = px - x;
|
|
410
|
+
const dy = py - y;
|
|
411
|
+
const dz = pz - z;
|
|
412
|
+
const d = dx * dx + dy * dy + dz * dz;
|
|
413
|
+
if (d < bestD) {
|
|
414
|
+
bestD = d;
|
|
415
|
+
out.x = px;
|
|
416
|
+
out.y = py;
|
|
417
|
+
out.z = pz;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return bestD;
|
|
421
|
+
}
|
|
422
|
+
/** The polygon whose XZ footprint holds `(x, z)`, nearest in height to `y`; -1 when none. */
|
|
423
|
+
findPolyAt(x, y, z) {
|
|
424
|
+
const c = this.gx(x) + this.gz(z) * this.gridW;
|
|
425
|
+
const end = this.gridStart[c + 1];
|
|
426
|
+
let best = -1;
|
|
427
|
+
let bestDy = Number.POSITIVE_INFINITY;
|
|
428
|
+
for (let i = this.gridStart[c]; i < end; i++) {
|
|
429
|
+
const p = this.gridItems[i];
|
|
430
|
+
if (!this.containsXZ(p, x, z))
|
|
431
|
+
continue;
|
|
432
|
+
const dy = Math.abs(this.polyHeight(p, x, z) - y);
|
|
433
|
+
if (dy < bestDy) {
|
|
434
|
+
bestDy = dy;
|
|
435
|
+
best = p;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return best;
|
|
439
|
+
}
|
|
440
|
+
/** The surface height at `(x, z)`: of `poly` when given, else of the polygon under it; NaN off the mesh. */
|
|
441
|
+
height(x, z, poly = -1) {
|
|
442
|
+
const p = poly >= 0 ? poly : this.findPolyAt(x, 0, z);
|
|
443
|
+
if (p < 0)
|
|
444
|
+
return Number.NaN;
|
|
445
|
+
return this.polyHeight(p, x, z);
|
|
446
|
+
}
|
|
447
|
+
/** A uniformly random point on the mesh into `out`; returns its polygon (-1 on an empty mesh). */
|
|
448
|
+
findRandomPoint(out, rng = Math.random) {
|
|
449
|
+
if (this.polyCount === 0)
|
|
450
|
+
return -1;
|
|
451
|
+
const total = this.cumArea[this.polyCount - 1];
|
|
452
|
+
const target = rng() * total;
|
|
453
|
+
let lo = 0;
|
|
454
|
+
let hi = this.polyCount - 1;
|
|
455
|
+
while (lo < hi) {
|
|
456
|
+
const mid = (lo + hi) >> 1;
|
|
457
|
+
if (this.cumArea[mid] < target)
|
|
458
|
+
lo = mid + 1;
|
|
459
|
+
else
|
|
460
|
+
hi = mid;
|
|
461
|
+
}
|
|
462
|
+
const p = lo;
|
|
463
|
+
const n = this.nverts[p];
|
|
464
|
+
const nvp = this.maxVertsPerPoly;
|
|
465
|
+
const v0 = this.polys[p * nvp] * 3;
|
|
466
|
+
let acc = 0;
|
|
467
|
+
for (let k = 1; k + 1 < n; k++) {
|
|
468
|
+
const v1 = this.polys[p * nvp + k] * 3;
|
|
469
|
+
const v2 = this.polys[p * nvp + k + 1] * 3;
|
|
470
|
+
acc += Math.abs(area2(this.verts[v0], this.verts[v0 + 2], this.verts[v1], this.verts[v1 + 2], this.verts[v2], this.verts[v2 + 2]));
|
|
471
|
+
this.triArea[k] = acc;
|
|
472
|
+
}
|
|
473
|
+
const pick = rng() * acc;
|
|
474
|
+
let k = 1;
|
|
475
|
+
while (k + 2 < n && this.triArea[k] < pick)
|
|
476
|
+
k++;
|
|
477
|
+
const v1 = this.polys[p * nvp + k] * 3;
|
|
478
|
+
const v2 = this.polys[p * nvp + k + 1] * 3;
|
|
479
|
+
let s = rng();
|
|
480
|
+
let t = rng();
|
|
481
|
+
if (s + t > 1) {
|
|
482
|
+
s = 1 - s;
|
|
483
|
+
t = 1 - t;
|
|
484
|
+
}
|
|
485
|
+
const u = 1 - s - t;
|
|
486
|
+
out.x = u * this.verts[v0] + s * this.verts[v1] + t * this.verts[v2];
|
|
487
|
+
out.y = u * this.verts[v0 + 1] + s * this.verts[v1 + 1] + t * this.verts[v2 + 1];
|
|
488
|
+
out.z = u * this.verts[v0 + 2] + s * this.verts[v1 + 2] + t * this.verts[v2 + 2];
|
|
489
|
+
return p;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Walks the segment `from → to` across polygon edges. Returns `true` when a boundary edge
|
|
493
|
+
* stops it, with the hit point in `out`; otherwise `false` with `to` in `out`. A start off the
|
|
494
|
+
* mesh hits at once. `startPoly` skips the lookup of the polygon under `from`.
|
|
495
|
+
*/
|
|
496
|
+
raycast(from, to, out, startPoly = -1) {
|
|
497
|
+
let p = startPoly >= 0 ? startPoly : this.findPolyAt(from.x, from.y, from.z);
|
|
498
|
+
if (p < 0) {
|
|
499
|
+
out.x = from.x;
|
|
500
|
+
out.y = from.y;
|
|
501
|
+
out.z = from.z;
|
|
502
|
+
return true;
|
|
503
|
+
}
|
|
504
|
+
const nvp = this.maxVertsPerPoly;
|
|
505
|
+
for (let guard = 0; guard <= this.polyCount; guard++) {
|
|
506
|
+
// The segment leaves `p` through the edge whose exit parameter is smallest.
|
|
507
|
+
const n = this.nverts[p];
|
|
508
|
+
let tmax = Number.POSITIVE_INFINITY;
|
|
509
|
+
let exit = -1;
|
|
510
|
+
const dx = to.x - from.x;
|
|
511
|
+
const dz = to.z - from.z;
|
|
512
|
+
for (let k = 0; k < n; k++) {
|
|
513
|
+
const a = this.polys[p * nvp + k] * 3;
|
|
514
|
+
const b = this.polys[p * nvp + (k + 1 === n ? 0 : k + 1)] * 3;
|
|
515
|
+
const ax = this.verts[a];
|
|
516
|
+
const az = this.verts[a + 2];
|
|
517
|
+
const ex = this.verts[b] - ax;
|
|
518
|
+
const ez = this.verts[b + 2] - az;
|
|
519
|
+
// area2(a, b, from + d t) = dist + t * denom; the ray exits across this edge when that
|
|
520
|
+
// falls to zero, which needs denom < 0 (dist is >= 0 inside a CCW polygon).
|
|
521
|
+
const denom = ex * dz - ez * dx;
|
|
522
|
+
if (denom >= -1e-12)
|
|
523
|
+
continue;
|
|
524
|
+
const dist = area2(ax, az, this.verts[b], this.verts[b + 2], from.x, from.z);
|
|
525
|
+
const t = dist / -denom;
|
|
526
|
+
if (t < tmax) {
|
|
527
|
+
tmax = t;
|
|
528
|
+
exit = k;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
if (exit === -1 || tmax >= 1) {
|
|
532
|
+
out.x = to.x;
|
|
533
|
+
out.y = to.y;
|
|
534
|
+
out.z = to.z;
|
|
535
|
+
return false;
|
|
536
|
+
}
|
|
537
|
+
const t = Math.max(0, tmax);
|
|
538
|
+
const next = this.adjacency[p * nvp + exit];
|
|
539
|
+
if (next < 0) {
|
|
540
|
+
out.x = from.x + dx * t;
|
|
541
|
+
out.z = from.z + dz * t;
|
|
542
|
+
out.y = this.polyHeight(p, out.x, out.z);
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
p = next;
|
|
546
|
+
}
|
|
547
|
+
out.x = to.x;
|
|
548
|
+
out.y = to.y;
|
|
549
|
+
out.z = to.z;
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
const scratch = { x: 0, y: 0, z: 0 };
|
|
554
|
+
/** Pairs polygons across shared edges (both directions) into a fresh adjacency array. */
|
|
555
|
+
export function buildAdjacency(polys, polyCount, nvp, nverts, vertCount) {
|
|
556
|
+
const adjacency = new Int32Array(Math.max(1, polyCount) * nvp).fill(-1);
|
|
557
|
+
const edgeOf = new Map();
|
|
558
|
+
for (let p = 0; p < polyCount; p++) {
|
|
559
|
+
const n = nverts[p];
|
|
560
|
+
for (let e = 0; e < n; e++) {
|
|
561
|
+
const v0 = polys[p * nvp + e];
|
|
562
|
+
const v1 = polys[p * nvp + (e + 1 === n ? 0 : e + 1)];
|
|
563
|
+
const key = v0 < v1 ? v0 * vertCount + v1 : v1 * vertCount + v0;
|
|
564
|
+
const other = edgeOf.get(key);
|
|
565
|
+
if (other === undefined) {
|
|
566
|
+
edgeOf.set(key, p * nvp + e);
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
const op = Math.floor(other / nvp);
|
|
570
|
+
if (op !== p) {
|
|
571
|
+
adjacency[p * nvp + e] = op;
|
|
572
|
+
adjacency[other] = p;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return adjacency;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Bakes a navmesh from triangle soup: voxelise, filter by height, climb and slope, erode by the
|
|
581
|
+
* agent radius, partition into regions, trace and simplify contours, triangulate and merge into
|
|
582
|
+
* convex polygons, then stamp `opts.areas` (if any). Bake-time only; allocates freely. Options
|
|
583
|
+
* left out take the `resolveNavBakeOptions` defaults; a bad one throws a `NavBakeError`. An input
|
|
584
|
+
* with no triangles gives an empty mesh; one whose triangles yield no polygon gives an empty mesh
|
|
585
|
+
* and one `console.warn`.
|
|
586
|
+
*/
|
|
587
|
+
export function bakeNavMesh(input, options) {
|
|
588
|
+
const opts = resolveNavBakeOptions(options);
|
|
589
|
+
const sources = Array.isArray(input) ? input : [input];
|
|
590
|
+
const cs = opts.cellSize;
|
|
591
|
+
const ch = opts.cellHeight;
|
|
592
|
+
const nvp = opts.maxVertsPerPoly;
|
|
593
|
+
const bmin = [0, 0, 0];
|
|
594
|
+
const bmax = [0, 0, 0];
|
|
595
|
+
if (!computeBounds(sources, bmin, bmax)) {
|
|
596
|
+
return new NavMesh(new Float32Array(0), 0, new Int32Array(0), 0, nvp, cs, ch);
|
|
597
|
+
}
|
|
598
|
+
const walkableHeight = Math.ceil(opts.agentHeight / ch);
|
|
599
|
+
const walkableClimb = Math.floor(opts.agentMaxClimb / ch);
|
|
600
|
+
const walkableRadius = Math.ceil(opts.agentRadius / cs);
|
|
601
|
+
// Pad by the radius so erosion sees the true edge of the world, not the heightfield's.
|
|
602
|
+
const pad = (walkableRadius + 1) * cs;
|
|
603
|
+
bmin[0] -= pad;
|
|
604
|
+
bmin[2] -= pad;
|
|
605
|
+
bmax[0] += pad;
|
|
606
|
+
bmax[2] += pad;
|
|
607
|
+
bmin[1] -= ch;
|
|
608
|
+
bmax[1] += ch;
|
|
609
|
+
const width = Math.ceil((bmax[0] - bmin[0]) / cs);
|
|
610
|
+
const height = Math.ceil((bmax[2] - bmin[2]) / cs);
|
|
611
|
+
const hf = createHeightfield(width, height, bmin, bmax, cs, ch);
|
|
612
|
+
rasterizeSources(hf, sources, opts.agentMaxSlope, walkableClimb);
|
|
613
|
+
filterLowHangingWalkableObstacles(hf, walkableClimb);
|
|
614
|
+
filterLedgeSpans(hf, walkableHeight, walkableClimb);
|
|
615
|
+
filterWalkableLowHeightSpans(hf, walkableHeight);
|
|
616
|
+
const chf = buildCompactHeightfield(hf, walkableHeight, walkableClimb);
|
|
617
|
+
erodeWalkableArea(chf, walkableRadius);
|
|
618
|
+
// Recast's convention: the region thresholds are areas in cells.
|
|
619
|
+
buildRegions(chf, opts.minRegionArea, opts.mergeRegionArea);
|
|
620
|
+
const maxError = opts.maxSimplification / cs;
|
|
621
|
+
const maxEdgeLen = Math.floor(opts.maxEdgeLength / cs);
|
|
622
|
+
const contours = buildContours(chf, maxError, maxEdgeLen);
|
|
623
|
+
const pm = buildPolyMesh(contours, nvp);
|
|
624
|
+
const verts = new Float32Array(Math.max(1, pm.vertCount) * 3);
|
|
625
|
+
for (let i = 0; i < pm.vertCount; i++) {
|
|
626
|
+
verts[i * 3] = bmin[0] + pm.verts[i * 3] * cs;
|
|
627
|
+
verts[i * 3 + 1] = bmin[1] + pm.verts[i * 3 + 1] * ch;
|
|
628
|
+
verts[i * 3 + 2] = bmin[2] + pm.verts[i * 3 + 2] * cs;
|
|
629
|
+
}
|
|
630
|
+
const polys = pm.polys.slice(0, Math.max(1, pm.polyCount) * nvp);
|
|
631
|
+
const mesh = new NavMesh(verts, pm.vertCount, polys, pm.polyCount, nvp, cs, ch);
|
|
632
|
+
if (pm.polyCount === 0) {
|
|
633
|
+
console.warn(`[nav] bakeNavMesh: 0 polygons from ${countTriangles(sources)} triangles (cellSize ${cs}, cellHeight ${ch}, agentHeight ${opts.agentHeight}, agentRadius ${opts.agentRadius}, agentMaxClimb ${opts.agentMaxClimb}, agentMaxSlope ${opts.agentMaxSlope}); nothing is walkable`);
|
|
634
|
+
}
|
|
635
|
+
if (options.areas) {
|
|
636
|
+
for (const stamp of options.areas)
|
|
637
|
+
markArea(mesh, stamp.shape, stamp.area);
|
|
638
|
+
mesh.version = 0;
|
|
639
|
+
}
|
|
640
|
+
return mesh;
|
|
641
|
+
}
|
|
642
|
+
function countTriangles(sources) {
|
|
643
|
+
let n = 0;
|
|
644
|
+
for (const s of sources)
|
|
645
|
+
n += Math.floor(s.indices.length / 3);
|
|
646
|
+
return n;
|
|
647
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navmesh bake, stage four: contours to convex polygons. Each contour is ear-clipped into
|
|
3
|
+
* triangles, triangles are merged pairwise while the result stays convex and under
|
|
4
|
+
* `maxVertsPerPoly`, vertices are shared between contours, and every polygon learns its
|
|
5
|
+
* neighbour across each edge. Recast `rcBuildPolyMesh`, in cells.
|
|
6
|
+
*/
|
|
7
|
+
import type { Contour } from './contour.js';
|
|
8
|
+
export interface PolyMesh {
|
|
9
|
+
/** `x, y, z` per vertex (cells). */
|
|
10
|
+
verts: Int32Array;
|
|
11
|
+
vertCount: number;
|
|
12
|
+
/** `maxVertsPerPoly` indices per polygon, -1 padded. */
|
|
13
|
+
polys: Int32Array;
|
|
14
|
+
/** `maxVertsPerPoly` neighbour polygons per polygon (per edge `i` from vertex `i` to `i + 1`), -1 none. */
|
|
15
|
+
adjacency: Int32Array;
|
|
16
|
+
regs: Uint16Array;
|
|
17
|
+
areas: Uint8Array;
|
|
18
|
+
polyCount: number;
|
|
19
|
+
maxVertsPerPoly: number;
|
|
20
|
+
}
|
|
21
|
+
declare function countPolyVerts(polys: Int32Array, p: number, nvp: number): number;
|
|
22
|
+
/** Builds the polygon mesh from the contours. `maxVertsPerPoly` is 3..6. */
|
|
23
|
+
export declare function buildPolyMesh(contours: readonly Contour[], maxVertsPerPoly: number): PolyMesh;
|
|
24
|
+
export { countPolyVerts };
|