| 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 ) 2002 Tels <http://bloodgate.com> based on BoxEmitter | 
|---|
| 8 | Also see acknowledgements in Readme.html | 
|---|
| 9 |  | 
|---|
| 10 | This program is free software; you can redistribute it and/or modify it under | 
|---|
| 11 | the terms of the GNU Lesser General Public License as published by the Free Software | 
|---|
| 12 | Foundation; either version 2 of the License, or (at your option) any later | 
|---|
| 13 | version. | 
|---|
| 14 |  | 
|---|
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT | 
|---|
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 
|---|
| 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. | 
|---|
| 18 |  | 
|---|
| 19 | You should have received a copy of the GNU Lesser General Public License along with | 
|---|
| 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple | 
|---|
| 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to | 
|---|
| 22 | http://www.gnu.org/copyleft/lesser.txt. | 
|---|
| 23 |  | 
|---|
| 24 | You may alternatively use this source under the terms of a specific version of | 
|---|
| 25 | the OGRE Unrestricted License provided you have obtained such a license from | 
|---|
| 26 | Torus Knot Software Ltd. | 
|---|
| 27 | ----------------------------------------------------------------------------- | 
|---|
| 28 | */ | 
|---|
| 29 | #include "OgreRingEmitter.h" | 
|---|
| 30 | #include "OgreParticle.h" | 
|---|
| 31 | #include "OgreException.h" | 
|---|
| 32 | #include "OgreStringConverter.h" | 
|---|
| 33 |  | 
|---|
| 34 |  | 
|---|
| 35 | /* Implements an Emitter whose emitting points all lie inside a ring. | 
|---|
| 36 | */ | 
|---|
| 37 |  | 
|---|
| 38 | namespace Ogre { | 
|---|
| 39 |  | 
|---|
| 40 |     RingEmitter::CmdInnerX RingEmitter::msCmdInnerX; | 
|---|
| 41 |     RingEmitter::CmdInnerY RingEmitter::msCmdInnerY; | 
|---|
| 42 |  | 
|---|
| 43 |     //----------------------------------------------------------------------- | 
|---|
| 44 |     RingEmitter::RingEmitter(ParticleSystem* psys) | 
|---|
| 45 |         : AreaEmitter(psys) | 
|---|
| 46 |     { | 
|---|
| 47 |         if (initDefaults("Ring")) | 
|---|
| 48 |         { | 
|---|
| 49 |             // Add custom parameters | 
|---|
| 50 |             ParamDictionary* pDict = getParamDictionary(); | 
|---|
| 51 |  | 
|---|
| 52 |             pDict->addParameter(ParameterDef("inner_width", "Parametric value describing the proportion of the " | 
|---|
| 53 |                 "shape which is hollow.", PT_REAL), &msCmdInnerX); | 
|---|
| 54 |             pDict->addParameter(ParameterDef("inner_height", "Parametric value describing the proportion of the " | 
|---|
| 55 |                 "shape which is hollow.", PT_REAL), &msCmdInnerY); | 
|---|
| 56 |         } | 
|---|
| 57 |         // default is half empty | 
|---|
| 58 |         setInnerSize(0.5,0.5); | 
|---|
| 59 |     } | 
|---|
| 60 |     //----------------------------------------------------------------------- | 
|---|
| 61 |     void RingEmitter::_initParticle(Particle* pParticle) | 
|---|
| 62 |     { | 
|---|
| 63 |         Real a, b, x, y, z; | 
|---|
| 64 |  | 
|---|
| 65 |         // Call superclass | 
|---|
| 66 |         AreaEmitter::_initParticle(pParticle); | 
|---|
| 67 |         // create a random angle from 0 .. PI*2 | 
|---|
| 68 |         Radian alpha ( Math::RangeRandom(0,Math::TWO_PI) ); | 
|---|
| 69 |    | 
|---|
| 70 |         // create two random radius values that are bigger than the inner size | 
|---|
| 71 |         a = Math::RangeRandom(mInnerSizex,1.0); | 
|---|
| 72 |         b = Math::RangeRandom(mInnerSizey,1.0); | 
|---|
| 73 |  | 
|---|
| 74 |         // with a and b we have defined a random ellipse inside the inner | 
|---|
| 75 |         // ellipse and the outer circle (radius 1.0) | 
|---|
| 76 |         // with alpha, and a and b we select a random point on this ellipse | 
|---|
| 77 |         // and calculate it's coordinates | 
|---|
| 78 |         x = a * Math::Sin(alpha); | 
|---|
| 79 |         y = b * Math::Cos(alpha); | 
|---|
| 80 |         // the height is simple -1 to 1 | 
|---|
| 81 |         z = Math::SymmetricRandom();      | 
|---|
| 82 |  | 
|---|
| 83 |         // scale the found point to the ring's size and move it | 
|---|
| 84 |         // relatively to the center of the emitter point | 
|---|
| 85 |  | 
|---|
| 86 |         pParticle->position = mPosition +  | 
|---|
| 87 |          + x * mXRange + y * mYRange + z * mZRange; | 
|---|
| 88 |  | 
|---|
| 89 |         // Generate complex data by reference | 
|---|
| 90 |         genEmissionColour(pParticle->colour); | 
|---|
| 91 |         genEmissionDirection(pParticle->direction); | 
|---|
| 92 |         genEmissionVelocity(pParticle->direction); | 
|---|
| 93 |  | 
|---|
| 94 |         // Generate simpler data | 
|---|
| 95 |         pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); | 
|---|
| 96 |          | 
|---|
| 97 |     } | 
|---|
| 98 |     //----------------------------------------------------------------------- | 
|---|
| 99 |     void RingEmitter::setInnerSize(Real x, Real y) | 
|---|
| 100 |     { | 
|---|
| 101 |         // TODO: should really throw some exception | 
|---|
| 102 |         if ((x > 0) && (x < 1.0) && | 
|---|
| 103 |             (y > 0) && (y < 1.0)) | 
|---|
| 104 |             { | 
|---|
| 105 |             mInnerSizex = x; | 
|---|
| 106 |             mInnerSizey = y; | 
|---|
| 107 |             } | 
|---|
| 108 |     } | 
|---|
| 109 |     //----------------------------------------------------------------------- | 
|---|
| 110 |     void RingEmitter::setInnerSizeX(Real x) | 
|---|
| 111 |     { | 
|---|
| 112 |         assert(x > 0 && x < 1.0); | 
|---|
| 113 |  | 
|---|
| 114 |         mInnerSizex = x; | 
|---|
| 115 |     } | 
|---|
| 116 |     //----------------------------------------------------------------------- | 
|---|
| 117 |     void RingEmitter::setInnerSizeY(Real y) | 
|---|
| 118 |     { | 
|---|
| 119 |         assert(y > 0 && y < 1.0); | 
|---|
| 120 |  | 
|---|
| 121 |         mInnerSizey = y; | 
|---|
| 122 |     } | 
|---|
| 123 |     //----------------------------------------------------------------------- | 
|---|
| 124 |     Real RingEmitter::getInnerSizeX(void) const | 
|---|
| 125 |     { | 
|---|
| 126 |         return mInnerSizex; | 
|---|
| 127 |     } | 
|---|
| 128 |     //----------------------------------------------------------------------- | 
|---|
| 129 |     Real RingEmitter::getInnerSizeY(void) const | 
|---|
| 130 |     { | 
|---|
| 131 |         return mInnerSizey; | 
|---|
| 132 |     } | 
|---|
| 133 |     //----------------------------------------------------------------------- | 
|---|
| 134 |     //----------------------------------------------------------------------- | 
|---|
| 135 |     // Command objects | 
|---|
| 136 |     //----------------------------------------------------------------------- | 
|---|
| 137 |     //----------------------------------------------------------------------- | 
|---|
| 138 |     String RingEmitter::CmdInnerX::doGet(const void* target) const | 
|---|
| 139 |     { | 
|---|
| 140 |         return StringConverter::toString( | 
|---|
| 141 |             static_cast<const RingEmitter*>(target)->getInnerSizeX() ); | 
|---|
| 142 |     } | 
|---|
| 143 |     void RingEmitter::CmdInnerX::doSet(void* target, const String& val) | 
|---|
| 144 |     { | 
|---|
| 145 |         static_cast<RingEmitter*>(target)->setInnerSizeX(StringConverter::parseReal(val)); | 
|---|
| 146 |     } | 
|---|
| 147 |     //----------------------------------------------------------------------- | 
|---|
| 148 |     String RingEmitter::CmdInnerY::doGet(const void* target) const | 
|---|
| 149 |     { | 
|---|
| 150 |         return StringConverter::toString( | 
|---|
| 151 |             static_cast<const RingEmitter*>(target)->getInnerSizeY() ); | 
|---|
| 152 |     } | 
|---|
| 153 |     void RingEmitter::CmdInnerY::doSet(void* target, const String& val) | 
|---|
| 154 |     { | 
|---|
| 155 |         static_cast<RingEmitter*>(target)->setInnerSizeY(StringConverter::parseReal(val)); | 
|---|
| 156 |     } | 
|---|
| 157 |  | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 |  | 
|---|