source: OGRE/trunk/ogrenew/OgreMain/src/OgreParticleEmitter.cpp @ 657

Revision 657, 21.5 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4        (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26
27#include "OgreParticleEmitter.h"
28#include "OgreParticleEmitterFactory.h"
29
30namespace Ogre {
31
32    // Define static members
33    EmitterCommands::CmdAngle ParticleEmitter::msAngleCmd;
34    EmitterCommands::CmdColour ParticleEmitter::msColourCmd;
35    EmitterCommands::CmdColourRangeStart ParticleEmitter::msColourRangeStartCmd;
36    EmitterCommands::CmdColourRangeEnd ParticleEmitter::msColourRangeEndCmd;
37    EmitterCommands::CmdDirection ParticleEmitter::msDirectionCmd;
38    EmitterCommands::CmdEmissionRate ParticleEmitter::msEmissionRateCmd;
39    EmitterCommands::CmdMaxTTL ParticleEmitter::msMaxTTLCmd;
40    EmitterCommands::CmdMaxVelocity ParticleEmitter::msMaxVelocityCmd;
41    EmitterCommands::CmdMinTTL ParticleEmitter::msMinTTLCmd;
42    EmitterCommands::CmdMinVelocity ParticleEmitter::msMinVelocityCmd;
43    EmitterCommands::CmdPosition ParticleEmitter::msPositionCmd;
44    EmitterCommands::CmdTTL ParticleEmitter::msTTLCmd;
45    EmitterCommands::CmdVelocity ParticleEmitter::msVelocityCmd;
46    EmitterCommands::CmdDuration ParticleEmitter::msDurationCmd;
47    EmitterCommands::CmdMinDuration ParticleEmitter::msMinDurationCmd;
48    EmitterCommands::CmdMaxDuration ParticleEmitter::msMaxDurationCmd;
49    EmitterCommands::CmdRepeatDelay ParticleEmitter::msRepeatDelayCmd;
50    EmitterCommands::CmdMinRepeatDelay ParticleEmitter::msMinRepeatDelayCmd;
51    EmitterCommands::CmdMaxRepeatDelay ParticleEmitter::msMaxRepeatDelayCmd;
52
53
54    //-----------------------------------------------------------------------
55    ParticleEmitter::ParticleEmitter(ParticleSystem* psys)
56      : mParent(psys),
57        mStartTime(0),
58        mDurationMin(0),
59        mDurationMax(0),
60        mDurationRemain(0),
61        mRepeatDelayMin(0),
62        mRepeatDelayMax(0),
63        mRepeatDelayRemain(0)
64    {
65
66        // Reasonable defaults
67        mAngle = 0;
68        setDirection(Vector3::UNIT_X);
69        mEmissionRate = 10;
70        mMaxSpeed = mMinSpeed = 1;
71        mMaxTTL = mMinTTL = 5;
72        mPosition = Vector3::ZERO;
73        mColourRangeStart = mColourRangeEnd = ColourValue::White;
74        mEnabled = true;
75        mRemainder = 0;
76
77    }
78    //-----------------------------------------------------------------------
79    ParticleEmitter::~ParticleEmitter()
80    {
81    }
82    //-----------------------------------------------------------------------
83    void ParticleEmitter::setPosition(const Vector3& pos)
84    {
85        mPosition = pos;
86    }
87    //-----------------------------------------------------------------------
88    const Vector3& ParticleEmitter::getPosition(void) const
89    {
90        return mPosition;
91    }
92    //-----------------------------------------------------------------------
93    void ParticleEmitter::setDirection(const Vector3& direction)
94    {
95        mDirection = direction;
96        mDirection.normalise();
97        // Generate an up vector (any will do)
98        mUp = mDirection.perpendicular();
99        mUp.normalise();
100    }
101    //-----------------------------------------------------------------------
102    const Vector3& ParticleEmitter::getDirection(void) const
103    {
104        return mDirection;
105    }
106    //-----------------------------------------------------------------------
107    void ParticleEmitter::setAngle(const Radian& angle)
108    {
109        // Store as radians for efficiency
110        mAngle = angle;
111    }
112    //-----------------------------------------------------------------------
113    const Radian& ParticleEmitter::getAngle(void) const
114    {
115        return mAngle;
116    }
117    //-----------------------------------------------------------------------
118    void ParticleEmitter::setParticleVelocity(Real speed)
119    {
120        mMinSpeed = mMaxSpeed = speed;
121    }
122    //-----------------------------------------------------------------------
123    void ParticleEmitter::setParticleVelocity(Real min, Real max)
124    {
125        mMinSpeed = min;
126        mMaxSpeed = max;
127    }
128    //-----------------------------------------------------------------------
129    void ParticleEmitter::setEmissionRate(Real particlesPerSecond)
130    {
131        mEmissionRate = particlesPerSecond;
132    }
133    //-----------------------------------------------------------------------
134    Real ParticleEmitter::getEmissionRate(void) const
135    {
136        return mEmissionRate;
137    }
138    //-----------------------------------------------------------------------
139    void ParticleEmitter::setTimeToLive(Real ttl)
140    {
141        mMinTTL = mMaxTTL = ttl;
142    }
143    //-----------------------------------------------------------------------
144    void ParticleEmitter::setTimeToLive(Real minTtl, Real maxTtl)
145    {
146        mMinTTL = minTtl;
147        mMaxTTL = maxTtl;
148    }
149    //-----------------------------------------------------------------------
150    void ParticleEmitter::setColour(const ColourValue& colour)
151    {
152        mColourRangeStart = mColourRangeEnd = colour;
153    }
154    //-----------------------------------------------------------------------
155    void ParticleEmitter::setColour(const ColourValue& colourStart, const ColourValue& colourEnd)
156    {
157        mColourRangeStart = colourStart;
158        mColourRangeEnd = colourEnd;
159    }
160    //-----------------------------------------------------------------------
161    void ParticleEmitter::genEmissionDirection(Vector3& destVector)
162    {
163        if (mAngle != Radian(0))
164        {
165            // Randomise angle
166            Radian angle = Math::UnitRandom() * mAngle;
167
168            // Randomise direction
169            destVector = mDirection.randomDeviant(angle, mUp);
170        }
171        else
172        {
173            // Constant angle
174            destVector = mDirection;
175        }
176
177        // Don't normalise, we can assume that it will still be a unit vector since
178        // both direction and 'up' are.
179
180    }
181    //-----------------------------------------------------------------------
182    void ParticleEmitter::genEmissionVelocity(Vector3& destVector)
183    {
184        Real scalar;
185        if (mMinSpeed != mMaxSpeed)
186        {
187            scalar = mMinSpeed + (Math::UnitRandom() * (mMaxSpeed - mMinSpeed));
188        }
189        else
190        {
191            scalar = mMinSpeed;
192        }
193
194        destVector *= scalar;
195    }
196    //-----------------------------------------------------------------------
197    Real ParticleEmitter::genEmissionTTL(void)
198    {
199        if (mMaxTTL != mMinTTL)
200        {
201            return mMinTTL + (Math::UnitRandom() * (mMaxTTL - mMinTTL));
202        }
203        else
204        {
205            return mMinTTL;
206        }
207    }
208    //-----------------------------------------------------------------------
209    unsigned short ParticleEmitter::genConstantEmissionCount(Real timeElapsed)
210    {
211        unsigned short intRequest;
212       
213        if (mEnabled)
214        {
215            // Keep fractions, otherwise a high frame rate will result in zero emissions!
216            mRemainder += mEmissionRate * timeElapsed;
217            intRequest = (unsigned short)mRemainder;
218            mRemainder -= intRequest;
219
220            // Check duration
221            if (mDurationMax)
222            {
223                mDurationRemain -= timeElapsed;
224                if (mDurationRemain <= 0)
225                {
226                    // Disable, duration is out (takes effect next time)
227                    setEnabled(false);
228                }
229            }
230            return intRequest;
231        }
232        else
233        {
234            // Check repeat
235            if (mRepeatDelayMax)
236            {
237                mRepeatDelayRemain -= timeElapsed;
238                if (mRepeatDelayRemain <= 0)
239                {
240                    // Enable, repeat delay is out (takes effect next time)
241                    setEnabled(true);
242                }
243            }
244            if(mStartTime)
245            {
246                mStartTime -= timeElapsed;
247                if(mStartTime <= 0)
248                {
249                    setEnabled(true);
250                    mStartTime = 0;
251                }
252            }
253            return 0;
254        }
255
256    }
257    //-----------------------------------------------------------------------
258    void ParticleEmitter::genEmissionColour(ColourValue& destColour)
259    {
260        if (mColourRangeStart != mColourRangeEnd)
261        {
262            // Randomise
263            //Real t = Math::UnitRandom();
264            destColour.r = mColourRangeStart.r + (Math::UnitRandom() * (mColourRangeEnd.r - mColourRangeStart.r));
265            destColour.g = mColourRangeStart.g + (Math::UnitRandom() * (mColourRangeEnd.g - mColourRangeStart.g));
266            destColour.b = mColourRangeStart.b + (Math::UnitRandom() * (mColourRangeEnd.b - mColourRangeStart.b));
267            destColour.a = mColourRangeStart.a + (Math::UnitRandom() * (mColourRangeEnd.a - mColourRangeStart.a));
268        }
269        else
270        {
271            destColour = mColourRangeStart;
272        }
273    }
274    //-----------------------------------------------------------------------
275    void ParticleEmitter::addBaseParameters(void)   
276    {
277        ParamDictionary* dict = getParamDictionary();
278
279        dict->addParameter(ParameterDef("angle",
280            "The angle up to which particles may vary in their initial direction "
281            "from the emitters direction, in degrees." , PT_REAL),
282            &msAngleCmd);
283
284        dict->addParameter(ParameterDef("colour",
285            "The colour of emitted particles.", PT_COLOURVALUE),
286            &msColourCmd);
287
288        dict->addParameter(ParameterDef("colour_range_start",
289            "The start of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
290            &msColourRangeStartCmd);
291
292        dict->addParameter(ParameterDef("colour_range_end",
293            "The end of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
294            &msColourRangeEndCmd);
295
296        dict->addParameter(ParameterDef("direction",
297            "The base direction of the emitter." , PT_VECTOR3),
298            &msDirectionCmd);
299
300        dict->addParameter(ParameterDef("emission_rate",
301            "The number of particles emitted per second." , PT_REAL),
302            &msEmissionRateCmd);
303
304        dict->addParameter(ParameterDef("position",
305            "The position of the emitter relative to the particle system center." , PT_VECTOR3),
306            &msPositionCmd);
307
308        dict->addParameter(ParameterDef("velocity",
309            "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL),
310            &msVelocityCmd);
311
312        dict->addParameter(ParameterDef("velocity_min",
313            "The minimum initial velocity to be assigned to each particle." , PT_REAL),
314            &msMinVelocityCmd);
315
316        dict->addParameter(ParameterDef("velocity_max",
317            "The maximum initial velocity to be assigned to each particle." , PT_REAL),
318            &msMaxVelocityCmd);
319
320        dict->addParameter(ParameterDef("time_to_live",
321            "The lifetime of each particle in seconds." , PT_REAL),
322            &msTTLCmd);
323
324        dict->addParameter(ParameterDef("time_to_live_min",
325            "The minimum lifetime of each particle in seconds." , PT_REAL),
326            &msMinTTLCmd);
327
328        dict->addParameter(ParameterDef("time_to_live_max",
329            "The maximum lifetime of each particle in seconds." , PT_REAL),
330            &msMaxTTLCmd);
331
332        dict->addParameter(ParameterDef("duration",
333            "The length of time in seconds which an emitter stays enabled for." , PT_REAL),
334            &msDurationCmd);
335
336        dict->addParameter(ParameterDef("duration_min",
337            "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL),
338            &msMinDurationCmd);
339
340        dict->addParameter(ParameterDef("duration_max",
341            "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL),
342            &msMaxDurationCmd);
343
344        dict->addParameter(ParameterDef("repeat_delay",
345            "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL),
346            &msRepeatDelayCmd);
347
348        dict->addParameter(ParameterDef("repeat_delay_min",
349            "If set, after disabling an emitter will repeat (reenable) after this minimum number of seconds." , PT_REAL),
350            &msMinRepeatDelayCmd);
351
352        dict->addParameter(ParameterDef("repeat_delay_max",
353            "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL),
354            &msMaxRepeatDelayCmd);
355    }
356    //-----------------------------------------------------------------------
357    Real ParticleEmitter::getParticleVelocity(void) const
358    {
359        return mMinSpeed;
360    }
361    //-----------------------------------------------------------------------
362    Real ParticleEmitter::getMinParticleVelocity(void) const
363    {
364        return mMinSpeed;
365    }
366    //-----------------------------------------------------------------------
367    Real ParticleEmitter::getMaxParticleVelocity(void) const
368    {
369        return mMaxSpeed;
370    }
371    //-----------------------------------------------------------------------
372    void ParticleEmitter::setMinParticleVelocity(Real min)
373    {
374        mMinSpeed = min;
375    }
376    //-----------------------------------------------------------------------
377    void ParticleEmitter::setMaxParticleVelocity(Real max)
378    {
379        mMaxSpeed = max;
380    }
381    //-----------------------------------------------------------------------
382    Real ParticleEmitter::getTimeToLive(void) const
383    {
384        return mMinTTL;
385    }
386    //-----------------------------------------------------------------------
387    Real ParticleEmitter::getMinTimeToLive(void) const
388    {
389        return mMinTTL;
390    }
391    //-----------------------------------------------------------------------
392    Real ParticleEmitter::getMaxTimeToLive(void) const
393    {
394        return mMaxTTL;
395    }
396    //-----------------------------------------------------------------------
397    void ParticleEmitter::setMinTimeToLive(Real min)
398    {
399        mMinTTL = min;
400    }
401    //-----------------------------------------------------------------------
402    void ParticleEmitter::setMaxTimeToLive(Real max)
403    {
404        mMaxTTL = max;
405    }
406    //-----------------------------------------------------------------------
407    const ColourValue& ParticleEmitter::getColour(void) const
408    {
409        return mColourRangeStart;
410    }
411    //-----------------------------------------------------------------------
412    const ColourValue& ParticleEmitter::getColourRangeStart(void) const
413    {
414        return mColourRangeStart;
415    }
416    //-----------------------------------------------------------------------
417    const ColourValue& ParticleEmitter::getColourRangeEnd(void) const
418    {
419        return mColourRangeEnd;
420    }
421    //-----------------------------------------------------------------------
422    void ParticleEmitter::setColourRangeStart(const ColourValue& val)
423    {
424        mColourRangeStart = val;
425    }
426    //-----------------------------------------------------------------------
427    void ParticleEmitter::setColourRangeEnd(const ColourValue& val )
428    {
429        mColourRangeEnd = val;
430    }
431    //-----------------------------------------------------------------------
432    void ParticleEmitter::setEnabled(bool enabled)
433    {
434        mEnabled = enabled;
435        // Reset duration & repeat
436        initDurationRepeat();
437    }
438    //-----------------------------------------------------------------------
439    bool ParticleEmitter::getEnabled(void) const
440    {
441        return mEnabled;
442    }
443    //-----------------------------------------------------------------------
444    void ParticleEmitter::setStartTime(Real startTime)
445    {
446        setEnabled(false);
447        mStartTime = startTime;
448    }
449    //-----------------------------------------------------------------------
450    Real ParticleEmitter::getStartTime(void) const
451    {
452        return mStartTime;
453    }
454    //-----------------------------------------------------------------------
455    void ParticleEmitter::setDuration(Real duration)
456    {
457        setDuration(duration, duration);
458    }
459    //-----------------------------------------------------------------------
460    Real ParticleEmitter::getDuration(void) const
461    {
462        return mDurationMin;
463    }
464    //-----------------------------------------------------------------------
465    void ParticleEmitter::setDuration(Real min, Real max)
466    {
467        mDurationMin = min;
468        mDurationMax = max;
469        initDurationRepeat();
470    }
471    //-----------------------------------------------------------------------
472    void ParticleEmitter::setMinDuration(Real min)
473    {
474        mDurationMin = min;
475        initDurationRepeat();
476    }
477    //-----------------------------------------------------------------------
478    void ParticleEmitter::setMaxDuration(Real max)
479    {
480        mDurationMax = max;
481        initDurationRepeat();
482    }
483    //-----------------------------------------------------------------------
484    void ParticleEmitter::initDurationRepeat(void)
485    {
486        if (mEnabled)
487        {
488            if (mDurationMin == mDurationMax)
489            {
490                mDurationRemain = mDurationMin;
491            }
492            else
493            {
494                mDurationRemain = Math::RangeRandom(mDurationMin, mDurationMax);
495            }
496        }
497        else
498        {
499            // Reset repeat
500            if (mRepeatDelayMin == mRepeatDelayMax)
501            {
502                mRepeatDelayRemain = mRepeatDelayMin;
503            }
504            else
505            {
506                mRepeatDelayRemain = Math::RangeRandom(mRepeatDelayMax, mRepeatDelayMin);
507            }
508
509        }
510    }
511    //-----------------------------------------------------------------------
512    void ParticleEmitter::setRepeatDelay(Real delay)
513    {
514        setRepeatDelay(delay, delay);
515    }
516    //-----------------------------------------------------------------------
517    Real ParticleEmitter::getRepeatDelay(void) const
518    {
519        return mRepeatDelayMin;
520    }
521    //-----------------------------------------------------------------------
522    void ParticleEmitter::setRepeatDelay(Real min, Real max)
523    {
524        mRepeatDelayMin = min;
525        mRepeatDelayMax = max;
526        initDurationRepeat();
527    }
528    //-----------------------------------------------------------------------
529    void ParticleEmitter::setMinRepeatDelay(Real min)
530    {
531        mRepeatDelayMin = min;
532        initDurationRepeat();
533    }
534    //-----------------------------------------------------------------------
535    void ParticleEmitter::setMaxRepeatDelay(Real max)
536    {
537        mRepeatDelayMax = max;
538        initDurationRepeat();
539    }
540    //-----------------------------------------------------------------------
541    Real ParticleEmitter::getMinDuration(void) const
542    {
543        return mDurationMin;
544    }
545    //-----------------------------------------------------------------------
546    Real ParticleEmitter::getMaxDuration(void) const
547    {
548        return mDurationMax;
549    }
550    //-----------------------------------------------------------------------
551    Real ParticleEmitter::getMinRepeatDelay(void) const
552    {
553        return mRepeatDelayMin;   
554    }
555    //-----------------------------------------------------------------------
556    Real ParticleEmitter::getMaxRepeatDelay(void) const
557    {
558        return mRepeatDelayMax;   
559    }
560
561    //-----------------------------------------------------------------------
562    ParticleEmitterFactory::~ParticleEmitterFactory()
563    {
564        // Destroy all emitters
565        std::vector<ParticleEmitter*>::iterator i;
566        for (i = mEmitters.begin(); i != mEmitters.end(); ++i)
567        {
568            delete (*i);
569        }
570           
571        mEmitters.clear();
572
573    }
574    //-----------------------------------------------------------------------
575    void ParticleEmitterFactory::destroyEmitter(ParticleEmitter* e)       
576    {
577        std::vector<ParticleEmitter*>::iterator i;
578        for (i = mEmitters.begin(); i != mEmitters.end(); ++i)
579        {
580            if ((*i) == e)
581            {
582                mEmitters.erase(i);
583                delete e;
584                break;
585            }
586        }
587    }
588
589    //-----------------------------------------------------------------------
590
591}
592
Note: See TracBrowser for help on using the repository browser.