Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/atmospheric_engine/src/lib/graphics/effects/rain_effect.cc @ 8771

Last change on this file since 8771 was 8771, checked in by amaechler, 18 years ago

branches/atmospheric_engine: rainsound fade working and comments

File size: 8.7 KB
Line 
1/*
2  orxonox - the future of 3D-vertical-scrollers
3 
4  Copyright (C) 2004 orx
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)
9  any later version.
10 
11### File Specific:
12  main-programmer: hdavid, amaechler
13*/
14
15#include "rain_effect.h"
16
17#include "util/loading/load_param.h"
18#include "util/loading/factory.h"
19#include "util/loading/resource_manager.h"
20
21#include "glincl.h"
22#include "p_node.h"
23#include "state.h"
24#include "spark_particles.h"
25#include "plane_emitter.h"
26#include "shell_command.h"
27#include "light.h"
28
29#include "parser/tinyxml/tinyxml.h"
30
31// Define shell commands
32SHELL_COMMAND(activate, RainEffect, activateRain);
33SHELL_COMMAND(deactivate, RainEffect, deactivateRain);
34SHELL_COMMAND(startraining, RainEffect, startRaining);
35SHELL_COMMAND(stopraining, RainEffect, stopRaining);
36
37using namespace std;
38
39CREATE_FACTORY(RainEffect, CL_RAIN_EFFECT);
40
41/**
42 * @brief standard constructor
43 */
44RainEffect::RainEffect(const TiXmlElement* root)
45{
46  this->setClassID(CL_RAIN_EFFECT, "RainEffect");
47
48  this->init();
49
50  if (root != NULL)
51    this->loadParams(root);
52
53  //load rain sound
54  if (this->rainBuffer != NULL)
55    ResourceManager::getInstance()->unload(this->rainBuffer);
56  this->rainBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/rain.wav", WAV);
57
58  //load wind sound
59  if (this->rainWindForce != 0)
60  {
61    if (this->windBuffer != NULL)
62      ResourceManager::getInstance()->unload(this->windBuffer);
63    this->windBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/wind.wav", WAV);
64  }
65
66  if(rainActivate)
67  {
68    this->activate();
69    RainEffect::rainParticles->precache((int)this->rainLife * 2);
70  }
71}
72
73/**
74 * @brief standard deconstructor
75 */
76RainEffect::~RainEffect()
77{
78  this->deactivate();
79
80  if (this->rainBuffer != NULL)
81    ResourceManager::getInstance()->unload(this->rainBuffer);
82
83  if (this->windBuffer != NULL)
84    ResourceManager::getInstance()->unload(this->windBuffer);
85}
86
87/**
88 * @brief initalizes the rain effect with default values
89 */
90void RainEffect::init()
91{
92  //Default values
93  this->rainActivate = false;
94  this->rainMove = false;
95  this->rainCoord = Vector(500, 500, 500);
96  this->rainSize = Vector2D(1000, 1000);
97  this->rainRate = 4000;
98  this->rainVelocity = -300;
99  this->rainLife = 4;
100  this->rainWindForce  = 0;
101  this->rainFadeInDuration = 0;
102  this->rainFadeOutDuration = 0;
103
104  this->rainMaxParticles = this->rainRate * this->rainLife;
105  this->localTimer = 0;
106  this->soundRainVolume = 0.3f;
107  this->emitter = new PlaneEmitter(this->rainSize);
108
109  lightMan = LightManager::getInstance();
110  this->rainAmbient = lightMan->getAmbientColor();
111}
112
113/**
114 * @brief loads the rain effect parameters.
115 * @param root: the XML-Element to load the data from
116 */
117void RainEffect::loadParams(const TiXmlElement* root)
118{
119  WeatherEffect::loadParams(root);
120
121  LoadParam(root, "coord", this, RainEffect, setRainCoord);
122  LoadParam(root, "size", this, RainEffect, setRainSize);
123  LoadParam(root, "rate", this, RainEffect, setRainRate);
124  LoadParam(root, "velocity", this, RainEffect, setRainVelocity);
125  LoadParam(root, "life", this, RainEffect, setRainLife);
126  LoadParam(root, "wind", this, RainEffect, setRainWind);
127  LoadParam(root, "fadeinduration", this, RainEffect, setRainFadeIn);
128  LoadParam(root, "fadeoutduration", this, RainEffect, setRainFadeOut);
129
130  LOAD_PARAM_START_CYCLE(root, element);
131  {
132    LoadParam_CYCLE(element, "option", this, RainEffect, setRainOption);
133  }
134  LOAD_PARAM_END_CYCLE(element);
135}
136
137SparkParticles* RainEffect::rainParticles = NULL;
138
139/**
140 * @brief activates the rain effect
141 */
142void RainEffect::activate()
143{
144  PRINTF(0)( "Activating RainEffect, coord: %f, %f, %f, size: %f, %f, rate: %f, velocity: %f, moveRain: %s\n", this->rainCoord.x, this->rainCoord.y, this->rainCoord.z, this->rainSize.x, this-> rainSize.y, this->rainRate, this->rainVelocity, this->rainMove ? "true" : "false" );
145
146  this->rainActivate = true;
147
148  if (unlikely(RainEffect::rainParticles == NULL))
149  {
150    RainEffect::rainParticles = new SparkParticles((int) this->rainMaxParticles);
151    RainEffect::rainParticles->setName("RainParticles");
152    RainEffect::rainParticles->setLifeSpan(this->rainLife, 2);
153    RainEffect::rainParticles->setRadius(0, 0.03);
154    RainEffect::rainParticles->setRadius(0.2, 0.02);
155    RainEffect::rainParticles->setRadius(1, 0.01);
156    RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2); // grey blue 1
157    RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2); // grey blue 2
158    RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2); // light grey
159  }
160
161  this->emitter->setSystem(RainEffect::rainParticles);
162
163  this->emitter->setRelCoor(this->rainCoord);
164
165  this->emitter->setEmissionRate(this->rainRate);
166  this->emitter->setEmissionVelocity(this->rainVelocity);
167
168  this->emitter->setSpread(this->rainWindForce / 50, 0.2);
169
170  // plays the rain sound and loops it
171  this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
172
173  // if there is wind, play the wind sound
174  if (this->rainWindForce != 0)
175    this->soundSource.play(this->windBuffer, 0.1f * this->rainWindForce, true);
176
177  if (this->rainFadeInDuration == 0)
178    lightMan->setAmbientColor(.1,.1,.1);
179}
180
181/**
182 * @brief deactivates the rain effect
183 */
184void RainEffect::deactivate()
185{
186  PRINTF(0)("Deactivating RainEffect\n");
187
188  this->rainActivate = false;
189  this->emitter->setSystem(NULL);
190
191  // Stop Sound
192  this->soundSource.stop();
193
194  // Restore Light Ambient
195  lightMan->setAmbientColor(this->rainAmbient, this->rainAmbient, this->rainAmbient);
196}
197
198/**
199 * @brief ticks the rain effect
200 * @param dt: tick float
201 */
202void RainEffect::tick (float dt)
203{
204  if (!this->rainActivate)
205    return;
206
207  if (this->rainMove)
208  {
209    this->rainCoord = State::getCameraNode()->getAbsCoor();
210    this->emitter->setRelCoor(this->rainCoord.x , this->rainCoord.y+800, this->rainCoord.z);
211  }
212
213  if (this->rainFadeInDuration != 0 && this->localTimer < this->rainFadeInDuration)
214  {
215    this->localTimer += dt;
216    float progress = this->localTimer / this->rainFadeInDuration;
217
218    // Dim Light
219    lightMan->setAmbientColor(1 - progress * 0.9, 1 - progress * 0.9, 1 - progress * 0.9);
220
221    // use alpha in color to fade in
222    RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
223    RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
224    RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
225
226    // increase radius for more "heavy" rain
227    RainEffect::rainParticles->setRadius(0, 0.03 * progress);
228    RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
229    RainEffect::rainParticles->setRadius(1, 0.01 * progress);
230
231    // increase sound volume
232    if (!this->soundSource.isPlaying())
233      this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
234
235    this->soundSource.gain(this->rainBuffer, this->soundRainVolume * progress);
236  }
237  else if ( this->rainFadeOutDuration != 0 )
238  {
239    if ( this->localTimer < this->rainFadeOutDuration )
240    {
241      this->localTimer += dt;
242      float progress = 1 - (this->localTimer / this->rainFadeOutDuration);
243
244      // Fade In Light
245      lightMan->setAmbientColor(1 - progress * 0.9, 1 - progress * 0.9, 1 - progress * 0.9);
246
247      // use alpha in color to fade out
248      RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
249      RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
250      RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
251
252      // decrease radius
253      RainEffect::rainParticles->setRadius(0, 0.03 * progress);
254      RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
255      RainEffect::rainParticles->setRadius(1, 0.01 * progress);
256
257      // decrease sound volume
258      if (!this->soundSource.isPlaying())
259        this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
260
261      this->soundSource.gain(this->rainBuffer, this->soundRainVolume * progress);
262    }
263    else
264      this->deactivate();
265  }
266}
267
268/**
269 * @brief starts raining slowly
270*/
271void RainEffect::startRaining()
272{
273
274  if (this->rainActivate)
275    this->deactivate();
276
277  if (!this->rainFadeInDuration > 0)
278    this->rainFadeInDuration = 20;
279
280  this->localTimer = 0;
281
282  this->activate();
283}
284
285/**
286 * @brief stops raining slowly
287 */
288void RainEffect::stopRaining()
289{
290
291  if (!this->rainActivate)
292    this->activate();
293
294  if (!this->rainFadeOutDuration > 0)
295    this->rainFadeOutDuration = 20;
296
297  this->localTimer = 0;
298}
299
300/**
301 * @brief hides the rain
302 */
303void RainEffect::hideRain()
304{
305  RainEffect::rainParticles->setColor(0, 0,0,0, 0);
306  RainEffect::rainParticles->setColor(0, 0,0,0, 0);
307}
Note: See TracBrowser for help on using the repository browser.