]> git.mxchange.org Git - simgear.git/commitdiff
Precipitation updates from ThorstenR
authorTorsten Dreyer <torsten@ŧ3r.de>
Tue, 21 Oct 2014 08:44:13 +0000 (10:44 +0200)
committerTorsten Dreyer <torsten@ŧ3r.de>
Tue, 21 Oct 2014 08:46:48 +0000 (10:46 +0200)
Since the consensus seems to be that the precipitation clipping issue is with the panel code, attached is  my proposed update for the precipitation system in SG and FG

* without corresponding control structures in FGData it falls back to default, except I have fixed an inconsistency in freezing behavior - previously rain changed suddenly to snow when the temperature dropped below zero, but the reverse transition was dragged out and gave odd visible motion with the wind as snow gradually changed back to rain with the particle speed not well defined. Now both transitions are sudden. And I see no more particles flow against the wind

* with

 <!-- definitions for the detailed precipitation manager -->
 <precipitation-control>
     <rain-droplet-size type="float" userarchive="n">0.015</rain-droplet-size>
     <snow-flake-size type="float" userarchive="n">0.03</snow-flake-size>
     <detailed-precipitation type="bool" userarchive="n">false</detailed-precipitation>
     <illumination type="float" userarchive="n">1.0</illumination>
     <clip-distance type="float" userarchive="n">5.0</clip-distance>
  </precipitation-control>

added to Environment/environment.xml, the new system allows to switch more detailed management on. This provides

* explicit setting of rain droplet size and snow flake size by the weather system

* automatic sqrt(r) scaling of the vertical speed of raindrops

* automatic transition to snow when freezing for small droplets but hail for large droplet sizes (looks like snow, but has different particle dynamics)

* an illumination scaling factor to dim the precipitating based on the light we have in the scene (I still need to devise a property rule to set this automatically)

The clip distance is also exposed now and considered at startup of the system - might be useful for e.g. airships when the gas bag provides rain cover (?)   or to be simply off for open airplanes

simgear/environment/precipitation.cxx
simgear/environment/precipitation.hxx

index 073c06d81869012a6af592b737a949c6abdec7b6..8ffa22106dacaea71d942c754a3095da5efd5ff7 100644 (file)
@@ -37,7 +37,7 @@
  * Build a new OSG object from osgParticle.
  */
 SGPrecipitation::SGPrecipitation() :
-    _freeze(false), _enabled(true), _snow_intensity(0.0), _rain_intensity(0.0), _clip_distance(5.0)
+    _freeze(false), _enabled(true), _droplet_external(false), _snow_intensity(0.0), _rain_intensity(0.0), _clip_distance(5.0), _rain_droplet_size(0.0), _snow_flake_size(0.0), _illumination(1.0)
 {
     _precipitationEffect = new osgParticle::PrecipitationEffect;
 }
@@ -47,6 +47,11 @@ void SGPrecipitation::setEnabled( bool value )
     _enabled = value;
 }
 
