* 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
*
*/
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());
}
*/
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
*/
osg::Group * FGPrecipitationMgr::getObject(void)
{
- return this->group;
+ return this->group.get();
}
-
/**
* @brief Calculate the max alitutude with precipitation
*
*/
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();
}
-
-