2 * @file precipitation_mgr.cxx
3 * @author Nicolas VIVIEN
6 * @note Copyright (C) 2008 Nicolas VIVIEN
8 * @brief Precipitation manager
9 * This manager calculate the intensity of precipitation in function of the altitude,
10 * calculate the wind direction and velocity, then update the drawing of precipitation.
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
33 #include <osg/MatrixTransform>
35 #include <simgear/constants.h>
36 #include <simgear/math/SGMath.hxx>
37 #include <simgear/scene/sky/sky.hxx>
38 #include <simgear/scene/sky/cloud.hxx>
40 #include <Main/fg_props.hxx>
41 #include <Main/globals.hxx>
42 #include <Scenery/scenery.hxx>
44 #include "precipitation_mgr.hxx"
51 * @brief FGPrecipitation Manager constructor
53 * Build a new object to manage the precipitation object
55 FGPrecipitationMgr::FGPrecipitationMgr()
57 group = new osg::Group();
58 transform = new osg::MatrixTransform();
59 precipitation = new SGPrecipitation();
62 // By default, no precipitation
63 precipitation->setRainIntensity(0);
64 precipitation->setSnowIntensity(0);
66 transform->addChild(precipitation->build());
67 group->addChild(transform.get());
72 * @brief FGPrecipitaiton Manager destructor
74 FGPrecipitationMgr::~FGPrecipitationMgr()
80 * SGSubsystem initialization
82 void FGPrecipitationMgr::init()
84 // Read latitude and longitude position
85 SGGeod geod = SGGeod::fromDegM(fgGetDouble("/position/longitude-deg", 0.0),
86 fgGetDouble("/position/latitude-deg", 0.0),
88 osg::Matrix position(geod.makeZUpFrame());
89 // Move the precipitation object to player position
90 transform->setMatrix(position);
92 osg::Group* scenery = globals->get_scenery()->get_scene_graph();
93 scenery->addChild(getObject());
97 * @brief Get OSG precipitation object
99 * @returns A pointer on the OSG object (osg::Group *)
101 osg::Group * FGPrecipitationMgr::getObject(void)
103 return this->group.get();
108 * @brief Calculate the max alitutude with precipitation
110 * @returns Elevation max in meter
112 * This function permits you to know what is the altitude max where we can
113 * find precipitation. The value is returned in meter.
115 float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void)
122 // By default (not cloud layer)
123 max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES;
126 // To avoid messing up
130 // For each cloud layer
131 for (i=0; i<thesky->get_cloud_layer_count(); i++) {
135 // Value for q are (meaning / thickness) :
139 // 2 : "scattered" / 600
140 // 1 : "broken" / 750
141 // 0 : "overcast" / 1000
142 q = thesky->get_cloud_layer(i)->getCoverage();
144 // Save the coverage max
147 result = thesky->get_cloud_layer(i)->getElevation_m();
156 * @brief Update the precipitation drawing
159 void FGPrecipitationMgr::update(double dt)
163 double rain_intensity;
164 double snow_intensity;
166 float altitudeAircraft;
167 float altitudeCloudLayer;
169 // Get the elevation of aicraft and of the cloud layer
170 altitudeAircraft = fgGetDouble("/position/altitude-ft", 0.0);
171 altitudeCloudLayer = this->getPrecipitationAtAltitudeMax() * SG_METER_TO_FEET;
173 if (altitudeAircraft > altitudeCloudLayer) {
174 // The aircraft is above the cloud layer
179 // The aircraft is bellow the cloud layer
180 rain_intensity = fgGetDouble("/environment/metar/rain-norm", 0.0);
181 snow_intensity = fgGetDouble("/environment/metar/snow-norm", 0.0);
184 // Get the current and dew temperature
185 dewtemp = fgGetDouble("/environment/dewpoint-degc", 0.0);
186 currtemp = fgGetDouble("/environment/temperature-degc", 0.0);
188 if (currtemp < dewtemp) {
189 // There is fog... and the weather is very steamy
190 if (rain_intensity == 0)
191 rain_intensity = 0.15;
194 // If the current temperature is below 0°C, we turn off the rain to snow...
196 precipitation->setFreezing(true);
198 precipitation->setFreezing(false);
201 // Set the wind property
202 precipitation->setWindProperty(
203 fgGetDouble("/environment/wind-from-heading-deg", 0.0),
204 fgGetDouble("/environment/wind-speed-kt", 0.0));
206 // Set the intensity of precipitation
207 precipitation->setRainIntensity(rain_intensity);
208 precipitation->setSnowIntensity(snow_intensity);
210 // Update the drawing...
211 precipitation->update();