@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,534 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shapes swept from 2D profiles, all in `VERTEX_LAYOUT_3D`: `extrude` (a closed outline pushed
|
|
3
|
+
* along +z with capped, optionally bevelled ends), `lathe` (an open profile revolved around +y),
|
|
4
|
+
* `sweep` (a closed outline carried along a 3D path with rotation-minimising or Frenet frames),
|
|
5
|
+
* `tube` (a circle swept) and `polygon` (a flat triangulated outline facing +y).
|
|
6
|
+
*
|
|
7
|
+
* Every surface is wound counter-clockwise from outside with u along the outline and v along the
|
|
8
|
+
* sweep, so the tangent frame `computeTangents` derives is right-handed (handedness +1) throughout.
|
|
9
|
+
* Outlines are `Profile2D` (x, y pairs, counter-clockwise; clockwise is reversed on entry).
|
|
10
|
+
*/
|
|
11
|
+
import { GeometryWriter } from './geometry.js';
|
|
12
|
+
import { profileArea2, triangulate } from './triangulate.js';
|
|
13
|
+
const TAU = Math.PI * 2;
|
|
14
|
+
/** A counter-clockwise `Float32Array` copy of `profile` (reversed when it came clockwise). */
|
|
15
|
+
function ccwProfile(profile, what) {
|
|
16
|
+
const n = profile.length >> 1;
|
|
17
|
+
if (n < 3)
|
|
18
|
+
throw new Error(`geom: ${what} needs a profile of at least 3 points, got ${n}`);
|
|
19
|
+
const out = new Float32Array(n * 2);
|
|
20
|
+
if (profileArea2(profile) >= 0) {
|
|
21
|
+
for (let i = 0; i < n * 2; i++)
|
|
22
|
+
out[i] = profile[i];
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
for (let i = 0; i < n; i++) {
|
|
26
|
+
out[i * 2] = profile[(n - 1 - i) * 2];
|
|
27
|
+
out[i * 2 + 1] = profile[(n - 1 - i) * 2 + 1];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Cumulative length fraction at each point of a profile (`n + 1` entries for a closed outline,
|
|
34
|
+
* the last 1; `n` for an open one), so u and v follow arc length rather than point index.
|
|
35
|
+
*/
|
|
36
|
+
function lengthFractions(p, closed) {
|
|
37
|
+
const n = p.length >> 1;
|
|
38
|
+
const out = new Float32Array(closed ? n + 1 : n);
|
|
39
|
+
let acc = 0;
|
|
40
|
+
const edges = closed ? n : n - 1;
|
|
41
|
+
for (let i = 0; i < edges; i++) {
|
|
42
|
+
const j = (i + 1) % n;
|
|
43
|
+
acc += Math.hypot(p[j * 2] - p[i * 2], p[j * 2 + 1] - p[i * 2 + 1]);
|
|
44
|
+
out[i + 1] = acc;
|
|
45
|
+
}
|
|
46
|
+
if (acc > 0)
|
|
47
|
+
for (let i = 0; i < out.length; i++)
|
|
48
|
+
out[i] = out[i] / acc;
|
|
49
|
+
else
|
|
50
|
+
for (let i = 0; i < out.length; i++)
|
|
51
|
+
out[i] = i / Math.max(1, out.length - 1);
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Smooth outward 2D normals, one per profile point: the normalised sum of the two adjacent edge
|
|
56
|
+
* normals `(dy, -dx)` (one edge at the ends of an open profile).
|
|
57
|
+
*/
|
|
58
|
+
function vertexNormals2(p, closed) {
|
|
59
|
+
const n = p.length >> 1;
|
|
60
|
+
const out = new Float32Array(n * 2);
|
|
61
|
+
for (let i = 0; i < n; i++) {
|
|
62
|
+
let nx = 0;
|
|
63
|
+
let ny = 0;
|
|
64
|
+
if (closed || i > 0) {
|
|
65
|
+
const a = (i - 1 + n) % n;
|
|
66
|
+
const dx = p[i * 2] - p[a * 2];
|
|
67
|
+
const dy = p[i * 2 + 1] - p[a * 2 + 1];
|
|
68
|
+
const l = Math.hypot(dx, dy) || 1;
|
|
69
|
+
nx += dy / l;
|
|
70
|
+
ny -= dx / l;
|
|
71
|
+
}
|
|
72
|
+
if (closed || i < n - 1) {
|
|
73
|
+
const b = (i + 1) % n;
|
|
74
|
+
const dx = p[b * 2] - p[i * 2];
|
|
75
|
+
const dy = p[b * 2 + 1] - p[i * 2 + 1];
|
|
76
|
+
const l = Math.hypot(dx, dy) || 1;
|
|
77
|
+
nx += dy / l;
|
|
78
|
+
ny -= dx / l;
|
|
79
|
+
}
|
|
80
|
+
const l = Math.hypot(nx, ny);
|
|
81
|
+
out[i * 2] = l > 0 ? nx / l : 1;
|
|
82
|
+
out[i * 2 + 1] = l > 0 ? ny / l : 0;
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
function bounds2(p) {
|
|
87
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
88
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
89
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
90
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
91
|
+
for (let i = 0; i < p.length; i += 2) {
|
|
92
|
+
const x = p[i];
|
|
93
|
+
const y = p[i + 1];
|
|
94
|
+
if (x < minX)
|
|
95
|
+
minX = x;
|
|
96
|
+
if (x > maxX)
|
|
97
|
+
maxX = x;
|
|
98
|
+
if (y < minY)
|
|
99
|
+
minY = y;
|
|
100
|
+
if (y > maxY)
|
|
101
|
+
maxY = y;
|
|
102
|
+
}
|
|
103
|
+
return [minX, minY, maxX - minX || 1, maxY - minY || 1];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A closed outline pushed along z from -depth/2 to +depth/2: flat side normals (two vertices per
|
|
107
|
+
* outline point per row), ear-clipped caps facing ±z, an optional 45° bevel. Side u runs around
|
|
108
|
+
* the outline by arc length (0 at the first point) and v along z (0 at the back); cap uvs span
|
|
109
|
+
* the outline's box in 0..1 (the back cap mirrored in u).
|
|
110
|
+
*/
|
|
111
|
+
export function extrude(profile, opts = {}) {
|
|
112
|
+
const p = ccwProfile(profile, 'extrude');
|
|
113
|
+
const n = p.length >> 1;
|
|
114
|
+
const depth = opts.depth ?? 1;
|
|
115
|
+
const rows = Math.floor(opts.segments ?? 1);
|
|
116
|
+
if (!(rows >= 1))
|
|
117
|
+
throw new Error(`geom: extrude segments must be at least 1, got ${rows}`);
|
|
118
|
+
const caps = opts.caps ?? true;
|
|
119
|
+
const bevel = caps ? Math.max(0, opts.bevel ?? 0) : 0;
|
|
120
|
+
const capTris = caps ? triangulate(p) : null;
|
|
121
|
+
const sideV = n * 2 * (rows + 1);
|
|
122
|
+
const sideI = n * rows * 6;
|
|
123
|
+
const capV = caps ? 2 * n : 0;
|
|
124
|
+
const capI = capTris ? capTris.length * 2 : 0;
|
|
125
|
+
const bevV = bevel > 0 ? 2 * n * 4 : 0;
|
|
126
|
+
const bevI = bevel > 0 ? 2 * n * 6 : 0;
|
|
127
|
+
const w = new GeometryWriter(sideV + capV + bevV, sideI + capI + bevI, opts);
|
|
128
|
+
const z0 = -depth / 2 + bevel;
|
|
129
|
+
const z1 = depth / 2 - bevel;
|
|
130
|
+
const frac = lengthFractions(p, true);
|
|
131
|
+
// Sides: one strip per edge, flat normal.
|
|
132
|
+
for (let e = 0; e < n; e++) {
|
|
133
|
+
const f = (e + 1) % n;
|
|
134
|
+
const ax = p[e * 2];
|
|
135
|
+
const ay = p[e * 2 + 1];
|
|
136
|
+
const bx = p[f * 2];
|
|
137
|
+
const by = p[f * 2 + 1];
|
|
138
|
+
const l = Math.hypot(bx - ax, by - ay) || 1;
|
|
139
|
+
const nx = (by - ay) / l;
|
|
140
|
+
const ny = -(bx - ax) / l;
|
|
141
|
+
const base = w.count;
|
|
142
|
+
for (let j = 0; j <= rows; j++) {
|
|
143
|
+
const t = j / rows;
|
|
144
|
+
const z = z0 + (z1 - z0) * t;
|
|
145
|
+
w.vertex(ax, ay, z, nx, ny, 0, frac[e], t);
|
|
146
|
+
w.vertex(bx, by, z, nx, ny, 0, frac[e + 1], t);
|
|
147
|
+
}
|
|
148
|
+
for (let j = 0; j < rows; j++) {
|
|
149
|
+
const a = base + j * 2;
|
|
150
|
+
w.quad(a, a + 1, a + 3, a + 2);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (caps && capTris) {
|
|
154
|
+
// Inset outline for the caps (the outline itself without a bevel).
|
|
155
|
+
const inset = new Float32Array(n * 2);
|
|
156
|
+
if (bevel > 0) {
|
|
157
|
+
for (let i = 0; i < n; i++) {
|
|
158
|
+
const a = (i - 1 + n) % n;
|
|
159
|
+
const b = (i + 1) % n;
|
|
160
|
+
const d0x = p[i * 2] - p[a * 2];
|
|
161
|
+
const d0y = p[i * 2 + 1] - p[a * 2 + 1];
|
|
162
|
+
const d1x = p[b * 2] - p[i * 2];
|
|
163
|
+
const d1y = p[b * 2 + 1] - p[i * 2 + 1];
|
|
164
|
+
const l0 = Math.hypot(d0x, d0y) || 1;
|
|
165
|
+
const l1 = Math.hypot(d1x, d1y) || 1;
|
|
166
|
+
const n0x = d0y / l0;
|
|
167
|
+
const n0y = -d0x / l0;
|
|
168
|
+
const n1x = d1y / l1;
|
|
169
|
+
const n1y = -d1x / l1;
|
|
170
|
+
// Mitre: (n0 + n1) / (1 + n0·n1) moves the offset edges by exactly `bevel`.
|
|
171
|
+
const k = Math.max(0.2, 1 + n0x * n1x + n0y * n1y);
|
|
172
|
+
inset[i * 2] = p[i * 2] - (bevel * (n0x + n1x)) / k;
|
|
173
|
+
inset[i * 2 + 1] = p[i * 2 + 1] - (bevel * (n0y + n1y)) / k;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
inset.set(p);
|
|
178
|
+
}
|
|
179
|
+
const [minX, minY, sx, sy] = bounds2(p);
|
|
180
|
+
const zf = depth / 2;
|
|
181
|
+
const front = w.count;
|
|
182
|
+
for (let i = 0; i < n; i++) {
|
|
183
|
+
const x = inset[i * 2];
|
|
184
|
+
const y = inset[i * 2 + 1];
|
|
185
|
+
w.vertex(x, y, zf, 0, 0, 1, (x - minX) / sx, (y - minY) / sy);
|
|
186
|
+
}
|
|
187
|
+
const back = w.count;
|
|
188
|
+
for (let i = 0; i < n; i++) {
|
|
189
|
+
const x = inset[i * 2];
|
|
190
|
+
const y = inset[i * 2 + 1];
|
|
191
|
+
w.vertex(x, y, -zf, 0, 0, -1, 1 - (x - minX) / sx, (y - minY) / sy);
|
|
192
|
+
}
|
|
193
|
+
for (let t = 0; t < capTris.length; t += 3) {
|
|
194
|
+
const a = capTris[t];
|
|
195
|
+
const b = capTris[t + 1];
|
|
196
|
+
const c = capTris[t + 2];
|
|
197
|
+
w.tri(front + a, front + b, front + c);
|
|
198
|
+
w.tri(back + a, back + c, back + b);
|
|
199
|
+
}
|
|
200
|
+
if (bevel > 0) {
|
|
201
|
+
const s = Math.SQRT1_2;
|
|
202
|
+
for (let e = 0; e < n; e++) {
|
|
203
|
+
const f = (e + 1) % n;
|
|
204
|
+
const ax = p[e * 2];
|
|
205
|
+
const ay = p[e * 2 + 1];
|
|
206
|
+
const bx = p[f * 2];
|
|
207
|
+
const by = p[f * 2 + 1];
|
|
208
|
+
const l = Math.hypot(bx - ax, by - ay) || 1;
|
|
209
|
+
const nx = ((by - ay) / l) * s;
|
|
210
|
+
const ny = (-(bx - ax) / l) * s;
|
|
211
|
+
const u0 = frac[e];
|
|
212
|
+
const u1 = frac[e + 1];
|
|
213
|
+
// Front chamfer: side's front edge (z1) up to the inset cap edge (zf).
|
|
214
|
+
let a = w.vertex(ax, ay, z1, nx, ny, s, u0, 0);
|
|
215
|
+
w.vertex(bx, by, z1, nx, ny, s, u1, 0);
|
|
216
|
+
w.vertex(inset[f * 2], inset[f * 2 + 1], zf, nx, ny, s, u1, 1);
|
|
217
|
+
w.vertex(inset[e * 2], inset[e * 2 + 1], zf, nx, ny, s, u0, 1);
|
|
218
|
+
w.quad(a, a + 1, a + 2, a + 3);
|
|
219
|
+
// Back chamfer: traversed the other way so the winding faces out; v still runs along +z
|
|
220
|
+
// (0 at the cap edge, 1 at the side) so the tangent frame stays right-handed.
|
|
221
|
+
a = w.vertex(bx, by, z0, nx, ny, -s, u1, 1);
|
|
222
|
+
w.vertex(ax, ay, z0, nx, ny, -s, u0, 1);
|
|
223
|
+
w.vertex(inset[e * 2], inset[e * 2 + 1], -zf, nx, ny, -s, u0, 0);
|
|
224
|
+
w.vertex(inset[f * 2], inset[f * 2 + 1], -zf, nx, ny, -s, u1, 0);
|
|
225
|
+
w.quad(a, a + 1, a + 2, a + 3);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return w.finish();
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* An open profile of (radius, y) points, ordered along the surface, revolved around +y: smooth
|
|
233
|
+
* normals (adjacent edge normals averaged, outward for a profile traced bottom to top), u around
|
|
234
|
+
* (0 at +z, as `cylinder`), v along the profile by arc length. A zero radius makes a pole.
|
|
235
|
+
*/
|
|
236
|
+
export function lathe(profile, opts = {}) {
|
|
237
|
+
const m = profile.length >> 1;
|
|
238
|
+
if (m < 2)
|
|
239
|
+
throw new Error(`geom: lathe needs a profile of at least 2 points, got ${m}`);
|
|
240
|
+
const p = new Float32Array(m * 2);
|
|
241
|
+
for (let i = 0; i < m * 2; i++)
|
|
242
|
+
p[i] = profile[i];
|
|
243
|
+
const cols = Math.floor(opts.segments ?? 24);
|
|
244
|
+
if (!(cols >= 3))
|
|
245
|
+
throw new Error(`geom: lathe segments must be at least 3, got ${cols}`);
|
|
246
|
+
const angle = opts.angle ?? TAU;
|
|
247
|
+
const w = new GeometryWriter(m * (cols + 1), (m - 1) * cols * 6, opts);
|
|
248
|
+
const nrm = vertexNormals2(p, false);
|
|
249
|
+
const frac = lengthFractions(p, false);
|
|
250
|
+
for (let j = 0; j < m; j++) {
|
|
251
|
+
const r = p[j * 2];
|
|
252
|
+
const y = p[j * 2 + 1];
|
|
253
|
+
const nr = nrm[j * 2];
|
|
254
|
+
const ny = nrm[j * 2 + 1];
|
|
255
|
+
for (let i = 0; i <= cols; i++) {
|
|
256
|
+
const phi = (i / cols) * angle;
|
|
257
|
+
const s = Math.sin(phi);
|
|
258
|
+
const c = Math.cos(phi);
|
|
259
|
+
w.vertex(r * s, y, r * c, nr * s, ny, nr * c, i / cols, frac[j]);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
for (let j = 0; j < m - 1; j++) {
|
|
263
|
+
const a = j * (cols + 1);
|
|
264
|
+
const b = a + cols + 1;
|
|
265
|
+
for (let i = 0; i < cols; i++)
|
|
266
|
+
w.quad(a + i, a + i + 1, b + i + 1, b + i);
|
|
267
|
+
}
|
|
268
|
+
return w.finish();
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Carry a frame normal from path point `q` to `o` (float offsets) by double reflection: across
|
|
272
|
+
* the chord's bisector plane, then across the plane between the reflected and the new tangent.
|
|
273
|
+
*/
|
|
274
|
+
function carryNormal(path, T, q, o, rx, ry, rz) {
|
|
275
|
+
const v1x = path[o] - path[q];
|
|
276
|
+
const v1y = path[o + 1] - path[q + 1];
|
|
277
|
+
const v1z = path[o + 2] - path[q + 2];
|
|
278
|
+
const c1 = v1x * v1x + v1y * v1y + v1z * v1z;
|
|
279
|
+
let tlx = T[q];
|
|
280
|
+
let tly = T[q + 1];
|
|
281
|
+
let tlz = T[q + 2];
|
|
282
|
+
if (c1 > 0) {
|
|
283
|
+
const k = (2 / c1) * (v1x * rx + v1y * ry + v1z * rz);
|
|
284
|
+
rx -= k * v1x;
|
|
285
|
+
ry -= k * v1y;
|
|
286
|
+
rz -= k * v1z;
|
|
287
|
+
const kt = (2 / c1) * (v1x * tlx + v1y * tly + v1z * tlz);
|
|
288
|
+
tlx -= kt * v1x;
|
|
289
|
+
tly -= kt * v1y;
|
|
290
|
+
tlz -= kt * v1z;
|
|
291
|
+
}
|
|
292
|
+
const v2x = T[o] - tlx;
|
|
293
|
+
const v2y = T[o + 1] - tly;
|
|
294
|
+
const v2z = T[o + 2] - tlz;
|
|
295
|
+
const c2 = v2x * v2x + v2y * v2y + v2z * v2z;
|
|
296
|
+
if (c2 > 0) {
|
|
297
|
+
const k = (2 / c2) * (v2x * rx + v2y * ry + v2z * rz);
|
|
298
|
+
rx -= k * v2x;
|
|
299
|
+
ry -= k * v2y;
|
|
300
|
+
rz -= k * v2z;
|
|
301
|
+
}
|
|
302
|
+
return [rx, ry, rz];
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* A closed outline carried along `path` (x, y, z triples, at least 2 points; the first and last
|
|
306
|
+
* point of a closed path are distinct). Each path point gets a ring of the outline in its frame
|
|
307
|
+
* (outline x along the frame's normal, y along its binormal), smooth normals across the outline,
|
|
308
|
+
* u around the outline by arc length, v along the path by point index. A closed sweep spreads the
|
|
309
|
+
* frame's end-to-start twist over the rings so the seam matches.
|
|
310
|
+
*/
|
|
311
|
+
export function sweep(profile, path, opts = {}) {
|
|
312
|
+
const p = ccwProfile(profile, 'sweep');
|
|
313
|
+
const n = p.length >> 1;
|
|
314
|
+
const m = path.length / 3;
|
|
315
|
+
if (!(m >= 2) || m !== Math.floor(m)) {
|
|
316
|
+
throw new Error(`geom: sweep needs a path of at least 2 xyz points, got ${path.length} floats`);
|
|
317
|
+
}
|
|
318
|
+
const closed = opts.closed ?? false;
|
|
319
|
+
const frenet = opts.frames === 'frenet';
|
|
320
|
+
const rings = m;
|
|
321
|
+
const spans = closed ? m : m - 1;
|
|
322
|
+
const w = new GeometryWriter(rings * (n + 1), spans * n * 6, opts);
|
|
323
|
+
const nrm = vertexNormals2(p, true);
|
|
324
|
+
const frac = lengthFractions(p, true);
|
|
325
|
+
// Tangents, central differences (wrapping when closed).
|
|
326
|
+
const T = new Float64Array(m * 3);
|
|
327
|
+
for (let j = 0; j < m; j++) {
|
|
328
|
+
let a = j - 1;
|
|
329
|
+
let b = j + 1;
|
|
330
|
+
if (closed) {
|
|
331
|
+
a = (a + m) % m;
|
|
332
|
+
b %= m;
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
if (a < 0)
|
|
336
|
+
a = 0;
|
|
337
|
+
if (b >= m)
|
|
338
|
+
b = m - 1;
|
|
339
|
+
}
|
|
340
|
+
let tx = path[b * 3] - path[a * 3];
|
|
341
|
+
let ty = path[b * 3 + 1] - path[a * 3 + 1];
|
|
342
|
+
let tz = path[b * 3 + 2] - path[a * 3 + 2];
|
|
343
|
+
const l = Math.hypot(tx, ty, tz);
|
|
344
|
+
if (l > 0) {
|
|
345
|
+
tx /= l;
|
|
346
|
+
ty /= l;
|
|
347
|
+
tz /= l;
|
|
348
|
+
}
|
|
349
|
+
else if (j > 0) {
|
|
350
|
+
tx = T[(j - 1) * 3];
|
|
351
|
+
ty = T[(j - 1) * 3 + 1];
|
|
352
|
+
tz = T[(j - 1) * 3 + 2];
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
tz = 1;
|
|
356
|
+
}
|
|
357
|
+
T[j * 3] = tx;
|
|
358
|
+
T[j * 3 + 1] = ty;
|
|
359
|
+
T[j * 3 + 2] = tz;
|
|
360
|
+
}
|
|
361
|
+
// Normals N (perpendicular to T) per ring; B = T × N.
|
|
362
|
+
const N = new Float64Array(m * 3);
|
|
363
|
+
// Start: the world axis least aligned with T0, made perpendicular.
|
|
364
|
+
{
|
|
365
|
+
const tx = T[0];
|
|
366
|
+
const ty = T[1];
|
|
367
|
+
const tz = T[2];
|
|
368
|
+
const ax = Math.abs(tx);
|
|
369
|
+
const ay = Math.abs(ty);
|
|
370
|
+
const az = Math.abs(tz);
|
|
371
|
+
let ux = 0;
|
|
372
|
+
let uy = 0;
|
|
373
|
+
let uz = 0;
|
|
374
|
+
if (ay <= ax && ay <= az)
|
|
375
|
+
uy = 1;
|
|
376
|
+
else if (ax <= az)
|
|
377
|
+
ux = 1;
|
|
378
|
+
else
|
|
379
|
+
uz = 1;
|
|
380
|
+
const d = ux * tx + uy * ty + uz * tz;
|
|
381
|
+
ux -= d * tx;
|
|
382
|
+
uy -= d * ty;
|
|
383
|
+
uz -= d * tz;
|
|
384
|
+
const l = Math.hypot(ux, uy, uz);
|
|
385
|
+
N[0] = ux / l;
|
|
386
|
+
N[1] = uy / l;
|
|
387
|
+
N[2] = uz / l;
|
|
388
|
+
}
|
|
389
|
+
for (let j = 1; j < m; j++) {
|
|
390
|
+
const o = j * 3;
|
|
391
|
+
const q = o - 3;
|
|
392
|
+
if (frenet) {
|
|
393
|
+
// Curvature direction: the change in tangent, perpendicular to T.
|
|
394
|
+
const a = closed ? ((j - 1 + m) % m) * 3 : Math.max(0, j - 1) * 3;
|
|
395
|
+
const b = closed ? ((j + 1) % m) * 3 : Math.min(m - 1, j + 1) * 3;
|
|
396
|
+
let kx = T[b] - T[a];
|
|
397
|
+
let ky = T[b + 1] - T[a + 1];
|
|
398
|
+
let kz = T[b + 2] - T[a + 2];
|
|
399
|
+
const d = kx * T[o] + ky * T[o + 1] + kz * T[o + 2];
|
|
400
|
+
kx -= d * T[o];
|
|
401
|
+
ky -= d * T[o + 1];
|
|
402
|
+
kz -= d * T[o + 2];
|
|
403
|
+
const l = Math.hypot(kx, ky, kz);
|
|
404
|
+
if (l > 1e-9) {
|
|
405
|
+
N[o] = kx / l;
|
|
406
|
+
N[o + 1] = ky / l;
|
|
407
|
+
N[o + 2] = kz / l;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// Double reflection: the previous normal carried across the chord (see `carryNormal`).
|
|
412
|
+
const [rx0, ry0, rz0] = carryNormal(path, T, q, o, N[q], N[q + 1], N[q + 2]);
|
|
413
|
+
let rx = rx0;
|
|
414
|
+
let ry = ry0;
|
|
415
|
+
let rz = rz0;
|
|
416
|
+
// Re-orthogonalise against T to stop drift.
|
|
417
|
+
const d = rx * T[o] + ry * T[o + 1] + rz * T[o + 2];
|
|
418
|
+
rx -= d * T[o];
|
|
419
|
+
ry -= d * T[o + 1];
|
|
420
|
+
rz -= d * T[o + 2];
|
|
421
|
+
const l = Math.hypot(rx, ry, rz) || 1;
|
|
422
|
+
N[o] = rx / l;
|
|
423
|
+
N[o + 1] = ry / l;
|
|
424
|
+
N[o + 2] = rz / l;
|
|
425
|
+
}
|
|
426
|
+
// Closed: the frame carried once more around to ring 0 differs from N0 by a twist; spread the
|
|
427
|
+
// correction over the rings so ring m-1 meets ring 0 without a step.
|
|
428
|
+
let twist = 0;
|
|
429
|
+
if (closed && !frenet) {
|
|
430
|
+
const q = (m - 1) * 3;
|
|
431
|
+
const [rx, ry, rz] = carryNormal(path, T, q, 0, N[q], N[q + 1], N[q + 2]);
|
|
432
|
+
// Angle from the carried normal to N0 about T0.
|
|
433
|
+
const bx = T[1] * N[2] - T[2] * N[1];
|
|
434
|
+
const by = T[2] * N[0] - T[0] * N[2];
|
|
435
|
+
const bz = T[0] * N[1] - T[1] * N[0];
|
|
436
|
+
const cosA = rx * N[0] + ry * N[1] + rz * N[2];
|
|
437
|
+
const sinA = rx * bx + ry * by + rz * bz;
|
|
438
|
+
twist = Math.atan2(sinA, cosA);
|
|
439
|
+
}
|
|
440
|
+
for (let j = 0; j < rings; j++) {
|
|
441
|
+
const o = j * 3;
|
|
442
|
+
const tx = T[o];
|
|
443
|
+
const ty = T[o + 1];
|
|
444
|
+
const tz = T[o + 2];
|
|
445
|
+
let nx = N[o];
|
|
446
|
+
let ny = N[o + 1];
|
|
447
|
+
let nz = N[o + 2];
|
|
448
|
+
let bx = ty * nz - tz * ny;
|
|
449
|
+
let by = tz * nx - tx * nz;
|
|
450
|
+
let bz = tx * ny - ty * nx;
|
|
451
|
+
if (twist !== 0) {
|
|
452
|
+
// Rotate N, B about T by the share of the twist this ring takes.
|
|
453
|
+
const a = (twist * j) / m;
|
|
454
|
+
const ca = Math.cos(a);
|
|
455
|
+
const sa = Math.sin(a);
|
|
456
|
+
const rnx = nx * ca + bx * sa;
|
|
457
|
+
const rny = ny * ca + by * sa;
|
|
458
|
+
const rnz = nz * ca + bz * sa;
|
|
459
|
+
bx = bx * ca - nx * sa;
|
|
460
|
+
by = by * ca - ny * sa;
|
|
461
|
+
bz = bz * ca - nz * sa;
|
|
462
|
+
nx = rnx;
|
|
463
|
+
ny = rny;
|
|
464
|
+
nz = rnz;
|
|
465
|
+
}
|
|
466
|
+
const px = path[o];
|
|
467
|
+
const py = path[o + 1];
|
|
468
|
+
const pz = path[o + 2];
|
|
469
|
+
const v = j / spans;
|
|
470
|
+
for (let i = 0; i <= n; i++) {
|
|
471
|
+
const k = i % n;
|
|
472
|
+
const x2 = p[k * 2];
|
|
473
|
+
const y2 = p[k * 2 + 1];
|
|
474
|
+
const nx2 = nrm[k * 2];
|
|
475
|
+
const ny2 = nrm[k * 2 + 1];
|
|
476
|
+
w.vertex(px + nx * x2 + bx * y2, py + ny * x2 + by * y2, pz + nz * x2 + bz * y2, nx * nx2 + bx * ny2, ny * nx2 + by * ny2, nz * nx2 + bz * ny2, frac[i], v);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
for (let j = 0; j < spans; j++) {
|
|
480
|
+
const a = j * (n + 1);
|
|
481
|
+
const b = ((j + 1) % rings) * (n + 1);
|
|
482
|
+
for (let i = 0; i < n; i++)
|
|
483
|
+
w.quad(a + i, a + i + 1, b + i + 1, b + i);
|
|
484
|
+
}
|
|
485
|
+
return w.finish();
|
|
486
|
+
}
|
|
487
|
+
/** `sweep` of a circle: a round tube along `path` (`SweepOptions` apply). */
|
|
488
|
+
export function tube(path, opts = {}) {
|
|
489
|
+
const r = opts.radius ?? 0.1;
|
|
490
|
+
const k = Math.floor(opts.segments ?? 12);
|
|
491
|
+
if (!(k >= 3))
|
|
492
|
+
throw new Error(`geom: tube segments must be at least 3, got ${k}`);
|
|
493
|
+
const circle = new Float32Array(k * 2);
|
|
494
|
+
for (let i = 0; i < k; i++) {
|
|
495
|
+
const a = (i / k) * TAU;
|
|
496
|
+
circle[i * 2] = r * Math.cos(a);
|
|
497
|
+
circle[i * 2 + 1] = r * Math.sin(a);
|
|
498
|
+
}
|
|
499
|
+
return sweep(circle, path, opts);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* A flat outline in the xz plane facing +y: outline x → x, outline y → -z (so a counter-clockwise
|
|
503
|
+
* outline stays counter-clockwise seen from above), ear-clipped, uv the outline's box in 0..1.
|
|
504
|
+
*/
|
|
505
|
+
export function polygon(points, opts = {}) {
|
|
506
|
+
const p = ccwProfile(points, 'polygon');
|
|
507
|
+
const n = p.length >> 1;
|
|
508
|
+
const tris = triangulate(p);
|
|
509
|
+
const two = opts.doubleSided ?? false;
|
|
510
|
+
const y = opts.y ?? 0;
|
|
511
|
+
const w = new GeometryWriter(two ? n * 2 : n, two ? tris.length * 2 : tris.length, opts);
|
|
512
|
+
const [minX, minY, sx, sy] = bounds2(p);
|
|
513
|
+
for (let i = 0; i < n; i++) {
|
|
514
|
+
const x = p[i * 2];
|
|
515
|
+
const z = p[i * 2 + 1];
|
|
516
|
+
w.vertex(x, y, -z, 0, 1, 0, (x - minX) / sx, (z - minY) / sy);
|
|
517
|
+
}
|
|
518
|
+
if (two) {
|
|
519
|
+
for (let i = 0; i < n; i++) {
|
|
520
|
+
const x = p[i * 2];
|
|
521
|
+
const z = p[i * 2 + 1];
|
|
522
|
+
w.vertex(x, y, -z, 0, -1, 0, 1 - (x - minX) / sx, (z - minY) / sy);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
for (let t = 0; t < tris.length; t += 3) {
|
|
526
|
+
w.tri(tris[t], tris[t + 1], tris[t + 2]);
|
|
527
|
+
}
|
|
528
|
+
if (two) {
|
|
529
|
+
for (let t = 0; t < tris.length; t += 3) {
|
|
530
|
+
w.tri(n + tris[t], n + tris[t + 2], n + tris[t + 1]);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return w.finish();
|
|
534
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Geometry } from './geometry.js';
|
|
2
|
+
/** A `Geometry` whose `layout` is `VERTEX_LAYOUT_3D_TANGENT` (16 floats per vertex). */
|
|
3
|
+
export type GeometryTangent = Geometry;
|
|
4
|
+
/** Floats per vertex in `VERTEX_LAYOUT_3D_TANGENT`. */
|
|
5
|
+
export declare const TANGENT_FLOATS: number;
|
|
6
|
+
/**
|
|
7
|
+
* Per-vertex tangents in the MikkTSpace manner: each triangle's tangent and bitangent (the
|
|
8
|
+
* directions in which u and v grow across it, scaled by its area over its uv area) are
|
|
9
|
+
* accumulated on its three vertices; each sum is then Gram-Schmidt orthogonalised against the
|
|
10
|
+
* vertex normal and normalised, and w = +1 when `cross(normal, tangent)` points along the accumulated
|
|
11
|
+
* bitangent, -1 when the uv mapping is mirrored. A vertex with no uv area (or none at all) gets
|
|
12
|
+
* an arbitrary unit tangent perpendicular to its normal and w = 1. Returns a new geometry in
|
|
13
|
+
* `VERTEX_LAYOUT_3D_TANGENT` with the same indices object and bounds; the input is untouched.
|
|
14
|
+
* Allocates the output and one scratch array.
|
|
15
|
+
*/
|
|
16
|
+
export declare function computeTangents(g: Geometry): GeometryTangent;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tangent frames for normal-mapped materials: `computeTangents` turns a `VERTEX_LAYOUT_3D`
|
|
3
|
+
* geometry into one in `VERTEX_LAYOUT_3D_TANGENT` (16 floats: the 12 of the 3D layout, then the
|
|
4
|
+
* unit tangent xyz and its handedness in w).
|
|
5
|
+
*/
|
|
6
|
+
import { VERTEX_LAYOUT_3D, VERTEX_LAYOUT_3D_TANGENT } from '../render/mesh.js';
|
|
7
|
+
import { GEOMETRY_FLOATS } from './geometry.js';
|
|
8
|
+
/** Floats per vertex in `VERTEX_LAYOUT_3D_TANGENT`. */
|
|
9
|
+
export const TANGENT_FLOATS = VERTEX_LAYOUT_3D_TANGENT.floats;
|
|
10
|
+
/**
|
|
11
|
+
* Per-vertex tangents in the MikkTSpace manner: each triangle's tangent and bitangent (the
|
|
12
|
+
* directions in which u and v grow across it, scaled by its area over its uv area) are
|
|
13
|
+
* accumulated on its three vertices; each sum is then Gram-Schmidt orthogonalised against the
|
|
14
|
+
* vertex normal and normalised, and w = +1 when `cross(normal, tangent)` points along the accumulated
|
|
15
|
+
* bitangent, -1 when the uv mapping is mirrored. A vertex with no uv area (or none at all) gets
|
|
16
|
+
* an arbitrary unit tangent perpendicular to its normal and w = 1. Returns a new geometry in
|
|
17
|
+
* `VERTEX_LAYOUT_3D_TANGENT` with the same indices object and bounds; the input is untouched.
|
|
18
|
+
* Allocates the output and one scratch array.
|
|
19
|
+
*/
|
|
20
|
+
export function computeTangents(g) {
|
|
21
|
+
if (g.layout !== VERTEX_LAYOUT_3D) {
|
|
22
|
+
throw new Error(`geom: computeTangents needs VERTEX_LAYOUT_3D, got '${g.layout.name}'`);
|
|
23
|
+
}
|
|
24
|
+
const F = GEOMETRY_FLOATS;
|
|
25
|
+
const T = TANGENT_FLOATS;
|
|
26
|
+
const src = g.vertices;
|
|
27
|
+
const n = src.length / F;
|
|
28
|
+
const out = new Float32Array(n * T);
|
|
29
|
+
// Tangent sums live in the output's tangent slots; bitangent sums in the scratch array.
|
|
30
|
+
const bit = new Float32Array(n * 3);
|
|
31
|
+
for (let i = 0; i < n; i++)
|
|
32
|
+
out.set(src.subarray(i * F, i * F + F), i * T);
|
|
33
|
+
const idx = g.indices;
|
|
34
|
+
for (let t = 0; t < idx.length; t += 3) {
|
|
35
|
+
const a = idx[t] * F;
|
|
36
|
+
const b = idx[t + 1] * F;
|
|
37
|
+
const c = idx[t + 2] * F;
|
|
38
|
+
const e1x = src[b] - src[a];
|
|
39
|
+
const e1y = src[b + 1] - src[a + 1];
|
|
40
|
+
const e1z = src[b + 2] - src[a + 2];
|
|
41
|
+
const e2x = src[c] - src[a];
|
|
42
|
+
const e2y = src[c + 1] - src[a + 1];
|
|
43
|
+
const e2z = src[c + 2] - src[a + 2];
|
|
44
|
+
const du1 = src[b + 6] - src[a + 6];
|
|
45
|
+
const dv1 = src[b + 7] - src[a + 7];
|
|
46
|
+
const du2 = src[c + 6] - src[a + 6];
|
|
47
|
+
const dv2 = src[c + 7] - src[a + 7];
|
|
48
|
+
const det = du1 * dv2 - du2 * dv1;
|
|
49
|
+
if (det === 0)
|
|
50
|
+
continue;
|
|
51
|
+
const r = 1 / det;
|
|
52
|
+
// Tangent = direction of +u, bitangent = direction of +v (Lengyel); a mirrored mapping
|
|
53
|
+
// flips the sign of `det`, so both still point along +u and +v but B lands on the far side of
|
|
54
|
+
// cross(n, t), which is what w records.
|
|
55
|
+
const tx = (e1x * dv2 - e2x * dv1) * r;
|
|
56
|
+
const ty = (e1y * dv2 - e2y * dv1) * r;
|
|
57
|
+
const tz = (e1z * dv2 - e2z * dv1) * r;
|
|
58
|
+
const bx = (e2x * du1 - e1x * du2) * r;
|
|
59
|
+
const by = (e2y * du1 - e1y * du2) * r;
|
|
60
|
+
const bz = (e2z * du1 - e1z * du2) * r;
|
|
61
|
+
for (let k = 0; k < 3; k++) {
|
|
62
|
+
const v = idx[t + k];
|
|
63
|
+
const o = v * T + 12;
|
|
64
|
+
out[o] = out[o] + tx;
|
|
65
|
+
out[o + 1] = out[o + 1] + ty;
|
|
66
|
+
out[o + 2] = out[o + 2] + tz;
|
|
67
|
+
const p = v * 3;
|
|
68
|
+
bit[p] = bit[p] + bx;
|
|
69
|
+
bit[p + 1] = bit[p + 1] + by;
|
|
70
|
+
bit[p + 2] = bit[p + 2] + bz;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
for (let i = 0; i < n; i++) {
|
|
74
|
+
const o = i * T;
|
|
75
|
+
const nx = out[o + 3];
|
|
76
|
+
const ny = out[o + 4];
|
|
77
|
+
const nz = out[o + 5];
|
|
78
|
+
let tx = out[o + 12];
|
|
79
|
+
let ty = out[o + 13];
|
|
80
|
+
let tz = out[o + 14];
|
|
81
|
+
// Gram-Schmidt: remove the normal component.
|
|
82
|
+
const d = tx * nx + ty * ny + tz * nz;
|
|
83
|
+
tx -= d * nx;
|
|
84
|
+
ty -= d * ny;
|
|
85
|
+
tz -= d * nz;
|
|
86
|
+
let len = Math.hypot(tx, ty, tz);
|
|
87
|
+
if (len < 1e-12) {
|
|
88
|
+
// No usable uv gradient: any unit vector perpendicular to the normal.
|
|
89
|
+
if (Math.abs(nx) < 0.9) {
|
|
90
|
+
tx = 0;
|
|
91
|
+
ty = nz;
|
|
92
|
+
tz = -ny;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
tx = -nz;
|
|
96
|
+
ty = 0;
|
|
97
|
+
tz = nx;
|
|
98
|
+
}
|
|
99
|
+
len = Math.hypot(tx, ty, tz) || 1;
|
|
100
|
+
}
|
|
101
|
+
tx /= len;
|
|
102
|
+
ty /= len;
|
|
103
|
+
tz /= len;
|
|
104
|
+
// Handedness: does cross(n, t) agree with the accumulated bitangent?
|
|
105
|
+
const cx = ny * tz - nz * ty;
|
|
106
|
+
const cy = nz * tx - nx * tz;
|
|
107
|
+
const cz = nx * ty - ny * tx;
|
|
108
|
+
const p = i * 3;
|
|
109
|
+
const h = cx * bit[p] + cy * bit[p + 1] + cz * bit[p + 2];
|
|
110
|
+
out[o + 12] = tx;
|
|
111
|
+
out[o + 13] = ty;
|
|
112
|
+
out[o + 14] = tz;
|
|
113
|
+
out[o + 15] = h < 0 ? -1 : 1;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
vertices: out,
|
|
117
|
+
indices: g.indices,
|
|
118
|
+
bounds: {
|
|
119
|
+
center: [g.bounds.center[0], g.bounds.center[1], g.bounds.center[2]],
|
|
120
|
+
radius: g.bounds.radius,
|
|
121
|
+
},
|
|
122
|
+
layout: VERTEX_LAYOUT_3D_TANGENT,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ear-clipping triangulation of a simple polygon (`triangulate`), the cap step of `extrude` and
|
|
3
|
+
* the whole of `polygon`. Pure arithmetic over x, y pairs.
|
|
4
|
+
*/
|
|
5
|
+
/** A closed 2D outline as x, y pairs, counter-clockwise (clockwise is accepted and reversed). */
|
|
6
|
+
export type Profile2D = Float32Array | number[];
|
|
7
|
+
/** Twice the signed area of a profile: positive counter-clockwise, negative clockwise. */
|
|
8
|
+
export declare function profileArea2(profile: Profile2D): number;
|
|
9
|
+
/**
|
|
10
|
+
* Triangulate a simple polygon by ear clipping: up to `n - 2` triangles over the profile's vertex
|
|
11
|
+
* indices, wound counter-clockwise in the profile's plane whatever its input winding. Concave
|
|
12
|
+
* outlines are handled; collinear or repeated points are dropped as zero-area ears (so fewer
|
|
13
|
+
* triangles come back). Self-intersection detection is out of scope: a self-intersecting outline
|
|
14
|
+
* still triangulates completely, but which side is "inside" is undefined there. `Uint16Array` up
|
|
15
|
+
* to 65535 points, `Uint32Array` past it. Fewer than three points gives an empty array. Cost is
|
|
16
|
+
* O(n · r) for r reflex (inward-turning) corners, so convex outlines fan in O(n); a huge outline
|
|
17
|
+
* whose corners jitter in and out of convexity (float32 rounding on a 70000-gon) is quadratic.
|
|
18
|
+
*/
|
|
19
|
+
export declare function triangulate(profile: Profile2D): Uint16Array | Uint32Array;
|