Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 6822 in orxonox.OLD for trunk/src/lib/particles/dot_emitter.cc


Ignore:
Timestamp:
Jan 29, 2006, 1:57:03 AM (19 years ago)
Author:
bensch
Message:

trunk: ParticleEmitters now splitted into SubClasses.
Also fixed a little Boeg in the ClassID

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/particles/dot_emitter.cc

    r6820 r6822  
    1616#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
    1717
    18 #include "particle_emitter.h"
     18#include "dot_emitter.h"
    1919
    2020#include "particle_system.h"
     
    2828
    2929
    30 CREATE_FACTORY(ParticleEmitter, CL_PARTICLE_EMITTER);
     30CREATE_FACTORY(DotEmitter, CL_DOT_EMITTER);
    3131
    3232/**
    3333 *  standard constructor
    3434*/
    35 ParticleEmitter::ParticleEmitter(const Vector& direction, float angle, float emissionRate,
    36                   float velocity)
     35DotEmitter::DotEmitter(const Vector& direction, float angle, float emissionRate,
     36                       float velocity)
     37  : ParticleEmitter(direction, angle, emissionRate, velocity)
    3738{
    3839  this->init();
    39 
    40   this->direction = direction;
    41   this->setSpread(angle);
    42   this->setEmissionRate(emissionRate);
    43   this->setEmissionVelocity(velocity);
    4440}
    4541
    4642/**
    47  *  constructs and loads a ParticleEmitter from a XML-element
     43 *  constructs and loads a DotEmitter from a XML-element
    4844 * @param root the XML-element to load from
    4945*/
    50 ParticleEmitter::ParticleEmitter(const TiXmlElement* root)
     46DotEmitter::DotEmitter(const TiXmlElement* root)
     47  : ParticleEmitter()
    5148{
    5249  this->init();
     
    6158   removes the EmitterSystem from the ParticleEngine
    6259*/
    63 ParticleEmitter::~ParticleEmitter ()
     60DotEmitter::~DotEmitter ()
    6461{
    6562  this->setSystem(NULL);
     
    6966  @brief initializes default values of a ParitcleEmitter
    7067*/
    71 void ParticleEmitter::init()
     68void DotEmitter::init()
    7269{
    73   this->setClassID(CL_PARTICLE_EMITTER, "ParticleEmitter");
    74 
    75   this->type = PARTICLE_EMITTER_DEFAULT_TYPE;
    76   this->emitterSize = PARTICLE_EMITTER_DEFAULT_SIZE;
    77   this->setInheritSpeed(PARTICLE_EMITTER_DEFAULT_INHERIT_SPEED);
    78   this->setEmissionRate(PARTICLE_EMITTER_DEFAULT_EMISSION_RATE);
    79   this->setSize(PARTICLE_EMITTER_DEFAULT_SIZE);
    80   this->setEmissionMomentum(0);
    81   this->setEmissionVelocity(1.0);
    82   this->setSpread(M_PI);
    83 
    84   this->system = NULL;
    85 
    86   this->saveTime = 0.0;
     70  this->setClassID(CL_DOT_EMITTER, "DotEmitter");
    8771}
    8872
    89 /**
    90  *  loads a ParticleEmitter from a XML-element
    91  * @param root the XML-element to load from
    92 */
    93 void ParticleEmitter::loadParams(const TiXmlElement* root)
     73void DotEmitter::emitParticles(unsigned int count) const
    9474{
    95   PNode::loadParams(root);
     75  Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
    9676
    97   LoadParam(root, "type", this, ParticleEmitter, setType)
    98     .describe("What type of emitter is this [dot, plane, cube, sphere].");
     77  for (unsigned int i = 0; i < count; i++)
     78  {
     79    Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
     80    randDir.normalize();
     81    randDir = (this->getAbsDir()*Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->direction);
     82    Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
    9983
    100   LoadParam(root, "size", this, ParticleEmitter, setSize)
    101     .describe("How big the emitter is (no effect on dot-emitters)");
     84    // ROTATIONAL CALCULATION (this must not be done for all types of particles.)
     85    randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
     86    randDir.normalize();
     87    Quaternion orient = Quaternion(M_PI, randDir);
     88    Quaternion moment = Quaternion(this->momentum + this->momentumRandom, randDir);
    10289
    103   LoadParam(root, "rate", this, ParticleEmitter, setEmissionRate)
    104     .describe("How many particles should be emittet from this emitter");
     90    this->getSystem()->addParticle(this->getAbsCoor(), velocityV, orient, moment);
    10591
    106   LoadParam(root, "inherit-speed", this, ParticleEmitter, setInheritSpeed)
    107     .describe("the extent, the speed of the emitter has on the particles");
    108 
    109   LoadParam(root, "emission-velocity", this, ParticleEmitter, setEmissionVelocity)
    110     .describe("How fast the particles are emittet (their initial speed)");
    111 
    112   LoadParam(root, "emission-momentum", this, ParticleEmitter, setEmissionMomentum)
    113       .describe("How fast the particles rotation is at emissiontime (their initial momentum)");
    114 
    115   LoadParam(root, "spread", this, ParticleEmitter, setSpread)
    116     .describe("The angle the particles are emitted from (angle, deviation)");
    117 
    118 
    119   LoadParam(root, "emission-direction", this, ParticleEmitter, setDirection);
    120 }
    121 
    122 void ParticleEmitter::setSystem(ParticleSystem* system)
    123 {
    124   if (system != NULL)
    125     system->addEmitter(this);
    126   else if (this->system != NULL)
    127     this->system->removeEmitter(this);
    128 }
    129 
    130 /**
    131  *  this start the emitter
    132 */
    133 void ParticleEmitter::start() {}
    134 
    135 
    136 /**
    137  *  this stops the emitter
    138 */
    139 void ParticleEmitter::stop() {}
    140 
    141 
    142 
    143 
    144 
    145 /**
    146  * @param type the new Type of this emitter
    147 */
    148 void ParticleEmitter::setType(EMITTER_TYPE type)
    149 {
    150   this->type = type;
    151 }
    152 
    153 /**
    154  *  sets the type of emitter
    155  * @param type the type as a const char*
    156    dot: EMITTER_DOT, plane: EMITTER_PLANE, cube: EMITTER_CUBE, sphere, EMITTER_SPHERE;
    157 */
    158 void ParticleEmitter::setType(const char* type)
    159 {
    160   if (!strcmp(type, "plane"))
    161     this->setType(EMITTER_PLANE);
    162   else if (!strcmp(type, "cube"))
    163     this->setType(EMITTER_CUBE);
    164   else if (!strcmp(type, "sphere"))
    165     this->setType(EMITTER_SPHERE);
    166   else
    167     this->setType(EMITTER_DOT);
    168 }
    169 
    170 const char* ParticleEmitter::getTypeC() const
    171 {
    172   if (this->type == EMITTER_PLANE)
    173     return "EMITTER_PLANE";
    174   else if (this->type == EMITTER_CUBE)
    175     return "EMITTER_CUBE";
    176   else if (this->type == EMITTER_SPHERE)
    177     return "EMITTER_SPHERE";
    178   else
    179     return "EMITTER_DOT";
    180 }
    181 
    182 /**
    183  *  sets a new size to the emitter
    184 */
    185 void ParticleEmitter::setSize(float emitterSize)
    186 {
    187   if (emitterSize > 0.0)
    188     this->emitterSize = emitterSize;
    189   else
    190     emitterSize = 0.0;
    191 }
    192 
    193 /**
    194  *  set the emission rate
    195  * @param emissionRate: sets the number of particles emitted per second
    196 
    197    if you want to change the value of this variable during emission time (to make it more dynamic)
    198    you may want to use the animation class
    199 */
    200 void ParticleEmitter::setEmissionRate(float emissionRate)
    201 {
    202   if (emissionRate > 0.0)
    203     this->emissionRate = emissionRate;
    204   else
    205     this->emissionRate = 0.0;
    206 }
    207 
    208 /**
    209  *  how much of the speed from the ParticleEmitter should flow onto the ParticleSystem
    210  * @param value a Value between zero and one
    211 
    212    if you want to change the value of this variable during emission time (to make it more dynamic)
    213    you may want to use the animation class
    214 */
    215 void ParticleEmitter::setInheritSpeed(float value)
    216 {
    217   if (unlikely(value > 1.0))
    218     this->inheritSpeed = 1;
    219   else if (unlikely(value < 0.0))
    220     this->inheritSpeed = 0;
    221   else
    222     this->inheritSpeed = value;
    223 }
    224 
    225 /**
    226  *  set the angle of the emitter
    227  * @param angle around the direction in which there are particles to be emitted
    228  * @param randomAngle A random spread-angle, the +- randomness of this option
    229 
    230    if you want to change the value of this variable during emission time (to make it more dynamic)
    231    you may want to use the animation class
    232 */
    233 void ParticleEmitter::setSpread(float angle, float randomAngle)
    234 {
    235   this->angle = angle;
    236   this->randomAngle = randomAngle;
    237 }
    238 
    239 /**
    240  *  sets the initial velocity of all particles emitted
    241  * @param velocity The starting velocity of the emitted particles
    242  * @param randomVelocity A random starting velocity, the +- randomness of this option
    243 
    244    if you want to change the value of this variable during emission time (to make it more dynamic)
    245    you may want to use the animation class
    246 */
    247 void ParticleEmitter::setEmissionVelocity(float velocity, float randomVelocity)
    248 {
    249   this->velocity = velocity;
    250   this->randomVelocity = randomVelocity;
    251 }
    252 
    253 /**
    254  *  sets the initial Momentum of all particles emitted
    255  * @param momentum the new Momentum (just a float for being not too complicated).
    256  * @param randomMomentum variation from the given value.
    257  */
    258 void ParticleEmitter::setEmissionMomentum(float momentum, float randomMomentum)
    259 {
    260   this->momentum = momentum;
    261   this->momentumRandom = randomMomentum;
    262 }
    263 
    264 /**
    265  *  this set the time to life of a particle, after which it will die
    266  * @param dt: the time to live in seconds
    267  * @param system: the system into which to emitt
    268 
    269    if you want to change the value of this variable during emission time (to make it more dynamic)
    270    you may want to use the animation class
    271 */
    272 void ParticleEmitter::tick(float dt)
    273 {
    274   assert (this->system != NULL);
    275   if (likely(dt > 0.0 && this->emissionRate > 0.0))
    276   {
    277     // saving the time (particles only partly emitted in this timestep)
    278     float count = (dt+this->saveTime) * this->emissionRate;
    279     this->saveTime = modff(count, &count) / this->emissionRate;
    280     PRINTF(5)("emitting %f particles, saving %f seconds for the next timestep\n", count, this->saveTime);
    281 
    282     if (likely(count > 0))
    283     {
    284       Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
    285       for (int i = 0; i < (int)count; i++)
    286       {
    287         Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
    288         randDir.normalize();
    289         randDir = (this->getAbsDir()*Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->direction);
    290         Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
    291 
    292         // this should spread the Particles evenly. if the Emitter is moved around quickly
    293         Vector equalSpread = this->getVelocity() * rand()/RAND_MAX * dt;
    294         Vector extension; // the Vector for different fields.
    295 
    296         if (this->type & EMITTER_PLANE)
    297         {
    298           extension = Vector(this->emitterSize * ((float)rand()/RAND_MAX -.5), 0, this->emitterSize * ((float)rand()/RAND_MAX - .5));
    299           extension = this->getAbsDir().apply(extension);
    300         }
    301         else if (this->type & EMITTER_CUBE)
    302         {
    303           extension = Vector((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * this->emitterSize;
    304         }
    305 
    306 
    307         // ROTATIONAL CALCULATION (this must not be done for all types of particles.)
    308         randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
    309         randDir.normalize();
    310         Quaternion orient = Quaternion(M_PI, randDir);
    311         Quaternion moment = Quaternion(this->momentum + this->momentumRandom, randDir);
    312 
    313         this->system->addParticle(this->getAbsCoor() + extension - equalSpread, velocityV, orient, moment);
    314       }
    315     }
    31692  }
    31793}
    318 
    319 /**
    320  *  outputs some nice debug information
    321 */
    322 void ParticleEmitter::debug() const
    323 {
    324   PRINT(0)(" Emitter %s\n", this->getName());
    325   PRINT(0)("  EmissionRate: %f, Speed: %f, SpreadAngle: %f\n", this->getEmissionRate(), this->getEmissionVelocity(), this->getSpread());
    326   PRINT(0)("  Size %f, Type: %s\n", this->getSize(), this->getTypeC());
    327 }
Note: See TracChangeset for help on using the changeset viewer.