+void SGPrecipitation::setDropletExternal( bool value )
+{
+    _droplet_external = value;
+}
+
 bool SGPrecipitation::getEnabled() const
 {
     return _enabled;
@@ -66,7 +71,7 @@ osg::Group* SGPrecipitation::build(void)
     _precipitationEffect->rain(0);     
 
     if (_clip_distance!=0.0)
-    {    
+    {
         osg::ref_ptr<osg::ClipNode> clipNode = new osg::ClipNode;
         clipNode->addClipPlane( new osg::ClipPlane( 0 ) );
         clipNode->getClipPlane(0)->setClipPlane( 0.0, 0.0, -1.0, -_clip_distance );
@@ -119,17 +124,72 @@ void SGPrecipitation::setRainIntensity(float intensity)
         this->_rain_intensity = intensity;
 }
 
+/**
+ * @brief Define the rain droplet size
+ *
+ * This function permits you to define and change the rain droplet size
+ * which is used if external droplet size control is enabled
+ */
+
+void SGPrecipitation::setRainDropletSize(float size)
+{
+    _rain_droplet_size = size;
+}
+
 
-/** 
+/**
+ * @brief Define the illumination multiplier
+ *
+ * This function permits you to define and change the rain droplet size
+ * which is used if external droplet size control is enabled
+ */
+
+void SGPrecipitation::setIllumination(float illumination)
+{
+    _illumination = illumination;
+}
+
+/**
+ * @brief Define the snow flake size
+ *
+ * This function permits you to define and change the snow flake size
+ * which is used if external droplet size control is enabled
+ */
+
+void SGPrecipitation::setSnowFlakeSize(float size)
+{
+    _snow_flake_size = size;
+}
+
+
+/**
+ * @brief Define the rain droplet size
+ *
+ * This function permits you to define and change the rain droplet size
+ * which is used if external droplet size control is enabled
+ */
+
+void SGPrecipitation::setClipDistance(float distance)
+{
+    _clip_distance = distance;
+}
+
+/**
  * @brief Freeze the rain to snow
- * 
- * @param freeze Boolean 
- * 
+ *
+ * @param freeze Boolean
+ *
  * This function permits you to turn off the rain to snow.
  */
 void SGPrecipitation::setFreezing(bool freeze)
 {
+    if ((this->_freeze)&&(!freeze)) // rain freezes suddenly, so we need to unfreeze
+       {
+       this->_rain_intensity = this->_snow_intensity;
+       this->_snow_intensity = 0.0;
+       }
     this->_freeze = freeze;
+
 }
 
 
@@ -137,7 +197,7 @@ void SGPrecipitation::setFreezing(bool freeze)
  * @brief Define the wind direction and speed
  *
  * This function permits you to define and change the wind direction
- * 
+ *
  * After apply the MatrixTransform to the osg::Precipitation object,
  * x points full south... From wind heading and speed, we can calculate
  * the wind vector.
@@ -169,34 +229,74 @@ void SGPrecipitation::setWindProperty(double heading, double speed)
 bool SGPrecipitation::update(void)
 {
     if (this->_freeze) {
-        if (this->_rain_intensity > 0) 
-            this->_snow_intensity = this->_rain_intensity;
+        if (this->_rain_intensity > 0) {
+               this->_snow_intensity = this->_rain_intensity;
+       }
     }
 
     if (_enabled && this->_snow_intensity > 0) {
         _precipitationEffect->setWind(_wind_vec);
-        _precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
+
                
-        _precipitationEffect->setParticleSize(0.02f + 0.03f*_snow_intensity);
-        _precipitationEffect->setMaximumParticleDensity(_snow_intensity * 7.2f);
+       if(_droplet_external)
+               {
+
+               if ((_freeze) && (_rain_droplet_size > 0.03)) // this is hail or sleet
+                       {
+                       _precipitationEffect->setParticleSize(_rain_droplet_size*1.5f);
+                       _precipitationEffect->setParticleSpeed( -1.0f - 22.36f*sqrtf(_rain_droplet_size));
+                       _precipitationEffect->setMaximumParticleDensity(_snow_intensity * 4.8f);
+                       }
+               else if (_freeze) // this is snow from frozen small rain droplets
+                       {
+                       _precipitationEffect->setParticleSize(_rain_droplet_size*1.3f);
+                       _precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
+                       _precipitationEffect->setMaximumParticleDensity(_snow_intensity * 10.0f);
+                       }
+               else // this was snow in the first place
+                       {
+                       _precipitationEffect->setParticleSize(_snow_flake_size);
+                       _precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
+                       _precipitationEffect->setMaximumParticleDensity(_snow_intensity * 7.2f);
+                       }
+               }
+       else
+               {
+               _precipitationEffect->setMaximumParticleDensity(_snow_intensity * 7.2f);
+               _precipitationEffect->setParticleSize(0.02f + 0.03f*_snow_intensity);
+               _precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
+               }
+
+
         _precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_snow_intensity), 5.0f / (0.25f+_snow_intensity), 5.0f));
                
         _precipitationEffect->setNearTransition(25.f);
         _precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_snow_intensity));
                
-        _precipitationEffect->setParticleColor(osg::Vec4(0.85, 0.85, 0.85, 1.0) - osg::Vec4(0.1, 0.1, 0.1, 1.0) * _snow_intensity);
+        _precipitationEffect->setParticleColor(osg::Vec4(0.85 * _illumination, 0.85 * _illumination, 0.85 * _illumination, 1.0) - osg::Vec4(0.1, 0.1, 0.1, 1.0) * _snow_intensity);
     } else if (_enabled && this->_rain_intensity > 0) {
+
         _precipitationEffect->setWind(_wind_vec);
-        _precipitationEffect->setParticleSpeed( -2.0f + -5.0f*_rain_intensity);
+
+               
+       if(_droplet_external)
+               {
+               _precipitationEffect->setParticleSize(_rain_droplet_size);
+               _precipitationEffect->setParticleSpeed( -1.0f - 22.36f*sqrtf(_rain_droplet_size));
+               }
+       else
+               {
+               _precipitationEffect->setParticleSize(0.01 + 0.02*_rain_intensity);
+               _precipitationEffect->setParticleSpeed( -2.0f + -5.0f*_rain_intensity);
+               }
                
-        _precipitationEffect->setParticleSize(0.01 + 0.02*_rain_intensity);
         _precipitationEffect->setMaximumParticleDensity(_rain_intensity * 7.5f);
         _precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_rain_intensity), 5.0f / (0.25f+_rain_intensity), 5.0f));
                
         _precipitationEffect->setNearTransition(25.f);
         _precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_rain_intensity));
                
-        _precipitationEffect->setParticleColor( osg::Vec4(0x7A, 0xCE, 0xFF, 0x80));
+       _precipitationEffect->setParticleColor( osg::Vec4(0.64 * _illumination, 0.64 * _illumination, 0.64 * _illumination, 0.5));
     } else {
         _precipitationEffect->snow(0); 
         _precipitationEffect->rain(0); 
index 363137e9cf062359595e219fdd3d922e0516935d..fb3e2b59ae277152a83409006f8f911c9084f8b3 100644 (file)
@@ -37,10 +37,14 @@ class SGPrecipitation : public osg::Referenced
 private:
     bool _freeze;
     bool _enabled;
+    bool _droplet_external;
 
     float _snow_intensity;
     float _rain_intensity;
     float _clip_distance;
+    float _rain_droplet_size;
+    float _snow_flake_size;
+    float _illumination;
        
     osg::Vec3 _wind_vec;
        
@@ -54,8 +58,13 @@ public:
        
     void setWindProperty(double, double);
     void setFreezing(bool);
+    void setDropletExternal(bool);
     void setRainIntensity(float);
     void setSnowIntensity(float);
+    void setRainDropletSize(float);
+    void setSnowFlakeSize(float);
+    void setIllumination(float);
+    void setClipDistance(float);
 
     void setEnabled( bool );
     bool getEnabled() const;