]> git.mxchange.org Git - flightgear.git/blobdiff - src/Environment/precipitation_mgr.cxx
fix a pointer reference.
[flightgear.git] / src / Environment / precipitation_mgr.cxx
index fcabe72ba351c085592cbd5e338b335e1b11fbbf..29d64cde06c5cfb3adcc37278130b075856b6c89 100644 (file)
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * @par CVS
- *   $Id$
  */
 
-#include <osgDB/ReadFile>
-#include <osgDB/FileUtils>
-#include <osgUtil/Optimizer>
-#include <osgUtil/CullVisitor>
-#include <osgViewer/Viewer>
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
 
-#include <osg/Depth>
-#include <osg/Stencil>
-#include <osg/ClipPlane>
-#include <osg/ClipNode>
 #include <osg/MatrixTransform>
-#include <osgUtil/TransformCallback>
 
 #include <simgear/constants.h>
+#include <simgear/math/SGMath.hxx>
 #include <simgear/scene/sky/sky.hxx>
 #include <simgear/scene/sky/cloud.hxx>
+#include <simgear/environment/visual_enviro.hxx>
 
 #include <Main/fg_props.hxx>
+#include <Main/globals.hxx>
+#include <Scenery/scenery.hxx>
 
 #include "precipitation_mgr.hxx"
 
-
 extern SGSky *thesky;
 
 
-void WorldCoordinate( osg::Matrix&, double,
-                             double, double, double);
-
 /** 
  * @brief FGPrecipitation Manager constructor 
  *
@@ -63,32 +54,16 @@ void WorldCoordinate( osg::Matrix&, double,
  */
 FGPrecipitationMgr::FGPrecipitationMgr()
 {      
-       osg::Matrix position;
-       double latitude, longitude;
-
-
-       group = new osg::Group();
-       transform = new osg::MatrixTransform();
-       precipitation = new SGPrecipitation();
-
-
-       // By default, none precipitation
-       precipitation->setRainIntensity(0);
-       precipitation->setSnowIntensity(0);
+    group = new osg::Group();
+    transform = new osg::MatrixTransform();
+    precipitation = new SGPrecipitation();
 
 
-       // Read latitude and longitude position
-       latitude = fgGetDouble("/position/latitude-deg", 0.0);
-       longitude = fgGetDouble("/position/longitude-deg", 0.0);
-
-       WorldCoordinate(position, latitude, longitude, 0, 0);
-
-
-       // Move the precipitation object to player position
-       transform->setMatrix(position);
-       transform->addChild(precipitation->build());
-
-       group->addChild(transform);
+    // By default, no precipitation
+    precipitation->setRainIntensity(0);
+    precipitation->setSnowIntensity(0);
+    transform->addChild(precipitation->build());
+    group->addChild(transform.get());
 }
 
 
@@ -97,9 +72,31 @@ FGPrecipitationMgr::FGPrecipitationMgr()
  */
 FGPrecipitationMgr::~FGPrecipitationMgr()
 {
-       delete precipitation;
+
+}
+
+/**
+ * SGSubsystem initialization
+ */
+void FGPrecipitationMgr::init()
+{
+    // Read latitude and longitude position
+    SGGeod geod = SGGeod::fromDegM(fgGetDouble("/position/longitude-deg", 0.0),
+                                   fgGetDouble("/position/latitude-deg", 0.0),
+                                   0.0);
+    osg::Matrix position(geod.makeZUpFrame());
+    // 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::setPrecipitationLevel(double a)
+{
+    fgSetDouble("environment/params/precipitation-level-ft",a);
+}
 
 /** 
  * @brief Get OSG precipitation object
@@ -108,10 +105,9 @@ FGPrecipitationMgr::~FGPrecipitationMgr()
  */
 osg::Group * FGPrecipitationMgr::getObject(void)
 {
-       return this->group;
+    return this->group.get();
 }
 
-
 /** 
  * @brief Calculate the max alitutude with precipitation
  * 
@@ -122,107 +118,146 @@ osg::Group * FGPrecipitationMgr::getObject(void)
  */
 float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void)
 {
-       int i;
-       int max;
-       float result;
-
-
-       // By default (not cloud layer)
-       max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES;
-       result = 0;
-
-       // To avoid messing up
-       if (thesky == NULL)
-               return result;
-
-       // For each cloud layer
-       for (i=0; i<thesky->get_cloud_layer_count(); i++) {
-               int q;
-
-               // Get coverage
-               // Value for q are (meaning / thickness) :
-               //   5 : "clear"                / 0
-               //   4 : "cirrus"       / ??
-               //   3 : "few"                  / 65
-               //   2 : "scattered"    / 600
-               //   1 : "broken"               / 750
-               //   0 : "overcast"             / 1000
-               q = thesky->get_cloud_layer(i)->getCoverage();
-
-               // Save the coverage max
-               if (q < max) {
-                       max = q;
-                       result = thesky->get_cloud_layer(i)->getElevation_m();
-               }
-       }
+    int i;
+    int max;
+       double elev;
+    float result;
+    SGPropertyNode *boundaryNode, *boundaryEntry;
+
+
+    // By default (not cloud layer)
+    max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES;
+    result = 0;
 
-       return result;
+    // To avoid messing up
+    if (thesky == NULL)
+        return result;
+
+    // For each cloud layer
+    for (i=0; i<thesky->get_cloud_layer_count(); i++) {
+        int q;
+
+        // Get coverage
+        // Value for q are (meaning / thickness) :
+        //   5 : "clear"               / 0
+        //   4 : "cirrus"       / ??
+        //   3 : "few"                         / 65
+        //   2 : "scattered"   / 600
+        //   1 : "broken"              / 750
+        //   0 : "overcast"            / 1000
+        q = thesky->get_cloud_layer(i)->getCoverage();
+
+        // Save the coverage max
+        if (q < max) {
+            max = q;
+            result = thesky->get_cloud_layer(i)->getElevation_m();
+        }
+    }
+
+
+    // 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 ) {
+            elev = boundaryEntry->getDoubleValue( "elevation-ft" );
+
+            if (elev > result)
+                result = elev;
+
+            ++i;
+        }
+    }
+
+       // Convert the result in meter
+       result = result * SG_FEET_TO_METER;
+
+    return result;
 }
 
 
 /** 
  * @brief Update the precipitation drawing
  * 
- * @returns true is all is OK
- *
- * This function permits you to update the precipitation drawing.
- * This function is called by the renderer.
+ * 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.
  */
