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 | SHELL_COMMAND(activate, RainEffect, activateRain); |
---|
32 | SHELL_COMMAND(deactivate, RainEffect, deactivateRain); |
---|
33 | |
---|
34 | SHELL_COMMAND(startRaining, RainEffect, startRaining); |
---|
35 | |
---|
36 | using namespace std; |
---|
37 | |
---|
38 | CREATE_FACTORY(RainEffect, CL_RAIN_EFFECT); |
---|
39 | |
---|
40 | // TODO: Dim Light with Rain, Finish preCaching, check out if multiple rain emitters work, Think about what happens with building poss. to hang movewithcam off, benchmark, possible to activate lightening, turn off visibility when in a building, variable emitter size depending on playable, also rain velocity |
---|
41 | |
---|
42 | RainEffect::RainEffect(const TiXmlElement* root) |
---|
43 | { |
---|
44 | this->setClassID(CL_RAIN_EFFECT, "RainEffect"); |
---|
45 | |
---|
46 | this->init(); |
---|
47 | |
---|
48 | if (root != NULL) |
---|
49 | this->loadParams(root); |
---|
50 | |
---|
51 | //load rain sound |
---|
52 | if (this->rainBuffer != NULL) |
---|
53 | ResourceManager::getInstance()->unload(this->rainBuffer); |
---|
54 | this->rainBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/rain.wav", WAV); |
---|
55 | |
---|
56 | //load wind sound |
---|
57 | if (this->rainWindForce != 0) { |
---|
58 | if (this->windBuffer != NULL) |
---|
59 | ResourceManager::getInstance()->unload(this->windBuffer); |
---|
60 | this->windBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/wind.wav", WAV); |
---|
61 | } |
---|
62 | |
---|
63 | if(rainActivate) |
---|
64 | this->activate(); |
---|
65 | } |
---|
66 | |
---|
67 | RainEffect::~RainEffect() |
---|
68 | { |
---|
69 | this->deactivate(); |
---|
70 | |
---|
71 | if (this->rainBuffer != NULL) |
---|
72 | ResourceManager::getInstance()->unload(this->rainBuffer); |
---|
73 | |
---|
74 | if (this->windBuffer != NULL) |
---|
75 | ResourceManager::getInstance()->unload(this->windBuffer); |
---|
76 | } |
---|
77 | |
---|
78 | void RainEffect::loadParams(const TiXmlElement* root) |
---|
79 | { |
---|
80 | WeatherEffect::loadParams(root); |
---|
81 | |
---|
82 | LoadParam(root, "coord", this, RainEffect, setRainCoord); |
---|
83 | LoadParam(root, "size", this, RainEffect, setRainSize); |
---|
84 | LoadParam(root, "rate", this, RainEffect, setRainRate); |
---|
85 | LoadParam(root, "velocity", this, RainEffect, setRainVelocity); |
---|
86 | LoadParam(root, "life", this, RainEffect, setRainLife); |
---|
87 | LoadParam(root, "wind", this, RainEffect, setRainWind); |
---|
88 | LoadParam(root, "startraining", this, RainEffect, setRainStart); |
---|
89 | |
---|
90 | LOAD_PARAM_START_CYCLE(root, element); |
---|
91 | { |
---|
92 | LoadParam_CYCLE(element, "option", this, RainEffect, setRainOption); |
---|
93 | } |
---|
94 | LOAD_PARAM_END_CYCLE(element); |
---|
95 | |
---|
96 | } |
---|
97 | |
---|
98 | |
---|
99 | bool RainEffect::init() |
---|
100 | { |
---|
101 | //Default values |
---|
102 | this->rainActivate = false; |
---|
103 | this->rainMove = false; |
---|
104 | this->rainCoord = Vector(500, 500, 500); |
---|
105 | this->rainSize = Vector2D(1000, 1000); |
---|
106 | this->rainRate = 3000; |
---|
107 | this->rainVelocity = -300; |
---|
108 | this->rainLife = 4; |
---|
109 | this->rainMaxParticles = this->rainRate * this->rainLife; |
---|
110 | this->rainWindForce = 0; |
---|
111 | this->rainStartDuration = 0; |
---|
112 | this->localTimer = 0; |
---|
113 | this->soundRainVolume = 0.8f; |
---|
114 | |
---|
115 | this->emitter = new PlaneEmitter(this->rainSize); |
---|
116 | |
---|
117 | lightMan = LightManager::getInstance(); |
---|
118 | this->rainAmbient = lightMan->getAmbientColor(); |
---|
119 | } |
---|
120 | |
---|
121 | |
---|
122 | SparkParticles* RainEffect::rainParticles = NULL; |
---|
123 | |
---|
124 | bool RainEffect::activate() |
---|
125 | { |
---|
126 | 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" ); |
---|
127 | |
---|
128 | this->rainActivate = true; |
---|
129 | |
---|
130 | if (unlikely(RainEffect::rainParticles == NULL)) |
---|
131 | { |
---|
132 | RainEffect::rainParticles = new SparkParticles((int) this->rainMaxParticles); |
---|
133 | RainEffect::rainParticles->setName("RainParticles"); |
---|
134 | RainEffect::rainParticles->precache((int)this->rainLife); |
---|
135 | RainEffect::rainParticles->setLifeSpan(this->rainLife, 2); |
---|
136 | RainEffect::rainParticles->setRadius(0, 0.03); |
---|
137 | RainEffect::rainParticles->setRadius(0.2, 0.02); |
---|
138 | RainEffect::rainParticles->setRadius(1, 0.01); |
---|
139 | RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2); // grey blue 1 |
---|
140 | RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2); // grey blue 2 |
---|
141 | RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2); // light grey |
---|
142 | } |
---|
143 | |
---|
144 | this->emitter->setSystem(RainEffect::rainParticles); |
---|
145 | |
---|
146 | this->emitter->setRelCoor(this->rainCoord); |
---|
147 | |
---|
148 | this->emitter->setEmissionRate(this->rainRate); |
---|
149 | this->emitter->setEmissionVelocity(this->rainVelocity); |
---|
150 | |
---|
151 | this->emitter->setSpread(this->rainWindForce / 50, 0.2); |
---|
152 | |
---|
153 | this->soundSource.loop(this->rainBuffer, this->soundRainVolume); |
---|
154 | if (this->rainWindForce != 0) this->soundSource.loop(this->windBuffer, 0.1f * this->rainWindForce); |
---|
155 | |
---|
156 | lightMan->setAmbientColor(.1,.1,.1); |
---|
157 | } |
---|
158 | |
---|
159 | |
---|
160 | bool RainEffect::deactivate() |
---|
161 | { |
---|
162 | PRINTF(0)("Deactivating RainEffect\n"); |
---|
163 | |
---|
164 | this->rainActivate = false; |
---|
165 | this->emitter->setSystem(NULL); |
---|
166 | |
---|
167 | // Stop Sound |
---|
168 | this->soundSource.stop(); |
---|
169 | |
---|
170 | // Restore Light Ambient |
---|
171 | lightMan->setAmbientColor(this->rainAmbient, this->rainAmbient, this->rainAmbient); |
---|
172 | } |
---|
173 | |
---|
174 | void RainEffect::tick (float dt) |
---|
175 | { |
---|
176 | if (!this->rainActivate) |
---|
177 | return; |
---|
178 | |
---|
179 | if (this->rainMove) { |
---|
180 | this->rainCoord = State::getCameraNode()->getAbsCoor(); |
---|
181 | this->emitter->setRelCoor(this->rainCoord.x , this->rainCoord.y+800, this->rainCoord.z); |
---|
182 | } |
---|
183 | |
---|
184 | if (this->rainStartDuration != 0 && this->localTimer < this->rainStartDuration) { |
---|
185 | this->localTimer += dt; |
---|
186 | float progress = this->localTimer / this->rainStartDuration; |
---|
187 | |
---|
188 | // Dim Light |
---|
189 | lightMan->setAmbientColor(1.1 - progress, 1.1 - progress, 1.1 - progress); |
---|
190 | |
---|
191 | // use alpha in color to fade in |
---|
192 | RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1 |
---|
193 | RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2 |
---|
194 | RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2 * progress); // light grey |
---|
195 | |
---|
196 | // increase radius for more "heavy" rain |
---|
197 | RainEffect::rainParticles->setRadius(0, 0.03 * progress); |
---|
198 | RainEffect::rainParticles->setRadius(0.2, 0.02 * progress); |
---|
199 | RainEffect::rainParticles->setRadius(1, 0.01 * progress); |
---|
200 | |
---|
201 | // increase sound volume |
---|
202 | // this->soundSource.fadein(this->rainBuffer, 10); |
---|
203 | } |
---|
204 | |
---|
205 | } |
---|
206 | |
---|
207 | void RainEffect::startRaining() { |
---|
208 | |
---|
209 | if (this->rainActivate) |
---|
210 | this->deactivate(); |
---|
211 | |
---|
212 | this->rainStartDuration = 10; |
---|
213 | this->localTimer = 0; |
---|
214 | this->activate(); |
---|
215 | |
---|
216 | } |
---|