]> git.mxchange.org Git - simgear.git/blob - simgear/environment/precipitation.cxx
b5467a600b816f0b86a114a0c4c4bd113e7601d7
[simgear.git] / simgear / environment / precipitation.cxx
1 /**
2  * @file precipitation.cxx
3  * @author Nicolas VIVIEN
4  * @date 2008-02-10
5  *
6  * @note Copyright (C) 2008 Nicolas VIVIEN
7  *
8  * @brief Precipitation effects to draw rain and snow.
9  *
10  * @par Licences
11  *   This program is free software; you can redistribute it and/or
12  *   modify it under the terms of the GNU General Public License as
13  *   published by the Free Software Foundation; either version 2 of the
14  *   License, or (at your option) any later version.
15  *
16  *   This program is distributed in the hope that it will be useful, but
17  *   WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  *   General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with this program; if not, write to the Free Software
23  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
24  *
25  */
26
27 #include "precipitation.hxx"
28
29 #include <simgear/constants.h>
30
31 /**
32  * @brief SGPrecipitation constructor
33  *
34  * Build a new OSG object from osgParticle.
35  */
36 SGPrecipitation::SGPrecipitation() :
37     _freeze(false), _snow_intensity(0.0), _rain_intensity(0.0)
38 {
39     _precipitationEffect = new osgParticle::PrecipitationEffect;
40 }
41
42
43 /**
44  * @brief Build and add the object "precipitationEffect"
45  *
46  * This function permits you to create an object precipitationEffect and initialize it.
47  * I define by default the color of water (for raining)
48  */
49 osg::Group* SGPrecipitation::build(void)
50 {
51     osg::Group* group = new osg::Group;
52
53     _precipitationEffect->snow(0);      
54     _precipitationEffect->rain(0);      
55
56     group->addChild(_precipitationEffect.get());
57
58     return group;
59 }
60
61
62 /**
63  * @brief Define the snow intensity
64  *
65  * This function permits you to define and change the snow intensity
66  * The param 'intensity' is normed (0 to 1).
67  */
68 void SGPrecipitation::setSnowIntensity(float intensity)
69 {
70     if (this->_snow_intensity < intensity-0.001)
71         this->_snow_intensity += 0.001;
72     else if (this->_snow_intensity > intensity+0.001)
73         this->_snow_intensity -= 0.001;
74     else
75         this->_snow_intensity = intensity;
76 }
77
78
79 /**
80  * @brief Define the rain intensity
81  *
82  * This function permits you to define and change the rain intensity
83  * The param 'intensity' is normed (0 to 1).
84  */
85 void SGPrecipitation::setRainIntensity(float intensity)
86 {
87     if (this->_rain_intensity < intensity-0.001)
88         this->_rain_intensity += 0.001;
89     else if (this->_rain_intensity > intensity+0.001)
90         this->_rain_intensity -= 0.001;
91     else
92         this->_rain_intensity = intensity;
93 }
94
95
96 /** 
97  * @brief Freeze the rain to snow
98  * 
99  * @param freeze Boolean 
100  * 
101  * This function permits you to turn off the rain to snow.
102  */
103 void SGPrecipitation::setFreezing(bool freeze)
104 {
105     this->_freeze = freeze;
106 }
107
108
109 /**
110  * @brief Define the wind direction and speed
111  *
112  * This function permits you to define and change the wind direction
113  * 
114  * After apply the MatrixTransform to the osg::Precipitation object,
115  * x points full south... From wind heading and speed, we can calculate
116  * the wind vector.
117  */
118 void SGPrecipitation::setWindProperty(double heading, double speed)
119 {
120     double x, y, z;
121
122     heading = (heading + 180) * SGD_DEGREES_TO_RADIANS;
123     speed = speed * SG_FEET_TO_METER;
124
125     x = -cos(heading) * speed;
126     y = sin(heading) * speed;
127     z = 0;
128
129     this->_wind_vec = osg::Vec3(x, y, z);
130 }
131
132
133 /**
134  * @brief Update the precipitation effects
135  *
136  * This function permits you to update the precipitation effects.
137  * Be careful, if snow and rain intensity are greater than '0', snow effect
138  * will be first.
139  *
140  * The settings come from the osgParticule/PrecipitationEffect.cpp exemple.
141  */
142 bool SGPrecipitation::update(void)
143 {
144     if (this->_freeze) {
145         if (this->_rain_intensity > 0) 
146             this->_snow_intensity = this->_rain_intensity;
147     }
148
149     if (this->_snow_intensity > 0) {
150         _precipitationEffect->setWind(_wind_vec);
151         _precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
152                 
153         _precipitationEffect->setParticleSize(0.02f + 0.03f*_snow_intensity);
154         _precipitationEffect->setMaximumParticleDensity(_snow_intensity * 7.2f);
155         _precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_snow_intensity), 5.0f / (0.25f+_snow_intensity), 5.0f));
156                 
157         _precipitationEffect->setNearTransition(25.f);
158         _precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_snow_intensity));
159                 
160         _precipitationEffect->setParticleColor(osg::Vec4(0.85, 0.85, 0.85, 1.0) - osg::Vec4(0.1, 0.1, 0.1, 1.0) * _snow_intensity);
161     } else if (this->_rain_intensity > 0){
162         _precipitationEffect->setWind(_wind_vec);
163         _precipitationEffect->setParticleSpeed( -2.0f + -5.0f*_rain_intensity);
164                 
165         _precipitationEffect->setParticleSize(0.01 + 0.02*_rain_intensity);
166         _precipitationEffect->setMaximumParticleDensity(_rain_intensity * 7.5f);
167         _precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_rain_intensity), 5.0f / (0.25f+_rain_intensity), 5.0f));
168                 
169         _precipitationEffect->setNearTransition(25.f);
170         _precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_rain_intensity));
171                 
172         _precipitationEffect->setParticleColor( osg::Vec4(0x7A, 0xCE, 0xFF, 0x80));
173     } else {
174         _precipitationEffect->snow(0);  
175         _precipitationEffect->rain(0);  
176     }
177
178     return true;
179 }