-bool FGPrecipitationMgr::update(void)
+void FGPrecipitationMgr::update(double dt)
 {
-       double dewtemp;
-       double currtemp;
-       double rain_intensity;
-       double snow_intensity;
-
-       float altitudeAircraft;
-       float altitudeCloudLayer;
-
-       // 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) {
-               // 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);
-       }
+    double dewtemp;
+    double currtemp;
+    double rain_intensity;
+    double snow_intensity;
 
-       // Get the current and dew temperature
-       dewtemp = fgGetDouble("/environment/dewpoint-degc", 0.0);
-       currtemp = fgGetDouble("/environment/temperature-degc", 0.0);
+    float altitudeAircraft;
+    float altitudeCloudLayer;
 
-       if (currtemp < dewtemp) {
-               // There is fog... and the weather is very steamy
-               if (rain_intensity == 0)
-                       rain_intensity = 0.15;
-       }
+    altitudeCloudLayer = this->getPrecipitationAtAltitudeMax() * SG_METER_TO_FEET;
+    setPrecipitationLevel(altitudeCloudLayer);
 
-       // If the current temperature is below 0°C, we turn off the rain to snow...
-       if (currtemp < 0)
-               precipitation->setFreezing(true);
-       else
-               precipitation->setFreezing(false);
+       // Does the user enable the precipitation ?
+       if (!sgEnviro.get_precipitation_enable_state()) {
+               // Disable precipitations
+           precipitation->setRainIntensity(0);
+           precipitation->setSnowIntensity(0);
 
+           // Update the drawing...
+           precipitation->update();
 
-       // Set the wind property
-       precipitation->setWindProperty(
-               fgGetDouble("/environment/wind-from-heading-deg", 0.0),
-               fgGetDouble("/environment/wind-speed-kt", 0.0));
-
-       // Set the intensity of precipitation
-       precipitation->setRainIntensity(rain_intensity);
-       precipitation->setSnowIntensity(snow_intensity);
-
-       // Update the drawing...
-       precipitation->update();
+               // Exit
+               return;
+       }
 
-       return true;
+    // Get the elevation of aicraft and of the cloud layer
+    altitudeAircraft = fgGetDouble("/position/altitude-ft", 0.0);
+
+    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);
+    }
+
+    // Get the current and dew temperature
+    dewtemp = fgGetDouble("/environment/dewpoint-degc", 0.0);
+    currtemp = fgGetDouble("/environment/temperature-degc", 0.0);
+
+    if (currtemp < dewtemp) {
+        // There is fog... and the weather is very steamy
+        if (rain_intensity == 0)
+            rain_intensity = 0.15;
+    }
+
+    // If the current temperature is below 0°C, we turn off the rain to snow...
+    if (currtemp < 0)
+        precipitation->setFreezing(true);
+    else
+        precipitation->setFreezing(false);
+
+
+    // Set the wind property
+    precipitation->setWindProperty(
+        fgGetDouble("/environment/wind-from-heading-deg", 0.0),
+        fgGetDouble("/environment/wind-speed-kt", 0.0));
+
+    // Set the intensity of precipitation
+    precipitation->setRainIntensity(rain_intensity);
+    precipitation->setSnowIntensity(snow_intensity);
+
+    // Update the drawing...
+    precipitation->update();
 }
-
-