X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FEnvironment%2Fprecipitation_mgr.cxx;h=9e83ab8529aeff365f7ce50939b5f6dfd17f16ef;hb=06e8fe747fb1733528aa1e01bc6bd285a53ec127;hp=d6b802d669fbfc2e852739623d1e0bf976636bec;hpb=278ab25f2106ed0db12e309e802aefc2ec955ac0;p=flightgear.git diff --git a/src/Environment/precipitation_mgr.cxx b/src/Environment/precipitation_mgr.cxx index d6b802d66..9e83ab852 100644 --- a/src/Environment/precipitation_mgr.cxx +++ b/src/Environment/precipitation_mgr.cxx @@ -33,20 +33,17 @@ #include #include -#include #include #include +#include #include
#include
+#include #include #include "precipitation_mgr.hxx" - -extern SGSky *thesky; - - /** * @brief FGPrecipitation Manager constructor * @@ -63,6 +60,8 @@ FGPrecipitationMgr::FGPrecipitationMgr() precipitation->setRainIntensity(0); precipitation->setSnowIntensity(0); + // set the clip distance from the config + precipitation->setClipDistance(fgGetFloat("/environment/precipitation-control/clip-distance",5.0)); transform->addChild(precipitation->build()); group->addChild(transform.get()); } @@ -85,12 +84,31 @@ void FGPrecipitationMgr::init() SGGeod geod = SGGeod::fromDegM(fgGetDouble("/position/longitude-deg", 0.0), fgGetDouble("/position/latitude-deg", 0.0), 0.0); - osg::Matrix position(geod.makeZUpFrame()); + osg::Matrix position(makeZUpFrame(geod)); // Move the precipitation object to player position transform->setMatrix(position); // Add to scene graph osg::Group* scenery = globals->get_scenery()->get_scene_graph(); scenery->addChild(getObject()); + fgGetNode("environment/params/precipitation-level-ft", true); +} + +void FGPrecipitationMgr::bind () +{ + _tiedProperties.setRoot( fgGetNode("/sim/rendering", true ) ); + _tiedProperties.Tie("precipitation-enable", precipitation.get(), + &SGPrecipitation::getEnabled, + &SGPrecipitation::setEnabled); +} + +void FGPrecipitationMgr::unbind () +{ + _tiedProperties.Untie(); +} + +void FGPrecipitationMgr::setPrecipitationLevel(double a) +{ + fgSetDouble("environment/params/precipitation-level-ft",a); } /** @@ -103,26 +121,34 @@ osg::Group * FGPrecipitationMgr::getObject(void) return this->group.get(); } - /** * @brief Calculate the max alitutude with precipitation * * @returns Elevation max in meter * * This function permits you to know what is the altitude max where we can - * find precipitation. The value is returned in meter. + * find precipitation. The value is returned in meters. */ float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void) { int i; int max; float result; + SGPropertyNode *boundaryNode, *boundaryEntry; + + if (fgGetBool("/environment/params/use-external-precipitation-level", false)) { + // If we're not modeling the precipitation level based on the cloud + // layers, take it directly from the property tree. + return fgGetFloat("/environment/params/external-precipitation-level-m", 0.0); + } // By default (not cloud layer) max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES; result = 0; + SGSky* thesky = globals->get_renderer()->getSky(); + // To avoid messing up if (thesky == NULL) return result; @@ -148,6 +174,32 @@ float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void) } } + + // If we haven't found clouds layers, we read the bounday layers table. + if (result > 0) + return result; + + + // Read boundary layers node + boundaryNode = fgGetNode("/environment/config/boundary"); + + if (boundaryNode != NULL) { + i = 0; + + // For each boundary layers + while ( ( boundaryEntry = boundaryNode->getNode( "entry", i ) ) != NULL ) { + double elev = boundaryEntry->getDoubleValue( "elevation-ft" ); + + if (elev > result) + result = elev; + + ++i; + } + } + + // Convert the result in meter + result = result * SG_FEET_TO_METER; + return result; } @@ -155,6 +207,10 @@ float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void) /** * @brief Update the precipitation drawing * + * To seem real, we stop the precipitation above the cloud or boundary layer. + * If METAR information doesn't give us this altitude, we will see precipitations + * in space... + * Moreover, below 0°C we change rain into snow. */ void FGPrecipitationMgr::update(double dt) { @@ -165,20 +221,51 @@ void FGPrecipitationMgr::update(double dt) float altitudeAircraft; float altitudeCloudLayer; + float rainDropletSize; + float snowFlakeSize; + float illumination; + + altitudeCloudLayer = this->getPrecipitationAtAltitudeMax() * SG_METER_TO_FEET; + setPrecipitationLevel(altitudeCloudLayer); + + + + // Does the user enable the precipitation ? + if (!precipitation->getEnabled() ) { + // Disable precipitations + precipitation->setRainIntensity(0); + precipitation->setSnowIntensity(0); + + // Update the drawing... + precipitation->update(); + + // Exit + return; + } + + // See if external droplet size and illumination are used + if (fgGetBool("/environment/precipitation-control/detailed-precipitation", false)) { + precipitation->setDropletExternal(true); + rainDropletSize = fgGetFloat("/environment/precipitation-control/rain-droplet-size", 0.015); + snowFlakeSize = fgGetFloat("/environment/precipitation-control/snow-flake-size", 0.03); + illumination = fgGetFloat("/environment/precipitation-control/illumination", 1.0); + precipitation->setRainDropletSize(rainDropletSize); + precipitation->setSnowFlakeSize(snowFlakeSize); + precipitation->setIllumination(illumination); + } // Get the elevation of aicraft and of the cloud layer altitudeAircraft = fgGetDouble("/position/altitude-ft", 0.0); - altitudeCloudLayer = this->getPrecipitationAtAltitudeMax() * SG_METER_TO_FEET; - if (altitudeAircraft > altitudeCloudLayer) { + if ((altitudeCloudLayer > 0) && (altitudeAircraft > altitudeCloudLayer)) { // The aircraft is above the cloud layer rain_intensity = 0; snow_intensity = 0; } else { // The aircraft is bellow the cloud layer - rain_intensity = fgGetDouble("/environment/metar/rain-norm", 0.0); - snow_intensity = fgGetDouble("/environment/metar/snow-norm", 0.0); + rain_intensity = fgGetDouble("/environment/rain-norm", 0.0); + snow_intensity = fgGetDouble("/environment/snow-norm", 0.0); } // Get the current and dew temperature