@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,671 @@
|
|
|
1
|
+
import { mat4 } from '../core/math.js';
|
|
2
|
+
/** Every layer bit set: the default `Camera.layers`. */
|
|
3
|
+
export const ALL_LAYERS = 0xffffffff;
|
|
4
|
+
/**
|
|
5
|
+
* Half the depth range of `Camera.ortho2d`, in design units: its near plane is at world
|
|
6
|
+
* z = -ORTHO2D_HALF_DEPTH, the far plane at +ORTHO2D_HALF_DEPTH, z = 0 at clip depth 0.5.
|
|
7
|
+
*/
|
|
8
|
+
export const ORTHO2D_HALF_DEPTH = 1024;
|
|
9
|
+
/**
|
|
10
|
+
* Floats in the WGSL `EngineCamera` block: 112 used (`jitter` ends at byte 448), padded
|
|
11
|
+
* to 512 bytes so the lights block that follows it in the view's uniform buffer stays on a
|
|
12
|
+
* 256-byte boundary (`minUniformBufferOffsetAlignment`).
|
|
13
|
+
*/
|
|
14
|
+
export const CAMERA_BLOCK_FLOATS = 128;
|
|
15
|
+
/** Float offset of `inv_view_proj` inside the camera block (byte 240). */
|
|
16
|
+
export const CAMERA_INV_VIEW_PROJ_OFFSET = 60;
|
|
17
|
+
/** Float offset of `prev_view_proj` (last frame's unjittered `view_proj`) inside the block. */
|
|
18
|
+
export const CAMERA_PREV_VIEW_PROJ_OFFSET = 76;
|
|
19
|
+
/** Float offset of `prev_view` (last frame's `view`) inside the block. */
|
|
20
|
+
export const CAMERA_PREV_VIEW_OFFSET = 92;
|
|
21
|
+
/** Float offset of `jitter` (clip-space dx, dy; the pixel offset x, y) inside the block. */
|
|
22
|
+
export const CAMERA_JITTER_OFFSET = 108;
|
|
23
|
+
/** Floats in `Camera.frustum`: six planes × (a, b, c, d). */
|
|
24
|
+
export const FRUSTUM_FLOATS = 24;
|
|
25
|
+
const tmp = [0, 0, 0];
|
|
26
|
+
/** `fitFreeRect`'s viewport in screen units (one per module; the camera reads it synchronously). */
|
|
27
|
+
const freeScratch = { x: 0, y: 0, width: 0, height: 0 };
|
|
28
|
+
/**
|
|
29
|
+
* A view-projection camera. Matrices are column-major `Float32Array(16)` (see `mat4` in
|
|
30
|
+
* `@thunderclap-engine/engine/core`), computed on read and cached until something changes.
|
|
31
|
+
*
|
|
32
|
+
* Two presets:
|
|
33
|
+
*
|
|
34
|
+
* - `Camera.ortho2d(designW, designH)`: 1 world unit = 1 design px, origin top-left, y down,
|
|
35
|
+
* z into the screen (right-handed with y down): world z in `±ORTHO2D_HALF_DEPTH` spans the
|
|
36
|
+
* depth buffer, z = 0 sits at clip depth 0.5 and larger z is farther. The 2D controls `x`,
|
|
37
|
+
* `y`, `zoom` and `rotation` move it over that space exactly like the engine's earlier 2D
|
|
38
|
+
* camera; `fitRect` frames a world rect.
|
|
39
|
+
* `Transform.z` is thus a stacking axis for 2D draws under a depth camera.
|
|
40
|
+
* - `Camera.perspective(fovY, aspect, near, far)`: right-handed, looking down -z; place it with
|
|
41
|
+
* `lookAt` or `setView`.
|
|
42
|
+
*
|
|
43
|
+
* `screen` is the rect the clip space spans, in the units `worldToScreen` returns and
|
|
44
|
+
* `screenToWorld` takes: the logical (design px) space for `ortho2d`, normalised 0..1 for
|
|
45
|
+
* `perspective` until a caller sets it.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* const cam = renderer.camera; // Camera.ortho2d(1920, 1080) by default
|
|
49
|
+
* cam.x = 120; cam.zoom = 1.5; // pan and zoom, as before
|
|
50
|
+
* const p = cam.screenToWorld(tapX, tapY); // logical px (surface.clientToLogical) → world
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export class Camera {
|
|
54
|
+
/** Depth test for draws through this camera. The 2D preset leaves it off. */
|
|
55
|
+
depthTest = false;
|
|
56
|
+
/** Depth write for draws through this camera. The 2D preset leaves it off. */
|
|
57
|
+
depthWrite = false;
|
|
58
|
+
/**
|
|
59
|
+
* Layer membership mask (u32): a draw is seen when `draw.layers & camera.layers` is nonzero.
|
|
60
|
+
* Default: every bit. Draw order within a camera is a separate sort key, not this mask.
|
|
61
|
+
*/
|
|
62
|
+
layers = ALL_LAYERS;
|
|
63
|
+
/** The rect clip space spans, in screen units (see the class comment). */
|
|
64
|
+
screen = { x: 0, y: 0, width: 1, height: 1 };
|
|
65
|
+
/**
|
|
66
|
+
* The `view_index` the camera block carries (u32): 0 by default; a stereo pair sets 0 and 1
|
|
67
|
+
* so a material can tell the eyes apart. The renderer writes it as given, whatever the order
|
|
68
|
+
* of the frame's `render` calls.
|
|
69
|
+
*/
|
|
70
|
+
viewIndex = 0;
|
|
71
|
+
/**
|
|
72
|
+
* Frustum-cull mesh draws through this camera: a draw whose bounding sphere (`mesh.bounds`
|
|
73
|
+
* through its instance matrix) lies outside any plane of `frustum` is skipped before the sort
|
|
74
|
+
* and counted in `renderer.stats.culled`. Off for `ortho2d` (the 2D path is untouched), on
|
|
75
|
+
* for `perspective`. Sprites and meshes without bounds are never culled.
|
|
76
|
+
*/
|
|
77
|
+
cull = false;
|
|
78
|
+
/**
|
|
79
|
+
* Scales the projected size the renderer picks `MeshLod` levels by (ws/render-5): above 1
|
|
80
|
+
* keeps finer levels farther out, below 1 drops to coarser ones sooner. Default 1.
|
|
81
|
+
*/
|
|
82
|
+
lodBias = 1;
|
|
83
|
+
/**
|
|
84
|
+
* Last frame's unjittered `viewProjection`, copied by the renderer at the start of each view
|
|
85
|
+
* it draws this camera through (`recordHistory`), before the camera is read; identity until
|
|
86
|
+
* the first frame. What a reprojecting post pass (TAA, motion blur) reads through
|
|
87
|
+
* `PostInputs.view.previousViewProj`. Read-only (`Float32Array(16)`).
|
|
88
|
+
*/
|
|
89
|
+
previousViewProj = mat4.create();
|
|
90
|
+
/** Last frame's `view`, kept like `previousViewProj`. Read-only. */
|
|
91
|
+
previousView = mat4.create();
|
|
92
|
+
viewM = mat4.create();
|
|
93
|
+
/** `viewProjM` before the jitter offset (what `previousViewProj` and the frustum use). */
|
|
94
|
+
steadyViewProjM = mat4.create();
|
|
95
|
+
/** What the last `recordHistory` saw: the matrices the next one moves into `previous*`. */
|
|
96
|
+
historyViewProjM = mat4.create();
|
|
97
|
+
historyViewM = mat4.create();
|
|
98
|
+
hasHistory = false;
|
|
99
|
+
/** Sub-pixel jitter in pixels of the current target (`setJitter`). */
|
|
100
|
+
jitterX = 0;
|
|
101
|
+
jitterY = 0;
|
|
102
|
+
/** The target size the jitter is measured against; 0 × 0 (the default) applies none. */
|
|
103
|
+
jitterW = 0;
|
|
104
|
+
jitterH = 0;
|
|
105
|
+
projM = mat4.create();
|
|
106
|
+
viewProjM = mat4.create();
|
|
107
|
+
invViewProjM = mat4.create();
|
|
108
|
+
invViewM = mat4.create();
|
|
109
|
+
pos = new Float32Array(3);
|
|
110
|
+
/** 'view2d': the view comes from x/y/zoom/rotation; 'custom': from setView/lookAt. */
|
|
111
|
+
viewSource = 'view2d';
|
|
112
|
+
/** 'ortho2d': design-space ortho; 'custom': setProjection/setPerspective. */
|
|
113
|
+
projSource = 'ortho2d';
|
|
114
|
+
designW = 1;
|
|
115
|
+
designH = 1;
|
|
116
|
+
_x = 0;
|
|
117
|
+
_y = 0;
|
|
118
|
+
_zoom = 1;
|
|
119
|
+
_rotation = 0;
|
|
120
|
+
dirty = true;
|
|
121
|
+
invDirty = true;
|
|
122
|
+
posDirty = true;
|
|
123
|
+
frustumDirty = true;
|
|
124
|
+
frustumM = new Float32Array(FRUSTUM_FLOATS);
|
|
125
|
+
/** 1 world unit = 1 design px over a `designW × designH` space, origin top-left, y down. */
|
|
126
|
+
static ortho2d(designW, designH) {
|
|
127
|
+
return new Camera().setOrtho2d(designW, designH);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Perspective camera at the origin looking down -z. `fovY` in radians; `far` may be
|
|
131
|
+
* `Infinity`. Depth test, depth write and frustum culling are on (`setPerspective` sets them).
|
|
132
|
+
*/
|
|
133
|
+
static perspective(fovY, aspect, near, far) {
|
|
134
|
+
const c = new Camera().setPerspective(fovY, aspect, near, far);
|
|
135
|
+
c.setView(mat4.identity(c.viewM));
|
|
136
|
+
return c;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Switch to the 2D preset over `designW × designH` (resets `screen` to that space; keeps the
|
|
140
|
+
* 2D controls). Depth flags are left as they are.
|
|
141
|
+
*/
|
|
142
|
+
setOrtho2d(designW, designH) {
|
|
143
|
+
this.designW = designW;
|
|
144
|
+
this.designH = designH;
|
|
145
|
+
this.projSource = 'ortho2d';
|
|
146
|
+
this.viewSource = 'view2d';
|
|
147
|
+
const s = this.screen;
|
|
148
|
+
s.x = 0;
|
|
149
|
+
s.y = 0;
|
|
150
|
+
s.width = designW;
|
|
151
|
+
s.height = designH;
|
|
152
|
+
return this.touch();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Replace the projection with a perspective one (radians; `far` may be `Infinity`) and
|
|
156
|
+
* configure the camera the way `Camera.perspective` does: `depthTest`, `depthWrite` and
|
|
157
|
+
* `cull` on (ws/camera-ergo). The view is untouched, so `cam.setPerspective(...)` on a
|
|
158
|
+
* default camera renders like `Camera.perspective(...)`; `setProjection` stays raw.
|
|
159
|
+
*/
|
|
160
|
+
setPerspective(fovY, aspect, near, far) {
|
|
161
|
+
mat4.perspective(this.projM, fovY, aspect, near, far);
|
|
162
|
+
this.projSource = 'custom';
|
|
163
|
+
this.depthTest = true;
|
|
164
|
+
this.depthWrite = true;
|
|
165
|
+
this.cull = true;
|
|
166
|
+
return this.touch();
|
|
167
|
+
}
|
|
168
|
+
/** Replace the projection matrix (copied). Raw: no depth or cull flag changes. */
|
|
169
|
+
setProjection(m) {
|
|
170
|
+
mat4.copy(this.projM, m);
|
|
171
|
+
this.projSource = 'custom';
|
|
172
|
+
return this.touch();
|
|
173
|
+
}
|
|
174
|
+
/** Replace the view matrix (copied). The 2D controls stop applying until `setOrtho2d`. */
|
|
175
|
+
setView(m) {
|
|
176
|
+
if (m !== this.viewM)
|
|
177
|
+
mat4.copy(this.viewM, m);
|
|
178
|
+
this.viewSource = 'custom';
|
|
179
|
+
return this.touch();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Replace the view matrix (copied); the same as `setView`, named for an XR eye whose
|
|
183
|
+
* `XRView.transform.inverse.matrix` is handed over as-is each frame (ws/xr).
|
|
184
|
+
*/
|
|
185
|
+
setViewMatrix(m) {
|
|
186
|
+
return this.setView(m);
|
|
187
|
+
}
|
|
188
|
+
/** Place the camera at `eye` looking at `target` (`up` defaults to +y). */
|
|
189
|
+
lookAt(eye, target, up = UP) {
|
|
190
|
+
mat4.lookAt(this.viewM, eye, target, up);
|
|
191
|
+
this.viewSource = 'custom';
|
|
192
|
+
return this.touch();
|
|
193
|
+
}
|
|
194
|
+
// ------------------------------------------------------------------ 2D controls
|
|
195
|
+
/** 2D pan (design px): the world point at the view centre is `designW/2 + x`. */
|
|
196
|
+
get x() {
|
|
197
|
+
return this._x;
|
|
198
|
+
}
|
|
199
|
+
set x(v) {
|
|
200
|
+
if (v !== this._x) {
|
|
201
|
+
this._x = v;
|
|
202
|
+
this.touch2d();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** 2D pan (design px). */
|
|
206
|
+
get y() {
|
|
207
|
+
return this._y;
|
|
208
|
+
}
|
|
209
|
+
set y(v) {
|
|
210
|
+
if (v !== this._y) {
|
|
211
|
+
this._y = v;
|
|
212
|
+
this.touch2d();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/** 2D zoom about the view centre. */
|
|
216
|
+
get zoom() {
|
|
217
|
+
return this._zoom;
|
|
218
|
+
}
|
|
219
|
+
set zoom(v) {
|
|
220
|
+
if (v !== this._zoom) {
|
|
221
|
+
this._zoom = v;
|
|
222
|
+
this.touch2d();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/** 2D view rotation about the view centre, radians (the view turns clockwise, the world counter-clockwise). */
|
|
226
|
+
get rotation() {
|
|
227
|
+
return this._rotation;
|
|
228
|
+
}
|
|
229
|
+
set rotation(v) {
|
|
230
|
+
if (v !== this._rotation) {
|
|
231
|
+
this._rotation = v;
|
|
232
|
+
this.touch2d();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Frame the world rect `rect` (z = 0) into `viewport` (screen units; default `screen`),
|
|
237
|
+
* contained and centred, with rotation reset. Needs the 2D view (`ortho2d`); for the
|
|
238
|
+
* world space a layout leaves, convert `layout.freeRect` to screen units first.
|
|
239
|
+
*/
|
|
240
|
+
fitRect(rect, viewport = this.screen) {
|
|
241
|
+
if (this.projSource !== 'ortho2d') {
|
|
242
|
+
throw new Error('Camera.fitRect needs the ortho2d preset');
|
|
243
|
+
}
|
|
244
|
+
const s = this.screen;
|
|
245
|
+
const W = this.designW;
|
|
246
|
+
const H = this.designH;
|
|
247
|
+
// The viewport in design px (the space the 2D view maps into).
|
|
248
|
+
const kx = W / s.width;
|
|
249
|
+
const ky = H / s.height;
|
|
250
|
+
const vw = viewport.width * kx;
|
|
251
|
+
const vh = viewport.height * ky;
|
|
252
|
+
const vcx = (viewport.x - s.x) * kx + vw / 2;
|
|
253
|
+
const vcy = (viewport.y - s.y) * ky + vh / 2;
|
|
254
|
+
const zoom = Math.min(vw / rect.width, vh / rect.height);
|
|
255
|
+
if (!(zoom > 0) || !Number.isFinite(zoom))
|
|
256
|
+
return this;
|
|
257
|
+
this.viewSource = 'view2d';
|
|
258
|
+
this._rotation = 0;
|
|
259
|
+
this._zoom = zoom;
|
|
260
|
+
// A world point p lands on W/2 + zoom (p - cx); put the rect centre on the viewport centre.
|
|
261
|
+
this._x = rect.x + rect.width / 2 - (vcx - W / 2) / zoom - W / 2;
|
|
262
|
+
this._y = rect.y + rect.height / 2 - (vcy - H / 2) / zoom - H / 2;
|
|
263
|
+
return this.touch();
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* `fitRect` into the part of the surface a layout leaves free: `free` is in CSS px relative to
|
|
267
|
+
* the surface's parent (`ui.layout.freeRect`), `surface.rect` is where the canvas sits in the
|
|
268
|
+
* same CSS px (`Surface.rect`); the free rect is mapped onto `screen` (its share of the canvas)
|
|
269
|
+
* and the world rect is fitted into that. Allocates nothing.
|
|
270
|
+
*/
|
|
271
|
+
fitFreeRect(rect, free, surface) {
|
|
272
|
+
const r = surface.rect;
|
|
273
|
+
if (!(r.width > 0) || !(r.height > 0) || !(free.width > 0) || !(free.height > 0))
|
|
274
|
+
return this;
|
|
275
|
+
const s = this.screen;
|
|
276
|
+
const kx = s.width / r.width;
|
|
277
|
+
const ky = s.height / r.height;
|
|
278
|
+
freeScratch.x = s.x + (free.x - r.x) * kx;
|
|
279
|
+
freeScratch.y = s.y + (free.y - r.y) * ky;
|
|
280
|
+
freeScratch.width = free.width * kx;
|
|
281
|
+
freeScratch.height = free.height * ky;
|
|
282
|
+
return this.fitRect(rect, freeScratch);
|
|
283
|
+
}
|
|
284
|
+
// ------------------------------------------------------------------ matrices
|
|
285
|
+
/** World → view. Read-only; change it with the 2D controls, `setView` or `lookAt`. */
|
|
286
|
+
get view() {
|
|
287
|
+
this.update();
|
|
288
|
+
return this.viewM;
|
|
289
|
+
}
|
|
290
|
+
/** View → clip. Read-only; change it with a preset or `setProjection`. */
|
|
291
|
+
get projection() {
|
|
292
|
+
this.update();
|
|
293
|
+
return this.projM;
|
|
294
|
+
}
|
|
295
|
+
/** World → clip (`projection × view`). Read-only. */
|
|
296
|
+
get viewProjection() {
|
|
297
|
+
this.update();
|
|
298
|
+
return this.viewProjM;
|
|
299
|
+
}
|
|
300
|
+
/** The eye position in world space (from the inverse view). Read-only. */
|
|
301
|
+
get position() {
|
|
302
|
+
this.update();
|
|
303
|
+
if (this.posDirty) {
|
|
304
|
+
this.posDirty = false;
|
|
305
|
+
if (mat4.invert(this.invViewM, this.viewM)) {
|
|
306
|
+
this.pos[0] = this.invViewM[12];
|
|
307
|
+
this.pos[1] = this.invViewM[13];
|
|
308
|
+
this.pos[2] = this.invViewM[14];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return this.pos;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Clip → world (`viewProjection⁻¹`), column-major like `viewProj`; cached and recomputed
|
|
315
|
+
* lazily after any view or projection change. Identity when `viewProjection` is singular.
|
|
316
|
+
* Read-only.
|
|
317
|
+
*/
|
|
318
|
+
get invViewProj() {
|
|
319
|
+
this.update();
|
|
320
|
+
if (this.invDirty) {
|
|
321
|
+
this.invDirty = false;
|
|
322
|
+
if (!mat4.invert(this.invViewProjM, this.viewProjM))
|
|
323
|
+
mat4.identity(this.invViewProjM);
|
|
324
|
+
}
|
|
325
|
+
return this.invViewProjM;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Offset the projection by `(x, y)` pixels of the current target (a TAA sample sequence):
|
|
329
|
+
* `viewProjection` and `invViewProj` carry it, `previousViewProj` and the frustum never do.
|
|
330
|
+
* Zero by default. The renderer applies it only when its post processor declares
|
|
331
|
+
* `wantsJitter` (and never through the 2D `ortho2d` projection), so a page without one
|
|
332
|
+
* draws exactly as before. +x moves the image right, +y down.
|
|
333
|
+
*/
|
|
334
|
+
setJitter(x, y) {
|
|
335
|
+
if (x === this.jitterX && y === this.jitterY)
|
|
336
|
+
return this;
|
|
337
|
+
this.jitterX = x;
|
|
338
|
+
this.jitterY = y;
|
|
339
|
+
if (this.jitterW > 0)
|
|
340
|
+
this.touch();
|
|
341
|
+
return this;
|
|
342
|
+
}
|
|
343
|
+
/** `setJitter(0, 0)`. */
|
|
344
|
+
clearJitter() {
|
|
345
|
+
return this.setJitter(0, 0);
|
|
346
|
+
}
|
|
347
|
+
/** The jitter set by `setJitter`, in pixels: `[x, y]`. */
|
|
348
|
+
get jitter() {
|
|
349
|
+
return [this.jitterX, this.jitterY];
|
|
350
|
+
}
|
|
351
|
+
/** `jitter` into `out` (no allocation): the pixels applied, `0, 0` when not applied. */
|
|
352
|
+
getJitter(out) {
|
|
353
|
+
const on = this.jitterW > 0 && this.projSource !== 'ortho2d';
|
|
354
|
+
out[0] = on ? this.jitterX : 0;
|
|
355
|
+
out[1] = on ? this.jitterY : 0;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* The target size the jitter applies against (0 × 0 ignores it). Engine-internal: the
|
|
359
|
+
* renderer sets it per view from the viewport when the post processor wants jitter.
|
|
360
|
+
*/
|
|
361
|
+
setJitterTarget(width, height) {
|
|
362
|
+
if (width === this.jitterW && height === this.jitterH)
|
|
363
|
+
return;
|
|
364
|
+
this.jitterW = width;
|
|
365
|
+
this.jitterH = height;
|
|
366
|
+
if (this.jitterX !== 0 || this.jitterY !== 0)
|
|
367
|
+
this.touch();
|
|
368
|
+
}
|
|
369
|
+
/** The clip-space offset the current jitter adds: `[dx, dy]` (0 when not applied). */
|
|
370
|
+
jitterClip(out) {
|
|
371
|
+
const on = this.jitterW > 0 && this.projSource !== 'ortho2d';
|
|
372
|
+
out[0] = on ? (2 * this.jitterX) / this.jitterW : 0;
|
|
373
|
+
out[1] = on ? (-2 * this.jitterY) / this.jitterH : 0;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Move the (unjittered) `viewProjection` and `view` seen by the last call into
|
|
377
|
+
* `previousViewProj` and `previousView`, and remember the current ones for the next call.
|
|
378
|
+
* Engine-internal: the renderer calls it at the start of each view, before reading the
|
|
379
|
+
* camera, so a post pass sees last frame's matrices beside this frame's. The first call
|
|
380
|
+
* (a camera's first view) sets previous = current: no motion.
|
|
381
|
+
*/
|
|
382
|
+
recordHistory() {
|
|
383
|
+
this.update();
|
|
384
|
+
if (this.hasHistory) {
|
|
385
|
+
this.previousViewProj.set(this.historyViewProjM);
|
|
386
|
+
this.previousView.set(this.historyViewM);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
this.previousViewProj.set(this.steadyViewProjM);
|
|
390
|
+
this.previousView.set(this.viewM);
|
|
391
|
+
this.hasHistory = true;
|
|
392
|
+
}
|
|
393
|
+
this.historyViewProjM.set(this.steadyViewProjM);
|
|
394
|
+
this.historyViewM.set(this.viewM);
|
|
395
|
+
}
|
|
396
|
+
/** Is a draw with layer mask `mask` seen by this camera? */
|
|
397
|
+
sees(mask) {
|
|
398
|
+
return (this.layers & mask) !== 0;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* View-space depth of a world point: its distance along the view axis, positive in front of
|
|
402
|
+
* the eye. Reads the view matrix's third row and negates it (`perspective` and `lookAt`
|
|
403
|
+
* look down -z). `ortho2d` looks down +z, so there it is `-worldZ` at rest. Allocates nothing.
|
|
404
|
+
*/
|
|
405
|
+
viewZ(x, y, z = 0) {
|
|
406
|
+
const v = this.view;
|
|
407
|
+
return -(v[2] * x + v[6] * y + v[10] * z + v[14]);
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* `worldToScreen` for many points without the per-point object: reads `count` points from
|
|
411
|
+
* `points` (x, y, z at `i * stride`; `stride` ≥ 3, default 3, `count` defaults to what fits)
|
|
412
|
+
* and writes screen x, screen y and clip depth as 3 floats per point at `out[i * 3]`, the
|
|
413
|
+
* same values `worldToScreen` returns. Returns how many landed inside the viewport: in
|
|
414
|
+
* front of the eye, within `screen` and with clip depth in 0..1. Allocates nothing.
|
|
415
|
+
*/
|
|
416
|
+
projectMany(points, out, count = Math.floor(points.length / 3), stride = 3) {
|
|
417
|
+
const vp = this.viewProjection;
|
|
418
|
+
const s = this.screen;
|
|
419
|
+
const n = Math.min(count, Math.floor(points.length / stride), Math.floor(out.length / 3));
|
|
420
|
+
let inside = 0;
|
|
421
|
+
for (let i = 0; i < n; i++) {
|
|
422
|
+
const p = i * stride;
|
|
423
|
+
const w = mat4.transformPoint(tmp, vp, points[p], points[p + 1], points[p + 2]);
|
|
424
|
+
const cx = tmp[0];
|
|
425
|
+
const cy = tmp[1];
|
|
426
|
+
const cz = tmp[2];
|
|
427
|
+
const o = i * 3;
|
|
428
|
+
out[o] = s.x + ((cx + 1) / 2) * s.width;
|
|
429
|
+
out[o + 1] = s.y + ((1 - cy) / 2) * s.height;
|
|
430
|
+
out[o + 2] = cz;
|
|
431
|
+
if (w > 0 && cx >= -1 && cx <= 1 && cy >= -1 && cy <= 1 && cz >= 0 && cz <= 1)
|
|
432
|
+
inside++;
|
|
433
|
+
}
|
|
434
|
+
return inside;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* The eight world-space corners of the view frustum into `out` (24 floats, x y z each):
|
|
438
|
+
* near plane first, then far, each as bottom-left, bottom-right, top-right, top-left in
|
|
439
|
+
* clip space (clip depth 0 then 1, through `invViewProj`). With `far = Infinity` the far
|
|
440
|
+
* corners have no finite position (w = 0) and come back as the undivided homogeneous
|
|
441
|
+
* coordinates, which are directions. Allocates nothing.
|
|
442
|
+
*/
|
|
443
|
+
frustumCorners(out) {
|
|
444
|
+
const inv = this.invViewProj;
|
|
445
|
+
let o = 0;
|
|
446
|
+
for (let d = 0; d <= 1; d++) {
|
|
447
|
+
for (let k = 0; k < 4; k++) {
|
|
448
|
+
mat4.transformPoint(tmp, inv, CORNER_X[k], CORNER_Y[k], d);
|
|
449
|
+
out[o++] = tmp[0];
|
|
450
|
+
out[o++] = tmp[1];
|
|
451
|
+
out[o++] = tmp[2];
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return out;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* World point → screen units (see `screen`); `z` of the result is clip depth (0 near, 1
|
|
458
|
+
* far). Pass `out` to avoid allocating.
|
|
459
|
+
*/
|
|
460
|
+
worldToScreen(x, y, z = 0, out = { x: 0, y: 0, z: 0 }) {
|
|
461
|
+
mat4.transformPoint(tmp, this.viewProjection, x, y, z);
|
|
462
|
+
const s = this.screen;
|
|
463
|
+
out.x = s.x + ((tmp[0] + 1) / 2) * s.width;
|
|
464
|
+
out.y = s.y + ((1 - tmp[1]) / 2) * s.height;
|
|
465
|
+
out.z = tmp[2];
|
|
466
|
+
return out;
|
|
467
|
+
}
|
|
468
|
+
screenToWorld(sx, sy, depthOrOut = 0, out = { x: 0, y: 0, z: 0 }) {
|
|
469
|
+
if (typeof depthOrOut === 'object')
|
|
470
|
+
return this.screenToPlane(sx, sy, depthOrOut);
|
|
471
|
+
const inv = this.invViewProj;
|
|
472
|
+
const s = this.screen;
|
|
473
|
+
const nx = ((sx - s.x) / s.width) * 2 - 1;
|
|
474
|
+
const ny = 1 - ((sy - s.y) / s.height) * 2;
|
|
475
|
+
mat4.transformPoint(tmp, inv, nx, ny, depthOrOut);
|
|
476
|
+
out.x = tmp[0];
|
|
477
|
+
out.y = tmp[1];
|
|
478
|
+
out.z = tmp[2];
|
|
479
|
+
return out;
|
|
480
|
+
}
|
|
481
|
+
/** The pick ray through a screen point, met with the plane z = 0. No allocation. */
|
|
482
|
+
screenToPlane(sx, sy, out) {
|
|
483
|
+
this.screenToWorld(sx, sy, 1, out);
|
|
484
|
+
const fx = out.x;
|
|
485
|
+
const fy = out.y;
|
|
486
|
+
const fz = out.z;
|
|
487
|
+
this.screenToWorld(sx, sy, 0, out);
|
|
488
|
+
const dz = fz - out.z;
|
|
489
|
+
if (Math.abs(dz) < 1e-12)
|
|
490
|
+
return out;
|
|
491
|
+
const t = -out.z / dz;
|
|
492
|
+
out.x += (fx - out.x) * t;
|
|
493
|
+
out.y += (fy - out.y) * t;
|
|
494
|
+
out.z = 0;
|
|
495
|
+
return out;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Write the WGSL `EngineCamera` block (`CAMERA_BLOCK_FLOATS` floats) at float offset `o`:
|
|
499
|
+
* `view`, `proj`, `view_proj`, `camera_pos`, `viewport` (target px: x, y, w, h),
|
|
500
|
+
* `view_index`, at `CAMERA_INV_VIEW_PROJ_OFFSET` `inv_view_proj`, then `prev_view_proj`,
|
|
501
|
+
* `prev_view` and `jitter` (clip dx, dy, pixel x, y). `u32` must view the same buffer as
|
|
502
|
+
* `f32`. Engine-internal.
|
|
503
|
+
*/
|
|
504
|
+
writeBlock(f32, u32, o, viewport, viewIndex = this.viewIndex) {
|
|
505
|
+
this.update();
|
|
506
|
+
f32.set(this.viewM, o);
|
|
507
|
+
f32.set(this.projM, o + 16);
|
|
508
|
+
f32.set(this.viewProjM, o + 32);
|
|
509
|
+
const p = this.position;
|
|
510
|
+
f32[o + 48] = p[0];
|
|
511
|
+
f32[o + 49] = p[1];
|
|
512
|
+
f32[o + 50] = p[2];
|
|
513
|
+
f32[o + 51] = 1;
|
|
514
|
+
f32[o + 52] = viewport.x;
|
|
515
|
+
f32[o + 53] = viewport.y;
|
|
516
|
+
f32[o + 54] = viewport.width;
|
|
517
|
+
f32[o + 55] = viewport.height;
|
|
518
|
+
u32[o + 56] = viewIndex >>> 0;
|
|
519
|
+
f32[o + 57] = 0;
|
|
520
|
+
f32[o + 58] = 0;
|
|
521
|
+
f32[o + 59] = 0;
|
|
522
|
+
f32.set(this.invViewProj, o + CAMERA_INV_VIEW_PROJ_OFFSET);
|
|
523
|
+
f32.set(this.previousViewProj, o + CAMERA_PREV_VIEW_PROJ_OFFSET);
|
|
524
|
+
f32.set(this.previousView, o + CAMERA_PREV_VIEW_OFFSET);
|
|
525
|
+
const j = o + CAMERA_JITTER_OFFSET;
|
|
526
|
+
this.jitterClip(jitterScratch);
|
|
527
|
+
f32[j] = jitterScratch[0];
|
|
528
|
+
f32[j + 1] = jitterScratch[1];
|
|
529
|
+
f32[j + 2] = this.jitterW > 0 ? this.jitterX : 0;
|
|
530
|
+
f32[j + 3] = this.jitterW > 0 ? this.jitterY : 0;
|
|
531
|
+
for (let i = CAMERA_JITTER_OFFSET + 4; i < CAMERA_BLOCK_FLOATS; i++)
|
|
532
|
+
f32[o + i] = 0;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* The six frustum planes of `viewProjection` as `FRUSTUM_FLOATS` (24) floats: left, right,
|
|
536
|
+
* bottom, top, near, far, each `(a, b, c, d)` with a unit normal pointing inside, so a point
|
|
537
|
+
* `p` is inside when `a·x + b·y + c·z + d >= 0` on every plane and a sphere of radius `r`
|
|
538
|
+
* is outside when that is `< -r` on any. Cached like the matrices. An infinite far plane
|
|
539
|
+
* (`far = Infinity`) is all zeros but `d > 0`, which never rejects. Read-only.
|
|
540
|
+
*/
|
|
541
|
+
get frustum() {
|
|
542
|
+
this.update();
|
|
543
|
+
if (this.frustumDirty) {
|
|
544
|
+
this.frustumDirty = false;
|
|
545
|
+
extractFrustum(this.frustumM, this.steadyViewProjM);
|
|
546
|
+
}
|
|
547
|
+
return this.frustumM;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Is a world-space sphere at least partly inside the frustum? `radius` 0 tests a point. Pure
|
|
551
|
+
* plane tests; nothing allocates.
|
|
552
|
+
*/
|
|
553
|
+
seesSphere(x, y, z, radius) {
|
|
554
|
+
const f = this.frustum;
|
|
555
|
+
for (let i = 0; i < FRUSTUM_FLOATS; i += 4) {
|
|
556
|
+
if (f[i] * x + f[i + 1] * y + f[i + 2] * z + f[i + 3] < -radius)
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
559
|
+
return true;
|
|
560
|
+
}
|
|
561
|
+
// ------------------------------------------------------------------ internals
|
|
562
|
+
touch2d() {
|
|
563
|
+
if (this.viewSource === 'view2d')
|
|
564
|
+
this.touch();
|
|
565
|
+
}
|
|
566
|
+
touch() {
|
|
567
|
+
this.dirty = true;
|
|
568
|
+
this.invDirty = true;
|
|
569
|
+
this.posDirty = true;
|
|
570
|
+
this.frustumDirty = true;
|
|
571
|
+
return this;
|
|
572
|
+
}
|
|
573
|
+
update() {
|
|
574
|
+
if (!this.dirty)
|
|
575
|
+
return;
|
|
576
|
+
this.dirty = false;
|
|
577
|
+
const W = this.designW;
|
|
578
|
+
const H = this.designH;
|
|
579
|
+
if (this.viewSource === 'view2d') {
|
|
580
|
+
mat4.view2d(this.viewM, this._x, this._y, this._zoom, this._rotation, W, H);
|
|
581
|
+
}
|
|
582
|
+
if (this.projSource === 'ortho2d') {
|
|
583
|
+
// y down; z into the screen: ±ORTHO2D_HALF_DEPTH → clip 0..1 (near at -D, far at +D).
|
|
584
|
+
mat4.ortho(this.projM, 0, W, H, 0, ORTHO2D_HALF_DEPTH, -ORTHO2D_HALF_DEPTH);
|
|
585
|
+
}
|
|
586
|
+
if (this.viewSource === 'view2d' && this.projSource === 'ortho2d') {
|
|
587
|
+
ortho2dViewProj(this.viewProjM, this._x, this._y, this._zoom, this._rotation, W, H);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
mat4.multiply(this.viewProjM, this.projM, this.viewM);
|
|
591
|
+
}
|
|
592
|
+
this.steadyViewProjM.set(this.viewProjM);
|
|
593
|
+
if (this.jitterW > 0 &&
|
|
594
|
+
this.projSource !== 'ortho2d' &&
|
|
595
|
+
(this.jitterX !== 0 || this.jitterY !== 0)) {
|
|
596
|
+
// A clip-space translation by (dx, dy): add dx·w, dy·w to x and y, column by column.
|
|
597
|
+
const dx = (2 * this.jitterX) / this.jitterW;
|
|
598
|
+
const dy = (-2 * this.jitterY) / this.jitterH;
|
|
599
|
+
const m = this.viewProjM;
|
|
600
|
+
for (let c = 0; c < 16; c += 4) {
|
|
601
|
+
m[c] = m[c] + dx * m[c + 3];
|
|
602
|
+
m[c + 1] = m[c + 1] + dy * m[c + 3];
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
const jitterScratch = [0, 0];
|
|
608
|
+
const UP = [0, 1, 0];
|
|
609
|
+
/** Clip-space corner order for `frustumCorners`: bottom-left, bottom-right, top-right, top-left. */
|
|
610
|
+
const CORNER_X = [-1, 1, 1, -1];
|
|
611
|
+
const CORNER_Y = [-1, -1, 1, 1];
|
|
612
|
+
/**
|
|
613
|
+
* `ortho × view2d` in one step, with the same arithmetic the renderer used before the matrix
|
|
614
|
+
* camera, so the 2D path stays bit-identical (multiplying the two f32 matrices would round
|
|
615
|
+
* differently).
|
|
616
|
+
*/
|
|
617
|
+
function ortho2dViewProj(g, x, y, zoom, rotation, W, H) {
|
|
618
|
+
const sx = 2 / W;
|
|
619
|
+
const sy = 2 / H;
|
|
620
|
+
const c = Math.cos(-rotation) * zoom;
|
|
621
|
+
const s = Math.sin(-rotation) * zoom;
|
|
622
|
+
const cx = W / 2 + x;
|
|
623
|
+
const cy = H / 2 + y;
|
|
624
|
+
g.fill(0);
|
|
625
|
+
g[0] = c * sx;
|
|
626
|
+
g[1] = -s * sy;
|
|
627
|
+
g[4] = -s * sx;
|
|
628
|
+
g[5] = -c * sy;
|
|
629
|
+
g[10] = 1 / (2 * ORTHO2D_HALF_DEPTH);
|
|
630
|
+
g[12] = -c * sx * cx + s * sx * cy;
|
|
631
|
+
g[13] = s * sy * cx + c * sy * cy;
|
|
632
|
+
g[14] = 0.5;
|
|
633
|
+
g[15] = 1;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* The six planes of a column-major clip matrix `m` (WebGPU clip space: `-w ≤ x, y ≤ w`,
|
|
637
|
+
* `0 ≤ z ≤ w`) into `out` (24 floats), normals normalised and pointing inside. Row `i` of `m`
|
|
638
|
+
* is `(m[i], m[4+i], m[8+i], m[12+i])`; the planes are `row3 ± row0`, `row3 ± row1`, `row2`
|
|
639
|
+
* and `row3 - row2`. A degenerate plane (an infinite far plane) is left unnormalised.
|
|
640
|
+
*/
|
|
641
|
+
function extractFrustum(out, m) {
|
|
642
|
+
const r0 = 0;
|
|
643
|
+
const r1 = 1;
|
|
644
|
+
const r2 = 2;
|
|
645
|
+
const r3 = 3;
|
|
646
|
+
plane(out, 0, m, r3, r0, 1);
|
|
647
|
+
plane(out, 4, m, r3, r0, -1);
|
|
648
|
+
plane(out, 8, m, r3, r1, 1);
|
|
649
|
+
plane(out, 12, m, r3, r1, -1);
|
|
650
|
+
plane(out, 16, m, r2, r2, 0);
|
|
651
|
+
plane(out, 20, m, r3, r2, -1);
|
|
652
|
+
}
|
|
653
|
+
/** `out[o..o+4) = normalise(row a + sign · row b)` of `m`; `sign` 0 copies row `a`. */
|
|
654
|
+
function plane(out, o, m, a, b, sign) {
|
|
655
|
+
let x = m[a] + sign * m[b];
|
|
656
|
+
let y = m[4 + a] + sign * m[4 + b];
|
|
657
|
+
let z = m[8 + a] + sign * m[8 + b];
|
|
658
|
+
let d = m[12 + a] + sign * m[12 + b];
|
|
659
|
+
const len = Math.hypot(x, y, z);
|
|
660
|
+
if (len > 0) {
|
|
661
|
+
const k = 1 / len;
|
|
662
|
+
x *= k;
|
|
663
|
+
y *= k;
|
|
664
|
+
z *= k;
|
|
665
|
+
d *= k;
|
|
666
|
+
}
|
|
667
|
+
out[o] = x;
|
|
668
|
+
out[o + 1] = y;
|
|
669
|
+
out[o + 2] = z;
|
|
670
|
+
out[o + 3] = d;
|
|
671
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colour helpers. The renderer works in **linear** RGB (HDR allowed, values > 1 glow).
|
|
3
|
+
* Author colours as sRGB hex and convert with `hex()`.
|
|
4
|
+
*/
|
|
5
|
+
export type RGBA = [number, number, number, number];
|
|
6
|
+
export declare function srgbToLinear(c: number): number;
|
|
7
|
+
export declare function linearToSrgb(c: number): number;
|
|
8
|
+
/**
|
|
9
|
+
* Parse `#rgb`, `#rrggbb` or `#rrggbbaa` (sRGB) into linear RGBA, optionally scaled by
|
|
10
|
+
* `intensity` (HDR multiplier on RGB, alpha untouched).
|
|
11
|
+
*/
|
|
12
|
+
export declare function hex(value: string, intensity?: number): RGBA;
|
|
13
|
+
/** Linear RGBA from components (no conversion). */
|
|
14
|
+
export declare function rgba(r: number, g: number, b: number, a?: number): RGBA;
|
|
15
|
+
/** Scale RGB by `k` (alpha untouched). Returns a new array. */
|
|
16
|
+
export declare function scaleRgb(c: ArrayLike<number>, k: number): RGBA;
|