]> git.mxchange.org Git - flightgear.git/blob - src/Environment/precipitation_mgr.cxx
header cleanups
[flightgear.git] / src / Environment / precipitation_mgr.cxx
1 /**
2  * @file precipitation_mgr.cxx
3  * @author Nicolas VIVIEN
4  * @date 2008-02-10
5  *
6  * @note Copyright (C) 2008 Nicolas VIVIEN
7  *
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.
11  *
12  * @par Licences
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.
17  *
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.
22  *
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.
26  *
27  */
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/math/SGMath.hxx>
37 #include <simgear/scene/sky/sky.hxx>
38 #include <simgear/scene/sky/cloud.hxx>
39
40 #include <Main/fg_props.hxx>
41 #include <Main/globals.hxx>
42 #include <Scenery/scenery.hxx>
43
44 #include "precipitation_mgr.hxx"
45
46
47 extern SGSky *thesky;
48
49
50 /** 
51  * @brief FGPrecipitation Manager constructor 
52  *
53  * Build a new object to manage the precipitation object
54  */
55 FGPrecipitationMgr::FGPrecipitationMgr()
56 {       
57     group = new osg::Group();
58     transform = new osg::MatrixTransform();
59     precipitation = new SGPrecipitation();
60
61
62     // By default, no precipitation
63     precipitation->setRainIntensity(0);
64     precipitation->setSnowIntensity(0);
65
66     transform->addChild(precipitation->build());
67     group->addChild(transform.get());
68 }
69
70
71 /** 
72  * @brief FGPrecipitaiton Manager destructor
73  */
74 FGPrecipitationMgr::~FGPrecipitationMgr()
75 {
76
77 }
78
79 /**
80  * SGSubsystem initialization
81  */
82 void FGPrecipitationMgr::init()
83 {
84     // Read latitude and longitude position
85     SGGeod geod = SGGeod::fromDegM(fgGetDouble("/position/longitude-deg", 0.0),
86                                    fgGetDouble("/position/latitude-deg", 0.0),
87                                    0.0);
88     osg::Matrix position(geod.makeZUpFrame());
89     // Move the precipitation object to player position
90     transform->setMatrix(position);
91     // Add to scene graph
92     osg::Group* scenery = globals->get_scenery()->get_scene_graph();
93     scenery->addChild(getObject());
94 }
95
96 /** 
97  * @brief Get OSG precipitation object
98  * 
99  * @returns A pointer on the OSG object (osg::Group *)
100  */
101 osg::Group * FGPrecipitationMgr::getObject(void)
102 {
103     return this->group.get();
104 }
105
106
107 /** 
108  * @brief Calculate the max alitutude with precipitation
109  * 
110  * @returns Elevation max in meter
111  *
112  * This function permits you to know what is the altitude max where we can
113  * find precipitation. The value is returned in meter.
114  */
115 float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void)
116 {
117     int i;
118     int max;
119     float result;
120
121
122     // By default (not cloud layer)
123     max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES;
124     result = 0;
125
126     // To avoid messing up
127     if (thesky == NULL)
128         return result;
129
130     // For each cloud layer
131     for (i=0; i<thesky->get_cloud_layer_count(); i++) {
132         int q;
133
134         // Get coverage
135         // Value for q are (meaning / thickness) :
136         //   5 : "clear"                / 0
137         //   4 : "cirrus"       / ??
138         //   3 : "few"                  / 65
139         //   2 : "scattered"    / 600
140         //   1 : "broken"               / 750
141         //   0 : "overcast"             / 1000
142         q = thesky->get_cloud_layer(i)->getCoverage();
143
144         // Save the coverage max
145         if (q < max) {
146             max = q;
147             result = thesky->get_cloud_layer(i)->getElevation_m();
148         }
149     }
150
151     return result;
152 }
153
154
155 /** 
156  * @brief Update the precipitation drawing
157  * 
158  */
159 void FGPrecipitationMgr::update(double dt)
160 {
161     double dewtemp;
162     double currtemp;
163     double rain_intensity;
164     double snow_intensity;
165
166     float altitudeAircraft;
167     float altitudeCloudLayer;
168
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;
172
173     if (altitudeAircraft > altitudeCloudLayer) {
174         // The aircraft is above the cloud layer
175         rain_intensity = 0;
176         snow_intensity = 0;
177     }
178     else {
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);
182     }
183
184     // Get the current and dew temperature
185     dewtemp = fgGetDouble("/environment/dewpoint-degc", 0.0);
186     currtemp = fgGetDouble("/environment/temperature-degc", 0.0);
187
188     if (currtemp < dewtemp) {
189         // There is fog... and the weather is very steamy
190         if (rain_intensity == 0)
191             rain_intensity = 0.15;
192     }
193
194     // If the current temperature is below 0°C, we turn off the rain to snow...
195     if (currtemp < 0)
196         precipitation->setFreezing(true);
197     else
198         precipitation->setFreezing(false);
199
200
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));
205
206     // Set the intensity of precipitation
207     precipitation->setRainIntensity(rain_intensity);
208     precipitation->setSnowIntensity(snow_intensity);
209
210     // Update the drawing...
211     precipitation->update();
212 }