@3driseai/3drise-viewer 0.1.26 → 0.1.27
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 +3 -0
- package/dist/animationsV2/ClipPlayer.d.ts.map +1 -1
- package/dist/animationsV2/ClipPlayer.js +67 -8
- package/dist/animationsV2/ClipsRuntime.d.ts +39 -0
- package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +245 -14
- package/dist/animationsV2/appliers.d.ts +5 -0
- package/dist/animationsV2/appliers.d.ts.map +1 -1
- package/dist/animationsV2/appliers.js +25 -7
- 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 +18 -7
- package/dist/animationsV2/sequenceUtils.d.ts +42 -1
- package/dist/animationsV2/sequenceUtils.d.ts.map +1 -1
- package/dist/animationsV2/sequenceUtils.js +103 -3
- package/dist/animationsV2/types.d.ts +20 -0
- package/dist/animationsV2/types.d.ts.map +1 -1
- package/dist/components/AdvancedGrid.d.ts +8 -2
- package/dist/components/AdvancedGrid.d.ts.map +1 -1
- package/dist/components/AdvancedGrid.js +31 -14
- package/dist/components/AnimatedObject.d.ts.map +1 -1
- package/dist/components/AnimatedObject.js +7 -5
- package/dist/components/Bubbles.d.ts +7 -1
- package/dist/components/Bubbles.d.ts.map +1 -1
- package/dist/components/Bubbles.js +42 -22
- package/dist/components/ChladniGrid.d.ts +8 -4
- package/dist/components/ChladniGrid.d.ts.map +1 -1
- package/dist/components/ChladniGrid.js +31 -13
- package/dist/components/CircuitGrid.d.ts +8 -11
- package/dist/components/CircuitGrid.d.ts.map +1 -1
- package/dist/components/CircuitGrid.js +31 -13
- package/dist/components/CloudsGenerator.d.ts +1 -1
- package/dist/components/CloudsGenerator.js +1 -1
- package/dist/components/ContourGrid.d.ts +8 -14
- package/dist/components/ContourGrid.d.ts.map +1 -1
- package/dist/components/ContourGrid.js +31 -13
- package/dist/components/EffectsGenerator.d.ts +7 -1
- package/dist/components/EffectsGenerator.d.ts.map +1 -1
- package/dist/components/EffectsGenerator.js +39 -38
- package/dist/components/EnvironmentManager.d.ts +4 -4
- package/dist/components/EnvironmentManager.d.ts.map +1 -1
- package/dist/components/FlowNetGrid.d.ts +8 -4
- package/dist/components/FlowNetGrid.d.ts.map +1 -1
- package/dist/components/FlowNetGrid.js +31 -13
- package/dist/components/FractalGrid.d.ts +8 -12
- package/dist/components/FractalGrid.d.ts.map +1 -1
- package/dist/components/FractalGrid.js +31 -13
- package/dist/components/GirihGrid.d.ts +8 -1
- package/dist/components/GirihGrid.d.ts.map +1 -1
- package/dist/components/GirihGrid.js +31 -13
- package/dist/components/Glyphs.d.ts +7 -1
- package/dist/components/Glyphs.d.ts.map +1 -1
- package/dist/components/Glyphs.js +40 -34
- package/dist/components/GravWaveGrid.d.ts +8 -1
- package/dist/components/GravWaveGrid.d.ts.map +1 -1
- package/dist/components/GravWaveGrid.js +31 -13
- package/dist/components/GridsGenerator.d.ts +7 -1
- package/dist/components/GridsGenerator.d.ts.map +1 -1
- package/dist/components/GridsGenerator.js +20 -18
- package/dist/components/HexGrid.d.ts +8 -10
- package/dist/components/HexGrid.d.ts.map +1 -1
- package/dist/components/HexGrid.js +31 -13
- package/dist/components/HyperbolicGrid.d.ts +8 -4
- package/dist/components/HyperbolicGrid.d.ts.map +1 -1
- package/dist/components/HyperbolicGrid.js +31 -13
- package/dist/components/LandscapeBuilder.d.ts +1 -1
- package/dist/components/LandscapeBuilder.d.ts.map +1 -1
- package/dist/components/LandscapeBuilder.js +1 -1
- package/dist/components/LandscapeObject.d.ts +1 -1
- package/dist/components/LandscapeObject.d.ts.map +1 -1
- package/dist/components/LandscapeObject.js +1 -1
- package/dist/components/MoireGrid.d.ts +8 -12
- package/dist/components/MoireGrid.d.ts.map +1 -1
- package/dist/components/MoireGrid.js +31 -13
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +2 -2
- package/dist/components/ObjectsRenderer.d.ts.map +1 -1
- package/dist/components/ObjectsRenderer.js +37 -3
- package/dist/components/OceanBuilder.d.ts +1 -1
- package/dist/components/OceanBuilder.js +1 -1
- package/dist/components/ParticlesGenerator.d.ts.map +1 -1
- package/dist/components/ParticlesGenerator.js +6 -0
- package/dist/components/QuasiGrid.d.ts +8 -11
- package/dist/components/QuasiGrid.d.ts.map +1 -1
- package/dist/components/QuasiGrid.js +31 -13
- package/dist/components/RadarGrid.d.ts +8 -13
- package/dist/components/RadarGrid.d.ts.map +1 -1
- package/dist/components/RadarGrid.js +31 -13
- package/dist/components/ReactionDiffusionGrid.d.ts +8 -1
- package/dist/components/ReactionDiffusionGrid.d.ts.map +1 -1
- package/dist/components/ReactionDiffusionGrid.js +33 -139
- package/dist/components/SceneBuilder.js +1 -1
- package/dist/components/SkySystem.d.ts +1 -1
- package/dist/components/SparklesBurst.d.ts +7 -1
- package/dist/components/SparklesBurst.d.ts.map +1 -1
- package/dist/components/SparklesBurst.js +31 -28
- package/dist/components/TerrainBuilder.d.ts +1 -1
- package/dist/components/TerrainBuilder.d.ts.map +1 -1
- package/dist/components/TerrainBuilder.js +1 -1
- package/dist/components/VoronoiGrid.d.ts +8 -10
- package/dist/components/VoronoiGrid.d.ts.map +1 -1
- package/dist/components/VoronoiGrid.js +31 -13
- package/dist/components/WallpaperGrid.d.ts +8 -1
- package/dist/components/WallpaperGrid.d.ts.map +1 -1
- package/dist/components/WallpaperGrid.js +33 -210
- package/dist/components/effects/AuraEffect.d.ts +8 -3
- package/dist/components/effects/AuraEffect.d.ts.map +1 -1
- package/dist/components/effects/AuraEffect.js +49 -24
- package/dist/components/effects/AuroraEffect.d.ts +8 -3
- package/dist/components/effects/AuroraEffect.d.ts.map +1 -1
- package/dist/components/effects/AuroraEffect.js +45 -25
- package/dist/components/effects/BlackHoleEffect.d.ts +8 -3
- package/dist/components/effects/BlackHoleEffect.d.ts.map +1 -1
- package/dist/components/effects/BlackHoleEffect.js +42 -21
- package/dist/components/effects/ConstellationEffect.d.ts +8 -3
- package/dist/components/effects/ConstellationEffect.d.ts.map +1 -1
- package/dist/components/effects/ConstellationEffect.js +49 -23
- package/dist/components/effects/DandelionSeedsEffect.d.ts +7 -2
- package/dist/components/effects/DandelionSeedsEffect.d.ts.map +1 -1
- package/dist/components/effects/DandelionSeedsEffect.js +19 -9
- package/dist/components/effects/DataStreamEffect.d.ts +8 -3
- package/dist/components/effects/DataStreamEffect.d.ts.map +1 -1
- package/dist/components/effects/DataStreamEffect.js +54 -26
- package/dist/components/effects/DnaHelixEffect.d.ts +8 -3
- package/dist/components/effects/DnaHelixEffect.d.ts.map +1 -1
- package/dist/components/effects/DnaHelixEffect.js +62 -30
- package/dist/components/effects/FallingLeavesEffect.d.ts +7 -2
- package/dist/components/effects/FallingLeavesEffect.d.ts.map +1 -1
- package/dist/components/effects/FallingLeavesEffect.js +19 -9
- package/dist/components/effects/FieldLinesEffect.d.ts +8 -3
- package/dist/components/effects/FieldLinesEffect.d.ts.map +1 -1
- package/dist/components/effects/FieldLinesEffect.js +30 -20
- package/dist/components/effects/Fire.d.ts +8 -3
- package/dist/components/effects/Fire.d.ts.map +1 -1
- package/dist/components/effects/Fire.js +47 -10
- package/dist/components/effects/FireflySwarmEffect.d.ts +7 -2
- package/dist/components/effects/FireflySwarmEffect.d.ts.map +1 -1
- package/dist/components/effects/FireflySwarmEffect.js +19 -9
- package/dist/components/effects/Flares.d.ts +10 -3
- package/dist/components/effects/Flares.d.ts.map +1 -1
- package/dist/components/effects/Flares.js +53 -56
- package/dist/components/effects/ForcefieldEffect.d.ts +8 -3
- package/dist/components/effects/ForcefieldEffect.d.ts.map +1 -1
- package/dist/components/effects/ForcefieldEffect.js +52 -33
- package/dist/components/effects/GalaxyEffect.d.ts +7 -2
- package/dist/components/effects/GalaxyEffect.d.ts.map +1 -1
- package/dist/components/effects/GalaxyEffect.js +19 -9
- package/dist/components/effects/HarmonicShellEffect.d.ts +8 -3
- package/dist/components/effects/HarmonicShellEffect.d.ts.map +1 -1
- package/dist/components/effects/HarmonicShellEffect.js +30 -22
- package/dist/components/effects/HologramEffect.d.ts +8 -3
- package/dist/components/effects/HologramEffect.d.ts.map +1 -1
- package/dist/components/effects/HologramEffect.js +52 -23
- package/dist/components/effects/IceCrystalsEffect.d.ts +8 -3
- package/dist/components/effects/IceCrystalsEffect.d.ts.map +1 -1
- package/dist/components/effects/IceCrystalsEffect.js +36 -21
- package/dist/components/effects/IceHaloEffect.d.ts +7 -2
- package/dist/components/effects/IceHaloEffect.d.ts.map +1 -1
- package/dist/components/effects/IceHaloEffect.js +19 -9
- package/dist/components/effects/LichtenbergEffect.d.ts +7 -2
- package/dist/components/effects/LichtenbergEffect.d.ts.map +1 -1
- package/dist/components/effects/LichtenbergEffect.js +19 -9
- package/dist/components/effects/LightningEffect.d.ts +8 -3
- package/dist/components/effects/LightningEffect.d.ts.map +1 -1
- package/dist/components/effects/LightningEffect.js +54 -32
- package/dist/components/effects/MoleculesEffect.d.ts +8 -3
- package/dist/components/effects/MoleculesEffect.d.ts.map +1 -1
- package/dist/components/effects/MoleculesEffect.js +31 -21
- package/dist/components/effects/MurmurationEffect.d.ts +7 -2
- package/dist/components/effects/MurmurationEffect.d.ts.map +1 -1
- package/dist/components/effects/MurmurationEffect.js +19 -9
- package/dist/components/effects/NeuralNetworkEffect.d.ts +8 -3
- package/dist/components/effects/NeuralNetworkEffect.d.ts.map +1 -1
- package/dist/components/effects/NeuralNetworkEffect.js +66 -33
- package/dist/components/effects/OrbEffect.d.ts +8 -3
- package/dist/components/effects/OrbEffect.d.ts.map +1 -1
- package/dist/components/effects/OrbEffect.js +89 -42
- package/dist/components/effects/PlanetaryRingsEffect.d.ts +7 -2
- package/dist/components/effects/PlanetaryRingsEffect.d.ts.map +1 -1
- package/dist/components/effects/PlanetaryRingsEffect.js +19 -9
- package/dist/components/effects/PortalEffect.d.ts +8 -3
- package/dist/components/effects/PortalEffect.d.ts.map +1 -1
- package/dist/components/effects/PortalEffect.js +41 -25
- package/dist/components/effects/ShockwaveEffect.d.ts +7 -2
- package/dist/components/effects/ShockwaveEffect.d.ts.map +1 -1
- package/dist/components/effects/ShockwaveEffect.js +19 -9
- package/dist/components/effects/SmokePlumeEffect.d.ts +8 -3
- package/dist/components/effects/SmokePlumeEffect.d.ts.map +1 -1
- package/dist/components/effects/SmokePlumeEffect.js +30 -20
- package/dist/components/effects/SmokeRibbon.d.ts +8 -2
- package/dist/components/effects/SmokeRibbon.d.ts.map +1 -1
- package/dist/components/effects/SmokeRibbon.js +34 -24
- package/dist/components/effects/SmokeRingEffect.d.ts +8 -3
- package/dist/components/effects/SmokeRingEffect.d.ts.map +1 -1
- package/dist/components/effects/SmokeRingEffect.js +33 -21
- package/dist/components/effects/StrangeAttractorEffect.d.ts +8 -3
- package/dist/components/effects/StrangeAttractorEffect.d.ts.map +1 -1
- package/dist/components/effects/StrangeAttractorEffect.js +30 -20
- package/dist/components/effects/VolumetricFogEffect.d.ts +8 -3
- package/dist/components/effects/VolumetricFogEffect.d.ts.map +1 -1
- package/dist/components/effects/VolumetricFogEffect.js +38 -20
- package/dist/components/effects/WaterCausticsEffect.d.ts +7 -2
- package/dist/components/effects/WaterCausticsEffect.d.ts.map +1 -1
- package/dist/components/effects/WaterCausticsEffect.js +19 -9
- package/dist/components/effects/index.d.ts +0 -1
- package/dist/components/effects/index.d.ts.map +1 -1
- package/dist/components/effects/index.js +0 -1
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +0 -1
- package/dist/components/landscape/LandscapeMesh.js +1 -1
- package/dist/components/landscape/types.d.ts +1 -1
- package/dist/components/landscape/types.d.ts.map +1 -1
- package/dist/components/particles/MagneticBottleParticles.d.ts +17 -0
- package/dist/components/particles/MagneticBottleParticles.d.ts.map +1 -0
- package/dist/components/particles/MagneticBottleParticles.js +618 -0
- package/dist/components/particles/ShapeBurstParticles.d.ts +17 -0
- package/dist/components/particles/ShapeBurstParticles.d.ts.map +1 -0
- package/dist/components/particles/ShapeBurstParticles.js +588 -0
- package/dist/components/particles/ShapeFlowParticles.d.ts +17 -0
- package/dist/components/particles/ShapeFlowParticles.d.ts.map +1 -0
- package/dist/components/particles/ShapeFlowParticles.js +755 -0
- package/dist/components/particles/index.d.ts +6 -0
- package/dist/components/particles/index.d.ts.map +1 -1
- package/dist/components/particles/index.js +3 -0
- package/dist/components/terrain/types.d.ts +1 -1
- package/dist/components/terrain/types.d.ts.map +1 -1
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +1 -1
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
- package/dist/components/volumetricClouds/types.d.ts +1 -1
- package/dist/components/volumetricClouds/types.d.ts.map +1 -1
- package/dist/components/water/types.d.ts +1 -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 +1 -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/useConfigDriver.d.ts +22 -0
- package/dist/hooks/useConfigDriver.d.ts.map +1 -0
- package/dist/hooks/useConfigDriver.js +43 -0
- package/dist/hooks/useConfigLive.d.ts +1 -1
- package/dist/hooks/useConfigLive.d.ts.map +1 -1
- package/dist/hooks/useLandscapeMaps.d.ts +1 -1
- package/dist/hooks/useLandscapeMaps.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.d.ts +1 -1
- package/dist/hooks/useThunder.d.ts +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/interactions/index.d.ts +2 -1
- package/dist/interactions/index.d.ts.map +1 -1
- package/dist/interactions/index.js +1 -1
- package/dist/interactions/runner.d.ts +18 -3
- package/dist/interactions/runner.d.ts.map +1 -1
- package/dist/interactions/runner.js +25 -2
- package/dist/operations/catalogue/curlSmoke.d.ts +3 -0
- package/dist/operations/catalogue/curlSmoke.d.ts.map +1 -0
- package/dist/operations/catalogue/curlSmoke.js +178 -0
- package/dist/operations/catalogue/displayImage.d.ts.map +1 -1
- package/dist/operations/catalogue/displayImage.js +1 -0
- package/dist/operations/catalogue/dissolve.d.ts +3 -0
- package/dist/operations/catalogue/dissolve.d.ts.map +1 -0
- package/dist/operations/catalogue/dissolve.js +57 -0
- package/dist/operations/catalogue/emberAsh.d.ts +3 -0
- package/dist/operations/catalogue/emberAsh.d.ts.map +1 -0
- package/dist/operations/catalogue/emberAsh.js +171 -0
- package/dist/operations/catalogue/fade.d.ts.map +1 -1
- package/dist/operations/catalogue/fade.js +1 -0
- package/dist/operations/catalogue/flip.d.ts +3 -0
- package/dist/operations/catalogue/flip.d.ts.map +1 -0
- package/dist/operations/catalogue/flip.js +69 -0
- package/dist/operations/catalogue/flock.d.ts +3 -0
- package/dist/operations/catalogue/flock.d.ts.map +1 -0
- package/dist/operations/catalogue/flock.js +163 -0
- package/dist/operations/catalogue/focus.d.ts.map +1 -1
- package/dist/operations/catalogue/focus.js +1 -0
- package/dist/operations/catalogue/frame.d.ts +3 -0
- package/dist/operations/catalogue/frame.d.ts.map +1 -0
- package/dist/operations/catalogue/frame.js +44 -0
- package/dist/operations/catalogue/frost.d.ts +3 -0
- package/dist/operations/catalogue/frost.d.ts.map +1 -0
- package/dist/operations/catalogue/frost.js +111 -0
- package/dist/operations/catalogue/fxInstances.d.ts +21 -0
- package/dist/operations/catalogue/fxInstances.d.ts.map +1 -0
- package/dist/operations/catalogue/fxInstances.js +47 -0
- package/dist/operations/catalogue/fxPoints.d.ts +22 -0
- package/dist/operations/catalogue/fxPoints.d.ts.map +1 -0
- package/dist/operations/catalogue/fxPoints.js +70 -0
- package/dist/operations/catalogue/glow.d.ts.map +1 -1
- package/dist/operations/catalogue/glow.js +2 -1
- package/dist/operations/catalogue/heatCracks.d.ts +3 -0
- package/dist/operations/catalogue/heatCracks.d.ts.map +1 -0
- package/dist/operations/catalogue/heatCracks.js +134 -0
- package/dist/operations/catalogue/hologram.d.ts +3 -0
- package/dist/operations/catalogue/hologram.d.ts.map +1 -0
- package/dist/operations/catalogue/hologram.js +118 -0
- package/dist/operations/catalogue/inkBloom.d.ts +3 -0
- package/dist/operations/catalogue/inkBloom.d.ts.map +1 -0
- package/dist/operations/catalogue/inkBloom.js +156 -0
- package/dist/operations/catalogue/ivy.d.ts +13 -0
- package/dist/operations/catalogue/ivy.d.ts.map +1 -0
- package/dist/operations/catalogue/ivy.js +469 -0
- package/dist/operations/catalogue/jelly.d.ts +3 -0
- package/dist/operations/catalogue/jelly.d.ts.map +1 -0
- package/dist/operations/catalogue/jelly.js +50 -0
- package/dist/operations/catalogue/kintsugi.d.ts +3 -0
- package/dist/operations/catalogue/kintsugi.d.ts.map +1 -0
- package/dist/operations/catalogue/kintsugi.js +173 -0
- package/dist/operations/catalogue/lidarScan.d.ts +3 -0
- package/dist/operations/catalogue/lidarScan.d.ts.map +1 -0
- package/dist/operations/catalogue/lidarScan.js +240 -0
- package/dist/operations/catalogue/liquidMetal.d.ts +3 -0
- package/dist/operations/catalogue/liquidMetal.d.ts.map +1 -0
- package/dist/operations/catalogue/liquidMetal.js +122 -0
- package/dist/operations/catalogue/metalize.d.ts +3 -0
- package/dist/operations/catalogue/metalize.d.ts.map +1 -0
- package/dist/operations/catalogue/metalize.js +135 -0
- package/dist/operations/catalogue/moveToFront.d.ts.map +1 -1
- package/dist/operations/catalogue/moveToFront.js +1 -0
- package/dist/operations/catalogue/orbit.d.ts +3 -0
- package/dist/operations/catalogue/orbit.d.ts.map +1 -0
- package/dist/operations/catalogue/orbit.js +29 -0
- package/dist/operations/catalogue/particleSwarm.d.ts +3 -0
- package/dist/operations/catalogue/particleSwarm.d.ts.map +1 -0
- package/dist/operations/catalogue/particleSwarm.js +138 -0
- package/dist/operations/catalogue/petalPeel.d.ts +3 -0
- package/dist/operations/catalogue/petalPeel.d.ts.map +1 -0
- package/dist/operations/catalogue/petalPeel.js +137 -0
- package/dist/operations/catalogue/petrify.d.ts +3 -0
- package/dist/operations/catalogue/petrify.d.ts.map +1 -0
- package/dist/operations/catalogue/petrify.js +94 -0
- package/dist/operations/catalogue/portal.d.ts +3 -0
- package/dist/operations/catalogue/portal.d.ts.map +1 -0
- package/dist/operations/catalogue/portal.js +224 -0
- package/dist/operations/catalogue/print3d.d.ts +3 -0
- package/dist/operations/catalogue/print3d.d.ts.map +1 -0
- package/dist/operations/catalogue/print3d.js +275 -0
- package/dist/operations/catalogue/rainBeads.d.ts +3 -0
- package/dist/operations/catalogue/rainBeads.d.ts.map +1 -0
- package/dist/operations/catalogue/rainBeads.js +223 -0
- package/dist/operations/catalogue/restPose.d.ts +21 -0
- package/dist/operations/catalogue/restPose.d.ts.map +1 -0
- package/dist/operations/catalogue/restPose.js +55 -0
- package/dist/operations/catalogue/rimLight.d.ts +3 -0
- package/dist/operations/catalogue/rimLight.d.ts.map +1 -0
- package/dist/operations/catalogue/rimLight.js +72 -0
- package/dist/operations/catalogue/sandErosion.d.ts +3 -0
- package/dist/operations/catalogue/sandErosion.d.ts.map +1 -0
- package/dist/operations/catalogue/sandErosion.js +167 -0
- package/dist/operations/catalogue/shaderLayers.d.ts +74 -0
- package/dist/operations/catalogue/shaderLayers.d.ts.map +1 -0
- package/dist/operations/catalogue/shaderLayers.js +322 -0
- package/dist/operations/catalogue/shatter.d.ts +3 -0
- package/dist/operations/catalogue/shatter.d.ts.map +1 -0
- package/dist/operations/catalogue/shatter.js +267 -0
- package/dist/operations/catalogue/silkDrape.d.ts +3 -0
- package/dist/operations/catalogue/silkDrape.d.ts.map +1 -0
- package/dist/operations/catalogue/silkDrape.js +340 -0
- package/dist/operations/catalogue/spin.d.ts +3 -0
- package/dist/operations/catalogue/spin.d.ts.map +1 -0
- package/dist/operations/catalogue/spin.js +42 -0
- package/dist/operations/catalogue/surfaceSample.d.ts +17 -0
- package/dist/operations/catalogue/surfaceSample.d.ts.map +1 -0
- package/dist/operations/catalogue/surfaceSample.js +187 -0
- package/dist/operations/catalogue/swirl.d.ts +3 -0
- package/dist/operations/catalogue/swirl.d.ts.map +1 -0
- package/dist/operations/catalogue/swirl.js +69 -0
- package/dist/operations/catalogue/teleport.d.ts +3 -0
- package/dist/operations/catalogue/teleport.d.ts.map +1 -0
- package/dist/operations/catalogue/teleport.js +213 -0
- package/dist/operations/catalogue/transitionField.d.ts +124 -0
- package/dist/operations/catalogue/transitionField.d.ts.map +1 -0
- package/dist/operations/catalogue/transitionField.js +278 -0
- package/dist/operations/catalogue/unweave.d.ts +3 -0
- package/dist/operations/catalogue/unweave.d.ts.map +1 -0
- package/dist/operations/catalogue/unweave.js +233 -0
- package/dist/operations/catalogue/visibility.d.ts.map +1 -1
- package/dist/operations/catalogue/visibility.js +1 -0
- package/dist/operations/catalogue/voxelize.d.ts +3 -0
- package/dist/operations/catalogue/voxelize.d.ts.map +1 -0
- package/dist/operations/catalogue/voxelize.js +148 -0
- package/dist/operations/catalogue/warmup.d.ts +22 -0
- package/dist/operations/catalogue/warmup.d.ts.map +1 -0
- package/dist/operations/catalogue/warmup.js +106 -0
- package/dist/operations/catalogue/zoom.d.ts.map +1 -1
- package/dist/operations/catalogue/zoom.js +1 -0
- package/dist/operations/index.d.ts +4 -2
- package/dist/operations/index.d.ts.map +1 -1
- package/dist/operations/index.js +4 -2
- package/dist/operations/objectEffects.d.ts +46 -0
- package/dist/operations/objectEffects.d.ts.map +1 -0
- package/dist/operations/objectEffects.js +136 -0
- package/dist/operations/registry.d.ts +7 -2
- package/dist/operations/registry.d.ts.map +1 -1
- package/dist/operations/registry.js +45 -3
- package/dist/operations/runtime.d.ts +40 -2
- package/dist/operations/runtime.d.ts.map +1 -1
- package/dist/operations/runtime.js +164 -8
- package/dist/operations/types.d.ts +29 -3
- package/dist/operations/types.d.ts.map +1 -1
- package/dist/operations/types.js +6 -0
- package/dist/operations/useObjectEffectLayers.d.ts +4 -0
- package/dist/operations/useObjectEffectLayers.d.ts.map +1 -0
- package/dist/operations/useObjectEffectLayers.js +42 -0
- package/dist/operations/useOperationsRuntime.d.ts.map +1 -1
- package/dist/operations/useOperationsRuntime.js +42 -4
- package/dist/presets/landscapePresets.d.ts +1 -1
- package/dist/presets/landscapePresets.d.ts.map +1 -1
- package/dist/presets/landscapePresets.js +1 -1
- package/dist/presets/landscapeTypes.d.ts +1 -1
- package/dist/presets/landscapeTypes.d.ts.map +1 -1
- package/dist/presets/landscapeTypes.js +1 -1
- package/dist/presets/oceanSurfacePresets.d.ts +1 -1
- package/dist/presets/terrainPresets.d.ts +1 -1
- package/dist/presets/terrainPresets.d.ts.map +1 -1
- package/dist/presets/volumetricCloudPresets.d.ts +1 -1
- package/dist/types/cloudConfigs.d.ts +2 -309
- package/dist/types/cloudConfigs.d.ts.map +1 -1
- package/dist/types/cloudConfigs.js +2 -339
- package/dist/types/index.d.ts +8 -8
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -4
- package/dist/types/landscapeConfigs.d.ts +2 -217
- package/dist/types/landscapeConfigs.d.ts.map +1 -1
- package/dist/types/landscapeConfigs.js +2 -256
- package/dist/types/oceanConfigs.d.ts +2 -289
- package/dist/types/oceanConfigs.d.ts.map +1 -1
- package/dist/types/oceanConfigs.js +2 -380
- package/dist/types/terrainConfigs.d.ts +2 -250
- package/dist/types/terrainConfigs.d.ts.map +1 -1
- package/dist/types/terrainConfigs.js +2 -292
- package/dist/utils/cloudUniforms.d.ts +1 -1
- package/dist/utils/configAnimations.d.ts +6 -0
- package/dist/utils/configAnimations.d.ts.map +1 -1
- package/dist/utils/configAnimations.js +14 -0
- package/dist/utils/gridConfig.d.ts +19 -0
- package/dist/utils/gridConfig.d.ts.map +1 -0
- package/dist/utils/gridConfig.js +52 -0
- package/dist/utils/handleCloudsAnimations.d.ts +1 -1
- package/dist/utils/handleCloudsAnimations.js +1 -1
- package/dist/utils/hasHoverAnimation.d.ts.map +1 -1
- package/dist/utils/hasHoverAnimation.js +0 -2
- package/dist/utils/landscapeUniforms.d.ts +1 -1
- package/dist/utils/landscapeUniforms.d.ts.map +1 -1
- package/dist/utils/oceanUniforms.d.ts +1 -1
- package/dist/utils/particleShape.d.ts +33 -0
- package/dist/utils/particleShape.d.ts.map +1 -0
- package/dist/utils/particleShape.js +207 -0
- package/dist/utils/particleTrails.d.ts.map +1 -1
- package/dist/utils/particleTrails.js +29 -14
- package/dist/utils/terrainUniforms.d.ts +1 -1
- package/dist/utils/terrainUniforms.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
import { useFrame } from '@react-three/fiber';
|
|
5
|
+
import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
|
|
6
|
+
import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
|
|
7
|
+
import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
|
|
8
|
+
import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
|
|
9
|
+
import { shapeField } from '../../utils/particleShape.js';
|
|
10
|
+
import { useObjectReady } from '../../hooks/useObjectReady.js';
|
|
11
|
+
import { useConfigLiveHandle } from '../../hooks/useConfigLive.js';
|
|
12
|
+
/**
|
|
13
|
+
* Shape Flow — A wind tunnel of particle streams flowing round an invisible mesh shape: divergence-free flow, wake eddies, streaklines coloured by pressure; the cursor is a second obstacle, a jet or a vortex. Use for tech, aero and product scenes.
|
|
14
|
+
*/
|
|
15
|
+
// Shape Flow — a wind tunnel: streams of tracer particles flowing past an invisible mesh shape.
|
|
16
|
+
// Movement: the air is an incompressible flow round the shape. A uniform wind U is written as a
|
|
17
|
+
// vector potential psi = (U x x) / 2 and constrained at the obstacle the Bridson way
|
|
18
|
+
// (curl-noise for procedural fluid flow, 2007): psi' = a(d) psi + (1 - a(d)) n (n . psi), with
|
|
19
|
+
// d the distance to the shape, n its normal and a a smooth ramp over a boundary layer. The
|
|
20
|
+
// velocity u = curl psi' is divergence-free and tangent to the surface, so the streams part
|
|
21
|
+
// at the front, speed round the sides and close behind. Downstream of the shape a wake of
|
|
22
|
+
// ABC (Arnold–Beltrami–Childress) eddies, carried with the wind and faded in behind the body,
|
|
23
|
+
// curls the closing streams. The base flow is precomputed on a grid when the shape changes.
|
|
24
|
+
// Tracers are released on a regular lattice of lanes upstream and advected with RK2, so the
|
|
25
|
+
// picture is a clean set of streaklines.
|
|
26
|
+
// Colour: exact, from Bernoulli: pressure coefficient Cp = 1 - |u|^2 / U^2. High pressure (the
|
|
27
|
+
// stagnation point at the nose, the slow wake) takes `color`; low pressure (fast flow round
|
|
28
|
+
// the shoulders) takes `fastColor`; the fastest flow whitens. Tails fade into trailColor.
|
|
29
|
+
// Mouse (pointerMode, cursor on the camera-facing plane through the object):
|
|
30
|
+
// obstacle — a second, spherical body at the cursor (the potential-flow sphere solution): the
|
|
31
|
+
// streams part round it too.
|
|
32
|
+
// jet — the cursor blows along its own motion: a travelling puff pushes the streams.
|
|
33
|
+
// vortex — a vortex line along the view axis at the cursor: the streams wrap round it.
|
|
34
|
+
// Trails (trailMode): streak = motion blur, comet = streaklines, echo = smoke.
|
|
35
|
+
//
|
|
36
|
+
// Generated from the approved lab module (particle lab, shapes batch). Sim units = object-local / size.
|
|
37
|
+
// config.shape is a mesh-builder geometry config ({ type, ...params }); utils/particleShape builds it with
|
|
38
|
+
// the core mesh builders (createMeshByType) and reads it as a surface.
|
|
39
|
+
// ---------------------------------------------------------------------------------------------
|
|
40
|
+
// Engine features
|
|
41
|
+
// ---------------------------------------------------------------------------------------------
|
|
42
|
+
const QUALITY_SCALE = { low: 0.5, medium: 1, high: 1.6 };
|
|
43
|
+
/** mulberry32 — seeded PRNG, returns a function giving floats in [0,1). */
|
|
44
|
+
function mulberry32(seed) {
|
|
45
|
+
let a = seed >>> 0;
|
|
46
|
+
return function () {
|
|
47
|
+
a = (a + 0x6d2b79f5) >>> 0;
|
|
48
|
+
let t = a;
|
|
49
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
50
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
51
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Viewport-height hook so point sizes are pixel-correct at any canvas size. */
|
|
55
|
+
function attachViewH(obj, u) {
|
|
56
|
+
const scratch = new THREE.Vector2();
|
|
57
|
+
obj.onBeforeRender = (renderer) => {
|
|
58
|
+
renderer.getDrawingBufferSize(scratch);
|
|
59
|
+
u.uViewH.value = scratch.y;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function colorUniform(hex) {
|
|
63
|
+
return { value: new THREE.Color(hex) };
|
|
64
|
+
}
|
|
65
|
+
function qualityScale(q) { return QUALITY_SCALE[q] || 1; }
|
|
66
|
+
function seedMix(base, seed) {
|
|
67
|
+
let h = (base ^ Math.imul((Math.round(seed) | 0) + 0x9e37, 0x85ebca6b)) >>> 0;
|
|
68
|
+
h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35) >>> 0;
|
|
69
|
+
return (h ^ (h >>> 16)) >>> 0;
|
|
70
|
+
}
|
|
71
|
+
function createFixedStep(H, maxSteps) {
|
|
72
|
+
let acc = 0;
|
|
73
|
+
return {
|
|
74
|
+
H,
|
|
75
|
+
run(d, step) {
|
|
76
|
+
acc += Math.max(d, 0);
|
|
77
|
+
let k = 0;
|
|
78
|
+
while (acc >= H && k < maxSteps) {
|
|
79
|
+
step(H);
|
|
80
|
+
acc -= H;
|
|
81
|
+
k++;
|
|
82
|
+
}
|
|
83
|
+
if (k === maxSteps)
|
|
84
|
+
acc = Math.min(acc, H);
|
|
85
|
+
return acc / H;
|
|
86
|
+
},
|
|
87
|
+
reset() { acc = 0; },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function createPickProxy(center, radius) {
|
|
91
|
+
const geo = new THREE.SphereGeometry(1, 16, 10);
|
|
92
|
+
const mat = new THREE.MeshBasicMaterial({ visible: false });
|
|
93
|
+
const mesh = new THREE.Mesh(geo, mat);
|
|
94
|
+
mesh.name = 'pickProxy';
|
|
95
|
+
mesh.position.set(center[0], center[1], center[2]);
|
|
96
|
+
mesh.scale.setScalar(radius);
|
|
97
|
+
return { mesh, dispose() { geo.dispose(); mat.dispose(); } };
|
|
98
|
+
}
|
|
99
|
+
const _frustum = new THREE.Frustum();
|
|
100
|
+
const _pm = new THREE.Matrix4();
|
|
101
|
+
const _sphere = new THREE.Sphere();
|
|
102
|
+
function inView(object, camera, center, radius, size) {
|
|
103
|
+
if (!camera || !camera.projectionMatrix)
|
|
104
|
+
return true;
|
|
105
|
+
object.updateWorldMatrix(true, false);
|
|
106
|
+
_sphere.center.set(center[0], center[1], center[2]).multiplyScalar(size).applyMatrix4(object.matrixWorld);
|
|
107
|
+
_sphere.radius = radius * size * object.matrixWorld.getMaxScaleOnAxis();
|
|
108
|
+
_pm.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
109
|
+
_frustum.setFromProjectionMatrix(_pm);
|
|
110
|
+
return _frustum.intersectsSphere(_sphere);
|
|
111
|
+
}
|
|
112
|
+
/** Shared GLSL for heads (a white-hot core in a coloured glow). */
|
|
113
|
+
const HEAD_FRAG = /* glsl */ `
|
|
114
|
+
varying vec3 vCol;
|
|
115
|
+
varying float vA;
|
|
116
|
+
void main() {
|
|
117
|
+
vec2 d = gl_PointCoord * 2.0 - 1.0;
|
|
118
|
+
float r2 = dot(d, d);
|
|
119
|
+
if (r2 > 1.0) discard;
|
|
120
|
+
float core = exp(-r2 * 40.0);
|
|
121
|
+
float glow = exp(-r2 * 8.0) * 0.5 + exp(-r2 * 2.5) * 0.1;
|
|
122
|
+
float a = clamp((core + glow) * (1.0 - r2) * vA, 0.0, 1.0);
|
|
123
|
+
if (a < 0.003) discard;
|
|
124
|
+
vec3 c = vCol / max(max(vCol.r, max(vCol.g, vCol.b)), 1.0);
|
|
125
|
+
gl_FragColor = vec4(mix(c, vec3(1.0), core * 0.9), a);
|
|
126
|
+
}
|
|
127
|
+
`;
|
|
128
|
+
const POINTER_MODES = ['obstacle', 'jet', 'vortex'];
|
|
129
|
+
const RAKES = ['tube', 'sheet', 'cross'];
|
|
130
|
+
const H_STEP = 1 / 90;
|
|
131
|
+
const U0 = 0.55; // wind speed (units / s) at flowSpeed 1
|
|
132
|
+
const XL0 = 1.7, YL0 = 1.15; // smallest tunnel half extents (along the wind / across)
|
|
133
|
+
const GX = 56, GY = 40, GZ = 40; // base-flow grid
|
|
134
|
+
const DELTA = 0.32; // boundary-layer thickness for the potential ramp
|
|
135
|
+
const TRAIL_LOOK = { streak: 0.35, comet: 1, echo: 1 };
|
|
136
|
+
const TRAIL_ALPHA = { streak: 1.8, comet: 2, echo: 2.6 };
|
|
137
|
+
const BOUNDS = { center: [0, 0, 0], radius: 1.6 };
|
|
138
|
+
function createUniforms() {
|
|
139
|
+
return {
|
|
140
|
+
uTime: { value: 0 },
|
|
141
|
+
uSize: { value: 1 },
|
|
142
|
+
uViewH: { value: 800 },
|
|
143
|
+
uIntensity: { value: 1 },
|
|
144
|
+
uSpeed: { value: 1 },
|
|
145
|
+
uOpacity: { value: 0.9 },
|
|
146
|
+
uColor: colorUniform('#ffffff'),
|
|
147
|
+
uParticleCount: { value: 0 },
|
|
148
|
+
uFlowSpeed: { value: 1 },
|
|
149
|
+
uWindPitch: { value: 0 },
|
|
150
|
+
uLanes: { value: 22 },
|
|
151
|
+
uStreamWidth: { value: 0.75 },
|
|
152
|
+
uTurbulence: { value: 0.6 },
|
|
153
|
+
uFastColor: colorUniform('#ffffff'),
|
|
154
|
+
uHeadSize: { value: 1 },
|
|
155
|
+
uPointerMode: { value: 0 },
|
|
156
|
+
uPointerStrength: { value: 1 },
|
|
157
|
+
uPointerRadius: { value: 1 },
|
|
158
|
+
uPointerColor: colorUniform('#ffffff'),
|
|
159
|
+
...createPointerUniforms(),
|
|
160
|
+
...createTrailUniforms(),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function applyConfig(u, c, size) {
|
|
164
|
+
u.uSize.value = size;
|
|
165
|
+
u.uIntensity.value = c.intensity;
|
|
166
|
+
u.uSpeed.value = c.speed;
|
|
167
|
+
u.uOpacity.value = c.opacity;
|
|
168
|
+
u.uColor.value.set(c.color);
|
|
169
|
+
u.uParticleCount.value = c.particleCount;
|
|
170
|
+
u.uFlowSpeed.value = c.flowSpeed;
|
|
171
|
+
u.uWindPitch.value = c.windPitch;
|
|
172
|
+
u.uLanes.value = c.lanes;
|
|
173
|
+
u.uStreamWidth.value = c.streamWidth;
|
|
174
|
+
u.uTurbulence.value = c.turbulence;
|
|
175
|
+
u.uFastColor.value.set(c.fastColor);
|
|
176
|
+
u.uHeadSize.value = c.headSize;
|
|
177
|
+
u.uPointerMode.value = POINTER_MODES.indexOf(c.pointerMode); // -1 = 'none' (off)
|
|
178
|
+
u.uPointerStrength.value = c.pointerStrength;
|
|
179
|
+
u.uPointerRadius.value = c.pointerRadius;
|
|
180
|
+
u.uPointerColor.value.set(c.pointerColor);
|
|
181
|
+
applyTrailConfig(u, c);
|
|
182
|
+
}
|
|
183
|
+
// code = speed ratio s = |u| / (1.8 U) (0..1) + 2 x cursor glow (0..31)
|
|
184
|
+
const PRESSURE_GLSL = /* glsl */ `
|
|
185
|
+
uniform vec3 uColor, uFastColor, uPointerColor;
|
|
186
|
+
vec3 pressureLight(float code) {
|
|
187
|
+
float glow = floor(code / 2.0) / 31.0;
|
|
188
|
+
float s = code - 2.0 * floor(code / 2.0);
|
|
189
|
+
float q = s * 1.8; // |u| / U
|
|
190
|
+
float cp = 1.0 - q * q; // Bernoulli pressure coefficient
|
|
191
|
+
float t = smoothstep(0.9, -1.4, cp); // 0 high pressure .. 1 low pressure
|
|
192
|
+
vec3 c = mix(uColor, uFastColor, t);
|
|
193
|
+
c = mix(c, vec3(1.0), 0.45 * smoothstep(-1.2, -2.2, cp)); // the fastest flow whitens
|
|
194
|
+
return mix(c, uPointerColor, 0.6 * glow) * (1.1 + 0.6 * t);
|
|
195
|
+
}
|
|
196
|
+
`;
|
|
197
|
+
const headVertex = /* glsl */ `
|
|
198
|
+
uniform float uSize, uViewH, uIntensity, uOpacity, uHeadSize;
|
|
199
|
+
${PRESSURE_GLSL}
|
|
200
|
+
attribute vec2 aH; // code, fade (spawn / exit)
|
|
201
|
+
varying vec3 vCol;
|
|
202
|
+
varying float vA;
|
|
203
|
+
void main() {
|
|
204
|
+
vec4 mv = modelViewMatrix * vec4(position * uSize, 1.0);
|
|
205
|
+
vCol = pressureLight(aH.x) * uIntensity;
|
|
206
|
+
vA = uOpacity * aH.y * 0.9;
|
|
207
|
+
gl_PointSize = clamp(uHeadSize * uSize * uViewH * 0.014 / -mv.z, 1.5, 22.0) * step(0.01, aH.y);
|
|
208
|
+
gl_Position = projectionMatrix * mv;
|
|
209
|
+
}
|
|
210
|
+
`;
|
|
211
|
+
// smooth ramp from Bridson's paper: 0 at the surface, 1 beyond the boundary layer
|
|
212
|
+
function ramp(r) {
|
|
213
|
+
if (r >= 1)
|
|
214
|
+
return 1;
|
|
215
|
+
if (r <= 0)
|
|
216
|
+
return 0;
|
|
217
|
+
return (15 / 8) * r - (10 / 8) * r * r * r + (3 / 8) * r * r * r * r * r;
|
|
218
|
+
}
|
|
219
|
+
function build(u, c, size) {
|
|
220
|
+
const q = qualityScale(c.quality);
|
|
221
|
+
const n = Math.max(50, Math.round(c.particleCount * q));
|
|
222
|
+
const rng = mulberry32(seedMix(0xf10e, c.seed));
|
|
223
|
+
const F = shapeField(c.shape);
|
|
224
|
+
// the tunnel grows with the shape: a margin upstream / downstream and round the sides
|
|
225
|
+
const ext = Math.max(F.rMax, (F.Y1 - F.Y0) / 2);
|
|
226
|
+
const XL = Math.max(XL0, ext + 0.95), YL = Math.max(YL0, ext + 0.4);
|
|
227
|
+
const bR = Math.max(BOUNDS.radius, Math.hypot(XL, YL) * 0.95);
|
|
228
|
+
const pitch = (c.windPitch * Math.PI) / 180;
|
|
229
|
+
const Ux = Math.cos(pitch), Uy = Math.sin(pitch); // unit wind direction (in the x-y plane)
|
|
230
|
+
// ---- signed distance to the shape, from its radial field ----
|
|
231
|
+
function sdf(x, y, z) {
|
|
232
|
+
const r = Math.hypot(x, z), th = Math.atan2(z, x);
|
|
233
|
+
const hc = Math.min(Math.max(y, F.Y0), F.Y1);
|
|
234
|
+
const R = F.rAt(th, hc);
|
|
235
|
+
const dr = r - R;
|
|
236
|
+
const dy = y > F.Y1 ? y - F.Y1 : y < F.Y0 ? F.Y0 - y : 0;
|
|
237
|
+
if (dy === 0) {
|
|
238
|
+
if (dr >= 0)
|
|
239
|
+
return dr;
|
|
240
|
+
return Math.max(dr, y - F.Y1, F.Y0 - y); // inside: nearest wall or cap
|
|
241
|
+
}
|
|
242
|
+
return dr <= 0 ? dy : Math.hypot(dr, dy); // above or below the caps
|
|
243
|
+
}
|
|
244
|
+
// ---- base flow on a grid: u = curl psi', psi' = a psi + (1 - a) n (n . psi), psi = (U x x) / 2 ----
|
|
245
|
+
const dx = (2 * XL) / (GX - 1), dy = (2 * YL) / (GY - 1), dz = (2 * YL) / (GZ - 1);
|
|
246
|
+
const NN = GX * GY * GZ;
|
|
247
|
+
const D = new Float32Array(NN);
|
|
248
|
+
const idx = (i, j, k) => (k * GY + j) * GX + i;
|
|
249
|
+
const gxp = (i) => -XL + i * dx, gyp = (j) => -YL + j * dy, gzp = (k) => -YL + k * dz;
|
|
250
|
+
for (let k = 0; k < GZ; k++)
|
|
251
|
+
for (let j = 0; j < GY; j++)
|
|
252
|
+
for (let i = 0; i < GX; i++)
|
|
253
|
+
D[idx(i, j, k)] = sdf(gxp(i), gyp(j), gzp(k));
|
|
254
|
+
const PS = new Float32Array(NN * 3);
|
|
255
|
+
for (let k = 0; k < GZ; k++)
|
|
256
|
+
for (let j = 0; j < GY; j++)
|
|
257
|
+
for (let i = 0; i < GX; i++) {
|
|
258
|
+
const o = idx(i, j, k);
|
|
259
|
+
const x = gxp(i), y = gyp(j), z = gzp(k);
|
|
260
|
+
// psi = (U x x) / 2 with U = (Ux, Uy, 0)
|
|
261
|
+
let px = 0.5 * (Uy * z), py = 0.5 * (-Ux * z), pz = 0.5 * (Ux * y - Uy * x);
|
|
262
|
+
const d = D[o];
|
|
263
|
+
const a = ramp(d / DELTA);
|
|
264
|
+
if (a < 1) {
|
|
265
|
+
// normal from the distance field
|
|
266
|
+
const i0 = Math.max(i - 1, 0), i1 = Math.min(i + 1, GX - 1), j0 = Math.max(j - 1, 0), j1 = Math.min(j + 1, GY - 1), k0 = Math.max(k - 1, 0), k1 = Math.min(k + 1, GZ - 1);
|
|
267
|
+
let nx = (D[idx(i1, j, k)] - D[idx(i0, j, k)]) / ((i1 - i0) * dx);
|
|
268
|
+
let ny = (D[idx(i, j1, k)] - D[idx(i, j0, k)]) / ((j1 - j0) * dy);
|
|
269
|
+
let nz = (D[idx(i, j, k1)] - D[idx(i, j, k0)]) / ((k1 - k0) * dz);
|
|
270
|
+
const nl = Math.hypot(nx, ny, nz) || 1;
|
|
271
|
+
nx /= nl;
|
|
272
|
+
ny /= nl;
|
|
273
|
+
nz /= nl;
|
|
274
|
+
const pn = px * nx + py * ny + pz * nz;
|
|
275
|
+
px = a * px + (1 - a) * nx * pn;
|
|
276
|
+
py = a * py + (1 - a) * ny * pn;
|
|
277
|
+
pz = a * pz + (1 - a) * nz * pn;
|
|
278
|
+
}
|
|
279
|
+
PS[o * 3] = px;
|
|
280
|
+
PS[o * 3 + 1] = py;
|
|
281
|
+
PS[o * 3 + 2] = pz;
|
|
282
|
+
}
|
|
283
|
+
const V = new Float32Array(NN * 3); // unit-wind velocity field
|
|
284
|
+
for (let k = 0; k < GZ; k++)
|
|
285
|
+
for (let j = 0; j < GY; j++)
|
|
286
|
+
for (let i = 0; i < GX; i++) {
|
|
287
|
+
const o = idx(i, j, k);
|
|
288
|
+
const i0 = Math.max(i - 1, 0), i1 = Math.min(i + 1, GX - 1), j0 = Math.max(j - 1, 0), j1 = Math.min(j + 1, GY - 1), k0 = Math.max(k - 1, 0), k1 = Math.min(k + 1, GZ - 1);
|
|
289
|
+
const ddy = (c2) => (PS[idx(i, j1, k) * 3 + c2] - PS[idx(i, j0, k) * 3 + c2]) / ((j1 - j0) * dy);
|
|
290
|
+
const ddz = (c2) => (PS[idx(i, j, k1) * 3 + c2] - PS[idx(i, j, k0) * 3 + c2]) / ((k1 - k0) * dz);
|
|
291
|
+
const ddx = (c2) => (PS[idx(i1, j, k) * 3 + c2] - PS[idx(i0, j, k) * 3 + c2]) / ((i1 - i0) * dx);
|
|
292
|
+
V[o * 3] = ddy(2) - ddz(1);
|
|
293
|
+
V[o * 3 + 1] = ddz(0) - ddx(2);
|
|
294
|
+
V[o * 3 + 2] = ddx(1) - ddy(0);
|
|
295
|
+
}
|
|
296
|
+
const NG = new Float32Array(NN * 3); // outward normal of the distance field
|
|
297
|
+
for (let k = 0; k < GZ; k++)
|
|
298
|
+
for (let j = 0; j < GY; j++)
|
|
299
|
+
for (let i = 0; i < GX; i++) {
|
|
300
|
+
const o = idx(i, j, k);
|
|
301
|
+
const i0 = Math.max(i - 1, 0), i1 = Math.min(i + 1, GX - 1), j0 = Math.max(j - 1, 0), j1 = Math.min(j + 1, GY - 1), k0 = Math.max(k - 1, 0), k1 = Math.min(k + 1, GZ - 1);
|
|
302
|
+
let nx = (D[idx(i1, j, k)] - D[idx(i0, j, k)]) / ((i1 - i0) * dx);
|
|
303
|
+
let ny = (D[idx(i, j1, k)] - D[idx(i, j0, k)]) / ((j1 - j0) * dy);
|
|
304
|
+
let nz = (D[idx(i, j, k1)] - D[idx(i, j, k0)]) / ((k1 - k0) * dz);
|
|
305
|
+
const nl = Math.hypot(nx, ny, nz) || 1;
|
|
306
|
+
NG[o * 3] = nx / nl;
|
|
307
|
+
NG[o * 3 + 1] = ny / nl;
|
|
308
|
+
NG[o * 3 + 2] = nz / nl;
|
|
309
|
+
}
|
|
310
|
+
const W = new Float32Array(NN); // wake mask: behind the body, outside it
|
|
311
|
+
for (let k = 0; k < GZ; k++)
|
|
312
|
+
for (let j = 0; j < GY; j++)
|
|
313
|
+
for (let i = 0; i < GX; i++) {
|
|
314
|
+
const o = idx(i, j, k);
|
|
315
|
+
const x = gxp(i), y = gyp(j), z = gzp(k);
|
|
316
|
+
const along = x * Ux + y * Uy, ax = x - along * Ux, ay = y - along * Uy;
|
|
317
|
+
const across = Math.hypot(ax, ay, z);
|
|
318
|
+
const behind = Math.min(Math.max((along - 0.1) / 0.5, 0), 1);
|
|
319
|
+
W[o] = behind * Math.exp(-(across * across) / (0.75 * 0.75)) * ramp(D[o] / 0.25);
|
|
320
|
+
}
|
|
321
|
+
const sv = new Float32Array(8);
|
|
322
|
+
function sample(x, y, z) {
|
|
323
|
+
let fx = (x + XL) / dx, fy = (y + YL) / dy, fz = (z + YL) / dz;
|
|
324
|
+
if (fx < 0)
|
|
325
|
+
fx = 0;
|
|
326
|
+
else if (fx > GX - 1.001)
|
|
327
|
+
fx = GX - 1.001;
|
|
328
|
+
if (fy < 0)
|
|
329
|
+
fy = 0;
|
|
330
|
+
else if (fy > GY - 1.001)
|
|
331
|
+
fy = GY - 1.001;
|
|
332
|
+
if (fz < 0)
|
|
333
|
+
fz = 0;
|
|
334
|
+
else if (fz > GZ - 1.001)
|
|
335
|
+
fz = GZ - 1.001;
|
|
336
|
+
const i = fx | 0, j = fy | 0, k = fz | 0, tx = fx - i, ty = fy - j, tz = fz - k;
|
|
337
|
+
const o000 = (k * GY + j) * GX + i, o100 = o000 + 1, o010 = o000 + GX, o110 = o010 + 1;
|
|
338
|
+
const o001 = o000 + GX * GY, o101 = o001 + 1, o011 = o001 + GX, o111 = o011 + 1;
|
|
339
|
+
const w000 = (1 - tx) * (1 - ty) * (1 - tz), w100 = tx * (1 - ty) * (1 - tz), w010 = (1 - tx) * ty * (1 - tz), w110 = tx * ty * (1 - tz);
|
|
340
|
+
const w001 = (1 - tx) * (1 - ty) * tz, w101 = tx * (1 - ty) * tz, w011 = (1 - tx) * ty * tz, w111 = tx * ty * tz;
|
|
341
|
+
for (let cc = 0; cc < 3; cc++) {
|
|
342
|
+
sv[cc] = V[o000 * 3 + cc] * w000 + V[o100 * 3 + cc] * w100 + V[o010 * 3 + cc] * w010 + V[o110 * 3 + cc] * w110
|
|
343
|
+
+ V[o001 * 3 + cc] * w001 + V[o101 * 3 + cc] * w101 + V[o011 * 3 + cc] * w011 + V[o111 * 3 + cc] * w111;
|
|
344
|
+
}
|
|
345
|
+
sv[3] = W[o000] * w000 + W[o100] * w100 + W[o010] * w010 + W[o110] * w110 + W[o001] * w001 + W[o101] * w101 + W[o011] * w011 + W[o111] * w111;
|
|
346
|
+
sv[4] = D[o000] * w000 + D[o100] * w100 + D[o010] * w010 + D[o110] * w110 + D[o001] * w001 + D[o101] * w101 + D[o011] * w011 + D[o111] * w111;
|
|
347
|
+
for (let cc = 0; cc < 3; cc++) {
|
|
348
|
+
sv[5 + cc] = NG[o000 * 3 + cc] * w000 + NG[o100 * 3 + cc] * w100 + NG[o010 * 3 + cc] * w010 + NG[o110 * 3 + cc] * w110
|
|
349
|
+
+ NG[o001 * 3 + cc] * w001 + NG[o101 * 3 + cc] * w101 + NG[o011 * 3 + cc] * w011 + NG[o111 * 3 + cc] * w111;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// ---- tracers on a lattice of lanes upstream ----
|
|
353
|
+
const L = Math.max(2, Math.round(c.lanes));
|
|
354
|
+
const e1x = -Uy, e1y = Ux; // across the wind in the x-y plane (e2 = z)
|
|
355
|
+
// the rake: where the streams are released. tube = a ring of lanes round the body (the stream tube
|
|
356
|
+
// bulges round the shape), sheet = one vertical smoke rake, cross = a vertical and a horizontal rake
|
|
357
|
+
const rake = RAKES.includes(c.rake) ? c.rake : 'tube';
|
|
358
|
+
const laneA = new Float32Array(n), laneB = new Float32Array(n), phase = new Float32Array(n);
|
|
359
|
+
const perLane = Math.ceil(n / L);
|
|
360
|
+
for (let i = 0; i < n; i++) {
|
|
361
|
+
const l = i % L, k = Math.floor(i / L);
|
|
362
|
+
const f = (l + 0.5) / L;
|
|
363
|
+
if (rake === 'tube') {
|
|
364
|
+
laneA[i] = Math.cos(f * Math.PI * 2) * 0.62;
|
|
365
|
+
laneB[i] = Math.sin(f * Math.PI * 2) * 0.62;
|
|
366
|
+
}
|
|
367
|
+
else if (rake === 'sheet') {
|
|
368
|
+
laneA[i] = f * 2 - 1;
|
|
369
|
+
laneB[i] = (l % 2 ? 1 : -1) * 0.012;
|
|
370
|
+
} // a hair either side of the symmetry plane
|
|
371
|
+
else {
|
|
372
|
+
const g = ((l >> 1) + 0.5) / Math.ceil(L / 2) * 2 - 1;
|
|
373
|
+
if (l % 2 === 0) {
|
|
374
|
+
laneA[i] = g;
|
|
375
|
+
laneB[i] = 0;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
laneA[i] = 0;
|
|
379
|
+
laneB[i] = g;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
phase[i] = (k + rng()) / perLane; // stratified along the lane, no synchronised fronts
|
|
383
|
+
}
|
|
384
|
+
const x = new Float32Array(n * 3), v = new Float32Array(n * 3), code = new Float32Array(n), fade = new Float32Array(n);
|
|
385
|
+
const hA = new Float32Array(n * 2), glow = new Float32Array(n);
|
|
386
|
+
const S0 = -XL * 0.95; // release plane, along the wind
|
|
387
|
+
let trail = null;
|
|
388
|
+
function release(i, frac) {
|
|
389
|
+
const w = u.uStreamWidth.value * YL * 0.95;
|
|
390
|
+
const a = laneA[i] * w, b = laneB[i] * w;
|
|
391
|
+
const along = S0 + frac * (2 * XL * 0.95);
|
|
392
|
+
x[i * 3] = along * Ux + a * e1x;
|
|
393
|
+
x[i * 3 + 1] = along * Uy + a * e1y;
|
|
394
|
+
x[i * 3 + 2] = b;
|
|
395
|
+
fade[i] = frac > 0.02 ? 1 : 0;
|
|
396
|
+
if (trail)
|
|
397
|
+
trail.reset(i);
|
|
398
|
+
}
|
|
399
|
+
let time = 0;
|
|
400
|
+
const P = new THREE.Vector3(), PV = new THREE.Vector3(), axis = new THREE.Vector3(0, 0, 1);
|
|
401
|
+
const vel = new Float32Array(3);
|
|
402
|
+
function velocity(px, py, pz, t, mode, S, Rp) {
|
|
403
|
+
sample(px, py, pz);
|
|
404
|
+
const Ug = U0 * u.uFlowSpeed.value;
|
|
405
|
+
let vx = sv[0] * Ug, vy = sv[1] * Ug, vz = sv[2] * Ug;
|
|
406
|
+
// skin of the body: a slip current along the surface carries tracers off the stagnation point, and
|
|
407
|
+
// anything that strays inside is pushed back out (tracers never pile up on the body)
|
|
408
|
+
const dd = sv[4];
|
|
409
|
+
if (dd < 0.15) {
|
|
410
|
+
const nx = sv[5], ny = sv[6], nz = sv[7];
|
|
411
|
+
if (dd < 0) {
|
|
412
|
+
// inside the body (only through grid leakage): straight back out
|
|
413
|
+
const out = Ug * (0.6 + 10 * -dd);
|
|
414
|
+
vx = nx * out;
|
|
415
|
+
vy = ny * out;
|
|
416
|
+
vz = nz * out;
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
// impermeable skin: remove any inflow through the surface (the coarse grid leaks a little)
|
|
420
|
+
const vn = vx * nx + vy * ny + vz * nz;
|
|
421
|
+
const wgt = 1 - dd / 0.15;
|
|
422
|
+
if (vn < 0) {
|
|
423
|
+
vx -= vn * nx * wgt;
|
|
424
|
+
vy -= vn * ny * wgt;
|
|
425
|
+
vz -= vn * nz * wgt;
|
|
426
|
+
}
|
|
427
|
+
// slip current along the skin carries tracers off the stagnation point
|
|
428
|
+
const un = Ux * nx + Uy * ny;
|
|
429
|
+
let tx = Ux - un * nx, ty = Uy - un * ny, tz = -un * nz;
|
|
430
|
+
if (Math.hypot(tx, ty, tz) < 0.35) {
|
|
431
|
+
// head-on (a flat face or an edge square to the wind): go round the side the tracer is on,
|
|
432
|
+
// i.e. away from the wind axis through the body, so a symmetric body splits the stream both ways
|
|
433
|
+
const al = px * Ux + py * Uy;
|
|
434
|
+
let rx = px - al * Ux, ry = py - al * Uy, rz = pz;
|
|
435
|
+
const rn = rx * nx + ry * ny + rz * nz;
|
|
436
|
+
rx -= rn * nx;
|
|
437
|
+
ry -= rn * ny;
|
|
438
|
+
rz -= rn * nz;
|
|
439
|
+
const rl = Math.hypot(rx, ry, rz);
|
|
440
|
+
if (rl > 1e-4) {
|
|
441
|
+
tx += rx / rl * 0.8;
|
|
442
|
+
ty += ry / rl * 0.8;
|
|
443
|
+
tz += rz / rl * 0.8;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
const tn = Math.hypot(tx, ty, tz) || 1;
|
|
447
|
+
const g = 0.6 * Ug * wgt;
|
|
448
|
+
vx += tx / tn * g;
|
|
449
|
+
vy += ty / tn * g;
|
|
450
|
+
vz += tz / tn * g;
|
|
451
|
+
if (dd < 0.03) {
|
|
452
|
+
const push = Ug * (0.03 - dd) * 30;
|
|
453
|
+
vx += nx * push;
|
|
454
|
+
vy += ny * push;
|
|
455
|
+
vz += nz * push;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// wake eddies: an ABC flow carried with the wind, faded in behind the body
|
|
460
|
+
const tb = u.uTurbulence.value * sv[3];
|
|
461
|
+
if (tb > 0.002) {
|
|
462
|
+
const kk = 4.2, ph = t * Ug * kk;
|
|
463
|
+
const X = px * kk - ph, Y = py * kk, Z = pz * kk;
|
|
464
|
+
const A = 0.55 * Ug * tb;
|
|
465
|
+
vx += A * (Math.sin(Z + 0.3 * ph) + Math.cos(Y));
|
|
466
|
+
vy += A * (Math.sin(X) + Math.cos(Z + 0.3 * ph));
|
|
467
|
+
vz += A * (Math.sin(Y) + Math.cos(X));
|
|
468
|
+
}
|
|
469
|
+
// the cursor
|
|
470
|
+
if (S > 0.001) {
|
|
471
|
+
let ex = px - P.x, ey = py - P.y, ez = pz - P.z;
|
|
472
|
+
if (mode === 0) { // a sphere in potential flow: U + (a^3/2)(U/r^3 - 3(U.x)x/r^5)
|
|
473
|
+
const a = 0.22 * u.uPointerRadius.value * Math.min(S, 2);
|
|
474
|
+
const r2 = ex * ex + ey * ey + ez * ez, r = Math.sqrt(r2) + 1e-4;
|
|
475
|
+
if (r < 5 * a) {
|
|
476
|
+
const ua = Ug * Ux, ub = Ug * Uy;
|
|
477
|
+
const ud = ua * ex + ub * ey;
|
|
478
|
+
const k3 = (a * a * a) / 2 / (r2 * r);
|
|
479
|
+
vx += k3 * (ua - 3 * ud * ex / r2);
|
|
480
|
+
vy += k3 * (ub - 3 * ud * ey / r2);
|
|
481
|
+
vz += k3 * (-3 * ud * ez / r2);
|
|
482
|
+
if (r < a * 1.02) {
|
|
483
|
+
vx += ex / r * Ug * 2;
|
|
484
|
+
vy += ey / r * Ug * 2;
|
|
485
|
+
vz += ez / r * Ug * 2;
|
|
486
|
+
} // never inside
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
const al = ex * axis.x + ey * axis.y + ez * axis.z;
|
|
491
|
+
ex -= axis.x * al;
|
|
492
|
+
ey -= axis.y * al;
|
|
493
|
+
ez -= axis.z * al;
|
|
494
|
+
const d2 = ex * ex + ey * ey + ez * ez;
|
|
495
|
+
if (d2 < 9 * Rp * Rp) {
|
|
496
|
+
const g = Math.exp(-d2 / (Rp * Rp));
|
|
497
|
+
if (mode === 1) { // a puff along the cursor's motion
|
|
498
|
+
vx += PV.x * 1.6 * S * g;
|
|
499
|
+
vy += PV.y * 1.6 * S * g;
|
|
500
|
+
vz += PV.z * 1.6 * S * g;
|
|
501
|
+
}
|
|
502
|
+
else { // line vortex (Rankine-softened)
|
|
503
|
+
const G = 0.5 * S * Ug / (d2 / (Rp * Rp) + 0.15) * Math.min(1, 3 * g + 0.2);
|
|
504
|
+
vx += (axis.y * ez - axis.z * ey) * G / Rp;
|
|
505
|
+
vy += (axis.z * ex - axis.x * ez) * G / Rp;
|
|
506
|
+
vz += (axis.x * ey - axis.y * ex) * G / Rp;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
vel[0] = vx;
|
|
512
|
+
vel[1] = vy;
|
|
513
|
+
vel[2] = vz;
|
|
514
|
+
}
|
|
515
|
+
function step(dt) {
|
|
516
|
+
time += dt;
|
|
517
|
+
const mode = u.uPointerMode.value;
|
|
518
|
+
const S = u.uPointerStrength.value * u.uPointerActive.value;
|
|
519
|
+
const Rp = 0.3 * u.uPointerRadius.value;
|
|
520
|
+
P.copy(u.uPointer.value);
|
|
521
|
+
PV.copy(u.uPointerVel.value);
|
|
522
|
+
const Ug = Math.max(U0 * u.uFlowSpeed.value, 1e-4);
|
|
523
|
+
for (let i = 0; i < n; i++) {
|
|
524
|
+
const j = i * 3;
|
|
525
|
+
const px = x[j], py = x[j + 1], pz = x[j + 2];
|
|
526
|
+
// RK2 (midpoint)
|
|
527
|
+
velocity(px, py, pz, time, mode, S, Rp);
|
|
528
|
+
const mx = px + vel[0] * dt * 0.5, my = py + vel[1] * dt * 0.5, mz = pz + vel[2] * dt * 0.5;
|
|
529
|
+
velocity(mx, my, mz, time + dt * 0.5, mode, S, Rp);
|
|
530
|
+
let nx = px + vel[0] * dt, ny = py + vel[1] * dt, nz = pz + vel[2] * dt;
|
|
531
|
+
v[j] = vel[0];
|
|
532
|
+
v[j + 1] = vel[1];
|
|
533
|
+
v[j + 2] = vel[2];
|
|
534
|
+
const along = nx * Ux + ny * Uy;
|
|
535
|
+
if (along > XL * 0.97 || Math.abs(nz) > YL || Math.abs(-nx * Uy + ny * Ux) > YL * 1.05) {
|
|
536
|
+
release(i, 0); // back to its lane at the release plane
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
x[j] = nx;
|
|
540
|
+
x[j + 1] = ny;
|
|
541
|
+
x[j + 2] = nz;
|
|
542
|
+
// fade in after release, out before the exit
|
|
543
|
+
const inF = Math.min((along - S0) / 0.25, 1), outF = Math.min((XL * 0.97 - along) / 0.35, 1);
|
|
544
|
+
fade[i] = Math.max(Math.min(inF, outF), 0);
|
|
545
|
+
// glow from the cursor (how much it is being pushed)
|
|
546
|
+
let gl = 0;
|
|
547
|
+
if (S > 0.001) {
|
|
548
|
+
const ex = nx - P.x, ey = ny - P.y, ez = nz - P.z;
|
|
549
|
+
gl = Math.exp(-(ex * ex + ey * ey + ez * ez) / (Rp * Rp * 1.5));
|
|
550
|
+
}
|
|
551
|
+
glow[i] += (gl - glow[i]) * Math.min(1, dt * 5);
|
|
552
|
+
const s = Math.min(Math.hypot(vel[0], vel[1], vel[2]) / (1.8 * Ug), 0.999);
|
|
553
|
+
code[i] = s + 2 * Math.round(Math.min(glow[i], 1) * 31);
|
|
554
|
+
hA[i * 2] = code[i];
|
|
555
|
+
hA[i * 2 + 1] = fade[i];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
const hgeo = new THREE.BufferGeometry();
|
|
559
|
+
const xAttr = new THREE.BufferAttribute(x, 3).setUsage(THREE.DynamicDrawUsage);
|
|
560
|
+
const hAttr = new THREE.BufferAttribute(hA, 2).setUsage(THREE.DynamicDrawUsage);
|
|
561
|
+
hgeo.setAttribute('position', xAttr);
|
|
562
|
+
hgeo.setAttribute('aH', hAttr);
|
|
563
|
+
const hmat = new THREE.ShaderMaterial({
|
|
564
|
+
uniforms: u, vertexShader: headVertex, fragmentShader: HEAD_FRAG,
|
|
565
|
+
transparent: true, depthWrite: false, blending: THREE.AdditiveBlending,
|
|
566
|
+
});
|
|
567
|
+
const heads = new THREE.Points(hgeo, hmat);
|
|
568
|
+
heads.frustumCulled = false;
|
|
569
|
+
heads.renderOrder = 3;
|
|
570
|
+
attachViewH(heads, u);
|
|
571
|
+
const object = new THREE.Group();
|
|
572
|
+
const proxy = createPickProxy(BOUNDS.center, bR);
|
|
573
|
+
object.add(heads, proxy.mesh);
|
|
574
|
+
// streaklines carry the pressure colour; the fade (spawn / exit) is packed as brightness in k
|
|
575
|
+
const tk = new Float32Array(n);
|
|
576
|
+
const trailGLSL = /* glsl */ `
|
|
577
|
+
${PRESSURE_GLSL}
|
|
578
|
+
vec3 trailShade(vec3 p, float f) {
|
|
579
|
+
float lvl = floor(TRAIL_K / 64.0);
|
|
580
|
+
vec3 c = pressureLight(TRAIL_K - 64.0 * lvl);
|
|
581
|
+
c /= max(max(c.r, max(c.g, c.b)), 1.0);
|
|
582
|
+
return mix(c, uTrailColor, smoothstep(0.0, 0.7, f)) * (lvl / 15.0);
|
|
583
|
+
}
|
|
584
|
+
vec3 trailView(vec3 mv, out float mag) { mag = 1.0; return mv; }
|
|
585
|
+
`;
|
|
586
|
+
let trailKey = '', look = 1;
|
|
587
|
+
const materials = [hmat];
|
|
588
|
+
function buildTrails(mode, share) {
|
|
589
|
+
look = TRAIL_LOOK[mode] || 1;
|
|
590
|
+
const key = mode + ':' + share;
|
|
591
|
+
if (key === trailKey)
|
|
592
|
+
return;
|
|
593
|
+
trailKey = key;
|
|
594
|
+
if (trail) {
|
|
595
|
+
object.remove(trail.object);
|
|
596
|
+
trail.dispose();
|
|
597
|
+
trail = null;
|
|
598
|
+
}
|
|
599
|
+
materials.length = 1;
|
|
600
|
+
trail = createCpuTrail(mode, { u, n, pos: x, vel: v, k: tk, glsl: trailGLSL, sizePx: 0.01, spacing: 0.0015, sub: 8, alpha: TRAIL_ALPHA[mode] });
|
|
601
|
+
if (!trail)
|
|
602
|
+
return;
|
|
603
|
+
trail.object.renderOrder = 2;
|
|
604
|
+
object.add(trail.object);
|
|
605
|
+
materials.push(...trail.materials);
|
|
606
|
+
}
|
|
607
|
+
buildTrails(c.trailMode, c.trailShare);
|
|
608
|
+
function packTrails() {
|
|
609
|
+
for (let i = 0; i < n; i++)
|
|
610
|
+
tk[i] = Math.min(code[i], 63.9) + 64 * Math.round(fade[i] * 15);
|
|
611
|
+
}
|
|
612
|
+
// steady state from the start: every tracer is released at its lane and carried along its own
|
|
613
|
+
// streamline for its phase of the crossing time (coarse steps, no cursor)
|
|
614
|
+
{
|
|
615
|
+
const Ug = Math.max(U0 * u.uFlowSpeed.value, 1e-3);
|
|
616
|
+
const cross = (2 * XL * 0.95) / Ug;
|
|
617
|
+
const hs = 0.05;
|
|
618
|
+
for (let i = 0; i < n; i++) {
|
|
619
|
+
release(i, 0);
|
|
620
|
+
const j = i * 3;
|
|
621
|
+
const steps = Math.round((phase[i] * cross) / hs);
|
|
622
|
+
let t0 = 0;
|
|
623
|
+
for (let s2 = 0; s2 < steps; s2++) {
|
|
624
|
+
velocity(x[j], x[j + 1], x[j + 2], t0, -1, 0, 1);
|
|
625
|
+
const mx = x[j] + vel[0] * hs * 0.5, my = x[j + 1] + vel[1] * hs * 0.5, mz = x[j + 2] + vel[2] * hs * 0.5;
|
|
626
|
+
velocity(mx, my, mz, t0 + hs * 0.5, -1, 0, 1);
|
|
627
|
+
x[j] += vel[0] * hs;
|
|
628
|
+
x[j + 1] += vel[1] * hs;
|
|
629
|
+
x[j + 2] += vel[2] * hs;
|
|
630
|
+
t0 += hs;
|
|
631
|
+
if (x[j] * Ux + x[j + 1] * Uy > XL * 0.9)
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
time = 0;
|
|
636
|
+
}
|
|
637
|
+
const stepper = createFixedStep(H_STEP, 6);
|
|
638
|
+
for (let s = 0; s < 45; s++)
|
|
639
|
+
step(H_STEP);
|
|
640
|
+
packTrails();
|
|
641
|
+
const invWorld = new THREE.Matrix4();
|
|
642
|
+
return {
|
|
643
|
+
object,
|
|
644
|
+
materials,
|
|
645
|
+
apply(cfg) { if (cfg)
|
|
646
|
+
buildTrails(cfg.trailMode, cfg.trailShare); },
|
|
647
|
+
update(dt, camera, pointer) {
|
|
648
|
+
const rdt = Math.min(Math.max(dt, 0), 1 / 20);
|
|
649
|
+
if (camera && !inView(object, camera, BOUNDS.center, bR, u.uSize.value))
|
|
650
|
+
return;
|
|
651
|
+
const d = rdt * u.uSpeed.value;
|
|
652
|
+
u.uTime.value += d;
|
|
653
|
+
if (camera) {
|
|
654
|
+
camera.getWorldDirection(axis);
|
|
655
|
+
axis.transformDirection(invWorld.copy(object.matrixWorld).invert()).normalize();
|
|
656
|
+
if (pointer)
|
|
657
|
+
stepPointerField(u, pointer, camera, object, u.uSize.value, rdt);
|
|
658
|
+
}
|
|
659
|
+
u.uVelScale.value = look;
|
|
660
|
+
let simD = 0;
|
|
661
|
+
stepper.run(d, (hh) => { step(hh); simD += hh; });
|
|
662
|
+
if (simD > 0) {
|
|
663
|
+
packTrails();
|
|
664
|
+
xAttr.needsUpdate = true;
|
|
665
|
+
hAttr.needsUpdate = true;
|
|
666
|
+
if (trail)
|
|
667
|
+
trail.update(simD / look);
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
seek(tt) { for (let s = 0; s < Math.round(tt / H_STEP); s++)
|
|
671
|
+
step(H_STEP); packTrails(); xAttr.needsUpdate = true; hAttr.needsUpdate = true; },
|
|
672
|
+
dispose() { hgeo.dispose(); hmat.dispose(); proxy.dispose(); if (trail)
|
|
673
|
+
trail.dispose(); },
|
|
674
|
+
_state: { x, code, V, D },
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
/** Defaults for every knob, so an older saved config still renders (identical to the catalog entry). */
|
|
678
|
+
const DEFAULTS = {
|
|
679
|
+
intensity: 1,
|
|
680
|
+
speed: 1,
|
|
681
|
+
opacity: 0.9,
|
|
682
|
+
size: 1,
|
|
683
|
+
color: '#3f7bff',
|
|
684
|
+
particleCount: 2400,
|
|
685
|
+
shape: { type: 'sphere', radius: 0.5, segments: 32, rings: 32 },
|
|
686
|
+
flowSpeed: 1,
|
|
687
|
+
windPitch: 0,
|
|
688
|
+
rake: 'sheet',
|
|
689
|
+
lanes: 44,
|
|
690
|
+
streamWidth: 0.85,
|
|
691
|
+
turbulence: 0.9,
|
|
692
|
+
fastColor: '#ff6a3d',
|
|
693
|
+
headSize: 1,
|
|
694
|
+
seed: 1,
|
|
695
|
+
quality: 'medium',
|
|
696
|
+
pointerMode: 'obstacle',
|
|
697
|
+
pointerStrength: 1,
|
|
698
|
+
pointerRadius: 1,
|
|
699
|
+
pointerColor: '#ffffff',
|
|
700
|
+
trailMode: 'comet',
|
|
701
|
+
trailLength: 1.2,
|
|
702
|
+
trailOpacity: 0.7,
|
|
703
|
+
trailColor: '#1b2a6b',
|
|
704
|
+
trailShare: 1,
|
|
705
|
+
};
|
|
706
|
+
/** Knobs that rebuild the simulation: they change on commit, never through the live path. */
|
|
707
|
+
const STRUCTURAL = ['particleCount', 'shape', 'rake', 'lanes', 'windPitch', 'seed', 'quality'];
|
|
708
|
+
/** Knobs an animation (or mouse move) may drive per frame — generated from applyConfig. */
|
|
709
|
+
const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.shapeFlow.map((p) => p.value));
|
|
710
|
+
const ShapeFlowParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
|
|
711
|
+
const rootRef = useRef(null);
|
|
712
|
+
useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
|
|
713
|
+
const s = size > 0 ? size : 1;
|
|
714
|
+
const cfg = useMemo(() => ({ ...DEFAULTS, ...config }), [config]);
|
|
715
|
+
// the shape is an object: rebuild on a change of its content, not of its identity
|
|
716
|
+
const shapeKey = JSON.stringify(cfg.shape);
|
|
717
|
+
// uniforms outlive the objects, so keyframe animations survive a rebuild
|
|
718
|
+
const uniforms = useMemo(() => createUniforms(), []);
|
|
719
|
+
// rebuilt only when a structural knob changes (trails rebuild inside apply())
|
|
720
|
+
const instance = useMemo(() => build(uniforms, cfg, s), [uniforms, cfg.particleCount, cfg.rake, cfg.lanes, cfg.windPitch, cfg.seed, cfg.quality, shapeKey]);
|
|
721
|
+
useEffect(() => () => instance.dispose(), [instance]);
|
|
722
|
+
useLayoutEffect(() => {
|
|
723
|
+
applyConfig(uniforms, cfg, s);
|
|
724
|
+
instance.apply(cfg);
|
|
725
|
+
}, [instance, uniforms, cfg, s]);
|
|
726
|
+
// Slider drags and keyframe animations are both overrides on the committed config.
|
|
727
|
+
// This is the one place they are merged and pushed, so they compose instead of
|
|
728
|
+
// overwriting each other; the animation wins, because it is the active driver.
|
|
729
|
+
const keyframes = animations?.particles?.animations;
|
|
730
|
+
const animOverride = useRef({});
|
|
731
|
+
const animFrom = useRef({});
|
|
732
|
+
const animStart = useRef(0);
|
|
733
|
+
// Editing a keyframe restarts its cycle rather than dropping the user mid-way.
|
|
734
|
+
useEffect(() => { animStart.current = performance.now(); animFrom.current = {}; }, [keyframes]);
|
|
735
|
+
const push = useCallback((overrides) => {
|
|
736
|
+
const merged = { ...cfg, ...overrides, ...animOverride.current };
|
|
737
|
+
const z = merged.size;
|
|
738
|
+
applyConfig(uniforms, merged, z && z > 0 ? z : s);
|
|
739
|
+
}, [cfg, uniforms, s]);
|
|
740
|
+
const live = useConfigLiveHandle(rootRef, id, 'particles', cfg, STRUCTURAL, push);
|
|
741
|
+
const pointer = usePointerField();
|
|
742
|
+
useFrame((state, delta) => {
|
|
743
|
+
instance.update(Math.min(delta, 0.1), state.camera, pointer);
|
|
744
|
+
// Keyframes first, pointer on top: a knob bound to both follows the cursor.
|
|
745
|
+
const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
|
|
746
|
+
if (keyframes?.length || pointerBound) {
|
|
747
|
+
applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
|
|
748
|
+
if (pointerBound)
|
|
749
|
+
applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
|
|
750
|
+
push(live.current);
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
return (_jsx("group", { ref: rootRef, children: _jsx("primitive", { object: instance.object }) }));
|
|
754
|
+
};
|
|
755
|
+
export default ShapeFlowParticles;
|