FlightGear next
precipitation_mgr.cxx
Go to the documentation of this file.
1
28
29#ifdef HAVE_CONFIG_H
30# include <config.h>
31#endif
32
33#include <osg/MatrixTransform>
34
35#include <simgear/constants.h>
36#include <simgear/scene/sky/sky.hxx>
37#include <simgear/scene/sky/cloud.hxx>
38#include <simgear/scene/util/OsgMath.hxx>
39
40#include <Main/fg_props.hxx>
41#include <Main/globals.hxx>
42#include <Viewer/renderer.hxx>
43#include <Scenery/scenery.hxx>
44
45#include "precipitation_mgr.hxx"
46
53{
54 // Try to set up the scenegraph.
56}
57
65
70{
71 // Read latitude and longitude position
72 SGGeod geod = SGGeod::fromDegM(fgGetDouble("/position/longitude-deg", 0.0),
73 fgGetDouble("/position/latitude-deg", 0.0),
74 0.0);
75 osg::Matrix position(makeZUpFrame(geod));
76 // Move the precipitation object to player position
77 transform->setMatrix(position);
78 fgGetNode("environment/params/precipitation-level-ft", true);
79}
80
82{
83 _tiedProperties.setRoot( fgGetNode("/sim/rendering", true ) );
84 _tiedProperties.Tie("precipitation-enable", precipitation.get(),
85 &SGPrecipitation::getEnabled,
86 &SGPrecipitation::setEnabled);
87}
88
90{
91 _tiedProperties.Untie();
92}
93
94// Set up the precipitation manager scenegraph.
96{
97 FGScenery* scenery = globals->get_scenery();
98 osg::Group* group = scenery->get_precipitation_branch();
99 transform = new osg::MatrixTransform();
100 precipitation = new SGPrecipitation();
101
102
103 // By default, no precipitation
104 precipitation->setRainIntensity(0);
105 precipitation->setSnowIntensity(0);
106
107 // set the clip distance from the config
108 precipitation->setClipDistance(fgGetFloat("/environment/precipitation-control/clip-distance",5.0));
109 transform->addChild(precipitation->build());
110 group->addChild(transform.get());
111}
112
113
115{
116 fgSetDouble("environment/params/precipitation-level-ft",a);
117}
118
127float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void)
128{
129 int i;
130 int max;
131 float result;
132 SGPropertyNode *boundaryNode, *boundaryEntry;
133
134 if (fgGetBool("/environment/params/use-external-precipitation-level", false)) {
135 // If we're not modeling the precipitation level based on the cloud
136 // layers, take it directly from the property tree.
137 return fgGetFloat("/environment/params/external-precipitation-level-m", 0.0);
138 }
139
140
141 // By default (not cloud layer)
142 max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES;
143 result = 0;
144
145 SGSky* thesky = globals->get_renderer()->getSky();
146
147 // To avoid messing up
148 if (thesky == NULL)
149 return result;
150
151 // For each cloud layer
152 for (i=0; i<thesky->get_cloud_layer_count(); i++) {
153 int q;
154
155 // Get coverage
156 // Value for q are (meaning / thickness) :
157 // 5 : "clear" / 0
158 // 4 : "cirrus" / ??
159 // 3 : "few" / 65
160 // 2 : "scattered" / 600
161 // 1 : "broken" / 750
162 // 0 : "overcast" / 1000
163 q = thesky->get_cloud_layer(i)->getCoverage();
164
165 // Save the coverage max
166 if (q < max) {
167 max = q;
168 result = thesky->get_cloud_layer(i)->getElevation_m();
169 }
170 }
171
172
173 // If we haven't found clouds layers, we read the bounday layers table.
174 if (result > 0)
175 return result;
176
177
178 // Read boundary layers node
179 boundaryNode = fgGetNode("/environment/config/boundary");
180
181 if (boundaryNode != NULL) {
182 i = 0;
183
184 // For each boundary layers
185 while ( ( boundaryEntry = boundaryNode->getNode( "entry", i ) ) != NULL ) {
186 double elev = boundaryEntry->getDoubleValue( "elevation-ft" );
187
188 if (elev > result)
189 result = elev;
190
191 ++i;
192 }
193 }
194
195 // Convert the result in meter
196 result = result * SG_FEET_TO_METER;
197
198 return result;
199}
200
201
211{
212 double dewtemp;
213 double currtemp;
214 double rain_intensity;
215 double snow_intensity;
216
217 float altitudeAircraft;
218 float altitudeCloudLayer;
219 float rainDropletSize;
220 float snowFlakeSize;
221 float illumination;
222
223 altitudeCloudLayer = this->getPrecipitationAtAltitudeMax() * SG_METER_TO_FEET;
224 setPrecipitationLevel(altitudeCloudLayer);
225
226
227
228 // Does the user enable the precipitation ?
229 if (!precipitation->getEnabled() ) {
230 // Disable precipitations
231 precipitation->setRainIntensity(0);
232 precipitation->setSnowIntensity(0);
233
234 // Update the drawing...
235 precipitation->update();
236
237 // Exit
238 return;
239 }
240
241 // See if external droplet size and illumination are used
242 if (fgGetBool("/environment/precipitation-control/detailed-precipitation", false)) {
243 precipitation->setDropletExternal(true);
244 rainDropletSize = fgGetFloat("/environment/precipitation-control/rain-droplet-size", 0.015);
245 snowFlakeSize = fgGetFloat("/environment/precipitation-control/snow-flake-size", 0.03);
246 illumination = fgGetFloat("/environment/precipitation-control/illumination", 1.0);
247 precipitation->setRainDropletSize(rainDropletSize);
248 precipitation->setSnowFlakeSize(snowFlakeSize);
249 precipitation->setIllumination(illumination);
250 }
251
252 // Get the elevation of aicraft and of the cloud layer
253 altitudeAircraft = fgGetDouble("/position/altitude-ft", 0.0);
254
255 if ((altitudeCloudLayer > 0) && (altitudeAircraft > altitudeCloudLayer)) {
256 // The aircraft is above the cloud layer
257 rain_intensity = 0;
258 snow_intensity = 0;
259 }
260 else {
261 // The aircraft is bellow the cloud layer
262 rain_intensity = fgGetDouble("/environment/rain-norm", 0.0);
263 snow_intensity = fgGetDouble("/environment/snow-norm", 0.0);
264 }
265
266 // Get the current and dew temperature
267 dewtemp = fgGetDouble("/environment/dewpoint-degc", 0.0);
268 currtemp = fgGetDouble("/environment/temperature-degc", 0.0);
269
270 if (currtemp < dewtemp) {
271 // There is fog... and the weather is very steamy
272 if (rain_intensity == 0)
273 rain_intensity = 0.15;
274 }
275
276 // If the current temperature is below 0°C, we turn off the rain to snow...
277 if (currtemp < 0)
278 precipitation->setFreezing(true);
279 else
280 precipitation->setFreezing(false);
281
282
283 // Set the wind property
284 precipitation->setWindProperty(
285 fgGetDouble("/environment/wind-from-heading-deg", 0.0),
286 fgGetDouble("/environment/wind-speed-kt", 0.0));
287
288 // Set the intensity of precipitation
289 precipitation->setRainIntensity(rain_intensity);
290 precipitation->setSnowIntensity(snow_intensity);
291
292 // Update the drawing...
293 precipitation->update();
294}
295
296
297// Register the subsystem.
298SGSubsystemMgr::Registrant<FGPrecipitationMgr> registrantFGPrecipitationMgr(
299 SGSubsystemMgr::GENERAL,
300 {{"FGScenery", SGSubsystemMgr::Dependency::HARD},
301 {"SGSky", SGSubsystemMgr::Dependency::NONSUBSYSTEM_HARD}});
#define i(x)
virtual FGRenderer * get_renderer() const
Definition globals.cxx:572
virtual ~FGPrecipitationMgr()
FGPrecipitaiton Manager destructor.
void init() override
SGSubsystem initialization.
void setPrecipitationLevel(double l)
FGPrecipitationMgr()
FGPrecipitation Manager constructor.
void update(double dt) override
Update the precipitation drawing.
SGSky * getSky() const
Definition renderer.cxx:856
osg::Group * get_precipitation_branch() const
Definition scenery.hxx:135
FGGlobals * globals
Definition globals.cxx:142
SGSubsystemMgr::Registrant< FGPrecipitationMgr > registrantFGPrecipitationMgr(SGSubsystemMgr::GENERAL, {{"FGScenery", SGSubsystemMgr::Dependency::HARD}, {"SGSky", SGSubsystemMgr::Dependency::NONSUBSYSTEM_HARD}})
Precipitation manager This manager calculate the intensity of precipitation in function of the altitu...
bool fgSetDouble(const char *name, double defaultValue)
Set a double value for a property.
Definition proptest.cpp:31
bool fgGetBool(char const *name, bool def)
Get a bool value for a property.
Definition proptest.cpp:25
double fgGetDouble(const char *name, double defaultValue)
Get a double value for a property.
Definition proptest.cpp:30
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
Definition proptest.cpp:27
float fgGetFloat(const char *name, float defaultValue)
Get a float value for a property.
Definition proptest.cpp:29