@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,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Root motion: split the root node's travel out of a clip so the character animates in place
|
|
3
|
+
* while the game moves its transform by the extracted motion, without guessing at speeds.
|
|
4
|
+
*
|
|
5
|
+
* `extractRootMotion` returns two clips sharing keyframe times: `clip` (in place: the root keeps
|
|
6
|
+
* its first-frame translation and yaw) and `motion` (the root's translation relative to the
|
|
7
|
+
* first frame and its yaw about +Y relative to the first frame). At every keyframe
|
|
8
|
+
* `motion + clip` (translation) and `motion · clip` (rotation) equal the original root transform.
|
|
9
|
+
* `applyRootMotionDelta` samples `motion` at two times and gives the game a position delta in the
|
|
10
|
+
* root's own heading frame plus a yaw delta, handling the loop wrap. Yaw is about +Y (Y up).
|
|
11
|
+
*/
|
|
12
|
+
import { sampleChannel } from './clip.js';
|
|
13
|
+
import { quatMultiply, quatNormalize } from './quat.js';
|
|
14
|
+
function copyChannel(ch) {
|
|
15
|
+
return {
|
|
16
|
+
node: ch.node,
|
|
17
|
+
path: ch.path,
|
|
18
|
+
interpolation: ch.interpolation,
|
|
19
|
+
times: new Float32Array(ch.times),
|
|
20
|
+
values: new Float32Array(ch.values),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const q = new Float32Array(4);
|
|
24
|
+
const twist = new Float32Array(4);
|
|
25
|
+
const twist0 = new Float32Array(4);
|
|
26
|
+
const conj0 = new Float32Array(4);
|
|
27
|
+
const rem = new Float32Array(4);
|
|
28
|
+
/** Yaw (rotation about +Y) part of `src[o..o+4)` into `out`, by swing-twist decomposition. */
|
|
29
|
+
function yawOf(out, src, o) {
|
|
30
|
+
out[0] = 0;
|
|
31
|
+
out[1] = src[o + 1];
|
|
32
|
+
out[2] = 0;
|
|
33
|
+
out[3] = src[o + 3];
|
|
34
|
+
quatNormalize(out, 0);
|
|
35
|
+
}
|
|
36
|
+
/** Flip `dst` so it sits on the same hemisphere as the key before it (no slerp flips). */
|
|
37
|
+
function hemisphere(dst, o) {
|
|
38
|
+
if (o < 4)
|
|
39
|
+
return;
|
|
40
|
+
const dot = dst[o] * dst[o - 4] +
|
|
41
|
+
dst[o + 1] * dst[o - 3] +
|
|
42
|
+
dst[o + 2] * dst[o - 2] +
|
|
43
|
+
dst[o + 3] * dst[o - 1];
|
|
44
|
+
if (dot < 0)
|
|
45
|
+
for (let i = 0; i < 4; i++)
|
|
46
|
+
dst[o + i] = -dst[o + i];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Split `clip` into an in-place clip and a motion clip for `rootNode`. Channels are copied, never
|
|
50
|
+
* aliased; the two clips share keyframe times with the input. Translation keeps `CUBICSPLINE`
|
|
51
|
+
* tangents (the in-place side's extracted components get zero tangents); a `CUBICSPLINE`
|
|
52
|
+
* rotation channel on the root comes back as two `LINEAR` channels over its key values. Clips
|
|
53
|
+
* with no root channel yield an empty `motion`. Allocates; call at load time.
|
|
54
|
+
*/
|
|
55
|
+
export function extractRootMotion(clip, rootNode, opts) {
|
|
56
|
+
const planar = opts?.planar ?? false;
|
|
57
|
+
const stay = [];
|
|
58
|
+
const move = [];
|
|
59
|
+
for (const ch of clip.channels) {
|
|
60
|
+
if (ch.node !== rootNode || ch.path === 'scale' || ch.path === 'weights') {
|
|
61
|
+
stay.push(copyChannel(ch));
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (ch.path === 'translation') {
|
|
65
|
+
const cubic = ch.interpolation === 'CUBICSPLINE';
|
|
66
|
+
const stride = cubic ? 9 : 3;
|
|
67
|
+
const valueOff = cubic ? 3 : 0;
|
|
68
|
+
const n = ch.times.length;
|
|
69
|
+
const s = new Float32Array(ch.values.length);
|
|
70
|
+
const m = new Float32Array(ch.values.length);
|
|
71
|
+
const src = ch.values;
|
|
72
|
+
for (let k = 0; k < n; k++) {
|
|
73
|
+
const base = k * stride;
|
|
74
|
+
for (let part = 0; part < (cubic ? 3 : 1); part++) {
|
|
75
|
+
const isValue = cubic ? part === 1 : true;
|
|
76
|
+
for (let comp = 0; comp < 3; comp++) {
|
|
77
|
+
const idx = base + part * 3 + comp;
|
|
78
|
+
const extract = !planar || comp !== 1;
|
|
79
|
+
const first = isValue ? src[valueOff + comp] : 0;
|
|
80
|
+
if (extract) {
|
|
81
|
+
m[idx] = src[idx] - first;
|
|
82
|
+
s[idx] = first;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
m[idx] = 0;
|
|
86
|
+
s[idx] = src[idx];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
stay.push({ ...copyChannel(ch), values: s });
|
|
92
|
+
move.push({ ...copyChannel(ch), values: m });
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// Rotation.
|
|
96
|
+
if (planar) {
|
|
97
|
+
stay.push(copyChannel(ch));
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const cubic = ch.interpolation === 'CUBICSPLINE';
|
|
101
|
+
const n = ch.times.length;
|
|
102
|
+
const s = new Float32Array(n * 4);
|
|
103
|
+
const m = new Float32Array(n * 4);
|
|
104
|
+
const src = ch.values;
|
|
105
|
+
if (n > 0)
|
|
106
|
+
yawOf(twist0, src, cubic ? 4 : 0);
|
|
107
|
+
conj0[0] = -twist0[0];
|
|
108
|
+
conj0[1] = -twist0[1];
|
|
109
|
+
conj0[2] = -twist0[2];
|
|
110
|
+
conj0[3] = twist0[3];
|
|
111
|
+
for (let k = 0; k < n; k++) {
|
|
112
|
+
const vo = cubic ? k * 12 + 4 : k * 4;
|
|
113
|
+
for (let i = 0; i < 4; i++)
|
|
114
|
+
q[i] = src[vo + i];
|
|
115
|
+
yawOf(twist, q, 0);
|
|
116
|
+
// q = twist · rem → rem = conj(twist) · q.
|
|
117
|
+
rem[0] = -twist[0];
|
|
118
|
+
rem[1] = -twist[1];
|
|
119
|
+
rem[2] = -twist[2];
|
|
120
|
+
rem[3] = twist[3];
|
|
121
|
+
quatMultiply(rem, 0, rem, 0, q, 0);
|
|
122
|
+
// motion = twist · conj(twist0); stay = twist0 · rem; motion · stay = twist · rem = q.
|
|
123
|
+
quatMultiply(m, k * 4, twist, 0, conj0, 0);
|
|
124
|
+
quatMultiply(s, k * 4, twist0, 0, rem, 0);
|
|
125
|
+
quatNormalize(m, k * 4);
|
|
126
|
+
quatNormalize(s, k * 4);
|
|
127
|
+
hemisphere(m, k * 4);
|
|
128
|
+
hemisphere(s, k * 4);
|
|
129
|
+
}
|
|
130
|
+
const interpolation = cubic ? 'LINEAR' : ch.interpolation;
|
|
131
|
+
const times = new Float32Array(ch.times);
|
|
132
|
+
stay.push({ node: ch.node, path: 'rotation', interpolation, times, values: s });
|
|
133
|
+
move.push({
|
|
134
|
+
node: ch.node,
|
|
135
|
+
path: 'rotation',
|
|
136
|
+
interpolation,
|
|
137
|
+
times: new Float32Array(times),
|
|
138
|
+
values: m,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const inPlace = { name: clip.name, duration: clip.duration, channels: stay };
|
|
142
|
+
if (clip.events)
|
|
143
|
+
inPlace.events = clip.events.map((e) => ({ ...e }));
|
|
144
|
+
return {
|
|
145
|
+
clip: inPlace,
|
|
146
|
+
motion: { name: `${clip.name}.motion`, duration: clip.duration, channels: move },
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const p0 = new Float32Array(3);
|
|
150
|
+
const p1 = new Float32Array(3);
|
|
151
|
+
const r0 = new Float32Array(4);
|
|
152
|
+
const r1 = new Float32Array(4);
|
|
153
|
+
const seg = new Float32Array(4);
|
|
154
|
+
/** Yaw angle (radians, about +Y) of a rotation channel at `t`, 0 without a channel. */
|
|
155
|
+
function yawAt(ch, t, out) {
|
|
156
|
+
if (!ch)
|
|
157
|
+
return 0;
|
|
158
|
+
sampleChannel(ch, t, out, 0);
|
|
159
|
+
return 2 * Math.atan2(out[1], out[3]);
|
|
160
|
+
}
|
|
161
|
+
function wrapAngle(a) {
|
|
162
|
+
let r = a % (2 * Math.PI);
|
|
163
|
+
if (r > Math.PI)
|
|
164
|
+
r -= 2 * Math.PI;
|
|
165
|
+
else if (r <= -Math.PI)
|
|
166
|
+
r += 2 * Math.PI;
|
|
167
|
+
return r;
|
|
168
|
+
}
|
|
169
|
+
/** One forward segment `t0 → t1` into `out`: the position delta in the heading frame at `t0`, yaw delta. */
|
|
170
|
+
function segment(tr, rot, t0, t1, out) {
|
|
171
|
+
if (tr) {
|
|
172
|
+
sampleChannel(tr, t0, p0, 0);
|
|
173
|
+
sampleChannel(tr, t1, p1, 0);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
p0.fill(0);
|
|
177
|
+
p1.fill(0);
|
|
178
|
+
}
|
|
179
|
+
const y0 = yawAt(rot, t0, r0);
|
|
180
|
+
const y1 = yawAt(rot, t1, r1);
|
|
181
|
+
const dx = p1[0] - p0[0];
|
|
182
|
+
const dy = p1[1] - p0[1];
|
|
183
|
+
const dz = p1[2] - p0[2];
|
|
184
|
+
// Undo the heading at t0: rotate by -y0 about +Y.
|
|
185
|
+
const c = Math.cos(-y0);
|
|
186
|
+
const s = Math.sin(-y0);
|
|
187
|
+
out[0] = dx * c + dz * s;
|
|
188
|
+
out[1] = dy;
|
|
189
|
+
out[2] = -dx * s + dz * c;
|
|
190
|
+
out[3] = wrapAngle(y1 - y0);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* The root's motion between `t0` and `t1` of a `motion` clip, into `outDelta` (4 floats):
|
|
194
|
+
* `[dx, dy, dz]` is the position delta expressed in the root's heading frame at `t0` (the motion
|
|
195
|
+
* clip's yaw there, zero at the first key: rotate the delta by the character's own heading, then
|
|
196
|
+
* add it to the position) and `[3]` is the yaw delta in radians about +Y (add it to the
|
|
197
|
+
* heading). When `t1 < t0` the clip has looped: the
|
|
198
|
+
* delta runs `t0 → duration` then `0 → t1`. Returns `outDelta`. No allocation.
|
|
199
|
+
*/
|
|
200
|
+
export function applyRootMotionDelta(motionClip, t0, t1, outDelta) {
|
|
201
|
+
let tr = null;
|
|
202
|
+
let rot = null;
|
|
203
|
+
for (const ch of motionClip.channels) {
|
|
204
|
+
if (ch.path === 'translation' && !tr)
|
|
205
|
+
tr = ch;
|
|
206
|
+
else if (ch.path === 'rotation' && !rot)
|
|
207
|
+
rot = ch;
|
|
208
|
+
}
|
|
209
|
+
if (t1 >= t0) {
|
|
210
|
+
segment(tr, rot, t0, t1, outDelta);
|
|
211
|
+
return outDelta;
|
|
212
|
+
}
|
|
213
|
+
segment(tr, rot, t0, motionClip.duration, outDelta);
|
|
214
|
+
segment(tr, rot, 0, t1, seg);
|
|
215
|
+
// The second segment is in the heading frame at 0; bring it into the frame at t0 by the yaw
|
|
216
|
+
// the first segment turned.
|
|
217
|
+
const c = Math.cos(outDelta[3]);
|
|
218
|
+
const s = Math.sin(outDelta[3]);
|
|
219
|
+
outDelta[0] = outDelta[0] + seg[0] * c + seg[2] * s;
|
|
220
|
+
outDelta[1] = outDelta[1] + seg[1];
|
|
221
|
+
outDelta[2] = outDelta[2] - seg[0] * s + seg[2] * c;
|
|
222
|
+
outDelta[3] = wrapAngle(outDelta[3] + seg[3]);
|
|
223
|
+
return outDelta;
|
|
224
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `skinPose`: one call per frame from an animated pose to a skin palette slot (ws/assets-4).
|
|
3
|
+
* It runs the steps a skinned character repeats every frame: advance the clips (`update(dt)`,
|
|
4
|
+
* when a source and a `dt` are given), resolve the pose into node world matrices
|
|
5
|
+
* (`poseToWorld`), multiply each joint by its inverse bind matrix (`skinMatrices`) and write
|
|
6
|
+
* the result straight into the palette's staging (`palette.write(slot)`). The world matrices
|
|
7
|
+
* live in a scratch array cached per skeleton and are returned, for sockets and IK. Nothing
|
|
8
|
+
* allocates after the first call for a skeleton.
|
|
9
|
+
*/
|
|
10
|
+
import type { SkinPalette } from '../render/skin.js';
|
|
11
|
+
import { type Pose, type Skeleton } from './pose.js';
|
|
12
|
+
/**
|
|
13
|
+
* What `skinPose` reads a pose from: an object that owns a pose and advances it, such as an
|
|
14
|
+
* `AnimationMixer`. An `AnimGraph` drives a mixer; pass that mixer (after `graph.update`) or
|
|
15
|
+
* its `pose`.
|
|
16
|
+
*/
|
|
17
|
+
export interface SkinPoseSource {
|
|
18
|
+
readonly pose: Pose;
|
|
19
|
+
update(dt: number): void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The part of a `SkinPalette` that `skinPose` uses: a slot's staging block to fill in place.
|
|
23
|
+
* When the target also has a `jointCount` (a `SkinPalette` does), `skinPose` checks it first.
|
|
24
|
+
*/
|
|
25
|
+
export type SkinPoseTarget = Pick<SkinPalette, 'write'>;
|
|
26
|
+
/**
|
|
27
|
+
* Pose one skinned instance into `palette` slot `slot` and return the node world matrices
|
|
28
|
+
* (3×4 row-major, `WORLD_NODE_FLOATS` per node). `source` is a `Pose`, used as it is, or a
|
|
29
|
+
* `SkinPoseSource` (an `AnimationMixer`): with `dt` given, `source.update(dt)` runs first;
|
|
30
|
+
* without it the source's current pose is used, so a game that updated a graph, or edited the
|
|
31
|
+
* pose with IK, passes no `dt`. The result equals `update(dt)` → `poseToWorld` →
|
|
32
|
+
* `skinMatrices(skeleton, world, palette.write(slot))` bit for bit. Throws when the
|
|
33
|
+
* skeleton has more joints than the palette's slot holds (ws/render-11; a `SkinPalette` is
|
|
34
|
+
* checked by `jointCount` before the source advances). The returned array is shared per skeleton and rewritten by the next call for the same skeleton: read it (sockets,
|
|
35
|
+
* `attachTransform`) before posing another instance of that skeleton, or pass your own
|
|
36
|
+
* `world`. Call `palette.flush()` once per frame after posing every slot. Allocates only the
|
|
37
|
+
* scratch array on the first call for a skeleton without `world`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function skinPose(skeleton: Skeleton, source: Pose | SkinPoseSource, palette: SkinPoseTarget, slot?: number, dt?: number, world?: Float32Array): Float32Array;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jointCount, poseToWorld, skinMatrices, WORLD_NODE_FLOATS, } from './pose.js';
|
|
2
|
+
const worldCache = new WeakMap();
|
|
3
|
+
/**
|
|
4
|
+
* Pose one skinned instance into `palette` slot `slot` and return the node world matrices
|
|
5
|
+
* (3×4 row-major, `WORLD_NODE_FLOATS` per node). `source` is a `Pose`, used as it is, or a
|
|
6
|
+
* `SkinPoseSource` (an `AnimationMixer`): with `dt` given, `source.update(dt)` runs first;
|
|
7
|
+
* without it the source's current pose is used, so a game that updated a graph, or edited the
|
|
8
|
+
* pose with IK, passes no `dt`. The result equals `update(dt)` → `poseToWorld` →
|
|
9
|
+
* `skinMatrices(skeleton, world, palette.write(slot))` bit for bit. Throws when the
|
|
10
|
+
* skeleton has more joints than the palette's slot holds (ws/render-11; a `SkinPalette` is
|
|
11
|
+
* checked by `jointCount` before the source advances). The returned array is shared per skeleton and rewritten by the next call for the same skeleton: read it (sockets,
|
|
12
|
+
* `attachTransform`) before posing another instance of that skeleton, or pass your own
|
|
13
|
+
* `world`. Call `palette.flush()` once per frame after posing every slot. Allocates only the
|
|
14
|
+
* scratch array on the first call for a skeleton without `world`.
|
|
15
|
+
*/
|
|
16
|
+
export function skinPose(skeleton, source, palette, slot = 0, dt, world) {
|
|
17
|
+
const joints = jointCount(skeleton);
|
|
18
|
+
const has = palette.jointCount;
|
|
19
|
+
if (has !== undefined && has < joints)
|
|
20
|
+
throw tooSmall(joints, has, slot);
|
|
21
|
+
let pose;
|
|
22
|
+
if (source instanceof Float32Array) {
|
|
23
|
+
pose = source;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (dt !== undefined)
|
|
27
|
+
source.update(dt);
|
|
28
|
+
pose = source.pose;
|
|
29
|
+
}
|
|
30
|
+
const out = world ?? worldFor(skeleton);
|
|
31
|
+
poseToWorld(skeleton, pose, out);
|
|
32
|
+
const block = palette.write(slot);
|
|
33
|
+
// A target without `jointCount`: its block's length says how many joints it holds.
|
|
34
|
+
// One 3×4 matrix (`WORLD_NODE_FLOATS`) per joint, as `skinMatrices` writes them.
|
|
35
|
+
if (block.length < joints * WORLD_NODE_FLOATS) {
|
|
36
|
+
throw tooSmall(joints, Math.floor(block.length / WORLD_NODE_FLOATS), slot);
|
|
37
|
+
}
|
|
38
|
+
skinMatrices(skeleton, out, block);
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
function tooSmall(joints, has, slot) {
|
|
42
|
+
return new Error(`skinPose: the skeleton has ${joints} joints but the palette holds ${has} per slot ` +
|
|
43
|
+
`(slot ${slot}); make the SkinPalette with joints: ${joints} or more`);
|
|
44
|
+
}
|
|
45
|
+
function worldFor(skeleton) {
|
|
46
|
+
const floats = skeleton.parents.length * WORLD_NODE_FLOATS;
|
|
47
|
+
let w = worldCache.get(skeleton);
|
|
48
|
+
if (!w || w.length !== floats) {
|
|
49
|
+
w = new Float32Array(floats);
|
|
50
|
+
worldCache.set(skeleton, w);
|
|
51
|
+
}
|
|
52
|
+
return w;
|
|
53
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attachment sockets: a joint plus a fixed local offset. Each frame a socket yields the world 3×4
|
|
3
|
+
* of whatever rides it (a second mesh, a particle emitter, a `Transform`), so cosmetics follow an
|
|
4
|
+
* animated skeleton with no code in the game beyond "attach here".
|
|
5
|
+
*
|
|
6
|
+
* `socketWorld = instanceWorld · world[joint] · offset`, all 3×4 row-major (`render/transform.ts`
|
|
7
|
+
* layout); nothing here allocates after `createSocket`. The only tie to `render/` is the
|
|
8
|
+
* `Transform` type `attachTransform` writes into, imported as a type.
|
|
9
|
+
*/
|
|
10
|
+
import type { Transform } from '../render/transform.js';
|
|
11
|
+
import { type Skeleton } from './pose.js';
|
|
12
|
+
/** A joint (node index into the world array `poseToWorld` writes) and a 3×4 offset in joint space. */
|
|
13
|
+
export interface Socket {
|
|
14
|
+
joint: number;
|
|
15
|
+
/** 12 floats, 3×4 row-major: `T · R · S` of `SocketLocal`. */
|
|
16
|
+
offset: Float32Array;
|
|
17
|
+
}
|
|
18
|
+
/** The offset of a socket in joint space; every part defaults to the identity. */
|
|
19
|
+
export interface SocketLocal {
|
|
20
|
+
/** `[x, y, z]` along the joint's axes. */
|
|
21
|
+
position?: ArrayLike<number>;
|
|
22
|
+
/** Unit quaternion `[x, y, z, w]`. */
|
|
23
|
+
rotation?: ArrayLike<number>;
|
|
24
|
+
/** `[x, y, z]`, or one number for all three. */
|
|
25
|
+
scale?: ArrayLike<number> | number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a socket on `joint` (a node index, or a name resolved through `Skeleton.names`) with the
|
|
29
|
+
* local offset `local`. Throws when the index is out of range, when a name is given without
|
|
30
|
+
* `names`, or when no node carries that name. Allocates (setup).
|
|
31
|
+
*/
|
|
32
|
+
export declare function createSocket(skeleton: Skeleton, joint: number | string, local?: SocketLocal): Socket;
|
|
33
|
+
/**
|
|
34
|
+
* `out = instanceWorld · worldPose[joint] · offset`: the socket's world 3×4 for the node world
|
|
35
|
+
* matrices `worldPose` (`poseToWorld` output) and the skeleton instance's own world matrix
|
|
36
|
+
* (`null` when the pose is already in world space, or the attached transform has the instance as
|
|
37
|
+
* its parent). Writes 12 floats at `out[0..12)` and returns `out`; `out` may not alias
|
|
38
|
+
* `worldPose`. No allocation.
|
|
39
|
+
*/
|
|
40
|
+
export declare function socketWorld(socket: Socket, worldPose: Float32Array, instanceWorld: Float32Array | null, out: Float32Array): Float32Array;
|
|
41
|
+
/**
|
|
42
|
+
* Write `socketWorld(...)` into `transform` (`Transform.setMatrix`), so the attached mesh draws
|
|
43
|
+
* through `frame.mesh(mesh, material, transform)` like any other. The transform should have no
|
|
44
|
+
* parent, or the skeleton instance's transform as its parent with `instanceWorld` `null`. No
|
|
45
|
+
* allocation.
|
|
46
|
+
*/
|
|
47
|
+
export declare function attachTransform(socket: Socket, worldPose: Float32Array, instanceWorld: Float32Array | null, transform: Transform): void;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { multiplyAffine, POSE_NODE_FLOATS, WORLD_NODE_FLOATS, writeNodeMatrix, } from './pose.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build a socket on `joint` (a node index, or a name resolved through `Skeleton.names`) with the
|
|
4
|
+
* local offset `local`. Throws when the index is out of range, when a name is given without
|
|
5
|
+
* `names`, or when no node carries that name. Allocates (setup).
|
|
6
|
+
*/
|
|
7
|
+
export function createSocket(skeleton, joint, local) {
|
|
8
|
+
const n = skeleton.parents.length;
|
|
9
|
+
let index;
|
|
10
|
+
if (typeof joint === 'string') {
|
|
11
|
+
const names = skeleton.names;
|
|
12
|
+
if (!names)
|
|
13
|
+
throw new Error(`createSocket: joint '${joint}' by name, but the skeleton has no names`);
|
|
14
|
+
index = names.indexOf(joint);
|
|
15
|
+
if (index < 0)
|
|
16
|
+
throw new Error(`createSocket: no node named '${joint}'`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
index = joint;
|
|
20
|
+
}
|
|
21
|
+
if (!Number.isInteger(index) || index < 0 || index >= n) {
|
|
22
|
+
throw new Error(`createSocket: joint ${index} is not a node (${n} nodes)`);
|
|
23
|
+
}
|
|
24
|
+
const node = new Float32Array(POSE_NODE_FLOATS);
|
|
25
|
+
node[6] = 1;
|
|
26
|
+
node[7] = node[8] = node[9] = 1;
|
|
27
|
+
if (local) {
|
|
28
|
+
const p = local.position;
|
|
29
|
+
if (p) {
|
|
30
|
+
node[0] = p[0];
|
|
31
|
+
node[1] = p[1];
|
|
32
|
+
node[2] = p[2];
|
|
33
|
+
}
|
|
34
|
+
const r = local.rotation;
|
|
35
|
+
if (r) {
|
|
36
|
+
const len = Math.hypot(r[0], r[1], r[2], r[3]) || 1;
|
|
37
|
+
node[3] = r[0] / len;
|
|
38
|
+
node[4] = r[1] / len;
|
|
39
|
+
node[5] = r[2] / len;
|
|
40
|
+
node[6] = r[3] / len;
|
|
41
|
+
}
|
|
42
|
+
const s = local.scale;
|
|
43
|
+
if (typeof s === 'number') {
|
|
44
|
+
node[7] = node[8] = node[9] = s;
|
|
45
|
+
}
|
|
46
|
+
else if (s) {
|
|
47
|
+
node[7] = s[0];
|
|
48
|
+
node[8] = s[1];
|
|
49
|
+
node[9] = s[2];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const offset = new Float32Array(WORLD_NODE_FLOATS);
|
|
53
|
+
writeNodeMatrix(offset, 0, node, 0);
|
|
54
|
+
return { joint: index, offset };
|
|
55
|
+
}
|
|
56
|
+
const scratch = new Float32Array(WORLD_NODE_FLOATS);
|
|
57
|
+
/**
|
|
58
|
+
* `out = instanceWorld · worldPose[joint] · offset`: the socket's world 3×4 for the node world
|
|
59
|
+
* matrices `worldPose` (`poseToWorld` output) and the skeleton instance's own world matrix
|
|
60
|
+
* (`null` when the pose is already in world space, or the attached transform has the instance as
|
|
61
|
+
* its parent). Writes 12 floats at `out[0..12)` and returns `out`; `out` may not alias
|
|
62
|
+
* `worldPose`. No allocation.
|
|
63
|
+
*/
|
|
64
|
+
export function socketWorld(socket, worldPose, instanceWorld, out) {
|
|
65
|
+
const jo = socket.joint * WORLD_NODE_FLOATS;
|
|
66
|
+
if (instanceWorld) {
|
|
67
|
+
multiplyAffine(scratch, 0, worldPose, jo, socket.offset, 0);
|
|
68
|
+
multiplyAffine(out, 0, instanceWorld, 0, scratch, 0);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
multiplyAffine(out, 0, worldPose, jo, socket.offset, 0);
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
const attached = new Float32Array(WORLD_NODE_FLOATS);
|
|
76
|
+
/**
|
|
77
|
+
* Write `socketWorld(...)` into `transform` (`Transform.setMatrix`), so the attached mesh draws
|
|
78
|
+
* through `frame.mesh(mesh, material, transform)` like any other. The transform should have no
|
|
79
|
+
* parent, or the skeleton instance's transform as its parent with `instanceWorld` `null`. No
|
|
80
|
+
* allocation.
|
|
81
|
+
*/
|
|
82
|
+
export function attachTransform(socket, worldPose, instanceWorld, transform) {
|
|
83
|
+
transform.setMatrix(socketWorld(socket, worldPose, instanceWorld, attached));
|
|
84
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type Pose, type Skeleton } from './pose.js';
|
|
2
|
+
/** A sphere in instance space. */
|
|
3
|
+
export interface SpringSphere {
|
|
4
|
+
center: ArrayLike<number>;
|
|
5
|
+
radius: number;
|
|
6
|
+
}
|
|
7
|
+
/** A capsule in instance space: the segment `a`–`b` swept by `radius`. */
|
|
8
|
+
export interface SpringCapsule {
|
|
9
|
+
a: ArrayLike<number>;
|
|
10
|
+
b: ArrayLike<number>;
|
|
11
|
+
radius: number;
|
|
12
|
+
}
|
|
13
|
+
export type SpringCollider = SpringSphere | SpringCapsule;
|
|
14
|
+
export interface SpringChainDesc {
|
|
15
|
+
/** The first joint of the chain; it is pinned to the animation and only turns. */
|
|
16
|
+
root: number;
|
|
17
|
+
/** The last joint: the chain is every node on the path from `root` down to `tip`. */
|
|
18
|
+
tip?: number;
|
|
19
|
+
/** Or the joints in order, parent before child, as an alternative to `tip`. */
|
|
20
|
+
joints?: ArrayLike<number>;
|
|
21
|
+
/** Spring toward the sampled position, per second². Default 80. */
|
|
22
|
+
stiffness?: number;
|
|
23
|
+
/** Velocity decay per second. Default 6. */
|
|
24
|
+
damping?: number;
|
|
25
|
+
/** Instance-space gravity, units per second². Default `[0, -9.8, 0]`. */
|
|
26
|
+
gravity?: ArrayLike<number>;
|
|
27
|
+
/** 0..1: the fraction of the sampled pose's own motion the joints inherit. Default 0. */
|
|
28
|
+
drag?: number;
|
|
29
|
+
/** Joint radius for collisions. Default 0. */
|
|
30
|
+
radius?: number;
|
|
31
|
+
/** Largest angle (radians) a bone may swing away from its sampled direction. Default π. */
|
|
32
|
+
limitAngle?: number;
|
|
33
|
+
/** Colliders, read every frame (mutate them in place to move them). */
|
|
34
|
+
collide?: SpringCollider[];
|
|
35
|
+
/** Largest sub-step; a frame is split into equal steps no longer than this. Default 1/120. */
|
|
36
|
+
maxDt?: number;
|
|
37
|
+
/** A root jump beyond this (instance units) in one frame shifts the chain with no velocity. Default 1. */
|
|
38
|
+
teleportDistance?: number;
|
|
39
|
+
}
|
|
40
|
+
/** A spring chain with its state, from `createSpringChain`. */
|
|
41
|
+
export interface SpringChain {
|
|
42
|
+
readonly joints: Int16Array;
|
|
43
|
+
stiffness: number;
|
|
44
|
+
damping: number;
|
|
45
|
+
readonly gravity: Float32Array;
|
|
46
|
+
drag: number;
|
|
47
|
+
radius: number;
|
|
48
|
+
limitAngle: number;
|
|
49
|
+
collide: SpringCollider[];
|
|
50
|
+
maxDt: number;
|
|
51
|
+
teleportDistance: number;
|
|
52
|
+
/** Simulated joint positions in instance space, 3 per joint, after the last update. */
|
|
53
|
+
readonly positions: Float32Array;
|
|
54
|
+
/** The sampled joint positions in instance space, 3 per joint, from the last update. */
|
|
55
|
+
readonly animated: Float32Array;
|
|
56
|
+
/** Forget the state: the next update starts the chain at the sampled pose with no velocity. */
|
|
57
|
+
reset(): void;
|
|
58
|
+
/** @internal */
|
|
59
|
+
readonly prev: Float32Array;
|
|
60
|
+
/** @internal */
|
|
61
|
+
readonly animPrev: Float32Array;
|
|
62
|
+
/** @internal */
|
|
63
|
+
readonly lengths: Float32Array;
|
|
64
|
+
/** @internal */
|
|
65
|
+
started: boolean;
|
|
66
|
+
}
|
|
67
|
+
/** Validate and allocate; call once. */
|
|
68
|
+
export declare function createSpringChain(skeleton: Skeleton, desc: SpringChainDesc): SpringChain;
|
|
69
|
+
/**
|
|
70
|
+
* Step the chain by `dt` (split into sub-steps of at most `maxDt`) and rewrite the chain's
|
|
71
|
+
* rotations in `pose`. Call after sampling and `poseToWorld`, before skinning. No allocation.
|
|
72
|
+
*/
|
|
73
|
+
export declare function updateSpringChain(pose: Pose, skeleton: Skeleton, worldPose: Float32Array, chain: SpringChain, instanceWorld: Float32Array | null, dt: number): void;
|