X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fenvironment%2Fprecipitation.cxx;h=8ffa22106dacaea71d942c754a3095da5efd5ff7;hb=84e5142195f5d3b2bf40b11119991457d7f8558b;hp=b5467a600b816f0b86a114a0c4c4bd113e7601d7;hpb=6d2f1ff81e76ea378b8dd471a6400649fdb029c8;p=simgear.git diff --git a/simgear/environment/precipitation.cxx b/simgear/environment/precipitation.cxx index b5467a60..8ffa2210 100644 --- a/simgear/environment/precipitation.cxx +++ b/simgear/environment/precipitation.cxx @@ -25,8 +25,11 @@ */ #include "precipitation.hxx" +//#include "visual_enviro.hxx" #include +#include +#include /** * @brief SGPrecipitation constructor @@ -34,11 +37,25 @@ * Build a new OSG object from osgParticle. */ SGPrecipitation::SGPrecipitation() : - _freeze(false), _snow_intensity(0.0), _rain_intensity(0.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; } +void SGPrecipitation::setEnabled( bool value ) +{ + _enabled = value; +} + +void SGPrecipitation::setDropletExternal( bool value ) +{ + _droplet_external = value; +} + +bool SGPrecipitation::getEnabled() const +{ + return _enabled; +} /** * @brief Build and add the object "precipitationEffect" @@ -53,7 +70,22 @@ osg::Group* SGPrecipitation::build(void) _precipitationEffect->snow(0); _precipitationEffect->rain(0); - group->addChild(_precipitationEffect.get()); + if (_clip_distance!=0.0) + { + osg::ref_ptr clipNode = new osg::ClipNode; + clipNode->addClipPlane( new osg::ClipPlane( 0 ) ); + clipNode->getClipPlane(0)->setClipPlane( 0.0, 0.0, -1.0, -_clip_distance ); + clipNode->setReferenceFrame(osg::ClipNode::ABSOLUTE_RF); + clipNode->addChild(_precipitationEffect.get()); + + group->addChild(clipNode.get()); + } + else + { + group->addChild(_precipitationEffect.get()); + } + + group->setNodeMask( ~(simgear::CASTSHADOW_BIT | simgear::MODELLIGHT_BIT) ); return group; } @@ -92,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; + } @@ -110,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. @@ -142,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 (this->_snow_intensity > 0) { + 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); - } else if (this->_rain_intensity > 0){ + _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);