@3driseai/3drise-viewer 0.1.27 → 0.1.29
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/dist/animationsV2/ClipPlayer.d.ts.map +1 -1
- package/dist/animationsV2/ClipPlayer.js +13 -9
- package/dist/animationsV2/ClipsRuntime.d.ts +44 -3
- package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +173 -55
- package/dist/animationsV2/appliers.d.ts.map +1 -1
- package/dist/animationsV2/appliers.js +21 -5
- package/dist/animationsV2/index.d.ts +1 -1
- package/dist/animationsV2/index.d.ts.map +1 -1
- package/dist/animationsV2/normalize.d.ts.map +1 -1
- package/dist/animationsV2/normalize.js +7 -3
- package/dist/animationsV2/sequenceUtils.d.ts +44 -6
- package/dist/animationsV2/sequenceUtils.d.ts.map +1 -1
- package/dist/animationsV2/sequenceUtils.js +58 -12
- package/dist/animationsV2/types.d.ts +22 -12
- package/dist/animationsV2/types.d.ts.map +1 -1
- package/dist/api/sceneHandle.d.ts +35 -1
- package/dist/api/sceneHandle.d.ts.map +1 -1
- package/dist/api/sceneHandle.js +88 -17
- package/dist/components/AdvancedGrid.d.ts +1 -5
- package/dist/components/AdvancedGrid.d.ts.map +1 -1
- package/dist/components/AdvancedGrid.js +6 -35
- package/dist/components/AnimatedObject.d.ts.map +1 -1
- package/dist/components/AnimatedObject.js +9 -4
- package/dist/components/ApollonianGrid.d.ts +25 -0
- package/dist/components/ApollonianGrid.d.ts.map +1 -0
- package/dist/components/ApollonianGrid.js +55 -0
- package/dist/components/ChladniGrid.d.ts +1 -1
- package/dist/components/ChladniGrid.d.ts.map +1 -1
- package/dist/components/ChladniGrid.js +6 -35
- package/dist/components/CircuitGrid.d.ts +1 -1
- package/dist/components/CircuitGrid.d.ts.map +1 -1
- package/dist/components/CircuitGrid.js +6 -34
- package/dist/components/ConformalGrid.d.ts +25 -0
- package/dist/components/ConformalGrid.d.ts.map +1 -0
- package/dist/components/ConformalGrid.js +66 -0
- package/dist/components/ContourGrid.d.ts +1 -1
- package/dist/components/ContourGrid.d.ts.map +1 -1
- package/dist/components/ContourGrid.js +6 -34
- package/dist/components/CustomPrimitive.js +1 -1
- package/dist/components/EnvironmentObject.d.ts.map +1 -1
- package/dist/components/EnvironmentObject.js +9 -7
- package/dist/components/FlowNetGrid.d.ts +1 -1
- package/dist/components/FlowNetGrid.d.ts.map +1 -1
- package/dist/components/FlowNetGrid.js +6 -34
- package/dist/components/FractalGrid.d.ts +1 -1
- package/dist/components/FractalGrid.d.ts.map +1 -1
- package/dist/components/FractalGrid.js +6 -37
- package/dist/components/Galaxy.d.ts.map +1 -1
- package/dist/components/Galaxy.js +9 -23
- package/dist/components/GirihGrid.d.ts +1 -1
- package/dist/components/GirihGrid.d.ts.map +1 -1
- package/dist/components/GirihGrid.js +6 -35
- package/dist/components/GravWaveGrid.d.ts +1 -1
- package/dist/components/GravWaveGrid.d.ts.map +1 -1
- package/dist/components/GravWaveGrid.js +6 -35
- package/dist/components/GridsGenerator.d.ts +2 -2
- package/dist/components/GridsGenerator.d.ts.map +1 -1
- package/dist/components/GridsGenerator.js +21 -0
- package/dist/components/HexGrid.d.ts +1 -5
- package/dist/components/HexGrid.d.ts.map +1 -1
- package/dist/components/HexGrid.js +6 -36
- package/dist/components/HilbertGrid.d.ts +25 -0
- package/dist/components/HilbertGrid.d.ts.map +1 -0
- package/dist/components/HilbertGrid.js +66 -0
- package/dist/components/HyperbolicGrid.d.ts +1 -1
- package/dist/components/HyperbolicGrid.d.ts.map +1 -1
- package/dist/components/HyperbolicGrid.js +6 -34
- package/dist/components/LandObject.d.ts +9 -0
- package/dist/components/LandObject.d.ts.map +1 -0
- package/dist/components/LandObject.js +15 -0
- package/dist/components/LensingGrid.d.ts +25 -0
- package/dist/components/LensingGrid.d.ts.map +1 -0
- package/dist/components/LensingGrid.js +55 -0
- package/dist/components/LightsManager.d.ts.map +1 -1
- package/dist/components/LightsManager.js +8 -0
- package/dist/components/ModelBoundary.d.ts +2 -0
- package/dist/components/ModelBoundary.d.ts.map +1 -1
- package/dist/components/ModelBoundary.js +3 -0
- package/dist/components/ModelPrimitive.d.ts.map +1 -1
- package/dist/components/ModelPrimitive.js +6 -0
- package/dist/components/MoireGrid.d.ts +1 -1
- package/dist/components/MoireGrid.d.ts.map +1 -1
- package/dist/components/MoireGrid.js +6 -35
- package/dist/components/MoonDisc.d.ts +11 -0
- package/dist/components/MoonDisc.d.ts.map +1 -0
- package/dist/components/MoonDisc.js +128 -0
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +15 -4
- package/dist/components/ObjectsRenderer.d.ts.map +1 -1
- package/dist/components/ObjectsRenderer.js +7 -5
- package/dist/components/OceanBuilder.d.ts.map +1 -1
- package/dist/components/OceanBuilder.js +2 -0
- package/dist/components/ParastichyGrid.d.ts +25 -0
- package/dist/components/ParastichyGrid.d.ts.map +1 -0
- package/dist/components/ParastichyGrid.js +55 -0
- package/dist/components/PhyllotaxisGrid.d.ts +25 -0
- package/dist/components/PhyllotaxisGrid.d.ts.map +1 -0
- package/dist/components/PhyllotaxisGrid.js +66 -0
- package/dist/components/ProjectLoader.d.ts +5 -3
- package/dist/components/ProjectLoader.d.ts.map +1 -1
- package/dist/components/ProjectLoader.js +6 -3
- package/dist/components/QuasiGrid.d.ts +1 -1
- package/dist/components/QuasiGrid.d.ts.map +1 -1
- package/dist/components/QuasiGrid.js +6 -33
- package/dist/components/RadarGrid.d.ts +1 -1
- package/dist/components/RadarGrid.d.ts.map +1 -1
- package/dist/components/RadarGrid.js +6 -34
- package/dist/components/ReactionDiffusionGrid.d.ts +1 -1
- package/dist/components/ReactionDiffusionGrid.d.ts.map +1 -1
- package/dist/components/ReactionDiffusionGrid.js +6 -35
- package/dist/components/SceneBuilder.d.ts +25 -3
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +68 -38
- package/dist/components/SkyController.d.ts +25 -1
- package/dist/components/SkyController.d.ts.map +1 -1
- package/dist/components/SkyController.js +189 -130
- package/dist/components/SkyMesh.d.ts.map +1 -1
- package/dist/components/SkyMesh.js +26 -1
- package/dist/components/SkyStars.d.ts +11 -0
- package/dist/components/SkyStars.d.ts.map +1 -0
- package/dist/components/SkyStars.js +187 -0
- package/dist/components/SkySystem.d.ts +3 -3
- package/dist/components/SkySystem.d.ts.map +1 -1
- package/dist/components/SkySystem.js +8 -2
- package/dist/components/Sun.d.ts +15 -1
- package/dist/components/Sun.d.ts.map +1 -1
- package/dist/components/Sun.js +64 -3
- package/dist/components/SunLight.d.ts +6 -1
- package/dist/components/SunLight.d.ts.map +1 -1
- package/dist/components/SunLight.js +96 -44
- package/dist/components/TerrainBuilder.d.ts.map +1 -1
- package/dist/components/TerrainBuilder.js +2 -0
- package/dist/components/TextGenerator.d.ts +9 -0
- package/dist/components/TextGenerator.d.ts.map +1 -0
- package/dist/components/TextGenerator.js +29 -0
- package/dist/components/TruchetGrid.d.ts +25 -0
- package/dist/components/TruchetGrid.d.ts.map +1 -0
- package/dist/components/TruchetGrid.js +55 -0
- package/dist/components/VoronoiGrid.d.ts +1 -1
- package/dist/components/VoronoiGrid.d.ts.map +1 -1
- package/dist/components/VoronoiGrid.js +6 -33
- package/dist/components/WallpaperGrid.d.ts +1 -1
- package/dist/components/WallpaperGrid.d.ts.map +1 -1
- package/dist/components/WallpaperGrid.js +6 -35
- package/dist/components/environment/Rain.d.ts +15 -0
- package/dist/components/environment/Rain.d.ts.map +1 -0
- package/dist/components/environment/Rain.js +110 -0
- package/dist/components/environment/Rainbow.d.ts +20 -0
- package/dist/components/environment/Rainbow.d.ts.map +1 -0
- package/dist/components/environment/Rainbow.js +974 -0
- package/dist/components/environment/Sandstorm.d.ts +20 -0
- package/dist/components/environment/Sandstorm.d.ts.map +1 -0
- package/dist/components/environment/Sandstorm.js +776 -0
- package/dist/components/environment/Snow.d.ts +20 -0
- package/dist/components/environment/Snow.d.ts.map +1 -0
- package/dist/components/environment/Snow.js +609 -0
- package/dist/components/environment/Thunderstorm.d.ts +20 -0
- package/dist/components/environment/Thunderstorm.d.ts.map +1 -0
- package/dist/components/environment/Thunderstorm.js +731 -0
- package/dist/components/environment/Tornado.d.ts +20 -0
- package/dist/components/environment/Tornado.d.ts.map +1 -0
- package/dist/components/environment/Tornado.js +762 -0
- package/dist/components/environment/index.d.ts +13 -0
- package/dist/components/environment/index.d.ts.map +1 -0
- package/dist/components/environment/index.js +7 -0
- package/dist/components/index.d.ts +24 -10
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +15 -6
- package/dist/components/land/LandPatch.d.ts +15 -0
- package/dist/components/land/LandPatch.d.ts.map +1 -0
- package/dist/components/land/LandPatch.js +170 -0
- package/dist/components/land/index.d.ts +3 -0
- package/dist/components/land/index.d.ts.map +1 -0
- package/dist/components/land/index.js +1 -0
- package/dist/components/space/Earth.d.ts +16 -0
- package/dist/components/space/Earth.d.ts.map +1 -0
- package/dist/components/space/Earth.js +75 -0
- package/dist/components/space/ShootingStar.d.ts +21 -0
- package/dist/components/space/ShootingStar.d.ts.map +1 -0
- package/dist/components/space/ShootingStar.js +101 -0
- package/dist/components/space/ShootingStars.d.ts +16 -0
- package/dist/components/space/ShootingStars.d.ts.map +1 -0
- package/dist/components/space/ShootingStars.js +71 -0
- package/dist/components/space/SolarSystem.d.ts +16 -0
- package/dist/components/space/SolarSystem.d.ts.map +1 -0
- package/dist/components/space/SolarSystem.js +141 -0
- package/dist/components/space/Stars.d.ts +20 -0
- package/dist/components/space/Stars.d.ts.map +1 -0
- package/dist/components/space/Stars.js +160 -0
- package/dist/components/space/index.d.ts +11 -0
- package/dist/components/space/index.d.ts.map +1 -0
- package/dist/components/space/index.js +8 -0
- package/dist/components/terrain/TerrainSurface.d.ts.map +1 -1
- package/dist/components/terrain/TerrainSurface.js +27 -3
- package/dist/components/terrain/types.d.ts +5 -1
- package/dist/components/terrain/types.d.ts.map +1 -1
- package/dist/components/text/BurnAwayText.d.ts +15 -0
- package/dist/components/text/BurnAwayText.d.ts.map +1 -0
- package/dist/components/text/BurnAwayText.js +4 -0
- package/dist/components/text/ChalkboardText.d.ts +15 -0
- package/dist/components/text/ChalkboardText.d.ts.map +1 -0
- package/dist/components/text/ChalkboardText.js +4 -0
- package/dist/components/text/ConstellationText.d.ts +15 -0
- package/dist/components/text/ConstellationText.d.ts.map +1 -0
- package/dist/components/text/ConstellationText.js +4 -0
- package/dist/components/text/EmbroideryText.d.ts +15 -0
- package/dist/components/text/EmbroideryText.d.ts.map +1 -0
- package/dist/components/text/EmbroideryText.js +4 -0
- package/dist/components/text/FourierSketchText.d.ts +15 -0
- package/dist/components/text/FourierSketchText.d.ts.map +1 -0
- package/dist/components/text/FourierSketchText.js +4 -0
- package/dist/components/text/FrostGrowthText.d.ts +15 -0
- package/dist/components/text/FrostGrowthText.d.ts.map +1 -0
- package/dist/components/text/FrostGrowthText.js +4 -0
- package/dist/components/text/HandwritingText.d.ts +15 -0
- package/dist/components/text/HandwritingText.d.ts.map +1 -0
- package/dist/components/text/HandwritingText.js +4 -0
- package/dist/components/text/InkBleedText.d.ts +15 -0
- package/dist/components/text/InkBleedText.d.ts.map +1 -0
- package/dist/components/text/InkBleedText.js +4 -0
- package/dist/components/text/LightPaintingText.d.ts +15 -0
- package/dist/components/text/LightPaintingText.d.ts.map +1 -0
- package/dist/components/text/LightPaintingText.js +4 -0
- package/dist/components/text/LiquidMetalText.d.ts +15 -0
- package/dist/components/text/LiquidMetalText.d.ts.map +1 -0
- package/dist/components/text/LiquidMetalText.js +4 -0
- package/dist/components/text/NeonTubeText.d.ts +15 -0
- package/dist/components/text/NeonTubeText.d.ts.map +1 -0
- package/dist/components/text/NeonTubeText.js +4 -0
- package/dist/components/text/PlasmaDischargeText.d.ts +15 -0
- package/dist/components/text/PlasmaDischargeText.d.ts.map +1 -0
- package/dist/components/text/PlasmaDischargeText.js +4 -0
- package/dist/components/text/TextObjectView.d.ts +12 -0
- package/dist/components/text/TextObjectView.d.ts.map +1 -0
- package/dist/components/text/TextObjectView.js +11 -0
- package/dist/components/text/engine/fieldkit.d.ts +24 -0
- package/dist/components/text/engine/fieldkit.d.ts.map +1 -0
- package/dist/components/text/engine/fieldkit.js +201 -0
- package/dist/components/text/engine/glyphs.d.ts +19 -0
- package/dist/components/text/engine/glyphs.d.ts.map +1 -0
- package/dist/components/text/engine/glyphs.js +269 -0
- package/dist/components/text/engine/looks/burnAway.d.ts +144 -0
- package/dist/components/text/engine/looks/burnAway.d.ts.map +1 -0
- package/dist/components/text/engine/looks/burnAway.js +593 -0
- package/dist/components/text/engine/looks/chalkboard.d.ts +135 -0
- package/dist/components/text/engine/looks/chalkboard.d.ts.map +1 -0
- package/dist/components/text/engine/looks/chalkboard.js +426 -0
- package/dist/components/text/engine/looks/constellation.d.ts +111 -0
- package/dist/components/text/engine/looks/constellation.d.ts.map +1 -0
- package/dist/components/text/engine/looks/constellation.js +496 -0
- package/dist/components/text/engine/looks/embroidery.d.ts +165 -0
- package/dist/components/text/engine/looks/embroidery.d.ts.map +1 -0
- package/dist/components/text/engine/looks/embroidery.js +645 -0
- package/dist/components/text/engine/looks/frostGrowth.d.ts +109 -0
- package/dist/components/text/engine/looks/frostGrowth.d.ts.map +1 -0
- package/dist/components/text/engine/looks/frostGrowth.js +727 -0
- package/dist/components/text/engine/looks/index.d.ts +2 -0
- package/dist/components/text/engine/looks/index.d.ts.map +1 -0
- package/dist/components/text/engine/looks/index.js +48 -0
- package/dist/components/text/engine/looks/inkBleed.d.ts +103 -0
- package/dist/components/text/engine/looks/inkBleed.d.ts.map +1 -0
- package/dist/components/text/engine/looks/inkBleed.js +590 -0
- package/dist/components/text/engine/looks/lightPainting.d.ts +132 -0
- package/dist/components/text/engine/looks/lightPainting.d.ts.map +1 -0
- package/dist/components/text/engine/looks/lightPainting.js +567 -0
- package/dist/components/text/engine/looks/liquidMetal.d.ts +135 -0
- package/dist/components/text/engine/looks/liquidMetal.d.ts.map +1 -0
- package/dist/components/text/engine/looks/liquidMetal.js +655 -0
- package/dist/components/text/engine/looks/plasmaDischarge.d.ts +126 -0
- package/dist/components/text/engine/looks/plasmaDischarge.d.ts.map +1 -0
- package/dist/components/text/engine/looks/plasmaDischarge.js +763 -0
- package/dist/components/text/engine/methods.d.ts +19 -0
- package/dist/components/text/engine/methods.d.ts.map +1 -0
- package/dist/components/text/engine/methods.js +126 -0
- package/dist/components/text/engine/playback.d.ts +40 -0
- package/dist/components/text/engine/playback.d.ts.map +1 -0
- package/dist/components/text/engine/playback.js +114 -0
- package/dist/components/text/engine/ribbon.d.ts +58 -0
- package/dist/components/text/engine/ribbon.d.ts.map +1 -0
- package/dist/components/text/engine/ribbon.js +250 -0
- package/dist/components/text/engine/variants.d.ts +159 -0
- package/dist/components/text/engine/variants.d.ts.map +1 -0
- package/dist/components/text/engine/variants.js +378 -0
- package/dist/components/text/fonts/architects-daughter.outline.d.ts +3 -0
- package/dist/components/text/fonts/architects-daughter.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/architects-daughter.outline.js +4 -0
- package/dist/components/text/fonts/architects-daughter.strokes.d.ts +3 -0
- package/dist/components/text/fonts/architects-daughter.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/architects-daughter.strokes.js +4 -0
- package/dist/components/text/fonts/caveat.outline.d.ts +3 -0
- package/dist/components/text/fonts/caveat.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/caveat.outline.js +4 -0
- package/dist/components/text/fonts/caveat.strokes.d.ts +3 -0
- package/dist/components/text/fonts/caveat.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/caveat.strokes.js +4 -0
- package/dist/components/text/fonts/courgette.outline.d.ts +3 -0
- package/dist/components/text/fonts/courgette.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/courgette.outline.js +4 -0
- package/dist/components/text/fonts/courgette.strokes.d.ts +3 -0
- package/dist/components/text/fonts/courgette.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/courgette.strokes.js +4 -0
- package/dist/components/text/fonts/dancing-script.outline.d.ts +3 -0
- package/dist/components/text/fonts/dancing-script.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/dancing-script.outline.js +4 -0
- package/dist/components/text/fonts/dancing-script.strokes.d.ts +3 -0
- package/dist/components/text/fonts/dancing-script.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/dancing-script.strokes.js +4 -0
- package/dist/components/text/fonts/gochi-hand.outline.d.ts +3 -0
- package/dist/components/text/fonts/gochi-hand.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/gochi-hand.outline.js +4 -0
- package/dist/components/text/fonts/gochi-hand.strokes.d.ts +3 -0
- package/dist/components/text/fonts/gochi-hand.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/gochi-hand.strokes.js +4 -0
- package/dist/components/text/fonts/handlee.outline.d.ts +3 -0
- package/dist/components/text/fonts/handlee.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/handlee.outline.js +4 -0
- package/dist/components/text/fonts/handlee.strokes.d.ts +3 -0
- package/dist/components/text/fonts/handlee.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/handlee.strokes.js +4 -0
- package/dist/components/text/fonts/index.d.ts +5 -0
- package/dist/components/text/fonts/index.d.ts.map +1 -0
- package/dist/components/text/fonts/index.js +44 -0
- package/dist/components/text/fonts/indie-flower.outline.d.ts +3 -0
- package/dist/components/text/fonts/indie-flower.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/indie-flower.outline.js +4 -0
- package/dist/components/text/fonts/indie-flower.strokes.d.ts +3 -0
- package/dist/components/text/fonts/indie-flower.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/indie-flower.strokes.js +4 -0
- package/dist/components/text/fonts/kalam.outline.d.ts +3 -0
- package/dist/components/text/fonts/kalam.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/kalam.outline.js +4 -0
- package/dist/components/text/fonts/kalam.strokes.d.ts +3 -0
- package/dist/components/text/fonts/kalam.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/kalam.strokes.js +4 -0
- package/dist/components/text/fonts/kaushan-script.outline.d.ts +3 -0
- package/dist/components/text/fonts/kaushan-script.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/kaushan-script.outline.js +4 -0
- package/dist/components/text/fonts/kaushan-script.strokes.d.ts +3 -0
- package/dist/components/text/fonts/kaushan-script.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/kaushan-script.strokes.js +4 -0
- package/dist/components/text/fonts/mynerve.outline.d.ts +3 -0
- package/dist/components/text/fonts/mynerve.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/mynerve.outline.js +4 -0
- package/dist/components/text/fonts/mynerve.strokes.d.ts +3 -0
- package/dist/components/text/fonts/mynerve.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/mynerve.strokes.js +4 -0
- package/dist/components/text/fonts/nanum-pen-script.outline.d.ts +3 -0
- package/dist/components/text/fonts/nanum-pen-script.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/nanum-pen-script.outline.js +4 -0
- package/dist/components/text/fonts/nanum-pen-script.strokes.d.ts +3 -0
- package/dist/components/text/fonts/nanum-pen-script.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/nanum-pen-script.strokes.js +4 -0
- package/dist/components/text/fonts/pacifico.outline.d.ts +3 -0
- package/dist/components/text/fonts/pacifico.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/pacifico.outline.js +4 -0
- package/dist/components/text/fonts/pacifico.strokes.d.ts +3 -0
- package/dist/components/text/fonts/pacifico.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/pacifico.strokes.js +4 -0
- package/dist/components/text/fonts/patrick-hand.outline.d.ts +3 -0
- package/dist/components/text/fonts/patrick-hand.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/patrick-hand.outline.js +4 -0
- package/dist/components/text/fonts/patrick-hand.strokes.d.ts +3 -0
- package/dist/components/text/fonts/patrick-hand.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/patrick-hand.strokes.js +4 -0
- package/dist/components/text/fonts/poppins.outline.d.ts +3 -0
- package/dist/components/text/fonts/poppins.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/poppins.outline.js +4 -0
- package/dist/components/text/fonts/poppins.strokes.d.ts +3 -0
- package/dist/components/text/fonts/poppins.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/poppins.strokes.js +4 -0
- package/dist/components/text/fonts/satisfy.outline.d.ts +3 -0
- package/dist/components/text/fonts/satisfy.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/satisfy.outline.js +4 -0
- package/dist/components/text/fonts/satisfy.strokes.d.ts +3 -0
- package/dist/components/text/fonts/satisfy.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/satisfy.strokes.js +4 -0
- package/dist/components/text/fonts/sriracha.outline.d.ts +3 -0
- package/dist/components/text/fonts/sriracha.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/sriracha.outline.js +4 -0
- package/dist/components/text/fonts/sriracha.strokes.d.ts +3 -0
- package/dist/components/text/fonts/sriracha.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/sriracha.strokes.js +4 -0
- package/dist/components/text/index.d.ts +27 -0
- package/dist/components/text/index.d.ts.map +1 -0
- package/dist/components/text/index.js +13 -0
- package/dist/components/text/useTextObject.d.ts +21 -0
- package/dist/components/text/useTextObject.d.ts.map +1 -0
- package/dist/components/text/useTextObject.js +118 -0
- package/dist/components/water/OceanSurface.d.ts.map +1 -1
- package/dist/components/water/OceanSurface.js +3 -1
- package/dist/components/water/WaterBody.d.ts.map +1 -1
- package/dist/components/water/WaterBody.js +3 -1
- package/dist/components/water/types.d.ts +5 -1
- package/dist/components/water/types.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useCloudSun.d.ts +9 -4
- package/dist/hooks/useCloudSun.d.ts.map +1 -1
- package/dist/hooks/useCloudSun.js +17 -7
- package/dist/hooks/useConfigLive.d.ts +3 -2
- package/dist/hooks/useConfigLive.d.ts.map +1 -1
- package/dist/hooks/useContinuousEffects.d.ts.map +1 -1
- package/dist/hooks/useContinuousEffects.js +4 -10
- package/dist/hooks/useEnvironmentProbe.d.ts +3 -22
- package/dist/hooks/useEnvironmentProbe.d.ts.map +1 -1
- package/dist/hooks/useEnvironmentProbe.js +47 -8
- package/dist/hooks/useGridSurface.d.ts +3 -10
- package/dist/hooks/useGridSurface.d.ts.map +1 -1
- package/dist/hooks/useGridSurface.js +5 -31
- package/dist/hooks/useInteraction.d.ts.map +1 -1
- package/dist/hooks/useInteraction.js +19 -72
- package/dist/hooks/useLightConfig.d.ts +2 -1
- package/dist/hooks/useLightConfig.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.d.ts +6 -2
- package/dist/hooks/useOceanMaterial.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.js +37 -2
- package/dist/hooks/useSkyLive.d.ts +23 -0
- package/dist/hooks/useSkyLive.d.ts.map +1 -0
- package/dist/hooks/useSkyLive.js +30 -0
- package/dist/hooks/useSkyUniforms.d.ts.map +1 -1
- package/dist/hooks/useSkyUniforms.js +2 -10
- package/dist/hooks/useTerrainLive.d.ts +3 -1
- package/dist/hooks/useTerrainLive.d.ts.map +1 -1
- package/dist/hooks/useTerrainTextures.d.ts +38 -0
- package/dist/hooks/useTerrainTextures.d.ts.map +1 -0
- package/dist/hooks/useTerrainTextures.js +149 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/operations/catalogue/blastOff.d.ts +3 -0
- package/dist/operations/catalogue/blastOff.d.ts.map +1 -0
- package/dist/operations/catalogue/blastOff.js +118 -0
- package/dist/operations/catalogue/bounce.d.ts +3 -0
- package/dist/operations/catalogue/bounce.d.ts.map +1 -0
- package/dist/operations/catalogue/bounce.js +34 -0
- package/dist/operations/catalogue/curlSmoke.d.ts.map +1 -1
- package/dist/operations/catalogue/curlSmoke.js +3 -1
- package/dist/operations/catalogue/dissolve.d.ts.map +1 -1
- package/dist/operations/catalogue/dissolve.js +2 -1
- package/dist/operations/catalogue/driftUp.d.ts +3 -0
- package/dist/operations/catalogue/driftUp.d.ts.map +1 -0
- package/dist/operations/catalogue/driftUp.js +57 -0
- package/dist/operations/catalogue/emberAsh.d.ts.map +1 -1
- package/dist/operations/catalogue/emberAsh.js +2 -1
- package/dist/operations/catalogue/flip.d.ts.map +1 -1
- package/dist/operations/catalogue/flip.js +19 -9
- package/dist/operations/catalogue/float.d.ts +3 -0
- package/dist/operations/catalogue/float.d.ts.map +1 -0
- package/dist/operations/catalogue/float.js +39 -0
- package/dist/operations/catalogue/flyBy.d.ts +3 -0
- package/dist/operations/catalogue/flyBy.d.ts.map +1 -0
- package/dist/operations/catalogue/flyBy.js +79 -0
- package/dist/operations/catalogue/frost.d.ts.map +1 -1
- package/dist/operations/catalogue/frost.js +10 -3
- package/dist/operations/catalogue/grow.d.ts +3 -0
- package/dist/operations/catalogue/grow.d.ts.map +1 -0
- package/dist/operations/catalogue/grow.js +19 -0
- package/dist/operations/catalogue/hologram.d.ts.map +1 -1
- package/dist/operations/catalogue/hologram.js +11 -5
- package/dist/operations/catalogue/jelly.d.ts.map +1 -1
- package/dist/operations/catalogue/jelly.js +18 -8
- package/dist/operations/catalogue/knockAway.d.ts +3 -0
- package/dist/operations/catalogue/knockAway.d.ts.map +1 -0
- package/dist/operations/catalogue/knockAway.js +74 -0
- package/dist/operations/catalogue/leafFall.d.ts +3 -0
- package/dist/operations/catalogue/leafFall.d.ts.map +1 -0
- package/dist/operations/catalogue/leafFall.js +74 -0
- package/dist/operations/catalogue/lidarScan.d.ts.map +1 -1
- package/dist/operations/catalogue/lidarScan.js +4 -1
- package/dist/operations/catalogue/metalize.d.ts.map +1 -1
- package/dist/operations/catalogue/metalize.js +8 -2
- package/dist/operations/catalogue/motionTrail.d.ts +6 -0
- package/dist/operations/catalogue/motionTrail.d.ts.map +1 -0
- package/dist/operations/catalogue/motionTrail.js +221 -0
- package/dist/operations/catalogue/petrify.d.ts.map +1 -1
- package/dist/operations/catalogue/petrify.js +9 -3
- package/dist/operations/catalogue/physicalExit.d.ts +55 -0
- package/dist/operations/catalogue/physicalExit.d.ts.map +1 -0
- package/dist/operations/catalogue/physicalExit.js +165 -0
- package/dist/operations/catalogue/physicalHeld.d.ts +41 -0
- package/dist/operations/catalogue/physicalHeld.d.ts.map +1 -0
- package/dist/operations/catalogue/physicalHeld.js +78 -0
- package/dist/operations/catalogue/physicalMix.d.ts +45 -0
- package/dist/operations/catalogue/physicalMix.d.ts.map +1 -0
- package/dist/operations/catalogue/physicalMix.js +144 -0
- package/dist/operations/catalogue/pop.d.ts +3 -0
- package/dist/operations/catalogue/pop.d.ts.map +1 -0
- package/dist/operations/catalogue/pop.js +44 -0
- package/dist/operations/catalogue/print3d.d.ts.map +1 -1
- package/dist/operations/catalogue/print3d.js +5 -1
- package/dist/operations/catalogue/pulse.d.ts +3 -0
- package/dist/operations/catalogue/pulse.d.ts.map +1 -0
- package/dist/operations/catalogue/pulse.js +29 -0
- package/dist/operations/catalogue/restPose.d.ts +5 -7
- package/dist/operations/catalogue/restPose.d.ts.map +1 -1
- package/dist/operations/catalogue/restPose.js +18 -48
- package/dist/operations/catalogue/rotate.d.ts +3 -0
- package/dist/operations/catalogue/rotate.d.ts.map +1 -0
- package/dist/operations/catalogue/rotate.js +49 -0
- package/dist/operations/catalogue/shake.d.ts +3 -0
- package/dist/operations/catalogue/shake.d.ts.map +1 -0
- package/dist/operations/catalogue/shake.js +31 -0
- package/dist/operations/catalogue/shatter.d.ts.map +1 -1
- package/dist/operations/catalogue/shatter.js +5 -1
- package/dist/operations/catalogue/slam.d.ts +3 -0
- package/dist/operations/catalogue/slam.d.ts.map +1 -0
- package/dist/operations/catalogue/slam.js +89 -0
- package/dist/operations/catalogue/slingshot.d.ts +3 -0
- package/dist/operations/catalogue/slingshot.d.ts.map +1 -0
- package/dist/operations/catalogue/slingshot.js +88 -0
- package/dist/operations/catalogue/spin.d.ts.map +1 -1
- package/dist/operations/catalogue/spin.js +24 -13
- package/dist/operations/catalogue/sway.d.ts +3 -0
- package/dist/operations/catalogue/sway.d.ts.map +1 -0
- package/dist/operations/catalogue/sway.js +23 -0
- package/dist/operations/catalogue/swirl.d.ts.map +1 -1
- package/dist/operations/catalogue/swirl.js +6 -5
- package/dist/operations/catalogue/trailCore.d.ts +89 -0
- package/dist/operations/catalogue/trailCore.d.ts.map +1 -0
- package/dist/operations/catalogue/trailCore.js +190 -0
- package/dist/operations/catalogue/trailGhosts.d.ts +5 -0
- package/dist/operations/catalogue/trailGhosts.d.ts.map +1 -0
- package/dist/operations/catalogue/trailGhosts.js +179 -0
- package/dist/operations/catalogue/trailStampStyles.d.ts +11 -0
- package/dist/operations/catalogue/trailStampStyles.d.ts.map +1 -0
- package/dist/operations/catalogue/trailStampStyles.js +479 -0
- package/dist/operations/catalogue/trailStamps.d.ts +57 -0
- package/dist/operations/catalogue/trailStamps.d.ts.map +1 -0
- package/dist/operations/catalogue/trailStamps.js +349 -0
- package/dist/operations/catalogue/trailStreaks.d.ts +3 -0
- package/dist/operations/catalogue/trailStreaks.d.ts.map +1 -0
- package/dist/operations/catalogue/trailStreaks.js +147 -0
- package/dist/operations/catalogue/transitionField.d.ts +30 -0
- package/dist/operations/catalogue/transitionField.d.ts.map +1 -1
- package/dist/operations/catalogue/transitionField.js +21 -0
- package/dist/operations/catalogue/turnAway.d.ts +3 -0
- package/dist/operations/catalogue/turnAway.d.ts.map +1 -0
- package/dist/operations/catalogue/turnAway.js +54 -0
- package/dist/operations/catalogue/vortexDrain.d.ts +3 -0
- package/dist/operations/catalogue/vortexDrain.d.ts.map +1 -0
- package/dist/operations/catalogue/vortexDrain.js +68 -0
- package/dist/operations/catalogue/warp.d.ts +3 -0
- package/dist/operations/catalogue/warp.d.ts.map +1 -0
- package/dist/operations/catalogue/warp.js +73 -0
- package/dist/operations/catalogue/whoosh.d.ts +3 -0
- package/dist/operations/catalogue/whoosh.d.ts.map +1 -0
- package/dist/operations/catalogue/whoosh.js +84 -0
- package/dist/operations/catalogue/wobble.d.ts +3 -0
- package/dist/operations/catalogue/wobble.d.ts.map +1 -0
- package/dist/operations/catalogue/wobble.js +23 -0
- package/dist/operations/clipPreview.d.ts +3 -0
- package/dist/operations/clipPreview.d.ts.map +1 -0
- package/dist/operations/clipPreview.js +20 -0
- package/dist/operations/groupFanout.d.ts +96 -0
- package/dist/operations/groupFanout.d.ts.map +1 -0
- package/dist/operations/groupFanout.js +365 -0
- package/dist/operations/groups.d.ts +20 -0
- package/dist/operations/groups.d.ts.map +1 -0
- package/dist/operations/groups.js +66 -0
- package/dist/operations/index.d.ts +5 -2
- package/dist/operations/index.d.ts.map +1 -1
- package/dist/operations/index.js +5 -2
- package/dist/operations/objectEffects.d.ts +161 -6
- package/dist/operations/objectEffects.d.ts.map +1 -1
- package/dist/operations/objectEffects.js +1091 -17
- package/dist/operations/registry.d.ts.map +1 -1
- package/dist/operations/registry.js +24 -2
- package/dist/operations/runtime.d.ts +57 -2
- package/dist/operations/runtime.d.ts.map +1 -1
- package/dist/operations/runtime.js +161 -18
- package/dist/operations/types.d.ts +60 -3
- package/dist/operations/types.d.ts.map +1 -1
- package/dist/operations/types.js +5 -1
- package/dist/operations/useObjectEffectLayers.d.ts +2 -2
- package/dist/operations/useObjectEffectLayers.d.ts.map +1 -1
- package/dist/operations/useObjectEffectLayers.js +31 -10
- package/dist/operations/usePresentedVisibility.d.ts +10 -0
- package/dist/operations/usePresentedVisibility.d.ts.map +1 -0
- package/dist/operations/usePresentedVisibility.js +53 -0
- package/dist/presets/terrainBiomes.d.ts +67 -0
- package/dist/presets/terrainBiomes.d.ts.map +1 -0
- package/dist/presets/terrainBiomes.js +294 -0
- package/dist/presets/terrainPresets.d.ts +6 -0
- package/dist/presets/terrainPresets.d.ts.map +1 -1
- package/dist/presets/terrainPresets.js +26 -38
- package/dist/shaders/glsl/oceanCore.glsl.d.ts +2 -2
- package/dist/shaders/glsl/oceanCore.glsl.d.ts.map +1 -1
- package/dist/shaders/glsl/oceanCore.glsl.js +17 -0
- package/dist/shaders/glsl/surfaceCore.glsl.d.ts +21 -0
- package/dist/shaders/glsl/surfaceCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/surfaceCore.glsl.js +120 -0
- package/dist/shaders/glsl/terrainCore.glsl.d.ts +16 -3
- package/dist/shaders/glsl/terrainCore.glsl.d.ts.map +1 -1
- package/dist/shaders/glsl/terrainCore.glsl.js +266 -20
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +2 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -1
- package/dist/shaders/ocean/OceanSurfaceMaterial.js +3 -0
- package/dist/shaders/terrain/TerrainMaterial.d.ts +17 -0
- package/dist/shaders/terrain/TerrainMaterial.d.ts.map +1 -1
- package/dist/shaders/terrain/TerrainMaterial.js +107 -8
- package/dist/triggers/engine.d.ts +44 -0
- package/dist/triggers/engine.d.ts.map +1 -0
- package/dist/triggers/engine.js +165 -0
- package/dist/triggers/hosts/actions.d.ts +8 -0
- package/dist/triggers/hosts/actions.d.ts.map +1 -0
- package/dist/triggers/hosts/actions.js +22 -0
- package/dist/triggers/hosts/interactions.d.ts +6 -0
- package/dist/triggers/hosts/interactions.d.ts.map +1 -0
- package/dist/triggers/hosts/interactions.js +4 -0
- package/dist/triggers/hosts/timelineCues.d.ts +2 -0
- package/dist/triggers/hosts/timelineCues.d.ts.map +1 -0
- package/dist/triggers/hosts/timelineCues.js +22 -0
- package/dist/triggers/index.d.ts +13 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/index.js +9 -0
- package/dist/triggers/kinds/action.d.ts +2 -0
- package/dist/triggers/kinds/action.d.ts.map +1 -0
- package/dist/triggers/kinds/action.js +31 -0
- package/dist/triggers/kinds/animations.d.ts +2 -0
- package/dist/triggers/kinds/animations.d.ts.map +1 -0
- package/dist/triggers/kinds/animations.js +75 -0
- package/dist/triggers/kinds/effects.d.ts +2 -0
- package/dist/triggers/kinds/effects.d.ts.map +1 -0
- package/dist/triggers/kinds/effects.js +27 -0
- package/dist/triggers/kinds/index.d.ts +4 -0
- package/dist/triggers/kinds/index.d.ts.map +1 -0
- package/dist/triggers/kinds/index.js +4 -0
- package/dist/triggers/log.d.ts +21 -0
- package/dist/triggers/log.d.ts.map +1 -0
- package/dist/triggers/log.js +43 -0
- package/dist/triggers/readiness.d.ts +40 -0
- package/dist/triggers/readiness.d.ts.map +1 -0
- package/dist/triggers/readiness.js +158 -0
- package/dist/triggers/registry.d.ts +41 -0
- package/dist/triggers/registry.d.ts.map +1 -0
- package/dist/triggers/registry.js +7 -0
- package/dist/types/gridConfigs.d.ts +117 -19
- package/dist/types/gridConfigs.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui/UiAnchorUpdater.d.ts +10 -0
- package/dist/ui/UiAnchorUpdater.d.ts.map +1 -0
- package/dist/ui/UiAnchorUpdater.js +111 -0
- package/dist/ui/UiLayers.d.ts +20 -0
- package/dist/ui/UiLayers.d.ts.map +1 -0
- package/dist/ui/UiLayers.js +57 -0
- package/dist/ui/index.d.ts +9 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +6 -0
- package/dist/ui/uiAnchors.d.ts +21 -0
- package/dist/ui/uiAnchors.d.ts.map +1 -0
- package/dist/ui/uiAnchors.js +22 -0
- package/dist/ui/uiBaseStyles.d.ts +2 -0
- package/dist/ui/uiBaseStyles.d.ts.map +1 -0
- package/dist/ui/uiBaseStyles.js +100 -0
- package/dist/ui/uiBinder.d.ts +30 -0
- package/dist/ui/uiBinder.d.ts.map +1 -0
- package/dist/ui/uiBinder.js +344 -0
- package/dist/utils/configAnimations.d.ts.map +1 -1
- package/dist/utils/configAnimations.js +5 -1
- package/dist/utils/gridConfig.d.ts +1 -1
- package/dist/utils/gridConfig.d.ts.map +1 -1
- package/dist/utils/gridConfig.js +1 -1
- package/dist/utils/landPatch.d.ts +33 -0
- package/dist/utils/landPatch.d.ts.map +1 -0
- package/dist/utils/landPatch.js +114 -0
- package/dist/utils/renderedSky.d.ts +32 -0
- package/dist/utils/renderedSky.d.ts.map +1 -0
- package/dist/utils/renderedSky.js +57 -0
- package/dist/utils/skyMoon.d.ts +35 -0
- package/dist/utils/skyMoon.d.ts.map +1 -0
- package/dist/utils/skyMoon.js +41 -0
- package/dist/utils/terrainHeight.d.ts +4 -0
- package/dist/utils/terrainHeight.d.ts.map +1 -0
- package/dist/utils/terrainHeight.js +150 -0
- package/dist/utils/terrainTextureResolver.d.ts +18 -0
- package/dist/utils/terrainTextureResolver.d.ts.map +1 -0
- package/dist/utils/terrainTextureResolver.js +17 -0
- package/dist/utils/terrainUniforms.d.ts +17 -0
- package/dist/utils/terrainUniforms.d.ts.map +1 -1
- package/dist/utils/terrainUniforms.js +84 -0
- package/dist/utils/textureArrays.d.ts +29 -0
- package/dist/utils/textureArrays.d.ts.map +1 -0
- package/dist/utils/textureArrays.js +140 -0
- package/package.json +2 -2
|
@@ -0,0 +1,763 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { REVEAL_UNIFORMS, uniformsBase, frag, setReveal } from '../ribbon.js';
|
|
3
|
+
import { prepare, applyDraw, applyErase, extentOf, DRAW_METHODS, ERASE_METHODS } from '../methods.js';
|
|
4
|
+
// =========================================================================================
|
|
5
|
+
// plasmaDischarge — dielectric breakdown (Lichtenberg figure) along the letter contours.
|
|
6
|
+
//
|
|
7
|
+
// MATHS / PHYSICS
|
|
8
|
+
// * The letter contours are the main conducting channels: a thin white-hot core (the arc column) inside a wider
|
|
9
|
+
// violet-blue N2 glow, both rendered as an exact distance field of the polyline (MAX-blended capsules).
|
|
10
|
+
// * Streamers are generated ONCE at build time by a seeded growth process (mulberry32 + `seed`): trunks leave the
|
|
11
|
+
// contour on the outward normal, weighted by convexity (field enhancement: stroke ends and corners spark most);
|
|
12
|
+
// each path is a midpoint-displaced crooked line, then forks recursively at shallow angles (16-37 deg) with
|
|
13
|
+
// length decaying per generation (dense near the channel, thinning with distance). A coarse occupancy grid
|
|
14
|
+
// (letters + every earlier streamer) truncates a branch where it would cross anything: no crossings, no tangle.
|
|
15
|
+
// Every branch carries a monotone random rank, so `branches` simply selects the subtree whose rank is below it.
|
|
16
|
+
// * Time: the leader races both ways round each contour from its sharpest point; a streamer is born where its
|
|
17
|
+
// parent was at that moment and grows ~2.4x faster than the leader (birth = parent birth + length / speed),
|
|
18
|
+
// which is written into the shared per-point schedule so every draw method works.
|
|
19
|
+
// * Colour is a quantity: channel temperature h = base + fresh-strike front + slow cooling burst + current pulse.
|
|
20
|
+
// h maps through a perceptual ramp afterglow-magenta -> colour (violet) -> colour2 (hot blue-white).
|
|
21
|
+
// * Idle: current pulses (soft tail, sharp front) travel along every contour and continue up the streamers that
|
|
22
|
+
// root there; the pulse phase is integrated on the CPU. Terminal streamers breathe in length, each with its own
|
|
23
|
+
// phase; all flicker is smooth value noise in time.
|
|
24
|
+
// * Erase: streamers/channels extinguish and cool through the ramp into a fading magenta afterglow.
|
|
25
|
+
// =========================================================================================
|
|
26
|
+
const hex = (h) => new THREE.Color(h);
|
|
27
|
+
function mulberry32(a) { return function () { a |= 0; a = (a + 0x6d2b79f5) | 0; let t = Math.imul(a ^ (a >>> 15), 1 | a); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; }
|
|
28
|
+
const clamp = (x, a, b) => Math.max(a, Math.min(b, x));
|
|
29
|
+
const sstep = (a, b, x) => { const t = clamp((x - a) / (b - a), 0, 1); return t * t * (3 - 2 * t); };
|
|
30
|
+
const REACH_MAX = 1.0; // em: the longest a streamer is ever generated (the live `reach` knob clips below it)
|
|
31
|
+
const SEG_CAP = 15000; // instance budget for branch segments
|
|
32
|
+
const W_SCALE = [1, 0.62, 0.46, 0.34, 0.26]; // core width per generation
|
|
33
|
+
const H_SCALE = [1, 0.72, 0.56, 0.46, 0.4]; // halo radius per generation
|
|
34
|
+
// ---------------------------------------------------------------------------------------------
|
|
35
|
+
// build-time: outward normals, convexity, material mask
|
|
36
|
+
// ---------------------------------------------------------------------------------------------
|
|
37
|
+
function glyphEdges(strokes, gN) {
|
|
38
|
+
const E = [];
|
|
39
|
+
for (let g = 0; g < gN; g++)
|
|
40
|
+
E.push([]);
|
|
41
|
+
for (const s of strokes) {
|
|
42
|
+
const n = s.pts.length / 2;
|
|
43
|
+
for (let i = 0; i < n - 1; i++)
|
|
44
|
+
E[s.glyph].push(s.pts[2 * i], s.pts[2 * i + 1], s.pts[2 * i + 2], s.pts[2 * i + 3]);
|
|
45
|
+
}
|
|
46
|
+
return E;
|
|
47
|
+
}
|
|
48
|
+
function insideGlyph(edges, x, y) {
|
|
49
|
+
let c = false;
|
|
50
|
+
for (let i = 0; i < edges.length; i += 4) {
|
|
51
|
+
const ax = edges[i], ay = edges[i + 1], bx = edges[i + 2], by = edges[i + 3];
|
|
52
|
+
if ((ay <= y) !== (by <= y)) {
|
|
53
|
+
const xx = ax + ((y - ay) / (by - ay)) * (bx - ax);
|
|
54
|
+
if (xx > x)
|
|
55
|
+
c = !c;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return c;
|
|
59
|
+
}
|
|
60
|
+
// per contour point: outward normal (out of the letter material) and convexity (1/em, > 0 on a convex corner)
|
|
61
|
+
function contourInfo(s, edges) {
|
|
62
|
+
const m = s.pts.length / 2 - 1;
|
|
63
|
+
const P = s.pts;
|
|
64
|
+
const nx = new Float32Array(m), ny = new Float32Array(m), conv = new Float32Array(m);
|
|
65
|
+
// index step so the chord spans ~0.05 em
|
|
66
|
+
const mean = s.len / m;
|
|
67
|
+
const k = Math.max(1, Math.round(0.05 / Math.max(1e-6, mean)));
|
|
68
|
+
for (let i = 0; i < m; i++) {
|
|
69
|
+
const a = (i - k + m * 4) % m, b = (i + k) % m;
|
|
70
|
+
let tx = P[2 * b] - P[2 * a], ty = P[2 * b + 1] - P[2 * a + 1];
|
|
71
|
+
const tl = Math.hypot(tx, ty) || 1;
|
|
72
|
+
tx /= tl;
|
|
73
|
+
ty /= tl;
|
|
74
|
+
let ox = ty, oy = -tx;
|
|
75
|
+
if (insideGlyph(edges, P[2 * i] + ox * 0.012, P[2 * i + 1] + oy * 0.012)) {
|
|
76
|
+
ox = -ox;
|
|
77
|
+
oy = -oy;
|
|
78
|
+
}
|
|
79
|
+
nx[i] = ox;
|
|
80
|
+
ny[i] = oy;
|
|
81
|
+
const cx = P[2 * a] + P[2 * b] - 2 * P[2 * i], cy = P[2 * a + 1] + P[2 * b + 1] - 2 * P[2 * i + 1];
|
|
82
|
+
const ch = Math.hypot(P[2 * b] - P[2 * a], P[2 * b + 1] - P[2 * a + 1]) * 0.5 + 1e-4;
|
|
83
|
+
conv[i] = -(cx * ox + cy * oy) / (ch * ch);
|
|
84
|
+
}
|
|
85
|
+
return { nx, ny, conv, k, m };
|
|
86
|
+
}
|
|
87
|
+
// Field-driven dielectric breakdown (DBM) growth.
|
|
88
|
+
// 1. Solve Laplace's equation div grad(phi) = 0 on a coarse grid: letters (and later every streamer) are conductors at
|
|
89
|
+
// phi = 1, the far boundary is ground at phi = 0. The start guess is the log-potential of the nearest conductor and
|
|
90
|
+
// SOR sweeps relax it, so the field piles up on stroke ends and corners all by itself.
|
|
91
|
+
// 2. Streamers are grown tip by tip, all tips interleaved (competition). A tip samples a fan of candidate directions and
|
|
92
|
+
// picks one with probability ~ (potential drop towards that direction)^eta: it follows the field lines, curves
|
|
93
|
+
// towards ground and bends around other letters. eta comes from `branchiness`.
|
|
94
|
+
// 3. Every new segment becomes a conductor (phi = 1) and the potential is re-relaxed around it, so neighbouring streamers
|
|
95
|
+
// screen each other: repulsion and gaps come out of the field, not from rejection tests.
|
|
96
|
+
// 4. A tip forks where the field at it is strong (fork chance ~ |E|), at shallow angles, with a shorter length budget.
|
|
97
|
+
function buildTree(strokes, gN, seed, info, branchiness) {
|
|
98
|
+
const rng = mulberry32((seed * 7919 + 1013) | 0);
|
|
99
|
+
const ETA = 12 - 9.5 * clamp(branchiness, 0, 1);
|
|
100
|
+
const ext = extentOf(strokes);
|
|
101
|
+
const PAD = REACH_MAX + 0.15;
|
|
102
|
+
const x0 = ext.x0 - PAD, y0 = ext.y0 - PAD, Wd = ext.w + 2 * PAD, Hd = ext.h + 2 * PAD;
|
|
103
|
+
let cell = 0.022;
|
|
104
|
+
while ((Wd / cell) * (Hd / cell) > 2.5e5)
|
|
105
|
+
cell *= 1.15;
|
|
106
|
+
const gw = Math.ceil(Wd / cell), gh = Math.ceil(Hd / cell), N = gw * gh;
|
|
107
|
+
const fixed = new Uint8Array(N); // 0 free, 1 conductor, 2 ground
|
|
108
|
+
const owner = new Int32Array(N).fill(-2); // -2 letter, >=0 streamer id
|
|
109
|
+
const phi = new Float32Array(N);
|
|
110
|
+
const cellOf = (x, y) => { const cx = Math.floor((x - x0) / cell), cy = Math.floor((y - y0) / cell); return cx < 1 || cy < 1 || cx >= gw - 1 || cy >= gh - 1 ? -1 : cy * gw + cx; };
|
|
111
|
+
const edges = glyphEdges(strokes, gN);
|
|
112
|
+
for (let g = 0; g < gN; g++) { // letter material (even-odd per glyph) is conductor
|
|
113
|
+
const E = edges[g];
|
|
114
|
+
if (!E.length)
|
|
115
|
+
continue;
|
|
116
|
+
let ya = 1e9, yb = -1e9;
|
|
117
|
+
for (let i = 1; i < E.length; i += 2) {
|
|
118
|
+
ya = Math.min(ya, E[i]);
|
|
119
|
+
yb = Math.max(yb, E[i]);
|
|
120
|
+
}
|
|
121
|
+
const r0 = Math.max(0, Math.floor((ya - y0) / cell)), r1 = Math.min(gh - 1, Math.ceil((yb - y0) / cell));
|
|
122
|
+
for (let r = r0; r <= r1; r++) {
|
|
123
|
+
const y = y0 + (r + 0.5) * cell;
|
|
124
|
+
const xs = [];
|
|
125
|
+
for (let i = 0; i < E.length; i += 4) {
|
|
126
|
+
const ay = E[i + 1], by = E[i + 3];
|
|
127
|
+
if ((ay <= y) !== (by <= y))
|
|
128
|
+
xs.push(E[i] + ((y - ay) / (by - ay)) * (E[i + 2] - E[i]));
|
|
129
|
+
}
|
|
130
|
+
xs.sort((a, b) => a - b);
|
|
131
|
+
for (let k = 0; k + 1 < xs.length; k += 2) {
|
|
132
|
+
const c0 = Math.max(0, Math.ceil((xs[k] - x0) / cell - 0.5)), c1 = Math.min(gw - 1, Math.floor((xs[k + 1] - x0) / cell - 0.5));
|
|
133
|
+
for (let c = c0; c <= c1; c++)
|
|
134
|
+
fixed[r * gw + c] = 1;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
for (const s of strokes) { // contour line itself (3x3 dilated) so thin letters are solid conductors
|
|
139
|
+
const n = s.pts.length / 2;
|
|
140
|
+
for (let i = 0; i < n - 1; i++) {
|
|
141
|
+
const ax = s.pts[2 * i], ay = s.pts[2 * i + 1], bx = s.pts[2 * i + 2], by = s.pts[2 * i + 3];
|
|
142
|
+
const l = Math.hypot(bx - ax, by - ay);
|
|
143
|
+
const st = Math.max(1, Math.ceil(l / (cell * 0.5)));
|
|
144
|
+
for (let q = 0; q <= st; q++) {
|
|
145
|
+
const c = cellOf(ax + (bx - ax) * q / st, ay + (by - ay) * q / st);
|
|
146
|
+
if (c < 0)
|
|
147
|
+
continue;
|
|
148
|
+
const cx = c % gw, cy = (c - cx) / gw;
|
|
149
|
+
for (let dy = -1; dy <= 1; dy++)
|
|
150
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
151
|
+
const X = cx + dx, Y = cy + dy;
|
|
152
|
+
if (X >= 0 && Y >= 0 && X < gw && Y < gh)
|
|
153
|
+
fixed[Y * gw + X] = 1;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
for (let x = 0; x < gw; x++) {
|
|
159
|
+
fixed[x] = 2;
|
|
160
|
+
fixed[(gh - 1) * gw + x] = 2;
|
|
161
|
+
}
|
|
162
|
+
for (let y = 0; y < gh; y++) {
|
|
163
|
+
fixed[y * gw] = 2;
|
|
164
|
+
fixed[y * gw + gw - 1] = 2;
|
|
165
|
+
}
|
|
166
|
+
// start guess: log potential of the nearest conductor (chamfer distance), then SOR relaxation
|
|
167
|
+
const dist = new Float32Array(N);
|
|
168
|
+
for (let i = 0; i < N; i++)
|
|
169
|
+
dist[i] = fixed[i] === 1 ? 0 : 1e9;
|
|
170
|
+
const rel = (i, v) => { if (v < dist[i])
|
|
171
|
+
dist[i] = v; };
|
|
172
|
+
for (let y = 1; y < gh - 1; y++)
|
|
173
|
+
for (let x = 1; x < gw - 1; x++) {
|
|
174
|
+
const i = y * gw + x;
|
|
175
|
+
rel(i, dist[i - 1] + 1);
|
|
176
|
+
rel(i, dist[i - gw] + 1);
|
|
177
|
+
rel(i, dist[i - gw - 1] + 1.414);
|
|
178
|
+
rel(i, dist[i - gw + 1] + 1.414);
|
|
179
|
+
}
|
|
180
|
+
for (let y = gh - 2; y > 0; y--)
|
|
181
|
+
for (let x = gw - 2; x > 0; x--) {
|
|
182
|
+
const i = y * gw + x;
|
|
183
|
+
rel(i, dist[i + 1] + 1);
|
|
184
|
+
rel(i, dist[i + gw] + 1);
|
|
185
|
+
rel(i, dist[i + gw + 1] + 1.414);
|
|
186
|
+
rel(i, dist[i + gw - 1] + 1.414);
|
|
187
|
+
}
|
|
188
|
+
const lnR = Math.log(1 + PAD / 0.04);
|
|
189
|
+
for (let i = 0; i < N; i++)
|
|
190
|
+
phi[i] = fixed[i] === 1 ? 1 : fixed[i] === 2 ? 0 : clamp(1 - Math.log(1 + (dist[i] * cell) / 0.04) / lnR, 0, 1);
|
|
191
|
+
const OM = 1.9;
|
|
192
|
+
function sweepAll(n) { for (let s = 0; s < n; s++)
|
|
193
|
+
for (let y = 1; y < gh - 1; y++)
|
|
194
|
+
for (let i = y * gw + 1, e = y * gw + gw - 1; i < e; i++) {
|
|
195
|
+
if (fixed[i])
|
|
196
|
+
continue;
|
|
197
|
+
phi[i] += OM * (0.25 * (phi[i - 1] + phi[i + 1] + phi[i - gw] + phi[i + gw]) - phi[i]);
|
|
198
|
+
} }
|
|
199
|
+
function sweepWin(cx, cy, R, n) {
|
|
200
|
+
const xa = Math.max(1, cx - R), xb = Math.min(gw - 2, cx + R), ya = Math.max(1, cy - R), yb = Math.min(gh - 2, cy + R);
|
|
201
|
+
for (let s = 0; s < n; s++)
|
|
202
|
+
for (let y = ya; y <= yb; y++)
|
|
203
|
+
for (let x = xa; x <= xb; x++) {
|
|
204
|
+
const i = y * gw + x;
|
|
205
|
+
if (fixed[i])
|
|
206
|
+
continue;
|
|
207
|
+
phi[i] += 1.5 * (0.25 * (phi[i - 1] + phi[i + 1] + phi[i - gw] + phi[i + gw]) - phi[i]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
sweepAll(Math.round(clamp(2.4e7 / N, 40, 160)));
|
|
211
|
+
const phiAt = (x, y) => {
|
|
212
|
+
const fx = (x - x0) / cell - 0.5, fy = (y - y0) / cell - 0.5;
|
|
213
|
+
const ix = Math.floor(fx), iy = Math.floor(fy);
|
|
214
|
+
if (ix < 0 || iy < 0 || ix >= gw - 1 || iy >= gh - 1)
|
|
215
|
+
return 0;
|
|
216
|
+
const tx = fx - ix, ty = fy - iy, a = iy * gw + ix;
|
|
217
|
+
return (phi[a] * (1 - tx) + phi[a + 1] * tx) * (1 - ty) + (phi[a + gw] * (1 - tx) + phi[a + gw + 1] * tx) * ty;
|
|
218
|
+
};
|
|
219
|
+
let Ex = 0, Ey = 0;
|
|
220
|
+
const fieldAt = (x, y) => { Ex = -(phiAt(x + cell, y) - phiAt(x - cell, y)) / (2 * cell); Ey = -(phiAt(x, y + cell) - phiAt(x, y - cell)) / (2 * cell); };
|
|
221
|
+
// trunk candidates: acceptance ~ field strength just outside the contour (field enhancement at ends and corners)
|
|
222
|
+
const probe = cell * 1.8;
|
|
223
|
+
const cands = [];
|
|
224
|
+
let Emax = 1e-6;
|
|
225
|
+
const samp = [];
|
|
226
|
+
strokes.forEach((s, si) => {
|
|
227
|
+
const I = info[si];
|
|
228
|
+
const m = I.m;
|
|
229
|
+
let d = 0.03 + rng() * 0.05;
|
|
230
|
+
let j = 0;
|
|
231
|
+
while (d < s.len) {
|
|
232
|
+
while (j < m - 1 && s.cum[j + 1] < d)
|
|
233
|
+
j++;
|
|
234
|
+
fieldAt(s.pts[2 * j] + I.nx[j] * probe, s.pts[2 * j + 1] + I.ny[j] * probe);
|
|
235
|
+
const e = Math.hypot(Ex, Ey);
|
|
236
|
+
samp.push({ si, idx: j, e, u: rng() });
|
|
237
|
+
Emax = Math.max(Emax, e);
|
|
238
|
+
d += 0.045 + rng() * 0.05;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
const sortedE = samp.map((c) => c.e).sort((a, b) => a - b);
|
|
242
|
+
const Eref = Math.max(1e-6, sortedE[Math.floor(sortedE.length * 0.92)] || Emax);
|
|
243
|
+
for (const c of samp) {
|
|
244
|
+
const w = clamp(0.3 + 0.7 * Math.pow(clamp(c.e / Eref, 0, 1.3), 0.8), 0, 1);
|
|
245
|
+
if (c.u < w)
|
|
246
|
+
cands.push({ si: c.si, idx: c.idx, rank: c.u / w, w });
|
|
247
|
+
}
|
|
248
|
+
cands.sort((a, b) => a.rank - b.rank);
|
|
249
|
+
const H = 0.04, KDIR = 9, SPAN = 1.0; // step (em), candidate fan, half-angle of the fan (rad)
|
|
250
|
+
const all = [];
|
|
251
|
+
const tips = [];
|
|
252
|
+
let total = 0, steps = 0;
|
|
253
|
+
const isAnc = (v, id) => { let b = id; while (b >= 0) {
|
|
254
|
+
if (b === v)
|
|
255
|
+
return true;
|
|
256
|
+
b = all[b].parent;
|
|
257
|
+
} return false; };
|
|
258
|
+
function fixSeg(ax, ay, bx, by, id) {
|
|
259
|
+
const l = Math.hypot(bx - ax, by - ay);
|
|
260
|
+
const st = Math.max(1, Math.ceil(l / (cell * 0.5)));
|
|
261
|
+
let lc = -1;
|
|
262
|
+
for (let q = 0; q <= st; q++) {
|
|
263
|
+
const c = cellOf(ax + ((bx - ax) * q) / st, ay + ((by - ay) * q) / st);
|
|
264
|
+
if (c < 0 || c === lc)
|
|
265
|
+
continue;
|
|
266
|
+
lc = c;
|
|
267
|
+
if (!fixed[c]) {
|
|
268
|
+
fixed[c] = 1;
|
|
269
|
+
owner[c] = id;
|
|
270
|
+
phi[c] = 1;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const c = cellOf((ax + bx) / 2, (ay + by) / 2);
|
|
274
|
+
if (c >= 0) {
|
|
275
|
+
const cx = c % gw;
|
|
276
|
+
sweepWin(cx, (c - cx) / gw, 8, 3);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function spawn(x, y, h, budget, level, parent, dist0, rank, root, forkCum, w) {
|
|
280
|
+
const id = all.length;
|
|
281
|
+
const b = { id, parent, level, rank, dist0, rootStroke: root.si, rootIdx: root.idx, forkCum, glyph: strokes[root.si].glyph, children: 0, phase: rng() * Math.PI * 2, seed: rng(),
|
|
282
|
+
p: [x, y], len: 0, h, budget, alive: true, since: 0, side: rng() < 0.5 ? 1 : -1 };
|
|
283
|
+
all.push(b);
|
|
284
|
+
tips.push(b);
|
|
285
|
+
if (parent >= 0)
|
|
286
|
+
all[parent].children++;
|
|
287
|
+
return b;
|
|
288
|
+
}
|
|
289
|
+
const roots = [];
|
|
290
|
+
for (const cd of cands) {
|
|
291
|
+
const s = strokes[cd.si], I = info[cd.si];
|
|
292
|
+
const i = cd.idx % I.m;
|
|
293
|
+
const px = s.pts[2 * i], py = s.pts[2 * i + 1];
|
|
294
|
+
if (roots.some((r) => (r[0] - px) * (r[0] - px) + (r[1] - py) * (r[1] - py) < 0.0064))
|
|
295
|
+
continue;
|
|
296
|
+
roots.push([px, py]);
|
|
297
|
+
const L = REACH_MAX * (0.34 + 0.66 * Math.pow(rng(), 1.5)) * (0.7 + 0.3 * cd.w);
|
|
298
|
+
spawn(px, py, Math.atan2(I.ny[i], I.nx[i]), L, 0, -1, 0, cd.rank, { si: cd.si, idx: i }, 0, cd.w);
|
|
299
|
+
}
|
|
300
|
+
const th = [];
|
|
301
|
+
for (let k = 0; k < KDIR; k++)
|
|
302
|
+
th.push(((k / (KDIR - 1)) * 2 - 1) * SPAN);
|
|
303
|
+
const wk = new Float32Array(KDIR), dr = new Float32Array(KDIR);
|
|
304
|
+
const bF = 0.55 + 0.9 * clamp(branchiness, 0, 1);
|
|
305
|
+
let active = tips.length;
|
|
306
|
+
while (active > 0 && total < SEG_CAP && steps < 60000) {
|
|
307
|
+
active = 0;
|
|
308
|
+
for (let ti = 0; ti < tips.length; ti++) {
|
|
309
|
+
const t = tips[ti];
|
|
310
|
+
if (!t.alive)
|
|
311
|
+
continue;
|
|
312
|
+
active++;
|
|
313
|
+
if (total >= SEG_CAP) {
|
|
314
|
+
t.alive = false;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
steps++;
|
|
318
|
+
const n = t.p.length;
|
|
319
|
+
const px = t.p[n - 2], py = t.p[n - 1];
|
|
320
|
+
fieldAt(px + Math.cos(t.h) * cell * 1.3, py + Math.sin(t.h) * cell * 1.3);
|
|
321
|
+
const Em = Math.hypot(Ex, Ey);
|
|
322
|
+
if (Em < 0.012 * Eref || t.len >= t.budget) {
|
|
323
|
+
t.alive = false;
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
// fork where the field at the tip is strong
|
|
327
|
+
t.since += H;
|
|
328
|
+
if (t.level < 4 && t.since >= 0.085 && t.len > 0.07) {
|
|
329
|
+
t.since = 0;
|
|
330
|
+
const pf = 0.8 * Math.pow(0.84, t.level) * clamp(0.3 + 0.9 * (Em / Eref), 0.3, 1.3) * bF;
|
|
331
|
+
const rem = t.budget - t.len;
|
|
332
|
+
if (rng() < pf && rem > 0.12 && t.dist0 + t.len < REACH_MAX - 0.1) {
|
|
333
|
+
t.side = -t.side;
|
|
334
|
+
const ca = t.h + t.side * (0.3 + 0.35 * rng());
|
|
335
|
+
const crank = t.rank + (1 - t.rank) * Math.pow(rng(), 1.2) * 0.85;
|
|
336
|
+
const ch = spawn(px, py, ca, Math.min(rem * (0.5 + 0.25 * rng()), REACH_MAX - t.dist0 - t.len), t.level + 1, t.id, t.dist0 + t.len, crank, { si: t.rootStroke, idx: t.rootIdx }, t.len, 0);
|
|
337
|
+
ch.ownerPar = t.id;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// choose a direction: p ~ (potential drop ahead)^eta, only with the field (E.d > 0)
|
|
341
|
+
let dmax = 1e-6, cnt = 0;
|
|
342
|
+
for (let k = 0; k < KDIR; k++) {
|
|
343
|
+
const a = t.h + th[k];
|
|
344
|
+
const ca = Math.cos(a), sa = Math.sin(a);
|
|
345
|
+
if (Ex * ca + Ey * sa <= 0) {
|
|
346
|
+
dr[k] = 0;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
dr[k] = Math.max(1e-5, 1 - phiAt(px + ca * H * 1.3, py + sa * H * 1.3)) * (0.35 + 0.65 * Math.cos(th[k] * 0.9));
|
|
350
|
+
dmax = Math.max(dmax, dr[k]);
|
|
351
|
+
cnt++;
|
|
352
|
+
}
|
|
353
|
+
if (!cnt) {
|
|
354
|
+
t.alive = false;
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
let sum = 0;
|
|
358
|
+
for (let k = 0; k < KDIR; k++) {
|
|
359
|
+
wk[k] = dr[k] > 0 ? Math.pow(dr[k] / dmax, ETA) : 0;
|
|
360
|
+
sum += wk[k];
|
|
361
|
+
}
|
|
362
|
+
let r = rng() * sum, kk = 0;
|
|
363
|
+
for (; kk < KDIR - 1; kk++) {
|
|
364
|
+
r -= wk[kk];
|
|
365
|
+
if (r <= 0)
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
const a = t.h + th[kk] + (rng() - 0.5) * 0.08;
|
|
369
|
+
const qx = px + Math.cos(a) * H, qy = py + Math.sin(a) * H;
|
|
370
|
+
// obstacles: a streamer stops at anything that is not its own trail (letters, other streamers, ground)
|
|
371
|
+
let hit = false;
|
|
372
|
+
const sl = Math.max(1, Math.ceil(H / (cell * 0.5)));
|
|
373
|
+
for (let q = 1; q <= sl && !hit; q++) {
|
|
374
|
+
const c = cellOf(px + ((qx - px) * q) / sl, py + ((qy - py) * q) / sl);
|
|
375
|
+
if (c < 0 || fixed[c] === 2) {
|
|
376
|
+
hit = true;
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
if (fixed[c] === 1 && t.len > 0.1) {
|
|
380
|
+
const o = owner[c];
|
|
381
|
+
if (o !== t.id && !(o >= 0 && t.len < 0.2 && isAnc(o, t.id)))
|
|
382
|
+
hit = true;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (hit) {
|
|
386
|
+
t.alive = false;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
fixSeg(px, py, qx, qy, t.id);
|
|
390
|
+
t.p.push(qx, qy);
|
|
391
|
+
t.len += H;
|
|
392
|
+
total++;
|
|
393
|
+
t.h = a;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
// finalise: drop stubs (unless they carry children), compact ids
|
|
397
|
+
const keep = all.filter((b) => b.p.length >= 6 && (b.len >= 0.09 || b.children > 0));
|
|
398
|
+
const idMap = new Map();
|
|
399
|
+
keep.forEach((b, i) => idMap.set(b.id, i));
|
|
400
|
+
const out = [];
|
|
401
|
+
for (const b of keep) {
|
|
402
|
+
let par = b.parent;
|
|
403
|
+
while (par >= 0 && !idMap.has(par))
|
|
404
|
+
par = all[par].parent;
|
|
405
|
+
const pts = Float32Array.from(b.p);
|
|
406
|
+
const n = pts.length / 2;
|
|
407
|
+
const cum = new Float32Array(n);
|
|
408
|
+
for (let i = 1; i < n; i++)
|
|
409
|
+
cum[i] = cum[i - 1] + Math.hypot(pts[2 * i] - pts[2 * i - 2], pts[2 * i + 1] - pts[2 * i - 1]);
|
|
410
|
+
out.push({ pts, cum, len: cum[n - 1], level: b.level, parent: par < 0 ? -1 : idMap.get(par), rank: b.rank, dist0: b.dist0, rootStroke: b.rootStroke, rootIdx: b.rootIdx, forkCum: b.forkCum,
|
|
411
|
+
glyph: b.glyph, leaf: true, phase: b.phase, seed: b.seed });
|
|
412
|
+
}
|
|
413
|
+
for (const b of out)
|
|
414
|
+
if (b.parent >= 0)
|
|
415
|
+
out[b.parent].leaf = false;
|
|
416
|
+
for (const b of out)
|
|
417
|
+
if (b.parent >= 0)
|
|
418
|
+
b.forkCum = Math.min(b.forkCum, out[b.parent].len);
|
|
419
|
+
return out;
|
|
420
|
+
}
|
|
421
|
+
// ---------------------------------------------------------------------------------------------
|
|
422
|
+
// schedule: look-native 'strike' + branch births for every method
|
|
423
|
+
// ---------------------------------------------------------------------------------------------
|
|
424
|
+
function strikeSched(strokes, o, G, info) {
|
|
425
|
+
const st = (o.stagger || 0.6) / G, win = 1 - (G - 1) * st;
|
|
426
|
+
return strokes.map((s, si) => {
|
|
427
|
+
const m = s.pts.length / 2;
|
|
428
|
+
const t = new Float32Array(m);
|
|
429
|
+
const k = info[si].start;
|
|
430
|
+
const c0 = s.cum[k];
|
|
431
|
+
for (let i = 0; i < m; i++) {
|
|
432
|
+
let u = (s.cum[i] - c0) / s.len;
|
|
433
|
+
u -= Math.floor(u);
|
|
434
|
+
t[i] = 2 * Math.min(u, 1 - u);
|
|
435
|
+
}
|
|
436
|
+
return { seg: [s.glyph * st, s.glyph * st + win], t };
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
function scheduleBranches(ch, brs, strike, clampEnd) {
|
|
440
|
+
let vr = 0;
|
|
441
|
+
for (const s of ch)
|
|
442
|
+
vr += s.len / Math.max(1e-3, (s.seg[1] - s.seg[0]) * (strike ? 2 : 1));
|
|
443
|
+
vr = Math.max(0.5, vr / Math.max(1, ch.length));
|
|
444
|
+
const vB = 2.4 * vr;
|
|
445
|
+
const lead = 0.006;
|
|
446
|
+
for (const b of brs) {
|
|
447
|
+
let tp;
|
|
448
|
+
if (b.parent < 0) {
|
|
449
|
+
const s = ch[b.rootStroke];
|
|
450
|
+
const t = s.t;
|
|
451
|
+
const i = Math.min(Math.floor(b.rootIdx), t.length - 2);
|
|
452
|
+
const fr = b.rootIdx - i;
|
|
453
|
+
tp = s.seg[0] + (t[i] + (t[i + 1] - t[i]) * fr) * (s.seg[1] - s.seg[0]);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
const p = brs[b.parent];
|
|
457
|
+
tp = p.seg[0] + (b.forkCum / p.len) * (p.seg[1] - p.seg[0]);
|
|
458
|
+
}
|
|
459
|
+
let s0 = Math.max(0, tp - (b.parent < 0 ? lead : 0));
|
|
460
|
+
const span = Math.max(0.01, b.len / vB);
|
|
461
|
+
let e0 = s0 + span;
|
|
462
|
+
if (clampEnd) {
|
|
463
|
+
e0 = Math.min(1, e0);
|
|
464
|
+
if (e0 - s0 < 0.012)
|
|
465
|
+
s0 = e0 - 0.012;
|
|
466
|
+
}
|
|
467
|
+
b.seg = [s0, e0];
|
|
468
|
+
b.t = Float32Array.from(b.cum, (c) => c / b.len);
|
|
469
|
+
}
|
|
470
|
+
if (!clampEnd) { // strike: stretch the whole schedule so the last streamer lands exactly at progress 1
|
|
471
|
+
let mx = 0;
|
|
472
|
+
for (const s of ch)
|
|
473
|
+
mx = Math.max(mx, s.seg[1]);
|
|
474
|
+
for (const b of brs)
|
|
475
|
+
mx = Math.max(mx, b.seg[1]);
|
|
476
|
+
const f = 1 / Math.max(1e-6, mx);
|
|
477
|
+
for (const s of ch)
|
|
478
|
+
s.seg = [s.seg[0] * f, s.seg[1] * f];
|
|
479
|
+
for (const b of brs)
|
|
480
|
+
b.seg = [b.seg[0] * f, b.seg[1] * f];
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
// ---------------------------------------------------------------------------------------------
|
|
484
|
+
// geometry: one instanced quad per polyline segment (channels + streamers), MAX-blended distance field
|
|
485
|
+
// ---------------------------------------------------------------------------------------------
|
|
486
|
+
function buildGeometry(ch, brs, pulseN, rng) {
|
|
487
|
+
let n = 0;
|
|
488
|
+
for (const s of ch)
|
|
489
|
+
n += s.pts.length / 2 - 1;
|
|
490
|
+
for (const b of brs)
|
|
491
|
+
n += b.pts.length / 2 - 1;
|
|
492
|
+
const A = new Float32Array(n * 2), B = new Float32Array(n * 2), T = new Float32Array(n * 2), TO = new Float32Array(n * 2), SG = new Float32Array(n * 2), SO = new Float32Array(n * 2), U = new Float32Array(n * 2), D = new Float32Array(n * 2), P = new Float32Array(n * 2), M = new Float32Array(n * 4), N = new Float32Array(n * 4);
|
|
493
|
+
let k = 0;
|
|
494
|
+
const pOff = new Float32Array(ch.length);
|
|
495
|
+
ch.forEach((s, si) => {
|
|
496
|
+
const m = s.pts.length / 2;
|
|
497
|
+
const np = pulseN[si];
|
|
498
|
+
const pa = 0.7 + 0.3 * rng();
|
|
499
|
+
const ph = rng() * 6.28, sd = rng();
|
|
500
|
+
const po = rng();
|
|
501
|
+
pOff[si] = po;
|
|
502
|
+
for (let i = 0; i < m - 1; i++, k++) {
|
|
503
|
+
A.set([s.pts[2 * i], s.pts[2 * i + 1]], 2 * k);
|
|
504
|
+
B.set([s.pts[2 * i + 2], s.pts[2 * i + 3]], 2 * k);
|
|
505
|
+
T.set([s.t[i], s.t[i + 1]], 2 * k);
|
|
506
|
+
TO.set([s.tO[i], s.tO[i + 1]], 2 * k);
|
|
507
|
+
SG.set(s.seg, 2 * k);
|
|
508
|
+
SO.set(s.segO, 2 * k);
|
|
509
|
+
const u0 = s.cum[i] / s.len, u1 = s.cum[i + 1] / s.len;
|
|
510
|
+
U.set([u0, u1], 2 * k);
|
|
511
|
+
D.set([0, 0], 2 * k);
|
|
512
|
+
P.set([np * u0 + po, np * u1 + po], 2 * k);
|
|
513
|
+
M.set([0, 0, 0, H_SCALE[0]], 4 * k);
|
|
514
|
+
N.set([0, ph, sd, pa], 4 * k);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
for (const b of brs) {
|
|
518
|
+
const m = b.pts.length / 2;
|
|
519
|
+
const rs = ch[b.rootStroke];
|
|
520
|
+
const np = pulseN[b.rootStroke];
|
|
521
|
+
const ri = Math.min(Math.floor(b.rootIdx), rs.pts.length / 2 - 2);
|
|
522
|
+
const u0r = (rs.cum[ri] + (rs.cum[ri + 1] - rs.cum[ri]) * (b.rootIdx - ri)) / rs.len;
|
|
523
|
+
const Kp = np / rs.len;
|
|
524
|
+
const lv = Math.min(4, b.level + 1);
|
|
525
|
+
for (let i = 0; i < m - 1; i++, k++) {
|
|
526
|
+
A.set([b.pts[2 * i], b.pts[2 * i + 1]], 2 * k);
|
|
527
|
+
B.set([b.pts[2 * i + 2], b.pts[2 * i + 3]], 2 * k);
|
|
528
|
+
T.set([b.t[i], b.t[i + 1]], 2 * k);
|
|
529
|
+
TO.set([b.tO[i], b.tO[i + 1]], 2 * k);
|
|
530
|
+
SG.set(b.seg, 2 * k);
|
|
531
|
+
SO.set(b.segO, 2 * k);
|
|
532
|
+
U.set([b.cum[i] / b.len, b.cum[i + 1] / b.len], 2 * k);
|
|
533
|
+
D.set([b.dist0 + b.cum[i], b.dist0 + b.cum[i + 1]], 2 * k);
|
|
534
|
+
P.set([np * u0r + pOff[b.rootStroke], np * u0r + pOff[b.rootStroke]], 2 * k);
|
|
535
|
+
M.set([b.level + 1, b.rank, Kp, H_SCALE[lv]], 4 * k);
|
|
536
|
+
N.set([b.leaf ? 1 : 0, b.phase, b.seed, 0.7 + 0.3 * ((b.seed * 7.3) % 1)], 4 * k);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
const g = new THREE.InstancedBufferGeometry();
|
|
540
|
+
g.setAttribute('aq', new THREE.BufferAttribute(new Float32Array([-1, -1, 1, -1, 1, 1, -1, 1]), 2));
|
|
541
|
+
g.setIndex([0, 1, 2, 0, 2, 3]);
|
|
542
|
+
const ia = (key, a, c) => g.setAttribute(key, new THREE.InstancedBufferAttribute(a, c));
|
|
543
|
+
ia('iA', A, 2);
|
|
544
|
+
ia('iB', B, 2);
|
|
545
|
+
ia('iT', T, 2);
|
|
546
|
+
ia('iTO', TO, 2);
|
|
547
|
+
ia('iSeg', SG, 2);
|
|
548
|
+
ia('iSegO', SO, 2);
|
|
549
|
+
ia('iU', U, 2);
|
|
550
|
+
ia('iDist', D, 2);
|
|
551
|
+
ia('iP', P, 2);
|
|
552
|
+
ia('iM', M, 4);
|
|
553
|
+
ia('iN', N, 4);
|
|
554
|
+
g.instanceCount = n;
|
|
555
|
+
g.boundingSphere = new THREE.Sphere(new THREE.Vector3(), 1e3);
|
|
556
|
+
return g;
|
|
557
|
+
}
|
|
558
|
+
const PD_VERT = /* glsl */ `
|
|
559
|
+
attribute vec2 aq; attribute vec2 iA; attribute vec2 iB; attribute vec2 iT; attribute vec2 iTO; attribute vec2 iSeg; attribute vec2 iSegO;
|
|
560
|
+
attribute vec2 iU; attribute vec2 iDist; attribute vec2 iP; attribute vec4 iM; attribute vec4 iN;
|
|
561
|
+
${REVEAL_UNIFORMS}
|
|
562
|
+
uniform float uBranches; uniform float uReach;
|
|
563
|
+
varying float vSide; varying vec2 vUU; varying vec4 vTT; varying vec2 vLL; varying vec2 vSI; varying float vVar; varying float vGlyph; varying float vSeed; varying vec2 vPos;
|
|
564
|
+
varying vec2 vXY; varying float vHL; varying float vR; varying vec2 vSO; varying vec2 vDst; varying vec2 vPh; varying vec4 vM; varying vec4 vN;
|
|
565
|
+
void main(){
|
|
566
|
+
float lvl = iM.x;
|
|
567
|
+
float vis = lvl < 0.5 ? 1.0 : 1.0 - smoothstep(uBranches - 0.05, uBranches, iM.y);
|
|
568
|
+
float dmin = min(iDist.x, iDist.y);
|
|
569
|
+
if (vis < 0.004 || (lvl > 0.5 && dmin > uReach)) { gl_Position = vec4(2.0, 2.0, 2.0, 1.0); return; }
|
|
570
|
+
vec2 d = iB - iA; float l = max(length(d), 1e-6); vec2 dir = d / l; vec2 perp = vec2(-dir.y, dir.x);
|
|
571
|
+
float hl = 0.5 * l; float R = uHalf * iM.w;
|
|
572
|
+
vec2 loc = vec2(aq.x * (hl + R), aq.y * R);
|
|
573
|
+
vec2 w = 0.5 * (iA + iB) + dir * loc.x + perp * loc.y;
|
|
574
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(w, 0.0, 1.0);
|
|
575
|
+
float sp = max(iSeg.y - iSeg.x, 1e-4), so = max(iSegO.y - iSegO.x, 1e-4);
|
|
576
|
+
vXY = loc; vHL = hl; vR = R; vSide = 0.0; vVar = 0.0; vGlyph = iN.z; vPos = w; vSeed = 0.0;
|
|
577
|
+
vTT = vec4(iT, iTO); vUU = iU; vSI = vec2(iSeg.x, sp);
|
|
578
|
+
vLL = vec2((uHead - iSeg.x) / sp, (uErase - iSegO.x) / so);
|
|
579
|
+
vSO = vec2(iSegO.x, so); vDst = iDist; vPh = iP; vM = iM; vN = iN;
|
|
580
|
+
}`;
|
|
581
|
+
const PD_FRAG = /* glsl */ `
|
|
582
|
+
uniform vec3 uColor; uniform vec3 uColor2; uniform float uCore; uniform float uGlow; uniform float uOpacity; uniform float uPulse; uniform float uSpec;
|
|
583
|
+
uniform float uPulsePh; uniform float uBreathPh; uniform float uBranches; uniform float uReach; uniform float uEDur;
|
|
584
|
+
float vn(float x, float seed){ float i = floor(x); float f = fract(x); f = f*f*(3.0 - 2.0*f); return mix(h21(vec2(i, seed)), h21(vec2(i + 1.0, seed)), f); }
|
|
585
|
+
// channel temperature h (0 cold .. 1 hot) -> perceptual ramp: afterglow magenta -> colour -> colour2
|
|
586
|
+
vec3 ramp(float h){
|
|
587
|
+
vec3 cool = mix(uColor, vec3(0.60, 0.035, 0.40), 0.62)*0.55;
|
|
588
|
+
vec3 hot = mix(uColor2, vec3(1.0), 0.1);
|
|
589
|
+
vec3 a = mix(cool, uColor, smoothstep(0.0, 0.55, h));
|
|
590
|
+
return mix(a, hot, smoothstep(0.5, 1.0, h));
|
|
591
|
+
}
|
|
592
|
+
// current pulse: sharp leading front, soft exponential tail, exactly 0 at the seam
|
|
593
|
+
float pulseShape(float x){ const float pk = 0.55; return exp(-max(pk - x, 0.0)*6.0)*smoothstep(0.0, 0.3, x)*(1.0 - smoothstep(pk, pk + 0.07, x)); }
|
|
594
|
+
void main(){
|
|
595
|
+
float d = length(vec2(max(abs(vXY.x) - vHL, 0.0), vXY.y));
|
|
596
|
+
float fw = max(fwidth(d), 1e-5);
|
|
597
|
+
float f = clamp((vXY.x + vHL)/(2.0*max(vHL, 1e-6)), 0.0, 1.0);
|
|
598
|
+
float lvl = vM.x; float isB = step(0.5, lvl);
|
|
599
|
+
float lit = revealIn(f);
|
|
600
|
+
float gone = revealOut(f);
|
|
601
|
+
float age = ageAt(f);
|
|
602
|
+
float s = mix(vDst.x, vDst.y, f);
|
|
603
|
+
float ub = mix(vUU.x, vUU.y, f);
|
|
604
|
+
// erase afterglow: what the erase front has passed cools into a fading magenta ember
|
|
605
|
+
float tOut = mix(vTT.z, vTT.w, f);
|
|
606
|
+
float eAge = max(uErase - (vSO.x + tOut*vSO.y), 0.0)*uEDur;
|
|
607
|
+
float after = (1.0 - gone)*exp(-eAge/0.6)*0.5*(1.0 - smoothstep(0.8, 1.0, uE))*(uFadeOut > 0.5 ? 0.0 : 1.0);
|
|
608
|
+
float live = gone + after;
|
|
609
|
+
// streamer gates: branches knob, reach knob, breathing length of terminal streamers
|
|
610
|
+
float rankV = isB > 0.5 ? 1.0 - smoothstep(uBranches - 0.05, uBranches, vM.y) : 1.0;
|
|
611
|
+
float reachV = isB > 0.5 ? 1.0 - smoothstep(0.7*uReach, uReach, s) : 1.0;
|
|
612
|
+
float g = 1.0 - 0.45*vN.x*(0.5 + 0.5*sin(uBreathPh + vN.y));
|
|
613
|
+
float breathV = 1.0 - vN.x*smoothstep(g - 0.16, g, ub);
|
|
614
|
+
float vis = lit*live*rankV*reachV*breathV;
|
|
615
|
+
// temperature
|
|
616
|
+
float base = isB > 0.5 ? 0.43 - 0.045*lvl - 0.2*clamp(s/max(uReach, 0.05), 0.0, 1.0) : 0.52;
|
|
617
|
+
float tauF = isB > 0.5 ? 0.13 : 0.24;
|
|
618
|
+
float front = exp(-age/tauF);
|
|
619
|
+
float burst = exp(-age/1.4);
|
|
620
|
+
float x = fract(mix(vPh.x, vPh.y, f) + vM.z*s - uPulsePh);
|
|
621
|
+
float pu = pulseShape(x)*uPulse*vN.w*exp(-s/0.5)*smoothstep(0.4, 1.4, age);
|
|
622
|
+
float h0 = clamp(base + 0.36*burst + 0.4*front, 0.0, 1.0);
|
|
623
|
+
float h = clamp(h0 + 0.45*pu, 0.0, 1.0);
|
|
624
|
+
h = mix(h, 0.02, 1.0 - gone); h0 = mix(h0, 0.02, 1.0 - gone);
|
|
625
|
+
// profile: white-hot core, plasma column, N2 halo
|
|
626
|
+
float wsc = pow(0.68, max(lvl - 1.0, 0.0))*(isB > 0.5 ? 0.62 : 1.0);
|
|
627
|
+
float cw = max(uCore*wsc*(1.0 + 0.45*front + 0.5*pu), 1.15*fw);
|
|
628
|
+
float core = 1.0 - smoothstep(0.3*cw, cw, d);
|
|
629
|
+
float sg = 1.9*cw; float col2 = exp(-0.5*d*d/(sg*sg))*(1.0 - smoothstep(0.5*vR, vR, d));
|
|
630
|
+
float Rh = vR*(0.78 + 0.2*clamp(front + 0.15*pu, 0.0, 1.0));
|
|
631
|
+
float halo = pow(max(1.0 - d/Rh, 0.0), 2.3);
|
|
632
|
+
// brightness by generation, taper along the streamer and with distance from the channel
|
|
633
|
+
float amp = isB > 0.5 ? pow(0.74, lvl)*(1.0 - 0.5*ub)*(1.0 - 0.45*clamp(s/max(uReach, 0.05), 0.0, 1.0)) : 1.0;
|
|
634
|
+
float gs = vN.z*37.0 + 5.0;
|
|
635
|
+
float fl = isB > 0.5 ? 0.82 + 0.18*vn(uTime*2.2 + vN.y, gs) : 0.95 + 0.05*vn(uTime*1.4, gs);
|
|
636
|
+
vec3 cc = ramp(min(h0, 0.8));
|
|
637
|
+
vec3 pc = ramp(min(h, 0.72));
|
|
638
|
+
vec3 coreCol = mix(ramp(min(1.0, h + 0.3)), vec3(1.0), isB > 0.5 ? 0.12 + 0.2*h : 0.3 + 0.4*h);
|
|
639
|
+
vec3 c = coreCol*core*0.9 + pc*col2*(0.4 + 0.3*pu) + cc*halo*0.36*uGlow*(1.0 + 0.12*pu)*(isB > 0.5 ? 0.6 : 1.0);
|
|
640
|
+
// emission lines: the hottest channel grows a faint orange-red atomic-line fringe just outside the white core
|
|
641
|
+
float fringe = exp(-pow((d - 4.6*cw)/(1.5*cw), 2.0))*smoothstep(0.6, 1.0, h);
|
|
642
|
+
c += vec3(1.0, 0.27, 0.03)*fringe*0.2*uSpec;
|
|
643
|
+
// recombination afterglow: a very faint, wide, long-lived magenta glow left behind the strike front
|
|
644
|
+
float rec = exp(-age/5.0)*(1.0 - front);
|
|
645
|
+
c += ramp(0.1)*rec*pow(max(1.0 - d/vR, 0.0), 1.5)*0.2*uSpec*uGlow;
|
|
646
|
+
c *= amp*fl*vis*uOpacity;
|
|
647
|
+
gl_FragColor = vec4(c, 1.0);
|
|
648
|
+
#include <tonemapping_fragment>
|
|
649
|
+
#include <colorspace_fragment>
|
|
650
|
+
}`;
|
|
651
|
+
export default {
|
|
652
|
+
key: 'plasmaDischarge', source: 'outline',
|
|
653
|
+
drawMethods: ['strike', ...DRAW_METHODS], eraseMethods: ERASE_METHODS, drawDefault: 'strike', eraseDefault: 'undraw',
|
|
654
|
+
methodInfo: { strike: { label: 'Strike', hint: 'A leader races both ways round each contour from its sharpest point; streamers shoot out ahead of it.' } },
|
|
655
|
+
catalog: {
|
|
656
|
+
name: 'Plasma Discharge',
|
|
657
|
+
description: 'Electrical breakdown along the letter contours: a white-hot arc channel with a violet halo, fractal streamers forking outward, current pulses and breathing branches. Use for sci-fi, energy and tech titles.',
|
|
658
|
+
tags: ['plasma', 'electric', 'lightning', 'lichtenberg', 'tesla', 'discharge', 'glow'],
|
|
659
|
+
},
|
|
660
|
+
defaults: { branches: 0.72, reach: 0.55, branchiness: 0.6, pulse: 0.8, glow: 1, spectrum: 0.5, core: 0.0065, color: '#6c3dff', color2: '#a9ceff', opacity: 1, seed: 7 },
|
|
661
|
+
ui: {
|
|
662
|
+
main: [
|
|
663
|
+
{ name: 'branches', label: 'Branching', description: 'How many streamers fork off the letters', type: 'number', min: 0, max: 1, step: 0.01 },
|
|
664
|
+
{ name: 'reach', label: 'Reach', description: 'How far the streamers reach from the letters', type: 'number', min: 0.05, max: 1, step: 0.01 },
|
|
665
|
+
{ name: 'branchiness', label: 'Branchiness', description: 'Low: straight streamers that follow the field closely. High: wandering, bushy, more forks', type: 'number', min: 0, max: 1, step: 0.01 },
|
|
666
|
+
{ name: 'glow', label: 'Glow', description: 'Brightness and size of the plasma halo', type: 'number', min: 0, max: 2, step: 0.01 },
|
|
667
|
+
],
|
|
668
|
+
more: [
|
|
669
|
+
{ name: 'pulse', label: 'Current pulses', description: 'Strength of the current pulses travelling along the channels', type: 'number', min: 0, max: 1.5, step: 0.01 },
|
|
670
|
+
{ name: 'spectrum', label: 'Emission lines', description: 'Orange-red atomic-line tinge in the hottest channel and the faint recombination afterglow', type: 'number', min: 0, max: 1, step: 0.01 },
|
|
671
|
+
{ name: 'core', label: 'Core width', description: 'Thickness of the white-hot arc core', type: 'number', min: 0.002, max: 0.02, step: 0.0005 },
|
|
672
|
+
{ name: 'color', label: 'Plasma', description: 'Colour of the plasma halo and cooling channels', type: 'color' },
|
|
673
|
+
{ name: 'color2', label: 'Hot core', description: 'Colour of the hottest, freshly struck channel', type: 'color' },
|
|
674
|
+
{ name: 'opacity', label: 'Opacity', description: 'Overall opacity', type: 'number', min: 0, max: 1, step: 0.01 },
|
|
675
|
+
{ name: 'seed', label: 'Seed', description: 'Different streamer layout', type: 'number', min: 0, max: 99, step: 1 },
|
|
676
|
+
],
|
|
677
|
+
},
|
|
678
|
+
structural: ['seed', 'branchiness'],
|
|
679
|
+
presets: [
|
|
680
|
+
{ name: 'Plasma', description: 'Violet-blue plasma, calm and layered', patch: {} },
|
|
681
|
+
{ name: 'Tesla Coil', description: 'Dense, far-reaching streamers', patch: { branches: 0.95, reach: 0.85, pulse: 1.1, glow: 1.2, color: '#6a6cff', color2: '#e6f0ff' } },
|
|
682
|
+
{ name: 'Quiet Arc', description: 'A few short streamers, soft pulses', patch: { branches: 0.3, reach: 0.3, pulse: 0.5, glow: 0.9 } },
|
|
683
|
+
{ name: 'Rose Plasma', description: 'Magenta discharge with a pale hot core', patch: { color: '#e04ab8', color2: '#ffe4f6', branches: 0.7, reach: 0.55 } },
|
|
684
|
+
{ name: 'Mercury Arc', description: 'Cold blue-cyan arc', patch: { color: '#3d8bff', color2: '#e0fbff', branches: 0.5, reach: 0.4, pulse: 0.9 } },
|
|
685
|
+
],
|
|
686
|
+
build(layout, cfg, anim) {
|
|
687
|
+
const strokes = layout.strokes;
|
|
688
|
+
const G = Math.max(1, layout.glyphs.length);
|
|
689
|
+
prepare(strokes, 'outline');
|
|
690
|
+
strokes.forEach((s) => { s.glyphN = s.glyph / Math.max(1, G - 1); });
|
|
691
|
+
const edges = glyphEdges(strokes, G);
|
|
692
|
+
const info = strokes.map((s) => contourInfo(s, edges[s.glyph]));
|
|
693
|
+
const rngS = mulberry32((cfg.seed * 131 + 17) | 0);
|
|
694
|
+
info.forEach((I) => { let best = 0, bs = -1e9; for (let i = 0; i < I.m; i++) {
|
|
695
|
+
const v = I.conv[i] * (1 + 0.15 * rngS());
|
|
696
|
+
if (v > bs) {
|
|
697
|
+
bs = v;
|
|
698
|
+
best = i;
|
|
699
|
+
}
|
|
700
|
+
} I.start = best; });
|
|
701
|
+
const brs = strokes.length ? buildTree(strokes, G, Math.round(cfg.seed), info, cfg.branchiness) : [];
|
|
702
|
+
brs.forEach((b) => { b.ptime = b.len; b.pt = null; });
|
|
703
|
+
// ---- schedule: channels first, then every streamer from its parent's birth ----
|
|
704
|
+
const ctx = { G, ext: extentOf(strokes) };
|
|
705
|
+
const o = anim.draw;
|
|
706
|
+
let infoD;
|
|
707
|
+
if (o.method === 'strike') {
|
|
708
|
+
const sch = strikeSched(strokes, o, G, info);
|
|
709
|
+
strokes.forEach((s, i) => { s.seg = sch[i].seg; s.t = sch[i].t; });
|
|
710
|
+
ctx.drawSched = sch;
|
|
711
|
+
infoD = { soft: 0.004, tip: false, fade: false };
|
|
712
|
+
}
|
|
713
|
+
else
|
|
714
|
+
infoD = applyDraw(o.method, strokes, o, ctx);
|
|
715
|
+
scheduleBranches(strokes, brs, o.method === 'strike', o.method !== 'strike');
|
|
716
|
+
const all = strokes.concat(brs);
|
|
717
|
+
ctx.drawSched = all.map((s) => ({ seg: s.seg, t: s.t }));
|
|
718
|
+
ctx.drawInfo = infoD;
|
|
719
|
+
const infoE = applyErase(anim.erase.method, all, anim.erase, ctx);
|
|
720
|
+
const pulseN = strokes.map((s) => Math.max(1, Math.round(s.len / 1.4)));
|
|
721
|
+
const rng = mulberry32((cfg.seed * 977 + 3) | 0);
|
|
722
|
+
const geo = buildGeometry(strokes, brs, pulseN, rng);
|
|
723
|
+
const mat = new THREE.ShaderMaterial({
|
|
724
|
+
uniforms: {
|
|
725
|
+
...uniformsBase(), uHalf: { value: 0.1 }, uColor: { value: hex(cfg.color) }, uColor2: { value: hex(cfg.color2) }, uCore: { value: cfg.core }, uGlow: { value: cfg.glow }, uOpacity: { value: 1 },
|
|
726
|
+
uPulse: { value: cfg.pulse }, uSpec: { value: cfg.spectrum }, uPulsePh: { value: 0 }, uBreathPh: { value: 0 }, uBranches: { value: cfg.branches }, uReach: { value: cfg.reach }, uEDur: { value: 2 },
|
|
727
|
+
},
|
|
728
|
+
vertexShader: PD_VERT, fragmentShader: frag(PD_FRAG, 'varying vec2 vXY; varying float vHL; varying float vR; varying vec2 vSO; varying vec2 vDst; varying vec2 vPh; varying vec4 vM; varying vec4 vN;\n'),
|
|
729
|
+
transparent: true, depthWrite: false, side: THREE.DoubleSide,
|
|
730
|
+
blending: THREE.CustomBlending, blendEquation: THREE.MaxEquation, blendSrc: THREE.OneFactor, blendDst: THREE.OneFactor,
|
|
731
|
+
});
|
|
732
|
+
const mesh = new THREE.Mesh(geo, mat);
|
|
733
|
+
mesh.frustumCulled = false;
|
|
734
|
+
const group = new THREE.Group();
|
|
735
|
+
group.add(mesh);
|
|
736
|
+
const api = {
|
|
737
|
+
object: group,
|
|
738
|
+
apply(c) {
|
|
739
|
+
const u = mat.uniforms;
|
|
740
|
+
u.uColor.value.set(c.color);
|
|
741
|
+
u.uColor2.value.set(c.color2);
|
|
742
|
+
u.uCore.value = c.core;
|
|
743
|
+
u.uGlow.value = c.glow;
|
|
744
|
+
u.uOpacity.value = c.opacity;
|
|
745
|
+
u.uPulse.value = c.pulse;
|
|
746
|
+
u.uSpec.value = c.spectrum;
|
|
747
|
+
u.uBranches.value = c.branches;
|
|
748
|
+
u.uReach.value = c.reach;
|
|
749
|
+
u.uHalf.value = 0.07 + 0.03 * Math.min(2, c.glow);
|
|
750
|
+
},
|
|
751
|
+
update(S, time) {
|
|
752
|
+
const u = mat.uniforms;
|
|
753
|
+
setReveal(u, S, infoD, infoE, anim.draw.duration, time);
|
|
754
|
+
u.uEDur.value = Math.max(0.05, anim.erase.duration);
|
|
755
|
+
u.uPulsePh.value = (time * 0.27) % 1; // current-pulse phase, integrated on the CPU
|
|
756
|
+
u.uBreathPh.value = (time * 0.7) % (Math.PI * 2); // streamer breathing phase
|
|
757
|
+
},
|
|
758
|
+
dispose() { geo.dispose(); mat.dispose(); },
|
|
759
|
+
};
|
|
760
|
+
api.apply(cfg);
|
|
761
|
+
return api;
|
|
762
|
+
},
|
|
763
|
+
};
|