@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,519 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mesh simplification for LODs and collision proxies (ws/geom-3): quadric-error edge collapse
|
|
3
|
+
* (Garland–Heckbert) over the welded position set.
|
|
4
|
+
*
|
|
5
|
+
* Every vertex is first mapped to a *position* (vertices within `WELD_EPSILON` on each axis are one
|
|
6
|
+
* position, so a uv seam or a hard edge does not split the surface). Each position accumulates
|
|
7
|
+
* the plane quadrics of its triangles (and, on an open border, of a plane through the border
|
|
8
|
+
* edge perpendicular to its triangle). An edge collapse moves one position onto the other
|
|
9
|
+
* (half-edge collapse: the kept position is an original vertex, so the result never leaves the
|
|
10
|
+
* input's vertex set, and its uv, normal, colour and tangent lanes are the kept vertex's). The
|
|
11
|
+
* candidates sit in a binary heap ordered by cost, then by the two position indices, so two runs
|
|
12
|
+
* over the same input make the same collapses in the same order and the output is byte-identical.
|
|
13
|
+
* A collapse is refused when it would flip or flatten a triangle, or pinch the surface (the link
|
|
14
|
+
* condition: the two positions share exactly the neighbours of the triangles on their edge).
|
|
15
|
+
*
|
|
16
|
+
* CPU, build-time: arrays are sized from the input; nothing here runs per frame.
|
|
17
|
+
*/
|
|
18
|
+
import { VERTEX_LAYOUT_3D, VERTEX_LAYOUT_3D_TANGENT } from '../render/mesh.js';
|
|
19
|
+
import { computeBounds, createIndices } from './geometry.js';
|
|
20
|
+
import { weld } from './ops.js';
|
|
21
|
+
/** Positions closer than this on every axis are one (a UV sphere's seam is off by ~1e-16). */
|
|
22
|
+
const WELD_EPSILON = 1e-6;
|
|
23
|
+
function floatsOf(g) {
|
|
24
|
+
if (g.layout !== VERTEX_LAYOUT_3D && g.layout !== VERTEX_LAYOUT_3D_TANGENT) {
|
|
25
|
+
throw new Error(`geom: simplifyGeometry needs a 3D vertex layout, got '${g.layout.name}'`);
|
|
26
|
+
}
|
|
27
|
+
return g.layout.floats;
|
|
28
|
+
}
|
|
29
|
+
/** Adds the plane `n · p + d = 0` (unit n), times `w`, into the quadric at `q[o..o+10)`. */
|
|
30
|
+
function addPlane(q, o, a, b, c, d, w) {
|
|
31
|
+
q[o] = q[o] + w * a * a;
|
|
32
|
+
q[o + 1] = q[o + 1] + w * a * b;
|
|
33
|
+
q[o + 2] = q[o + 2] + w * a * c;
|
|
34
|
+
q[o + 3] = q[o + 3] + w * a * d;
|
|
35
|
+
q[o + 4] = q[o + 4] + w * b * b;
|
|
36
|
+
q[o + 5] = q[o + 5] + w * b * c;
|
|
37
|
+
q[o + 6] = q[o + 6] + w * b * d;
|
|
38
|
+
q[o + 7] = q[o + 7] + w * c * c;
|
|
39
|
+
q[o + 8] = q[o + 8] + w * c * d;
|
|
40
|
+
q[o + 9] = q[o + 9] + w * d * d;
|
|
41
|
+
}
|
|
42
|
+
/** `p^T (Qa + Qb) p` for p = (x, y, z, 1). */
|
|
43
|
+
function quadricCost(q, a, b, x, y, z) {
|
|
44
|
+
const A = a * 10;
|
|
45
|
+
const B = b * 10;
|
|
46
|
+
const s = (k) => q[A + k] + q[B + k];
|
|
47
|
+
const e = s(0) * x * x +
|
|
48
|
+
2 * s(1) * x * y +
|
|
49
|
+
2 * s(2) * x * z +
|
|
50
|
+
2 * s(3) * x +
|
|
51
|
+
s(4) * y * y +
|
|
52
|
+
2 * s(5) * y * z +
|
|
53
|
+
2 * s(6) * y +
|
|
54
|
+
s(7) * z * z +
|
|
55
|
+
2 * s(8) * z +
|
|
56
|
+
s(9);
|
|
57
|
+
// Rounding can leave a tiny negative (or NaN on a degenerate quadric): clamp to 0.
|
|
58
|
+
if (e > 0)
|
|
59
|
+
return e;
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A min-heap of collapse candidates in parallel arrays: cost, the removed and kept positions,
|
|
64
|
+
* and the versions of both when the entry was made (a later collapse that changes either makes
|
|
65
|
+
* the entry stale). Ordered by cost, then removed index, then kept index: deterministic.
|
|
66
|
+
*/
|
|
67
|
+
class CandidateHeap {
|
|
68
|
+
cost = [];
|
|
69
|
+
rem = [];
|
|
70
|
+
keep = [];
|
|
71
|
+
vr = [];
|
|
72
|
+
vk = [];
|
|
73
|
+
lanes = [this.cost, this.rem, this.keep, this.vr, this.vk];
|
|
74
|
+
get size() {
|
|
75
|
+
return this.cost.length;
|
|
76
|
+
}
|
|
77
|
+
less(i, j) {
|
|
78
|
+
const ci = this.cost[i];
|
|
79
|
+
const cj = this.cost[j];
|
|
80
|
+
if (ci !== cj)
|
|
81
|
+
return ci < cj;
|
|
82
|
+
if (this.rem[i] !== this.rem[j])
|
|
83
|
+
return this.rem[i] < this.rem[j];
|
|
84
|
+
return this.keep[i] < this.keep[j];
|
|
85
|
+
}
|
|
86
|
+
swap(i, j) {
|
|
87
|
+
for (const a of this.lanes) {
|
|
88
|
+
const t = a[i];
|
|
89
|
+
a[i] = a[j];
|
|
90
|
+
a[j] = t;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
push(cost, rem, keep, vr, vk) {
|
|
94
|
+
let i = this.cost.length;
|
|
95
|
+
this.cost.push(cost);
|
|
96
|
+
this.rem.push(rem);
|
|
97
|
+
this.keep.push(keep);
|
|
98
|
+
this.vr.push(vr);
|
|
99
|
+
this.vk.push(vk);
|
|
100
|
+
while (i > 0) {
|
|
101
|
+
const p = (i - 1) >> 1;
|
|
102
|
+
if (!this.less(i, p))
|
|
103
|
+
break;
|
|
104
|
+
this.swap(i, p);
|
|
105
|
+
i = p;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Moves the top entry to the end of the arrays and pops it there; read it with `last*`. */
|
|
109
|
+
pop() {
|
|
110
|
+
const n = this.cost.length - 1;
|
|
111
|
+
this.swap(0, n);
|
|
112
|
+
let i = 0;
|
|
113
|
+
for (;;) {
|
|
114
|
+
const l = 2 * i + 1;
|
|
115
|
+
const r = l + 1;
|
|
116
|
+
let m = i;
|
|
117
|
+
if (l < n && this.less(l, m))
|
|
118
|
+
m = l;
|
|
119
|
+
if (r < n && this.less(r, m))
|
|
120
|
+
m = r;
|
|
121
|
+
if (m === i)
|
|
122
|
+
break;
|
|
123
|
+
this.swap(i, m);
|
|
124
|
+
i = m;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Drops the entry `pop` moved to the end. */
|
|
128
|
+
drop() {
|
|
129
|
+
this.cost.pop();
|
|
130
|
+
this.rem.pop();
|
|
131
|
+
this.keep.pop();
|
|
132
|
+
this.vr.pop();
|
|
133
|
+
this.vk.pop();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Simplify `g` by quadric-error edge collapse to `targetTriangles` (or `targetRatio` of its
|
|
138
|
+
* triangles), stopping early at `errorLimit`. Returns a new geometry in `g`'s layout (welded, its
|
|
139
|
+
* indices 16-bit when they fit) and the largest error made. `g` is untouched. Takes
|
|
140
|
+
* `VERTEX_LAYOUT_3D` or `VERTEX_LAYOUT_3D_TANGENT`.
|
|
141
|
+
*/
|
|
142
|
+
export function simplifyGeometry(g, opts = {}) {
|
|
143
|
+
const F = floatsOf(g);
|
|
144
|
+
const src = g.vertices;
|
|
145
|
+
const vCount = src.length / F;
|
|
146
|
+
const idx = g.indices;
|
|
147
|
+
const triIn = Math.floor(idx.length / 3);
|
|
148
|
+
const target = Math.max(0, Math.floor(opts.targetTriangles ?? Math.floor((opts.targetRatio ?? 0.5) * triIn)));
|
|
149
|
+
const limit = opts.errorLimit ?? Number.POSITIVE_INFINITY;
|
|
150
|
+
const limit2 = limit * limit;
|
|
151
|
+
// ---------------------------------------------------------------- the position set
|
|
152
|
+
// Vertices within WELD_EPSILON on every axis are one position (a spatial hash over cells of
|
|
153
|
+
// that size hashed to an int, the 27 neighbouring cells searched, every candidate compared),
|
|
154
|
+
// the first vertex's coordinates kept.
|
|
155
|
+
const posOf = new Int32Array(vCount);
|
|
156
|
+
const cells = new Map();
|
|
157
|
+
const cellKey = (cx, cy, cz) => Math.imul(cx | 0, 73856093) ^ Math.imul(cy | 0, 19349663) ^ Math.imul(cz | 0, 83492791);
|
|
158
|
+
const px = [];
|
|
159
|
+
/** First vertex of each position, and whether its vertices disagree (a seam). */
|
|
160
|
+
const firstVert = [];
|
|
161
|
+
const seam = [];
|
|
162
|
+
const inv = 1 / WELD_EPSILON;
|
|
163
|
+
for (let i = 0; i < vCount; i++) {
|
|
164
|
+
const o = i * F;
|
|
165
|
+
const x = src[o];
|
|
166
|
+
const y = src[o + 1];
|
|
167
|
+
const z = src[o + 2];
|
|
168
|
+
const cx = Math.round(x * inv);
|
|
169
|
+
const cy = Math.round(y * inv);
|
|
170
|
+
const cz = Math.round(z * inv);
|
|
171
|
+
let p;
|
|
172
|
+
search: for (let dx = -1; dx <= 1; dx++) {
|
|
173
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
174
|
+
for (let dz = -1; dz <= 1; dz++) {
|
|
175
|
+
const bucket = cells.get(cellKey(cx + dx, cy + dy, cz + dz));
|
|
176
|
+
if (!bucket)
|
|
177
|
+
continue;
|
|
178
|
+
for (const q of bucket) {
|
|
179
|
+
if (Math.abs(px[q * 3] - x) <= WELD_EPSILON &&
|
|
180
|
+
Math.abs(px[q * 3 + 1] - y) <= WELD_EPSILON &&
|
|
181
|
+
Math.abs(px[q * 3 + 2] - z) <= WELD_EPSILON) {
|
|
182
|
+
p = q;
|
|
183
|
+
break search;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (p === undefined) {
|
|
190
|
+
p = px.length / 3;
|
|
191
|
+
const key = cellKey(cx, cy, cz);
|
|
192
|
+
const bucket = cells.get(key);
|
|
193
|
+
if (bucket)
|
|
194
|
+
bucket.push(p);
|
|
195
|
+
else
|
|
196
|
+
cells.set(key, [p]);
|
|
197
|
+
px.push(x, y, z);
|
|
198
|
+
firstVert.push(i);
|
|
199
|
+
seam.push(0);
|
|
200
|
+
}
|
|
201
|
+
else if (!seam[p]) {
|
|
202
|
+
const f = firstVert[p] * F;
|
|
203
|
+
for (let k = 3; k < 8; k++) {
|
|
204
|
+
if (Math.abs(src[f + k] - src[o + k]) > 1e-6) {
|
|
205
|
+
seam[p] = 1;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
posOf[i] = p;
|
|
211
|
+
}
|
|
212
|
+
const P = px.length / 3;
|
|
213
|
+
// ---------------------------------------------------------------- faces and adjacency
|
|
214
|
+
/** Corner vertex indices, three per face; `alive[f]` 0 once collapsed or degenerate. */
|
|
215
|
+
const corner = new Int32Array(triIn * 3);
|
|
216
|
+
const alive = new Uint8Array(triIn);
|
|
217
|
+
const facesOf = Array.from({ length: P }, () => []);
|
|
218
|
+
let live = 0;
|
|
219
|
+
for (let f = 0; f < triIn; f++) {
|
|
220
|
+
const a = idx[f * 3];
|
|
221
|
+
const b = idx[f * 3 + 1];
|
|
222
|
+
const c = idx[f * 3 + 2];
|
|
223
|
+
corner[f * 3] = a;
|
|
224
|
+
corner[f * 3 + 1] = b;
|
|
225
|
+
corner[f * 3 + 2] = c;
|
|
226
|
+
const pa = posOf[a];
|
|
227
|
+
const pb = posOf[b];
|
|
228
|
+
const pc = posOf[c];
|
|
229
|
+
if (pa === pb || pb === pc || pa === pc)
|
|
230
|
+
continue;
|
|
231
|
+
alive[f] = 1;
|
|
232
|
+
live++;
|
|
233
|
+
facesOf[pa].push(f);
|
|
234
|
+
facesOf[pb].push(f);
|
|
235
|
+
facesOf[pc].push(f);
|
|
236
|
+
}
|
|
237
|
+
// ---------------------------------------------------------------- quadrics and borders
|
|
238
|
+
const Q = new Float64Array(P * 10);
|
|
239
|
+
const edgeUse = new Map();
|
|
240
|
+
const edgeFace = new Map();
|
|
241
|
+
const ekey = (a, b) => (a < b ? a * P + b : b * P + a);
|
|
242
|
+
const n3 = new Float64Array(4);
|
|
243
|
+
const faceNormal = (f, out) => {
|
|
244
|
+
const a = posOf[corner[f * 3]] * 3;
|
|
245
|
+
const b = posOf[corner[f * 3 + 1]] * 3;
|
|
246
|
+
const c = posOf[corner[f * 3 + 2]] * 3;
|
|
247
|
+
const ux = px[b] - px[a];
|
|
248
|
+
const uy = px[b + 1] - px[a + 1];
|
|
249
|
+
const uz = px[b + 2] - px[a + 2];
|
|
250
|
+
const vx = px[c] - px[a];
|
|
251
|
+
const vy = px[c + 1] - px[a + 1];
|
|
252
|
+
const vz = px[c + 2] - px[a + 2];
|
|
253
|
+
const nx = uy * vz - uz * vy;
|
|
254
|
+
const ny = uz * vx - ux * vz;
|
|
255
|
+
const nz = ux * vy - uy * vx;
|
|
256
|
+
const len = Math.hypot(nx, ny, nz);
|
|
257
|
+
out[0] = len > 0 ? nx / len : 0;
|
|
258
|
+
out[1] = len > 0 ? ny / len : 0;
|
|
259
|
+
out[2] = len > 0 ? nz / len : 0;
|
|
260
|
+
out[3] = -(out[0] * px[a] + out[1] * px[a + 1] + out[2] * px[a + 2]);
|
|
261
|
+
return len;
|
|
262
|
+
};
|
|
263
|
+
for (let f = 0; f < triIn; f++) {
|
|
264
|
+
if (!alive[f])
|
|
265
|
+
continue;
|
|
266
|
+
if (faceNormal(f, n3) === 0)
|
|
267
|
+
continue;
|
|
268
|
+
for (let k = 0; k < 3; k++) {
|
|
269
|
+
const p = posOf[corner[f * 3 + k]];
|
|
270
|
+
addPlane(Q, p * 10, n3[0], n3[1], n3[2], n3[3], 1);
|
|
271
|
+
const q = posOf[corner[f * 3 + ((k + 1) % 3)]];
|
|
272
|
+
const e = ekey(p, q);
|
|
273
|
+
edgeUse.set(e, (edgeUse.get(e) ?? 0) + 1);
|
|
274
|
+
edgeFace.set(e, f);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
const border = new Uint8Array(P);
|
|
278
|
+
for (const [e, uses] of edgeUse) {
|
|
279
|
+
if (uses !== 1)
|
|
280
|
+
continue;
|
|
281
|
+
const a = Math.floor(e / P);
|
|
282
|
+
const b = e - a * P;
|
|
283
|
+
border[a] = border[b] = 1;
|
|
284
|
+
// A plane through the border edge, perpendicular to its triangle: keeps the rim in place.
|
|
285
|
+
faceNormal(edgeFace.get(e), n3);
|
|
286
|
+
const ex = px[b * 3] - px[a * 3];
|
|
287
|
+
const ey = px[b * 3 + 1] - px[a * 3 + 1];
|
|
288
|
+
const ez = px[b * 3 + 2] - px[a * 3 + 2];
|
|
289
|
+
let mx = ey * n3[2] - ez * n3[1];
|
|
290
|
+
let my = ez * n3[0] - ex * n3[2];
|
|
291
|
+
let mz = ex * n3[1] - ey * n3[0];
|
|
292
|
+
const ml = Math.hypot(mx, my, mz);
|
|
293
|
+
if (ml === 0)
|
|
294
|
+
continue;
|
|
295
|
+
mx /= ml;
|
|
296
|
+
my /= ml;
|
|
297
|
+
mz /= ml;
|
|
298
|
+
const d = -(mx * px[a * 3] + my * px[a * 3 + 1] + mz * px[a * 3 + 2]);
|
|
299
|
+
addPlane(Q, a * 10, mx, my, mz, d, 1);
|
|
300
|
+
addPlane(Q, b * 10, mx, my, mz, d, 1);
|
|
301
|
+
}
|
|
302
|
+
const locked = new Uint8Array(P);
|
|
303
|
+
for (let p = 0; p < P; p++) {
|
|
304
|
+
if ((opts.preserveBorders && border[p]) || (opts.preserveUvSeams && seam[p]))
|
|
305
|
+
locked[p] = 1;
|
|
306
|
+
}
|
|
307
|
+
// ---------------------------------------------------------------- candidates
|
|
308
|
+
const version = new Int32Array(P);
|
|
309
|
+
const dead = new Uint8Array(P);
|
|
310
|
+
const heap = new CandidateHeap();
|
|
311
|
+
const mark = new Int32Array(P);
|
|
312
|
+
let stamp = 0;
|
|
313
|
+
const neighbours = [];
|
|
314
|
+
/** Live neighbour positions of `p` into `neighbours` (each once), stamped in `mark`. */
|
|
315
|
+
const gather = (p) => {
|
|
316
|
+
stamp++;
|
|
317
|
+
neighbours.length = 0;
|
|
318
|
+
for (const f of facesOf[p]) {
|
|
319
|
+
if (!alive[f])
|
|
320
|
+
continue;
|
|
321
|
+
for (let k = 0; k < 3; k++) {
|
|
322
|
+
const q = posOf[corner[f * 3 + k]];
|
|
323
|
+
if (q !== p && mark[q] !== stamp) {
|
|
324
|
+
mark[q] = stamp;
|
|
325
|
+
neighbours.push(q);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
const offer = (rem, keep) => {
|
|
331
|
+
if (locked[rem])
|
|
332
|
+
return;
|
|
333
|
+
if (border[rem] && !border[keep])
|
|
334
|
+
return;
|
|
335
|
+
const cost = quadricCost(Q, rem, keep, px[keep * 3], px[keep * 3 + 1], px[keep * 3 + 2]);
|
|
336
|
+
heap.push(cost, rem, keep, version[rem], version[keep]);
|
|
337
|
+
};
|
|
338
|
+
for (let p = 0; p < P; p++) {
|
|
339
|
+
gather(p);
|
|
340
|
+
for (const q of neighbours)
|
|
341
|
+
offer(p, q);
|
|
342
|
+
}
|
|
343
|
+
// ---------------------------------------------------------------- collapsing
|
|
344
|
+
const nA = new Float64Array(4);
|
|
345
|
+
const nB = new Float64Array(4);
|
|
346
|
+
const remap = new Map();
|
|
347
|
+
let maxCost = 0;
|
|
348
|
+
while (live > target && heap.size > 0) {
|
|
349
|
+
heap.pop();
|
|
350
|
+
const last = heap.size - 1;
|
|
351
|
+
const cost = heap.cost[last];
|
|
352
|
+
const u = heap.rem[last];
|
|
353
|
+
const v = heap.keep[last];
|
|
354
|
+
const stale = dead[u] || dead[v] || heap.vr[last] !== version[u] || heap.vk[last] !== version[v];
|
|
355
|
+
heap.drop();
|
|
356
|
+
if (stale)
|
|
357
|
+
continue;
|
|
358
|
+
if (cost > limit2)
|
|
359
|
+
break;
|
|
360
|
+
// Link condition: the common neighbours of u and v are exactly the far corners of the
|
|
361
|
+
// triangles on edge uv (one on a border, two inside), or the collapse pinches the surface.
|
|
362
|
+
gather(u);
|
|
363
|
+
const uStamp = stamp;
|
|
364
|
+
let shared = 0;
|
|
365
|
+
for (const f of facesOf[u]) {
|
|
366
|
+
if (!alive[f])
|
|
367
|
+
continue;
|
|
368
|
+
for (let k = 0; k < 3; k++)
|
|
369
|
+
if (posOf[corner[f * 3 + k]] === v)
|
|
370
|
+
shared++;
|
|
371
|
+
}
|
|
372
|
+
if (shared === 0)
|
|
373
|
+
continue;
|
|
374
|
+
if (border[u] && shared !== 1)
|
|
375
|
+
continue;
|
|
376
|
+
let common = 0;
|
|
377
|
+
for (const f of facesOf[v]) {
|
|
378
|
+
if (!alive[f])
|
|
379
|
+
continue;
|
|
380
|
+
for (let k = 0; k < 3; k++) {
|
|
381
|
+
const q = posOf[corner[f * 3 + k]];
|
|
382
|
+
if (q !== v && q !== u && mark[q] === uStamp) {
|
|
383
|
+
mark[q] = -1;
|
|
384
|
+
common++;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (common !== shared)
|
|
389
|
+
continue;
|
|
390
|
+
// No surviving triangle around u may flip or collapse to a sliver when u moves to v.
|
|
391
|
+
let ok = true;
|
|
392
|
+
for (const f of facesOf[u]) {
|
|
393
|
+
if (!alive[f])
|
|
394
|
+
continue;
|
|
395
|
+
let hasV = false;
|
|
396
|
+
for (let k = 0; k < 3; k++)
|
|
397
|
+
if (posOf[corner[f * 3 + k]] === v)
|
|
398
|
+
hasV = true;
|
|
399
|
+
if (hasV)
|
|
400
|
+
continue;
|
|
401
|
+
const before = faceNormal(f, nA);
|
|
402
|
+
// Evaluate the moved triangle by swapping u's position for v's in place.
|
|
403
|
+
const ux = px[u * 3];
|
|
404
|
+
const uy = px[u * 3 + 1];
|
|
405
|
+
const uz = px[u * 3 + 2];
|
|
406
|
+
px[u * 3] = px[v * 3];
|
|
407
|
+
px[u * 3 + 1] = px[v * 3 + 1];
|
|
408
|
+
px[u * 3 + 2] = px[v * 3 + 2];
|
|
409
|
+
const after = faceNormal(f, nB);
|
|
410
|
+
px[u * 3] = ux;
|
|
411
|
+
px[u * 3 + 1] = uy;
|
|
412
|
+
px[u * 3 + 2] = uz;
|
|
413
|
+
if (after <= before * 1e-3 || nA[0] * nB[0] + nA[1] * nB[1] + nA[2] * nB[2] < 0.2) {
|
|
414
|
+
ok = false;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (!ok)
|
|
419
|
+
continue;
|
|
420
|
+
// Collapse u into v. The dying triangles map u's corner vertex to v's, so a surviving
|
|
421
|
+
// triangle on the same side of a seam takes the matching vertex of v.
|
|
422
|
+
remap.clear();
|
|
423
|
+
let fallback = -1;
|
|
424
|
+
for (const f of facesOf[u]) {
|
|
425
|
+
if (!alive[f])
|
|
426
|
+
continue;
|
|
427
|
+
let cu = -1;
|
|
428
|
+
let cv = -1;
|
|
429
|
+
for (let k = 0; k < 3; k++) {
|
|
430
|
+
const c = corner[f * 3 + k];
|
|
431
|
+
if (posOf[c] === u)
|
|
432
|
+
cu = c;
|
|
433
|
+
else if (posOf[c] === v)
|
|
434
|
+
cv = c;
|
|
435
|
+
}
|
|
436
|
+
if (cv < 0)
|
|
437
|
+
continue;
|
|
438
|
+
if (!remap.has(cu))
|
|
439
|
+
remap.set(cu, cv);
|
|
440
|
+
if (fallback < 0)
|
|
441
|
+
fallback = cv;
|
|
442
|
+
alive[f] = 0;
|
|
443
|
+
live--;
|
|
444
|
+
}
|
|
445
|
+
for (const f of facesOf[u]) {
|
|
446
|
+
if (!alive[f])
|
|
447
|
+
continue;
|
|
448
|
+
for (let k = 0; k < 3; k++) {
|
|
449
|
+
const c = corner[f * 3 + k];
|
|
450
|
+
if (posOf[c] === u)
|
|
451
|
+
corner[f * 3 + k] = remap.get(c) ?? fallback;
|
|
452
|
+
}
|
|
453
|
+
facesOf[v].push(f);
|
|
454
|
+
}
|
|
455
|
+
dead[u] = 1;
|
|
456
|
+
facesOf[u].length = 0;
|
|
457
|
+
for (let k = 0; k < 10; k++)
|
|
458
|
+
Q[v * 10 + k] = Q[v * 10 + k] + Q[u * 10 + k];
|
|
459
|
+
if (cost > maxCost)
|
|
460
|
+
maxCost = cost;
|
|
461
|
+
version[v]++;
|
|
462
|
+
// Compact v's face list and offer its edges again with the merged quadric.
|
|
463
|
+
const fl = facesOf[v];
|
|
464
|
+
let w = 0;
|
|
465
|
+
for (const f of fl)
|
|
466
|
+
if (alive[f])
|
|
467
|
+
fl[w++] = f;
|
|
468
|
+
fl.length = w;
|
|
469
|
+
gather(v);
|
|
470
|
+
for (const q of neighbours) {
|
|
471
|
+
offer(v, q);
|
|
472
|
+
offer(q, v);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
// ---------------------------------------------------------------- output
|
|
476
|
+
const used = new Int32Array(vCount).fill(-1);
|
|
477
|
+
let outV = 0;
|
|
478
|
+
for (let f = 0; f < triIn; f++) {
|
|
479
|
+
if (!alive[f])
|
|
480
|
+
continue;
|
|
481
|
+
for (let k = 0; k < 3; k++) {
|
|
482
|
+
const c = corner[f * 3 + k];
|
|
483
|
+
if (used[c] === -1)
|
|
484
|
+
used[c] = outV++;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const vertices = new Float32Array(outV * F);
|
|
488
|
+
for (let i = 0; i < vCount; i++) {
|
|
489
|
+
const o = used[i];
|
|
490
|
+
if (o >= 0)
|
|
491
|
+
vertices.set(src.subarray(i * F, i * F + F), o * F);
|
|
492
|
+
}
|
|
493
|
+
const indices = createIndices(outV, live * 3);
|
|
494
|
+
let io = 0;
|
|
495
|
+
for (let f = 0; f < triIn; f++) {
|
|
496
|
+
if (!alive[f])
|
|
497
|
+
continue;
|
|
498
|
+
for (let k = 0; k < 3; k++)
|
|
499
|
+
indices[io++] = used[corner[f * 3 + k]];
|
|
500
|
+
}
|
|
501
|
+
const compact = {
|
|
502
|
+
vertices,
|
|
503
|
+
indices,
|
|
504
|
+
bounds: computeBounds(vertices, F),
|
|
505
|
+
layout: g.layout,
|
|
506
|
+
};
|
|
507
|
+
return { geometry: weld(compact, 1e-6), error: Math.sqrt(maxCost) };
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* A level-of-detail chain: level 0 is `g` itself, level `i` is `simplifyGeometry(g, { ...opts,
|
|
511
|
+
* targetRatio: ratios[i - 1] })` (each from the full mesh, so errors do not compound). Ratios are
|
|
512
|
+
* fractions of `g`'s triangles, typically decreasing (`[0.5, 0.25, 0.1]`).
|
|
513
|
+
*/
|
|
514
|
+
export function createLodChain(g, ratios, opts = {}) {
|
|
515
|
+
const out = [g];
|
|
516
|
+
for (const r of ratios)
|
|
517
|
+
out.push(simplifyGeometry(g, { ...opts, targetRatio: r }).geometry);
|
|
518
|
+
return out;
|
|
519
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Geometry } from './geometry.js';
|
|
2
|
+
/**
|
|
3
|
+
* Split `g` into parts. `'island'`: connected components, triangles joined where they share a
|
|
4
|
+
* vertex position (so a UV or normal seam does not split a mesh), in order of each island's
|
|
5
|
+
* first triangle. A function: `by(triangle)` (the triangle's index, `indices[3t..3t+2]`) names
|
|
6
|
+
* each triangle's group, a negative number drops it, and the groups come back in ascending
|
|
7
|
+
* order of their number. Each part holds only the vertices it uses, in `g`'s layout.
|
|
8
|
+
*/
|
|
9
|
+
export declare function splitGeometry(g: Geometry, by: 'island' | ((triangle: number) => number)): Geometry[];
|
|
10
|
+
/** A plane: the points `p` with `n · p = d`; "above" is the side `n` points to. */
|
|
11
|
+
export interface SlicePlane {
|
|
12
|
+
nx: number;
|
|
13
|
+
ny: number;
|
|
14
|
+
nz: number;
|
|
15
|
+
d: number;
|
|
16
|
+
}
|
|
17
|
+
export interface SliceOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Close each half where it was cut: every loop of the cut outline is triangulated as its own
|
|
20
|
+
* polygon (a loop inside another is not treated as a hole), facing out of its half, uv the
|
|
21
|
+
* cut's planar coordinates. Default false. Only a closed input leaves closed loops.
|
|
22
|
+
*/
|
|
23
|
+
cap?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface SliceResult {
|
|
26
|
+
above: Geometry;
|
|
27
|
+
below: Geometry;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Cut `g` by `plane` into the triangles above it and below it, each triangle the plane crosses
|
|
31
|
+
* split along the cut (every lane interpolated linearly; normals and tangents renormalised), so
|
|
32
|
+
* the two halves meet without cracks. A triangle lying in the plane goes below when it faces the
|
|
33
|
+
* normal's way and above otherwise, so slicing a box at its top face leaves it whole below.
|
|
34
|
+
* A plane that misses `g` leaves everything on one side and an empty geometry on the other.
|
|
35
|
+
* Both halves are in `g`'s layout.
|
|
36
|
+
*/
|
|
37
|
+
export declare function sliceGeometry(g: Geometry, plane: SlicePlane, opts?: SliceOptions): SliceResult;
|