@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,493 @@
|
|
|
1
|
+
import { gridTriangles } from './grid.js';
|
|
2
|
+
export const SOURCE_GEOMETRY = 0;
|
|
3
|
+
export const SOURCE_HEIGHTFIELD = 1;
|
|
4
|
+
export const SOURCE_GRID = 2;
|
|
5
|
+
/**
|
|
6
|
+
* A world of static triangles under a BVH. Build with `createStaticCollider`, query with
|
|
7
|
+
* `raycast`, `overlap`, `sweep` and `slide`, ship with `exportCollider`.
|
|
8
|
+
*/
|
|
9
|
+
export class StaticCollider {
|
|
10
|
+
/** World-space triangles, nine floats each, in BVH leaf order. */
|
|
11
|
+
tris;
|
|
12
|
+
/** The source index of each triangle. */
|
|
13
|
+
triSource;
|
|
14
|
+
nodeMin;
|
|
15
|
+
nodeMax;
|
|
16
|
+
nodeLeaf;
|
|
17
|
+
nodeA;
|
|
18
|
+
nodeB;
|
|
19
|
+
/** The root node index. */
|
|
20
|
+
root;
|
|
21
|
+
/** Top-level nodes over the sources occupy `[0, topCount)` (0 when there is one source). */
|
|
22
|
+
topCount;
|
|
23
|
+
sources;
|
|
24
|
+
leafSize;
|
|
25
|
+
/** The union of every live source, kept current by `refit` and `remove`. */
|
|
26
|
+
bounds = {
|
|
27
|
+
min: [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
|
28
|
+
max: [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
|
29
|
+
};
|
|
30
|
+
constructor(parts) {
|
|
31
|
+
this.tris = parts.tris;
|
|
32
|
+
this.triSource = parts.triSource;
|
|
33
|
+
this.nodeMin = parts.nodeMin;
|
|
34
|
+
this.nodeMax = parts.nodeMax;
|
|
35
|
+
this.nodeLeaf = parts.nodeLeaf;
|
|
36
|
+
this.nodeA = parts.nodeA;
|
|
37
|
+
this.nodeB = parts.nodeB;
|
|
38
|
+
this.root = parts.root;
|
|
39
|
+
this.topCount = parts.topCount;
|
|
40
|
+
this.sources = parts.sources;
|
|
41
|
+
this.leafSize = parts.leafSize;
|
|
42
|
+
this.updateBounds();
|
|
43
|
+
}
|
|
44
|
+
/** Triangles in the live (not removed) sources. */
|
|
45
|
+
get triangleCount() {
|
|
46
|
+
let n = 0;
|
|
47
|
+
for (const s of this.sources)
|
|
48
|
+
if (!s.removed)
|
|
49
|
+
n += s.count;
|
|
50
|
+
return n;
|
|
51
|
+
}
|
|
52
|
+
/** Number of sources, removed ones included (indices stay stable). */
|
|
53
|
+
get sourceCount() {
|
|
54
|
+
return this.sources.length;
|
|
55
|
+
}
|
|
56
|
+
/** The `userData` of a source (-1 or out of range gives `undefined`). */
|
|
57
|
+
userData(source) {
|
|
58
|
+
return this.sources[source]?.userData;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Moves a geometry source to `transform` (a 3×4 `Transform.world` or a 4×4 column-major
|
|
62
|
+
* matrix): rewrites its world triangles from the local copy, refits its leaves and inner nodes
|
|
63
|
+
* bottom-up, then the top-level nodes. Nothing is rebuilt; a tree whose leaves have drifted far
|
|
64
|
+
* apart only gets looser. Throws for a heightfield or grid source.
|
|
65
|
+
*/
|
|
66
|
+
refit(sourceIndex, transform) {
|
|
67
|
+
const s = this.sources[sourceIndex];
|
|
68
|
+
if (!s)
|
|
69
|
+
throw new Error(`collide: no source ${sourceIndex}`);
|
|
70
|
+
if (!s.local)
|
|
71
|
+
throw new Error(`collide: source ${sourceIndex} is not a geometry; only geometry sources refit`);
|
|
72
|
+
if (s.removed)
|
|
73
|
+
return;
|
|
74
|
+
const local = s.local;
|
|
75
|
+
const tris = this.tris;
|
|
76
|
+
const base = s.start * 9;
|
|
77
|
+
for (let i = 0; i < local.length; i += 3) {
|
|
78
|
+
applyTransform(transform, local[i], local[i + 1], local[i + 2], tris, base + i);
|
|
79
|
+
}
|
|
80
|
+
this.refitBlock(s.nodeStart, s.nodeEnd);
|
|
81
|
+
this.refitTop();
|
|
82
|
+
}
|
|
83
|
+
/** Drops a source from every query (its root box becomes empty). Indices do not shift. */
|
|
84
|
+
remove(sourceIndex) {
|
|
85
|
+
const s = this.sources[sourceIndex];
|
|
86
|
+
if (!s)
|
|
87
|
+
throw new Error(`collide: no source ${sourceIndex}`);
|
|
88
|
+
if (s.removed)
|
|
89
|
+
return;
|
|
90
|
+
s.removed = true;
|
|
91
|
+
setEmpty(this.nodeMin, this.nodeMax, s.root);
|
|
92
|
+
this.refitTop();
|
|
93
|
+
}
|
|
94
|
+
/** Recomputes the nodes of one block from its leaves up (children always follow parents). */
|
|
95
|
+
refitBlock(start, end) {
|
|
96
|
+
const { nodeMin, nodeMax, nodeLeaf, nodeA, nodeB, tris } = this;
|
|
97
|
+
for (let n = end - 1; n >= start; n--) {
|
|
98
|
+
if (nodeLeaf[n]) {
|
|
99
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
100
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
101
|
+
let minZ = Number.POSITIVE_INFINITY;
|
|
102
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
103
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
104
|
+
let maxZ = Number.NEGATIVE_INFINITY;
|
|
105
|
+
const t0 = nodeA[n] * 9;
|
|
106
|
+
const t1 = t0 + nodeB[n] * 9;
|
|
107
|
+
for (let i = t0; i < t1; i += 3) {
|
|
108
|
+
const x = tris[i];
|
|
109
|
+
const y = tris[i + 1];
|
|
110
|
+
const z = tris[i + 2];
|
|
111
|
+
if (x < minX)
|
|
112
|
+
minX = x;
|
|
113
|
+
if (x > maxX)
|
|
114
|
+
maxX = x;
|
|
115
|
+
if (y < minY)
|
|
116
|
+
minY = y;
|
|
117
|
+
if (y > maxY)
|
|
118
|
+
maxY = y;
|
|
119
|
+
if (z < minZ)
|
|
120
|
+
minZ = z;
|
|
121
|
+
if (z > maxZ)
|
|
122
|
+
maxZ = z;
|
|
123
|
+
}
|
|
124
|
+
nodeMin[n * 3] = minX;
|
|
125
|
+
nodeMin[n * 3 + 1] = minY;
|
|
126
|
+
nodeMin[n * 3 + 2] = minZ;
|
|
127
|
+
nodeMax[n * 3] = maxX;
|
|
128
|
+
nodeMax[n * 3 + 1] = maxY;
|
|
129
|
+
nodeMax[n * 3 + 2] = maxZ;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
unionChildren(nodeMin, nodeMax, n, nodeA[n], nodeB[n]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
refitTop() {
|
|
137
|
+
const { nodeMin, nodeMax, nodeA, nodeB } = this;
|
|
138
|
+
for (let n = this.topCount - 1; n >= 0; n--) {
|
|
139
|
+
unionChildren(nodeMin, nodeMax, n, nodeA[n], nodeB[n]);
|
|
140
|
+
}
|
|
141
|
+
this.updateBounds();
|
|
142
|
+
}
|
|
143
|
+
updateBounds() {
|
|
144
|
+
const r = this.root * 3;
|
|
145
|
+
const b = this.bounds;
|
|
146
|
+
b.min[0] = this.nodeMin[r];
|
|
147
|
+
b.min[1] = this.nodeMin[r + 1];
|
|
148
|
+
b.min[2] = this.nodeMin[r + 2];
|
|
149
|
+
b.max[0] = this.nodeMax[r];
|
|
150
|
+
b.max[1] = this.nodeMax[r + 1];
|
|
151
|
+
b.max[2] = this.nodeMax[r + 2];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function setEmpty(nodeMin, nodeMax, n) {
|
|
155
|
+
nodeMin[n * 3] = nodeMin[n * 3 + 1] = nodeMin[n * 3 + 2] = Number.POSITIVE_INFINITY;
|
|
156
|
+
nodeMax[n * 3] = nodeMax[n * 3 + 1] = nodeMax[n * 3 + 2] = Number.NEGATIVE_INFINITY;
|
|
157
|
+
}
|
|
158
|
+
function unionChildren(nodeMin, nodeMax, n, a, b) {
|
|
159
|
+
for (let k = 0; k < 3; k++) {
|
|
160
|
+
nodeMin[n * 3 + k] = Math.min(nodeMin[a * 3 + k], nodeMin[b * 3 + k]);
|
|
161
|
+
nodeMax[n * 3 + k] = Math.max(nodeMax[a * 3 + k], nodeMax[b * 3 + k]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Writes `m × (x, y, z, 1)` into `out` at `o`. `m` is a 3×4 row-major matrix (12 floats, as
|
|
166
|
+
* `Transform.world`) or a 4×4 column-major one (16 floats, as `Camera.view`). Anything else throws.
|
|
167
|
+
*/
|
|
168
|
+
export function applyTransform(m, x, y, z, out, o) {
|
|
169
|
+
if (m.length === 12) {
|
|
170
|
+
out[o] = m[0] * x + m[1] * y + m[2] * z + m[3];
|
|
171
|
+
out[o + 1] = m[4] * x + m[5] * y + m[6] * z + m[7];
|
|
172
|
+
out[o + 2] = m[8] * x + m[9] * y + m[10] * z + m[11];
|
|
173
|
+
}
|
|
174
|
+
else if (m.length === 16) {
|
|
175
|
+
out[o] = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
176
|
+
out[o + 1] = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
177
|
+
out[o + 2] = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
throw new Error(`collide: a transform has 12 (3×4 row-major) or 16 (4×4) floats, got ${m.length}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// ------------------------------------------------------------------ building
|
|
184
|
+
/**
|
|
185
|
+
* The nine floats per triangle of a vertex array (`floats` per vertex, xyz first) and its
|
|
186
|
+
* indices, in its own space: the one position accessor both triangle-set source forms go through.
|
|
187
|
+
*/
|
|
188
|
+
function indexedTriangles(v, floats, idx) {
|
|
189
|
+
if (idx.length % 3 !== 0) {
|
|
190
|
+
throw new Error(`collide: a source's index count must be a multiple of 3, got ${idx.length}`);
|
|
191
|
+
}
|
|
192
|
+
const out = new Float32Array(idx.length * 3);
|
|
193
|
+
for (let i = 0; i < idx.length; i++) {
|
|
194
|
+
const o = idx[i] * floats;
|
|
195
|
+
out[i * 3] = v[o];
|
|
196
|
+
out[i * 3 + 1] = v[o + 1];
|
|
197
|
+
out[i * 3 + 2] = v[o + 2];
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
/** Two triangles per cell, counter-clockwise seen from +y, the same surface `heightAt` samples. */
|
|
202
|
+
function heightfieldTriangles(hf) {
|
|
203
|
+
const { width, depth, heights, scale, origin } = hf;
|
|
204
|
+
const cells = (width - 1) * (depth - 1);
|
|
205
|
+
const out = new Float32Array(cells * 18);
|
|
206
|
+
let o = 0;
|
|
207
|
+
const at = (x, z, k) => {
|
|
208
|
+
out[o + k] = origin[0] + x * scale[0];
|
|
209
|
+
out[o + k + 1] = origin[1] + heights[z * width + x] * scale[1];
|
|
210
|
+
out[o + k + 2] = origin[2] + z * scale[2];
|
|
211
|
+
};
|
|
212
|
+
for (let z = 0; z < depth - 1; z++) {
|
|
213
|
+
for (let x = 0; x < width - 1; x++) {
|
|
214
|
+
// (x, z) (x, z+1) (x+1, z+1) and (x, z) (x+1, z+1) (x+1, z): CCW from above (+y).
|
|
215
|
+
at(x, z, 0);
|
|
216
|
+
at(x, z + 1, 3);
|
|
217
|
+
at(x + 1, z + 1, 6);
|
|
218
|
+
o += 9;
|
|
219
|
+
at(x, z, 0);
|
|
220
|
+
at(x + 1, z + 1, 3);
|
|
221
|
+
at(x + 1, z, 6);
|
|
222
|
+
o += 9;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return out;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Builds a subtree over triangles `order[lo..hi)` of `tris` into `tree`, node indices offset by
|
|
229
|
+
* `nodeBase` (the index the first node of this block gets). Returns the root's index.
|
|
230
|
+
*/
|
|
231
|
+
function buildSubtree(tris, order, centroids, lo, hi, leafSize, tree, nodeBase) {
|
|
232
|
+
const index = nodeBase + tree.leaf.length;
|
|
233
|
+
// Bounds of the range and of its centroids.
|
|
234
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
235
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
236
|
+
let minZ = Number.POSITIVE_INFINITY;
|
|
237
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
238
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
239
|
+
let maxZ = Number.NEGATIVE_INFINITY;
|
|
240
|
+
let cMinX = Number.POSITIVE_INFINITY;
|
|
241
|
+
let cMinY = Number.POSITIVE_INFINITY;
|
|
242
|
+
let cMinZ = Number.POSITIVE_INFINITY;
|
|
243
|
+
let cMaxX = Number.NEGATIVE_INFINITY;
|
|
244
|
+
let cMaxY = Number.NEGATIVE_INFINITY;
|
|
245
|
+
let cMaxZ = Number.NEGATIVE_INFINITY;
|
|
246
|
+
for (let i = lo; i < hi; i++) {
|
|
247
|
+
const t = order[i];
|
|
248
|
+
for (let k = 0; k < 9; k += 3) {
|
|
249
|
+
const x = tris[t * 9 + k];
|
|
250
|
+
const y = tris[t * 9 + k + 1];
|
|
251
|
+
const z = tris[t * 9 + k + 2];
|
|
252
|
+
if (x < minX)
|
|
253
|
+
minX = x;
|
|
254
|
+
if (x > maxX)
|
|
255
|
+
maxX = x;
|
|
256
|
+
if (y < minY)
|
|
257
|
+
minY = y;
|
|
258
|
+
if (y > maxY)
|
|
259
|
+
maxY = y;
|
|
260
|
+
if (z < minZ)
|
|
261
|
+
minZ = z;
|
|
262
|
+
if (z > maxZ)
|
|
263
|
+
maxZ = z;
|
|
264
|
+
}
|
|
265
|
+
const cx = centroids[t * 3];
|
|
266
|
+
const cy = centroids[t * 3 + 1];
|
|
267
|
+
const cz = centroids[t * 3 + 2];
|
|
268
|
+
if (cx < cMinX)
|
|
269
|
+
cMinX = cx;
|
|
270
|
+
if (cx > cMaxX)
|
|
271
|
+
cMaxX = cx;
|
|
272
|
+
if (cy < cMinY)
|
|
273
|
+
cMinY = cy;
|
|
274
|
+
if (cy > cMaxY)
|
|
275
|
+
cMaxY = cy;
|
|
276
|
+
if (cz < cMinZ)
|
|
277
|
+
cMinZ = cz;
|
|
278
|
+
if (cz > cMaxZ)
|
|
279
|
+
cMaxZ = cz;
|
|
280
|
+
}
|
|
281
|
+
tree.min.push(minX, minY, minZ);
|
|
282
|
+
tree.max.push(maxX, maxY, maxZ);
|
|
283
|
+
const count = hi - lo;
|
|
284
|
+
const ex = cMaxX - cMinX;
|
|
285
|
+
const ey = cMaxY - cMinY;
|
|
286
|
+
const ez = cMaxZ - cMinZ;
|
|
287
|
+
const widest = Math.max(ex, ey, ez);
|
|
288
|
+
if (count <= leafSize || count < 2 || !(widest > 0)) {
|
|
289
|
+
tree.leaf.push(1);
|
|
290
|
+
tree.a.push(lo);
|
|
291
|
+
tree.b.push(count);
|
|
292
|
+
return index;
|
|
293
|
+
}
|
|
294
|
+
const axis = widest === ex ? 0 : widest === ey ? 1 : 2;
|
|
295
|
+
order.subarray(lo, hi).sort((p, q) => centroids[p * 3 + axis] - centroids[q * 3 + axis]);
|
|
296
|
+
const mid = (lo + hi) >> 1;
|
|
297
|
+
tree.leaf.push(0);
|
|
298
|
+
tree.a.push(0);
|
|
299
|
+
tree.b.push(0);
|
|
300
|
+
const slot = index - nodeBase;
|
|
301
|
+
tree.a[slot] = buildSubtree(tris, order, centroids, lo, mid, leafSize, tree, nodeBase);
|
|
302
|
+
tree.b[slot] = buildSubtree(tris, order, centroids, mid, hi, leafSize, tree, nodeBase);
|
|
303
|
+
return index;
|
|
304
|
+
}
|
|
305
|
+
function prepareSource(src) {
|
|
306
|
+
const layer = src.layer ?? 0;
|
|
307
|
+
if (!(layer >= 0 && layer < 32 && Number.isInteger(layer))) {
|
|
308
|
+
throw new Error(`collide: layer must be an integer 0..31, got ${layer}`);
|
|
309
|
+
}
|
|
310
|
+
if ('geometry' in src || 'positions' in src) {
|
|
311
|
+
const local = 'geometry' in src
|
|
312
|
+
? indexedTriangles(src.geometry.vertices, src.geometry.layout.floats, src.geometry.indices)
|
|
313
|
+
: indexedTriangles(src.positions, 3, src.indices);
|
|
314
|
+
let world = local;
|
|
315
|
+
if (src.transform) {
|
|
316
|
+
world = new Float32Array(local.length);
|
|
317
|
+
for (let i = 0; i < local.length; i += 3) {
|
|
318
|
+
applyTransform(src.transform, local[i], local[i + 1], local[i + 2], world, i);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
world = new Float32Array(local);
|
|
323
|
+
}
|
|
324
|
+
return { kind: SOURCE_GEOMETRY, world, local, layer, userData: src.userData };
|
|
325
|
+
}
|
|
326
|
+
if ('heightfield' in src) {
|
|
327
|
+
return {
|
|
328
|
+
kind: SOURCE_HEIGHTFIELD,
|
|
329
|
+
world: heightfieldTriangles(src.heightfield),
|
|
330
|
+
local: null,
|
|
331
|
+
layer,
|
|
332
|
+
userData: src.userData,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
if ('grid' in src) {
|
|
336
|
+
return {
|
|
337
|
+
kind: SOURCE_GRID,
|
|
338
|
+
world: gridTriangles(src.grid),
|
|
339
|
+
local: null,
|
|
340
|
+
layer,
|
|
341
|
+
userData: src.userData,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
throw new Error('collide: a source is { geometry }, { positions, indices }, { heightfield } or { grid }');
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Builds a `StaticCollider` over `sources`. Every source becomes a block of triangles (world
|
|
348
|
+
* space) and a BVH sub-tree (median split on the widest centroid axis, leaves of at most
|
|
349
|
+
* `leafSize` triangles, default 4); a top-level tree over the sources' roots joins them.
|
|
350
|
+
* Build-time allocation only; queries then allocate nothing.
|
|
351
|
+
*/
|
|
352
|
+
export function createStaticCollider(sources, opts = {}) {
|
|
353
|
+
const leafSize = Math.max(1, Math.floor(opts.leafSize ?? 4));
|
|
354
|
+
if (sources.length === 0)
|
|
355
|
+
throw new Error('collide: at least one source is needed');
|
|
356
|
+
const builds = sources.map(prepareSource);
|
|
357
|
+
let total = 0;
|
|
358
|
+
for (const b of builds)
|
|
359
|
+
total += b.world.length / 9;
|
|
360
|
+
const tris = new Float32Array(total * 9);
|
|
361
|
+
const triSource = new Uint32Array(total);
|
|
362
|
+
const records = [];
|
|
363
|
+
const trees = [];
|
|
364
|
+
const roots = [];
|
|
365
|
+
// Top-level nodes come first: with S sources a binary tree over them has S - 1 inner nodes.
|
|
366
|
+
const topCount = builds.length > 1 ? builds.length - 1 : 0;
|
|
367
|
+
let nodeCursor = topCount;
|
|
368
|
+
let triCursor = 0;
|
|
369
|
+
for (let si = 0; si < builds.length; si++) {
|
|
370
|
+
const b = builds[si];
|
|
371
|
+
const n = b.world.length / 9;
|
|
372
|
+
const order = new Uint32Array(n);
|
|
373
|
+
const centroids = new Float32Array(n * 3);
|
|
374
|
+
for (let t = 0; t < n; t++) {
|
|
375
|
+
order[t] = t;
|
|
376
|
+
const o = t * 9;
|
|
377
|
+
centroids[t * 3] = (b.world[o] + b.world[o + 3] + b.world[o + 6]) / 3;
|
|
378
|
+
centroids[t * 3 + 1] = (b.world[o + 1] + b.world[o + 4] + b.world[o + 7]) / 3;
|
|
379
|
+
centroids[t * 3 + 2] = (b.world[o + 2] + b.world[o + 5] + b.world[o + 8]) / 3;
|
|
380
|
+
}
|
|
381
|
+
const tree = { min: [], max: [], leaf: [], a: [], b: [] };
|
|
382
|
+
let root;
|
|
383
|
+
if (n === 0) {
|
|
384
|
+
root = nodeCursor;
|
|
385
|
+
tree.min.push(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
|
|
386
|
+
tree.max.push(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY);
|
|
387
|
+
tree.leaf.push(1);
|
|
388
|
+
tree.a.push(0);
|
|
389
|
+
tree.b.push(0);
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
root = buildSubtree(b.world, order, centroids, 0, n, leafSize, tree, nodeCursor);
|
|
393
|
+
}
|
|
394
|
+
// Leaf triangle ranges are in `order` positions; place the triangles in that order.
|
|
395
|
+
for (let k = 0; k < tree.leaf.length; k++) {
|
|
396
|
+
if (tree.leaf[k])
|
|
397
|
+
tree.a[k] = tree.a[k] + triCursor;
|
|
398
|
+
}
|
|
399
|
+
const local = b.local ? new Float32Array(n * 9) : null;
|
|
400
|
+
for (let p = 0; p < n; p++) {
|
|
401
|
+
const t = order[p];
|
|
402
|
+
tris.set(b.world.subarray(t * 9, t * 9 + 9), (triCursor + p) * 9);
|
|
403
|
+
if (local && b.local)
|
|
404
|
+
local.set(b.local.subarray(t * 9, t * 9 + 9), p * 9);
|
|
405
|
+
triSource[triCursor + p] = si;
|
|
406
|
+
}
|
|
407
|
+
records.push({
|
|
408
|
+
kind: b.kind,
|
|
409
|
+
start: triCursor,
|
|
410
|
+
count: n,
|
|
411
|
+
root,
|
|
412
|
+
nodeStart: nodeCursor,
|
|
413
|
+
nodeEnd: nodeCursor + tree.leaf.length,
|
|
414
|
+
layer: b.layer,
|
|
415
|
+
removed: false,
|
|
416
|
+
local,
|
|
417
|
+
userData: b.userData,
|
|
418
|
+
});
|
|
419
|
+
trees.push(tree);
|
|
420
|
+
roots.push(root);
|
|
421
|
+
nodeCursor += tree.leaf.length;
|
|
422
|
+
triCursor += n;
|
|
423
|
+
}
|
|
424
|
+
const nodeCount = nodeCursor;
|
|
425
|
+
const nodeMin = new Float32Array(nodeCount * 3);
|
|
426
|
+
const nodeMax = new Float32Array(nodeCount * 3);
|
|
427
|
+
const nodeLeaf = new Uint8Array(nodeCount);
|
|
428
|
+
const nodeA = new Int32Array(nodeCount);
|
|
429
|
+
const nodeB = new Int32Array(nodeCount);
|
|
430
|
+
for (let si = 0; si < trees.length; si++) {
|
|
431
|
+
const tree = trees[si];
|
|
432
|
+
const base = records[si].nodeStart;
|
|
433
|
+
for (let k = 0; k < tree.leaf.length; k++) {
|
|
434
|
+
nodeMin.set(tree.min.slice(k * 3, k * 3 + 3), (base + k) * 3);
|
|
435
|
+
nodeMax.set(tree.max.slice(k * 3, k * 3 + 3), (base + k) * 3);
|
|
436
|
+
nodeLeaf[base + k] = tree.leaf[k];
|
|
437
|
+
nodeA[base + k] = tree.a[k];
|
|
438
|
+
nodeB[base + k] = tree.b[k];
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// The top-level tree: median split over the source roots by their box centres.
|
|
442
|
+
let root;
|
|
443
|
+
if (topCount === 0) {
|
|
444
|
+
root = roots[0];
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
let next = 0;
|
|
448
|
+
const centre = (n, axis) => (nodeMin[n * 3 + axis] + nodeMax[n * 3 + axis]) / 2;
|
|
449
|
+
const buildTop = (items) => {
|
|
450
|
+
if (items.length === 1)
|
|
451
|
+
return items[0];
|
|
452
|
+
const index = next++;
|
|
453
|
+
let axis = 0;
|
|
454
|
+
let widest = Number.NEGATIVE_INFINITY;
|
|
455
|
+
for (let k = 0; k < 3; k++) {
|
|
456
|
+
let lo = Number.POSITIVE_INFINITY;
|
|
457
|
+
let hi = Number.NEGATIVE_INFINITY;
|
|
458
|
+
for (const n of items) {
|
|
459
|
+
const c = centre(n, k);
|
|
460
|
+
if (Number.isFinite(c)) {
|
|
461
|
+
lo = Math.min(lo, c);
|
|
462
|
+
hi = Math.max(hi, c);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (hi - lo > widest) {
|
|
466
|
+
widest = hi - lo;
|
|
467
|
+
axis = k;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
const sorted = items.slice().sort((p, q) => centre(p, axis) - centre(q, axis));
|
|
471
|
+
const mid = sorted.length >> 1;
|
|
472
|
+
nodeLeaf[index] = 0;
|
|
473
|
+
nodeA[index] = buildTop(sorted.slice(0, mid));
|
|
474
|
+
nodeB[index] = buildTop(sorted.slice(mid));
|
|
475
|
+
unionChildren(nodeMin, nodeMax, index, nodeA[index], nodeB[index]);
|
|
476
|
+
return index;
|
|
477
|
+
};
|
|
478
|
+
root = buildTop(roots);
|
|
479
|
+
}
|
|
480
|
+
return new StaticCollider({
|
|
481
|
+
tris,
|
|
482
|
+
triSource,
|
|
483
|
+
nodeMin,
|
|
484
|
+
nodeMax,
|
|
485
|
+
nodeLeaf,
|
|
486
|
+
nodeA,
|
|
487
|
+
nodeB,
|
|
488
|
+
root,
|
|
489
|
+
topCount,
|
|
490
|
+
sources: records,
|
|
491
|
+
leafSize,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wireframes of a collider for `createDebugDraw`: either every triangle's three edges or the
|
|
3
|
+
* boxes of the BVH leaves (twelve edges each). Six floats per segment, `x0 y0 z0 x1 y1 z1`.
|
|
4
|
+
*/
|
|
5
|
+
import type { StaticCollider } from './bvh.js';
|
|
6
|
+
export type WireframeMode = 'triangles' | 'leaves';
|
|
7
|
+
/** The number of floats `colliderWireframe` writes for `c` in `mode`. */
|
|
8
|
+
export declare function colliderWireframeLength(c: StaticCollider, mode?: WireframeMode): number;
|
|
9
|
+
/**
|
|
10
|
+
* Line segments for the collider's live triangles (`'triangles'`) or BVH leaf boxes
|
|
11
|
+
* (`'leaves'`). Reuses `out` when it is long enough, else allocates; returns the array (which may
|
|
12
|
+
* be longer than the written part: `colliderWireframeLength` gives the exact count).
|
|
13
|
+
*/
|
|
14
|
+
export declare function colliderWireframe(c: StaticCollider, out?: Float32Array, mode?: WireframeMode): Float32Array;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/** The number of floats `colliderWireframe` writes for `c` in `mode`. */
|
|
2
|
+
export function colliderWireframeLength(c, mode = 'triangles') {
|
|
3
|
+
if (mode === 'leaves') {
|
|
4
|
+
let leaves = 0;
|
|
5
|
+
for (let n = 0; n < c.nodeLeaf.length; n++) {
|
|
6
|
+
if (c.nodeLeaf[n] && c.nodeB[n] > 0 && !c.sources[c.triSource[c.nodeA[n]]].removed)
|
|
7
|
+
leaves++;
|
|
8
|
+
}
|
|
9
|
+
return leaves * 12 * 6;
|
|
10
|
+
}
|
|
11
|
+
return c.triangleCount * 3 * 6;
|
|
12
|
+
}
|
|
13
|
+
const BOX_EDGES = [
|
|
14
|
+
[0, 1],
|
|
15
|
+
[1, 3],
|
|
16
|
+
[3, 2],
|
|
17
|
+
[2, 0],
|
|
18
|
+
[4, 5],
|
|
19
|
+
[5, 7],
|
|
20
|
+
[7, 6],
|
|
21
|
+
[6, 4],
|
|
22
|
+
[0, 4],
|
|
23
|
+
[1, 5],
|
|
24
|
+
[2, 6],
|
|
25
|
+
[3, 7],
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Line segments for the collider's live triangles (`'triangles'`) or BVH leaf boxes
|
|
29
|
+
* (`'leaves'`). Reuses `out` when it is long enough, else allocates; returns the array (which may
|
|
30
|
+
* be longer than the written part: `colliderWireframeLength` gives the exact count).
|
|
31
|
+
*/
|
|
32
|
+
export function colliderWireframe(c, out, mode = 'triangles') {
|
|
33
|
+
const need = colliderWireframeLength(c, mode);
|
|
34
|
+
const buf = out && out.length >= need ? out : new Float32Array(need);
|
|
35
|
+
let o = 0;
|
|
36
|
+
if (mode === 'leaves') {
|
|
37
|
+
for (let n = 0; n < c.nodeLeaf.length; n++) {
|
|
38
|
+
if (!c.nodeLeaf[n] || c.nodeB[n] <= 0)
|
|
39
|
+
continue;
|
|
40
|
+
if (c.sources[c.triSource[c.nodeA[n]]].removed)
|
|
41
|
+
continue;
|
|
42
|
+
const b = n * 3;
|
|
43
|
+
for (const [i, j] of BOX_EDGES) {
|
|
44
|
+
buf[o++] = i & 1 ? c.nodeMax[b] : c.nodeMin[b];
|
|
45
|
+
buf[o++] = i & 2 ? c.nodeMax[b + 1] : c.nodeMin[b + 1];
|
|
46
|
+
buf[o++] = i & 4 ? c.nodeMax[b + 2] : c.nodeMin[b + 2];
|
|
47
|
+
buf[o++] = j & 1 ? c.nodeMax[b] : c.nodeMin[b];
|
|
48
|
+
buf[o++] = j & 2 ? c.nodeMax[b + 1] : c.nodeMin[b + 1];
|
|
49
|
+
buf[o++] = j & 4 ? c.nodeMax[b + 2] : c.nodeMin[b + 2];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return buf;
|
|
53
|
+
}
|
|
54
|
+
const tris = c.tris;
|
|
55
|
+
for (const s of c.sources) {
|
|
56
|
+
if (s.removed)
|
|
57
|
+
continue;
|
|
58
|
+
const t0 = s.start * 9;
|
|
59
|
+
const t1 = t0 + s.count * 9;
|
|
60
|
+
for (let t = t0; t < t1; t += 9) {
|
|
61
|
+
for (let e = 0; e < 3; e++) {
|
|
62
|
+
const a = t + e * 3;
|
|
63
|
+
const b = t + ((e + 1) % 3) * 3;
|
|
64
|
+
buf[o++] = tris[a];
|
|
65
|
+
buf[o++] = tris[a + 1];
|
|
66
|
+
buf[o++] = tris[a + 2];
|
|
67
|
+
buf[o++] = tris[b];
|
|
68
|
+
buf[o++] = tris[b + 1];
|
|
69
|
+
buf[o++] = tris[b + 2];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return buf;
|
|
74
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 2D tile case: a grid of solid cells in the xz plane becomes boxes, `cellSize` wide and
|
|
3
|
+
* deep, from `y` to `y + wallHeight`. Faces shared by two solid cells are left out, so a wall of
|
|
4
|
+
* tiles is one flat run of quads and a circle sliding along it meets no interior edges (the
|
|
5
|
+
* corridor case). Column `x` runs along +x, row `z` along +z, `solid[z * width + x]`.
|
|
6
|
+
*/
|
|
7
|
+
export interface GridSource {
|
|
8
|
+
/** Cells along x. */
|
|
9
|
+
width: number;
|
|
10
|
+
/** Cells along z. */
|
|
11
|
+
height: number;
|
|
12
|
+
/** World size of one cell (x and z). */
|
|
13
|
+
cellSize: number;
|
|
14
|
+
/** World x, z of the corner of cell (0, 0). */
|
|
15
|
+
origin: [number, number];
|
|
16
|
+
/** Which cells are solid: a predicate over cell coordinates or a `width × height` array. */
|
|
17
|
+
solid: ((x: number, z: number) => boolean) | Uint8Array;
|
|
18
|
+
/** World y of the cells' bottom face. Default 0. */
|
|
19
|
+
y?: number;
|
|
20
|
+
/** Height of the cells' walls. Default `cellSize`. */
|
|
21
|
+
wallHeight?: number;
|
|
22
|
+
}
|
|
23
|
+
/** Whether cell (x, z) is solid; out-of-range cells are open. */
|
|
24
|
+
export declare function gridSolid(grid: GridSource, x: number, z: number): boolean;
|
|
25
|
+
/** The grid's exposed faces as triangles, nine floats each, counter-clockwise from outside. */
|
|
26
|
+
export declare function gridTriangles(grid: GridSource): Float32Array;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 2D tile case: a grid of solid cells in the xz plane becomes boxes, `cellSize` wide and
|
|
3
|
+
* deep, from `y` to `y + wallHeight`. Faces shared by two solid cells are left out, so a wall of
|
|
4
|
+
* tiles is one flat run of quads and a circle sliding along it meets no interior edges (the
|
|
5
|
+
* corridor case). Column `x` runs along +x, row `z` along +z, `solid[z * width + x]`.
|
|
6
|
+
*/
|
|
7
|
+
/** Whether cell (x, z) is solid; out-of-range cells are open. */
|
|
8
|
+
export function gridSolid(grid, x, z) {
|
|
9
|
+
if (x < 0 || z < 0 || x >= grid.width || z >= grid.height)
|
|
10
|
+
return false;
|
|
11
|
+
const s = grid.solid;
|
|
12
|
+
return typeof s === 'function' ? s(x, z) : s[z * grid.width + x] !== 0;
|
|
13
|
+
}
|
|
14
|
+
/** The grid's exposed faces as triangles, nine floats each, counter-clockwise from outside. */
|
|
15
|
+
export function gridTriangles(grid) {
|
|
16
|
+
const { width, height, cellSize } = grid;
|
|
17
|
+
if (!(width >= 1 && height >= 1)) {
|
|
18
|
+
throw new Error(`collide: a grid needs at least 1×1 cells, got ${width}×${height}`);
|
|
19
|
+
}
|
|
20
|
+
if (!(cellSize > 0))
|
|
21
|
+
throw new Error(`collide: grid cellSize must be positive, got ${cellSize}`);
|
|
22
|
+
const y0 = grid.y ?? 0;
|
|
23
|
+
const y1 = y0 + (grid.wallHeight ?? cellSize);
|
|
24
|
+
const ox = grid.origin[0];
|
|
25
|
+
const oz = grid.origin[1];
|
|
26
|
+
// Count faces first so the array is allocated once.
|
|
27
|
+
let faces = 0;
|
|
28
|
+
for (let z = 0; z < height; z++) {
|
|
29
|
+
for (let x = 0; x < width; x++) {
|
|
30
|
+
if (!gridSolid(grid, x, z))
|
|
31
|
+
continue;
|
|
32
|
+
faces += 2; // top and bottom
|
|
33
|
+
if (!gridSolid(grid, x - 1, z))
|
|
34
|
+
faces++;
|
|
35
|
+
if (!gridSolid(grid, x + 1, z))
|
|
36
|
+
faces++;
|
|
37
|
+
if (!gridSolid(grid, x, z - 1))
|
|
38
|
+
faces++;
|
|
39
|
+
if (!gridSolid(grid, x, z + 1))
|
|
40
|
+
faces++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const out = new Float32Array(faces * 18);
|
|
44
|
+
let o = 0;
|
|
45
|
+
const quad = (ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz) => {
|
|
46
|
+
out[o++] = ax;
|
|
47
|
+
out[o++] = ay;
|
|
48
|
+
out[o++] = az;
|
|
49
|
+
out[o++] = bx;
|
|
50
|
+
out[o++] = by;
|
|
51
|
+
out[o++] = bz;
|
|
52
|
+
out[o++] = cx;
|
|
53
|
+
out[o++] = cy;
|
|
54
|
+
out[o++] = cz;
|
|
55
|
+
out[o++] = ax;
|
|
56
|
+
out[o++] = ay;
|
|
57
|
+
out[o++] = az;
|
|
58
|
+
out[o++] = cx;
|
|
59
|
+
out[o++] = cy;
|
|
60
|
+
out[o++] = cz;
|
|
61
|
+
out[o++] = dx;
|
|
62
|
+
out[o++] = dy;
|
|
63
|
+
out[o++] = dz;
|
|
64
|
+
};
|
|
65
|
+
for (let z = 0; z < height; z++) {
|
|
66
|
+
for (let x = 0; x < width; x++) {
|
|
67
|
+
if (!gridSolid(grid, x, z))
|
|
68
|
+
continue;
|
|
69
|
+
const x0 = ox + x * cellSize;
|
|
70
|
+
const x1 = x0 + cellSize;
|
|
71
|
+
const z0 = oz + z * cellSize;
|
|
72
|
+
const z1 = z0 + cellSize;
|
|
73
|
+
// Top (+y) and bottom (-y).
|
|
74
|
+
quad(x0, y1, z0, x0, y1, z1, x1, y1, z1, x1, y1, z0);
|
|
75
|
+
quad(x0, y0, z0, x1, y0, z0, x1, y0, z1, x0, y0, z1);
|
|
76
|
+
// -x face
|
|
77
|
+
if (!gridSolid(grid, x - 1, z))
|
|
78
|
+
quad(x0, y0, z0, x0, y0, z1, x0, y1, z1, x0, y1, z0);
|
|
79
|
+
// +x face
|
|
80
|
+
if (!gridSolid(grid, x + 1, z))
|
|
81
|
+
quad(x1, y0, z1, x1, y0, z0, x1, y1, z0, x1, y1, z1);
|
|
82
|
+
// -z face
|
|
83
|
+
if (!gridSolid(grid, x, z - 1))
|
|
84
|
+
quad(x1, y0, z0, x0, y0, z0, x0, y1, z0, x1, y1, z0);
|
|
85
|
+
// +z face
|
|
86
|
+
if (!gridSolid(grid, x, z + 1))
|
|
87
|
+
quad(x0, y0, z1, x1, y0, z1, x1, y1, z1, x0, y1, z1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|