/src/ogre/OgreMain/src/OgreParticleEmitter.cpp
Line | Count | Source |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #include "OgreStableHeaders.h" |
29 | | |
30 | | #include "OgreParticleEmitter.h" |
31 | | #include "OgreParticleEmitterFactory.h" |
32 | | #include "OgreParticleEmitterCommands.h" |
33 | | |
34 | | namespace Ogre |
35 | | { |
36 | | // Command object for setting / getting parameters |
37 | | static EmitterCommands::CmdAngle msAngleCmd; |
38 | | static EmitterCommands::CmdColour msColourCmd; |
39 | | static EmitterCommands::CmdColourRangeStart msColourRangeStartCmd; |
40 | | static EmitterCommands::CmdColourRangeEnd msColourRangeEndCmd; |
41 | | static EmitterCommands::CmdDirection msDirectionCmd; |
42 | | static EmitterCommands::CmdUp msUpCmd; |
43 | | static EmitterCommands::CmdDirPositionRef msDirPositionRefCmd; |
44 | | static EmitterCommands::CmdEmissionRate msEmissionRateCmd; |
45 | | static EmitterCommands::CmdMaxTTL msMaxTTLCmd; |
46 | | static EmitterCommands::CmdMaxVelocity msMaxVelocityCmd; |
47 | | static EmitterCommands::CmdMinTTL msMinTTLCmd; |
48 | | static EmitterCommands::CmdMinVelocity msMinVelocityCmd; |
49 | | static EmitterCommands::CmdPosition msPositionCmd; |
50 | | static EmitterCommands::CmdTTL msTTLCmd; |
51 | | static EmitterCommands::CmdVelocity msVelocityCmd; |
52 | | static EmitterCommands::CmdDuration msDurationCmd; |
53 | | static EmitterCommands::CmdMinDuration msMinDurationCmd; |
54 | | static EmitterCommands::CmdMaxDuration msMaxDurationCmd; |
55 | | static EmitterCommands::CmdRepeatDelay msRepeatDelayCmd; |
56 | | static EmitterCommands::CmdMinRepeatDelay msMinRepeatDelayCmd; |
57 | | static EmitterCommands::CmdMaxRepeatDelay msMaxRepeatDelayCmd; |
58 | | static EmitterCommands::CmdName msNameCmd; |
59 | | static EmitterCommands::CmdEmittedEmitter msEmittedEmitterCmd; |
60 | | |
61 | | |
62 | | //----------------------------------------------------------------------- |
63 | | ParticleEmitter::ParticleEmitter(ParticleSystem* psys) |
64 | 0 | : mParent(psys), |
65 | 0 | mUseDirPositionRef(false), |
66 | 0 | mDirPositionRef(Vector3::ZERO), |
67 | 0 | mStartTime(0), |
68 | 0 | mDurationMin(0), |
69 | 0 | mDurationMax(0), |
70 | 0 | mDurationRemain(0), |
71 | 0 | mRepeatDelayMin(0), |
72 | 0 | mRepeatDelayMax(0), |
73 | 0 | mRepeatDelayRemain(0) |
74 | 0 | { |
75 | | |
76 | | // Reasonable defaults |
77 | 0 | mAngle = 0; |
78 | 0 | setDirection(Vector3::UNIT_X); |
79 | 0 | mEmissionRate = 10; |
80 | 0 | mMaxSpeed = mMinSpeed = 1; |
81 | 0 | mMaxTTL = mMinTTL = 5; |
82 | 0 | mPosition = Vector3::ZERO; |
83 | 0 | mColourRangeStart = mColourRangeEnd = ColourValue::White; |
84 | 0 | mEnabled = true; |
85 | 0 | mRemainder = 0; |
86 | 0 | mName = BLANKSTRING; |
87 | 0 | mEmittedEmitter = BLANKSTRING; |
88 | 0 | mEmitted = false; |
89 | 0 | } |
90 | | //----------------------------------------------------------------------- |
91 | | ParticleEmitter::~ParticleEmitter() |
92 | 0 | { |
93 | 0 | } |
94 | | //----------------------------------------------------------------------- |
95 | | void ParticleEmitter::setPosition(const Vector3& pos) |
96 | 0 | { |
97 | 0 | mPosition = pos; |
98 | 0 | } |
99 | | //----------------------------------------------------------------------- |
100 | | const Vector3& ParticleEmitter::getPosition(void) const |
101 | 0 | { |
102 | 0 | return mPosition; |
103 | 0 | } |
104 | | //----------------------------------------------------------------------- |
105 | | void ParticleEmitter::setDirection(const Vector3& inDirection) |
106 | 0 | { |
107 | 0 | mDirection = inDirection; |
108 | 0 | mDirection.normalise(); |
109 | | // Generate a default up vector. |
110 | 0 | mUp = mDirection.perpendicular(); |
111 | 0 | mUp.normalise(); |
112 | 0 | } |
113 | | //----------------------------------------------------------------------- |
114 | | const Vector3& ParticleEmitter::getDirection(void) const |
115 | 0 | { |
116 | 0 | return mDirection; |
117 | 0 | } |
118 | | //----------------------------------------------------------------------- |
119 | | void ParticleEmitter::setUp(const Vector3& inUp) |
120 | 0 | { |
121 | 0 | mUp = inUp; |
122 | 0 | mUp.normalise(); |
123 | 0 | } |
124 | | //----------------------------------------------------------------------- |
125 | | const Vector3& ParticleEmitter::getUp(void) const |
126 | 0 | { |
127 | 0 | return mUp; |
128 | 0 | } |
129 | | //----------------------------------------------------------------------- |
130 | | void ParticleEmitter::setDirPositionReference( const Vector3& nposition, bool enable ) |
131 | 0 | { |
132 | 0 | mUseDirPositionRef = enable; |
133 | 0 | mDirPositionRef = nposition; |
134 | 0 | } |
135 | | //----------------------------------------------------------------------- |
136 | | const Vector3& ParticleEmitter::getDirPositionReference() const |
137 | 0 | { |
138 | 0 | return mDirPositionRef; |
139 | 0 | } |
140 | | //----------------------------------------------------------------------- |
141 | | bool ParticleEmitter::getDirPositionReferenceEnabled() const |
142 | 0 | { |
143 | 0 | return mUseDirPositionRef; |
144 | 0 | } |
145 | | //----------------------------------------------------------------------- |
146 | | void ParticleEmitter::setAngle(const Radian& angle) |
147 | 0 | { |
148 | | // Store as radians for efficiency |
149 | 0 | mAngle = angle; |
150 | 0 | } |
151 | | //----------------------------------------------------------------------- |
152 | | const Radian& ParticleEmitter::getAngle(void) const |
153 | 0 | { |
154 | 0 | return mAngle; |
155 | 0 | } |
156 | | //----------------------------------------------------------------------- |
157 | | void ParticleEmitter::setParticleVelocity(Real speed) |
158 | 0 | { |
159 | 0 | assert(std::isfinite(speed)); |
160 | 0 | mMinSpeed = mMaxSpeed = speed; |
161 | 0 | } |
162 | | //----------------------------------------------------------------------- |
163 | | void ParticleEmitter::setParticleVelocity(Real min, Real max) |
164 | 0 | { |
165 | 0 | assert(std::isfinite(min) && std::isfinite(max)); |
166 | 0 | mMinSpeed = min; |
167 | 0 | mMaxSpeed = max; |
168 | 0 | } |
169 | | //----------------------------------------------------------------------- |
170 | | void ParticleEmitter::setEmissionRate(Real particlesPerSecond) |
171 | 0 | { |
172 | 0 | mEmissionRate = particlesPerSecond; |
173 | 0 | } |
174 | | //----------------------------------------------------------------------- |
175 | | Real ParticleEmitter::getEmissionRate(void) const |
176 | 0 | { |
177 | 0 | return mEmissionRate; |
178 | 0 | } |
179 | | //----------------------------------------------------------------------- |
180 | | void ParticleEmitter::setTimeToLive(Real ttl) |
181 | 0 | { |
182 | 0 | assert (ttl >= 0 && "Time to live can not be negative"); |
183 | 0 | mMinTTL = mMaxTTL = ttl; |
184 | 0 | } |
185 | | //----------------------------------------------------------------------- |
186 | | void ParticleEmitter::setTimeToLive(Real minTtl, Real maxTtl) |
187 | 0 | { |
188 | 0 | assert (minTtl >= 0 && "Time to live can not be negative"); |
189 | 0 | assert (maxTtl >= 0 && "Time to live can not be negative"); |
190 | 0 | mMinTTL = minTtl; |
191 | 0 | mMaxTTL = maxTtl; |
192 | 0 | } |
193 | | //----------------------------------------------------------------------- |
194 | | void ParticleEmitter::setColour(const ColourValue& inColour) |
195 | 0 | { |
196 | 0 | mColourRangeStart = mColourRangeEnd = inColour; |
197 | 0 | } |
198 | | //----------------------------------------------------------------------- |
199 | | void ParticleEmitter::setColour(const ColourValue& colourStart, const ColourValue& colourEnd) |
200 | 0 | { |
201 | 0 | mColourRangeStart = colourStart; |
202 | 0 | mColourRangeEnd = colourEnd; |
203 | 0 | } |
204 | | //----------------------------------------------------------------------- |
205 | | const String& ParticleEmitter::getName(void) const |
206 | 0 | { |
207 | 0 | return mName; |
208 | 0 | } |
209 | | //----------------------------------------------------------------------- |
210 | | void ParticleEmitter::setName(const String& newName) |
211 | 0 | { |
212 | 0 | mName = newName; |
213 | 0 | } |
214 | | //----------------------------------------------------------------------- |
215 | | const String& ParticleEmitter::getEmittedEmitter(void) const |
216 | 0 | { |
217 | 0 | return mEmittedEmitter; |
218 | 0 | } |
219 | | //----------------------------------------------------------------------- |
220 | | void ParticleEmitter::setEmittedEmitter(const String& emittedEmitter) |
221 | 0 | { |
222 | 0 | mEmittedEmitter = emittedEmitter; |
223 | 0 | } |
224 | | //----------------------------------------------------------------------- |
225 | | bool ParticleEmitter::isEmitted(void) const |
226 | 0 | { |
227 | 0 | return mEmitted; |
228 | 0 | } |
229 | | //----------------------------------------------------------------------- |
230 | | void ParticleEmitter::setEmitted(bool emitted) |
231 | 0 | { |
232 | 0 | mEmitted = emitted; |
233 | 0 | } |
234 | | //----------------------------------------------------------------------- |
235 | | static float sampleSphereUniform(const float& maxAngle) |
236 | 0 | { |
237 | 0 | float cosMax = -std::cos(maxAngle) + 1; // for maxAngle = pi, cosMax = 2 |
238 | | // see https://corysimon.github.io/articles/uniformdistn-on-sphere/ |
239 | 0 | return std::acos(1 - cosMax * Math::UnitRandom()); |
240 | 0 | } |
241 | | |
242 | | void ParticleEmitter::genEmissionDirection( const Vector3 &particlePos, Vector3& destVector ) |
243 | 0 | { |
244 | 0 | if( mUseDirPositionRef ) |
245 | 0 | { |
246 | 0 | Vector3 particleDir = particlePos - mDirPositionRef; |
247 | 0 | particleDir.normalise(); |
248 | |
|
249 | 0 | if (mAngle != Radian(0)) |
250 | 0 | { |
251 | | // Randomise angle |
252 | 0 | Radian angle(sampleSphereUniform(mAngle.valueRadians())); |
253 | | |
254 | | // Randomise direction |
255 | 0 | destVector = particleDir.randomDeviant( angle ); |
256 | 0 | } |
257 | 0 | else |
258 | 0 | { |
259 | | // Constant angle |
260 | 0 | destVector = particleDir; |
261 | 0 | } |
262 | 0 | } |
263 | 0 | else |
264 | 0 | { |
265 | 0 | if (mAngle != Radian(0)) |
266 | 0 | { |
267 | | // Randomise angle |
268 | 0 | Radian angle(sampleSphereUniform(mAngle.valueRadians())); |
269 | | |
270 | | // Randomise direction |
271 | 0 | destVector = mDirection.randomDeviant(angle, mUp); |
272 | 0 | } |
273 | 0 | else |
274 | 0 | { |
275 | | // Constant angle |
276 | 0 | destVector = mDirection; |
277 | 0 | } |
278 | 0 | } |
279 | | |
280 | | // Don't normalise, we can assume that it will still be a unit vector since |
281 | | // both direction and 'up' are. |
282 | 0 | } |
283 | | //----------------------------------------------------------------------- |
284 | | void ParticleEmitter::genEmissionVelocity(Vector3& destVector) |
285 | 0 | { |
286 | 0 | Real scalar; |
287 | 0 | if (mMinSpeed != mMaxSpeed) |
288 | 0 | { |
289 | 0 | scalar = Math::RangeRandom(mMinSpeed, mMaxSpeed); |
290 | 0 | } |
291 | 0 | else |
292 | 0 | { |
293 | 0 | scalar = mMinSpeed; |
294 | 0 | } |
295 | |
|
296 | 0 | destVector *= scalar; |
297 | 0 | } |
298 | | //----------------------------------------------------------------------- |
299 | | Real ParticleEmitter::genEmissionTTL(void) |
300 | 0 | { |
301 | 0 | if (mMaxTTL != mMinTTL) |
302 | 0 | { |
303 | 0 | return Math::RangeRandom(mMinTTL, mMaxTTL); |
304 | 0 | } |
305 | 0 | else |
306 | 0 | { |
307 | 0 | return mMinTTL; |
308 | 0 | } |
309 | 0 | } |
310 | | //----------------------------------------------------------------------- |
311 | | unsigned short ParticleEmitter::genConstantEmissionCount(Real timeElapsed) |
312 | 0 | { |
313 | 0 | if (mEnabled) |
314 | 0 | { |
315 | 0 | if(mDurationMax < 0) |
316 | 0 | { |
317 | | // single-shot burst |
318 | 0 | setEnabled(false); |
319 | 0 | return mEmissionRate; |
320 | 0 | } |
321 | | |
322 | 0 | unsigned short intRequest = (unsigned short)mRemainder; |
323 | 0 | mRemainder -= intRequest; |
324 | | |
325 | | // Keep fractions, otherwise a high frame rate will result in zero emissions! |
326 | 0 | mRemainder += mEmissionRate * timeElapsed; |
327 | | |
328 | | // Check duration |
329 | 0 | if (mDurationMax) |
330 | 0 | { |
331 | 0 | mDurationRemain -= timeElapsed; |
332 | 0 | if (mDurationRemain <= 0) |
333 | 0 | { |
334 | | // Disable, duration is out (takes effect next time) |
335 | 0 | setEnabled(false); |
336 | 0 | } |
337 | 0 | } |
338 | 0 | return intRequest; |
339 | 0 | } |
340 | 0 | else |
341 | 0 | { |
342 | | // Check repeat |
343 | 0 | if (mRepeatDelayMax) |
344 | 0 | { |
345 | 0 | mRepeatDelayRemain -= timeElapsed; |
346 | 0 | if (mRepeatDelayRemain <= 0) |
347 | 0 | { |
348 | | // Enable, repeat delay is out (takes effect next time) |
349 | 0 | setEnabled(true); |
350 | 0 | } |
351 | 0 | } |
352 | 0 | if(mStartTime) |
353 | 0 | { |
354 | 0 | mStartTime -= timeElapsed; |
355 | 0 | if(mStartTime <= 0) |
356 | 0 | { |
357 | 0 | setEnabled(true); |
358 | 0 | mStartTime = 0; |
359 | 0 | } |
360 | 0 | } |
361 | 0 | return 0; |
362 | 0 | } |
363 | |
|
364 | 0 | } |
365 | | //----------------------------------------------------------------------- |
366 | | void ParticleEmitter::genEmissionColour(RGBA& destColour) |
367 | 0 | { |
368 | 0 | if (mColourRangeStart != mColourRangeEnd) |
369 | 0 | { |
370 | | // Randomise |
371 | 0 | ColourValue t(Math::UnitRandom(), Math::UnitRandom(), Math::UnitRandom(), Math::UnitRandom()); |
372 | 0 | destColour = Math::lerp(mColourRangeStart, mColourRangeEnd, t).getAsBYTE(); |
373 | 0 | } |
374 | 0 | else |
375 | 0 | { |
376 | 0 | destColour = mColourRangeStart.getAsBYTE(); |
377 | 0 | } |
378 | 0 | } |
379 | | //----------------------------------------------------------------------- |
380 | | void ParticleEmitter::addBaseParameters(void) |
381 | 0 | { |
382 | 0 | ParamDictionary* dict = getParamDictionary(); |
383 | |
|
384 | 0 | dict->addParameter(ParameterDef("angle", |
385 | 0 | "The angle up to which particles may vary in their initial direction " |
386 | 0 | "from the emitters direction, in degrees." , PT_REAL), |
387 | 0 | &msAngleCmd); |
388 | |
|
389 | 0 | dict->addParameter(ParameterDef("colour", |
390 | 0 | "The colour of emitted particles.", PT_COLOURVALUE), |
391 | 0 | &msColourCmd); |
392 | |
|
393 | 0 | dict->addParameter(ParameterDef("colour_range_start", |
394 | 0 | "The start of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE), |
395 | 0 | &msColourRangeStartCmd); |
396 | |
|
397 | 0 | dict->addParameter(ParameterDef("colour_range_end", |
398 | 0 | "The end of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE), |
399 | 0 | &msColourRangeEndCmd); |
400 | |
|
401 | 0 | dict->addParameter(ParameterDef("direction", |
402 | 0 | "The base direction of the emitter." , PT_VECTOR3), |
403 | 0 | &msDirectionCmd); |
404 | |
|
405 | 0 | dict->addParameter(ParameterDef("up", |
406 | 0 | "The up vector of the emitter." , PT_VECTOR3), |
407 | 0 | &msUpCmd); |
408 | |
|
409 | 0 | dict->addParameter(ParameterDef("direction_position_reference", |
410 | 0 | "The reference position to calculate the direction of emitted particles " |
411 | 0 | "based on their position. Good for explosions and implosions (use negative velocity)" , PT_COLOURVALUE), |
412 | 0 | &msDirPositionRefCmd); |
413 | |
|
414 | 0 | dict->addParameter(ParameterDef("emission_rate", |
415 | 0 | "The number of particles emitted per second." , PT_REAL), |
416 | 0 | &msEmissionRateCmd); |
417 | |
|
418 | 0 | dict->addParameter(ParameterDef("position", |
419 | 0 | "The position of the emitter relative to the particle system center." , PT_VECTOR3), |
420 | 0 | &msPositionCmd); |
421 | |
|
422 | 0 | dict->addParameter(ParameterDef("velocity", |
423 | 0 | "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL), |
424 | 0 | &msVelocityCmd); |
425 | |
|
426 | 0 | dict->addParameter(ParameterDef("velocity_min", |
427 | 0 | "The minimum initial velocity to be assigned to each particle." , PT_REAL), |
428 | 0 | &msMinVelocityCmd); |
429 | |
|
430 | 0 | dict->addParameter(ParameterDef("velocity_max", |
431 | 0 | "The maximum initial velocity to be assigned to each particle." , PT_REAL), |
432 | 0 | &msMaxVelocityCmd); |
433 | |
|
434 | 0 | dict->addParameter(ParameterDef("time_to_live", |
435 | 0 | "The lifetime of each particle in seconds." , PT_REAL), |
436 | 0 | &msTTLCmd); |
437 | |
|
438 | 0 | dict->addParameter(ParameterDef("time_to_live_min", |
439 | 0 | "The minimum lifetime of each particle in seconds." , PT_REAL), |
440 | 0 | &msMinTTLCmd); |
441 | |
|
442 | 0 | dict->addParameter(ParameterDef("time_to_live_max", |
443 | 0 | "The maximum lifetime of each particle in seconds." , PT_REAL), |
444 | 0 | &msMaxTTLCmd); |
445 | |
|
446 | 0 | dict->addParameter(ParameterDef("duration", |
447 | 0 | "The length of time in seconds which an emitter stays enabled for." , PT_REAL), |
448 | 0 | &msDurationCmd); |
449 | |
|
450 | 0 | dict->addParameter(ParameterDef("duration_min", |
451 | 0 | "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL), |
452 | 0 | &msMinDurationCmd); |
453 | |
|
454 | 0 | dict->addParameter(ParameterDef("duration_max", |
455 | 0 | "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL), |
456 | 0 | &msMaxDurationCmd); |
457 | |
|
458 | 0 | dict->addParameter(ParameterDef("repeat_delay", |
459 | 0 | "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL), |
460 | 0 | &msRepeatDelayCmd); |
461 | |
|
462 | 0 | dict->addParameter(ParameterDef("repeat_delay_min", |
463 | 0 | "If set, after disabling an emitter will repeat (reenable) after this minimum number of seconds." , PT_REAL), |
464 | 0 | &msMinRepeatDelayCmd); |
465 | |
|
466 | 0 | dict->addParameter(ParameterDef("repeat_delay_max", |
467 | 0 | "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL), |
468 | 0 | &msMaxRepeatDelayCmd); |
469 | |
|
470 | 0 | dict->addParameter(ParameterDef("name", |
471 | 0 | "This is the name of the emitter" , PT_STRING), |
472 | 0 | &msNameCmd); |
473 | | |
474 | 0 | dict->addParameter(ParameterDef("emit_emitter", |
475 | 0 | "If set, this emitter will emit other emitters instead of visual particles" , PT_STRING), |
476 | 0 | &msEmittedEmitterCmd); |
477 | 0 | } |
478 | | //----------------------------------------------------------------------- |
479 | | Real ParticleEmitter::getParticleVelocity(void) const |
480 | 0 | { |
481 | 0 | return mMinSpeed; |
482 | 0 | } |
483 | | //----------------------------------------------------------------------- |
484 | | Real ParticleEmitter::getMinParticleVelocity(void) const |
485 | 0 | { |
486 | 0 | return mMinSpeed; |
487 | 0 | } |
488 | | //----------------------------------------------------------------------- |
489 | | Real ParticleEmitter::getMaxParticleVelocity(void) const |
490 | 0 | { |
491 | 0 | return mMaxSpeed; |
492 | 0 | } |
493 | | //----------------------------------------------------------------------- |
494 | | void ParticleEmitter::setMinParticleVelocity(Real min) |
495 | 0 | { |
496 | 0 | assert(std::isfinite(min)); |
497 | 0 | mMinSpeed = min; |
498 | 0 | } |
499 | | //----------------------------------------------------------------------- |
500 | | void ParticleEmitter::setMaxParticleVelocity(Real max) |
501 | 0 | { |
502 | 0 | assert(std::isfinite(max)); |
503 | 0 | mMaxSpeed = max; |
504 | 0 | } |
505 | | //----------------------------------------------------------------------- |
506 | | Real ParticleEmitter::getTimeToLive(void) const |
507 | 0 | { |
508 | 0 | return mMinTTL; |
509 | 0 | } |
510 | | //----------------------------------------------------------------------- |
511 | | Real ParticleEmitter::getMinTimeToLive(void) const |
512 | 0 | { |
513 | 0 | return mMinTTL; |
514 | 0 | } |
515 | | //----------------------------------------------------------------------- |
516 | | Real ParticleEmitter::getMaxTimeToLive(void) const |
517 | 0 | { |
518 | 0 | return mMaxTTL; |
519 | 0 | } |
520 | | //----------------------------------------------------------------------- |
521 | | void ParticleEmitter::setMinTimeToLive(Real min) |
522 | 0 | { |
523 | 0 | mMinTTL = min; |
524 | 0 | } |
525 | | //----------------------------------------------------------------------- |
526 | | void ParticleEmitter::setMaxTimeToLive(Real max) |
527 | 0 | { |
528 | 0 | mMaxTTL = max; |
529 | 0 | } |
530 | | //----------------------------------------------------------------------- |
531 | | const ColourValue& ParticleEmitter::getColour(void) const |
532 | 0 | { |
533 | 0 | return mColourRangeStart; |
534 | 0 | } |
535 | | //----------------------------------------------------------------------- |
536 | | const ColourValue& ParticleEmitter::getColourRangeStart(void) const |
537 | 0 | { |
538 | 0 | return mColourRangeStart; |
539 | 0 | } |
540 | | //----------------------------------------------------------------------- |
541 | | const ColourValue& ParticleEmitter::getColourRangeEnd(void) const |
542 | 0 | { |
543 | 0 | return mColourRangeEnd; |
544 | 0 | } |
545 | | //----------------------------------------------------------------------- |
546 | | void ParticleEmitter::setColourRangeStart(const ColourValue& val) |
547 | 0 | { |
548 | 0 | mColourRangeStart = val; |
549 | 0 | } |
550 | | //----------------------------------------------------------------------- |
551 | | void ParticleEmitter::setColourRangeEnd(const ColourValue& val ) |
552 | 0 | { |
553 | 0 | mColourRangeEnd = val; |
554 | 0 | } |
555 | | //----------------------------------------------------------------------- |
556 | | void ParticleEmitter::setEnabled(bool enabled) |
557 | 0 | { |
558 | 0 | mEnabled = enabled; |
559 | 0 | mRemainder = 1.0f; // make sure we emit a particle on next update. Turns emission rate to (t0;r] interval |
560 | | // Reset duration & repeat |
561 | 0 | initDurationRepeat(); |
562 | 0 | } |
563 | | //----------------------------------------------------------------------- |
564 | | bool ParticleEmitter::getEnabled(void) const |
565 | 0 | { |
566 | 0 | return mEnabled; |
567 | 0 | } |
568 | | //----------------------------------------------------------------------- |
569 | | void ParticleEmitter::setStartTime(Real startTime) |
570 | 0 | { |
571 | 0 | setEnabled(false); |
572 | 0 | mStartTime = startTime; |
573 | 0 | } |
574 | | //----------------------------------------------------------------------- |
575 | | Real ParticleEmitter::getStartTime(void) const |
576 | 0 | { |
577 | 0 | return mStartTime; |
578 | 0 | } |
579 | | //----------------------------------------------------------------------- |
580 | | void ParticleEmitter::setDuration(Real duration) |
581 | 0 | { |
582 | 0 | setDuration(duration, duration); |
583 | 0 | } |
584 | | //----------------------------------------------------------------------- |
585 | | Real ParticleEmitter::getDuration(void) const |
586 | 0 | { |
587 | 0 | return mDurationMin; |
588 | 0 | } |
589 | | //----------------------------------------------------------------------- |
590 | | void ParticleEmitter::setDuration(Real min, Real max) |
591 | 0 | { |
592 | 0 | mDurationMin = min; |
593 | 0 | mDurationMax = max; |
594 | 0 | initDurationRepeat(); |
595 | 0 | } |
596 | | //----------------------------------------------------------------------- |
597 | | void ParticleEmitter::setMinDuration(Real min) |
598 | 0 | { |
599 | 0 | mDurationMin = min; |
600 | 0 | initDurationRepeat(); |
601 | 0 | } |
602 | | //----------------------------------------------------------------------- |
603 | | void ParticleEmitter::setMaxDuration(Real max) |
604 | 0 | { |
605 | 0 | mDurationMax = max; |
606 | 0 | initDurationRepeat(); |
607 | 0 | } |
608 | | //----------------------------------------------------------------------- |
609 | | void ParticleEmitter::initDurationRepeat(void) |
610 | 0 | { |
611 | 0 | if (mEnabled) |
612 | 0 | { |
613 | 0 | if (mDurationMin == mDurationMax) |
614 | 0 | { |
615 | 0 | mDurationRemain = mDurationMin; |
616 | 0 | } |
617 | 0 | else |
618 | 0 | { |
619 | 0 | mDurationRemain = Math::RangeRandom(mDurationMin, mDurationMax); |
620 | 0 | } |
621 | 0 | } |
622 | 0 | else |
623 | 0 | { |
624 | | // Reset repeat |
625 | 0 | if (mRepeatDelayMin == mRepeatDelayMax) |
626 | 0 | { |
627 | 0 | mRepeatDelayRemain = mRepeatDelayMin; |
628 | 0 | } |
629 | 0 | else |
630 | 0 | { |
631 | 0 | mRepeatDelayRemain = Math::RangeRandom(mRepeatDelayMax, mRepeatDelayMin); |
632 | 0 | } |
633 | |
|
634 | 0 | } |
635 | 0 | } |
636 | | //----------------------------------------------------------------------- |
637 | | void ParticleEmitter::setRepeatDelay(Real delay) |
638 | 0 | { |
639 | 0 | setRepeatDelay(delay, delay); |
640 | 0 | } |
641 | | //----------------------------------------------------------------------- |
642 | | Real ParticleEmitter::getRepeatDelay(void) const |
643 | 0 | { |
644 | 0 | return mRepeatDelayMin; |
645 | 0 | } |
646 | | //----------------------------------------------------------------------- |
647 | | void ParticleEmitter::setRepeatDelay(Real min, Real max) |
648 | 0 | { |
649 | 0 | mRepeatDelayMin = min; |
650 | 0 | mRepeatDelayMax = max; |
651 | 0 | initDurationRepeat(); |
652 | 0 | } |
653 | | //----------------------------------------------------------------------- |
654 | | void ParticleEmitter::setMinRepeatDelay(Real min) |
655 | 0 | { |
656 | 0 | mRepeatDelayMin = min; |
657 | 0 | initDurationRepeat(); |
658 | 0 | } |
659 | | //----------------------------------------------------------------------- |
660 | | void ParticleEmitter::setMaxRepeatDelay(Real max) |
661 | 0 | { |
662 | 0 | mRepeatDelayMax = max; |
663 | 0 | initDurationRepeat(); |
664 | 0 | } |
665 | | //----------------------------------------------------------------------- |
666 | | Real ParticleEmitter::getMinDuration(void) const |
667 | 0 | { |
668 | 0 | return mDurationMin; |
669 | 0 | } |
670 | | //----------------------------------------------------------------------- |
671 | | Real ParticleEmitter::getMaxDuration(void) const |
672 | 0 | { |
673 | 0 | return mDurationMax; |
674 | 0 | } |
675 | | //----------------------------------------------------------------------- |
676 | | Real ParticleEmitter::getMinRepeatDelay(void) const |
677 | 0 | { |
678 | 0 | return mRepeatDelayMin; |
679 | 0 | } |
680 | | //----------------------------------------------------------------------- |
681 | | Real ParticleEmitter::getMaxRepeatDelay(void) const |
682 | 0 | { |
683 | 0 | return mRepeatDelayMax; |
684 | 0 | } |
685 | | |
686 | | //----------------------------------------------------------------------- |
687 | | ParticleEmitterFactory::~ParticleEmitterFactory() |
688 | 0 | { |
689 | 0 | OGRE_IGNORE_DEPRECATED_BEGIN |
690 | | // Destroy all emitters |
691 | 0 | for (auto& e : mEmitters) |
692 | 0 | { |
693 | 0 | OGRE_DELETE e; |
694 | 0 | } |
695 | | |
696 | 0 | mEmitters.clear(); |
697 | 0 | OGRE_IGNORE_DEPRECATED_END |
698 | 0 | } |
699 | | //----------------------------------------------------------------------- |
700 | | void ParticleEmitterFactory::destroyEmitter(ParticleEmitter* e) |
701 | 0 | { |
702 | 0 | delete e; |
703 | 0 | OGRE_IGNORE_DEPRECATED_BEGIN |
704 | 0 | auto i = std::find(std::begin(mEmitters), std::end(mEmitters), e); |
705 | 0 | if (i != std::end(mEmitters)) { |
706 | 0 | mEmitters.erase(i); |
707 | 0 | } |
708 | 0 | OGRE_IGNORE_DEPRECATED_END |
709 | 0 | } |
710 | | |
711 | | //----------------------------------------------------------------------- |
712 | | } |
713 | | |