Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreParticleEmitter.cpp @ 1

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