Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/particles/particle_emitter.cc @ 4439

Last change on this file since 4439 was 4439, checked in by bensch, 19 years ago

orxonox/trunk: again the particle-emitter is visile

File size: 6.3 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: Patrick Boenzli
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PARTICLE
17
18#include "particle_emitter.h"
19
20#include "particle_system.h"
21#include "particle_engine.h"
22
23#include "load_param.h"
24#include "debug.h"
25#include "stdlibincl.h"
26
27using namespace std;
28
29
30/**
31   \brief standard constructor
32*/
33ParticleEmitter::ParticleEmitter(const Vector& direction, float angle, float emissionRate, 
34                  float velocity)
35{
36  this->type = EMITTER_DOT;
37  this->emitterSize = 1.0;
38  this->direction = direction;
39  this->setSpread(angle);
40  this->setEmissionRate(emissionRate);
41  this->setEmissionVelocity(velocity);
42}
43
44ParticleEmitter::ParticleEmitter(const TiXmlElement* root)
45{
46   this->setClassID(CL_PARTICLE_EMITTER, "ParticleEmitter");
47
48   this->saveTime = 0.0;
49
50   if (root)
51     this->loadParams(root);
52
53   ParticleEngine::getInstance()->addEmitter(this);
54}
55
56/**
57   \brief standard destructor
58
59*/
60ParticleEmitter::~ParticleEmitter () 
61{
62  ParticleEngine::getInstance()->removeEmitter(this);
63}
64
65void ParticleEmitter::loadParams(const TiXmlElement* root)
66{
67  static_cast<PNode*>(this)->loadParams(root);
68
69  LoadParam<ParticleEmitter>(root, "type", this, &ParticleEmitter::setType)
70    .describe("What type of emitter is this [dot, plane, cube, sphere].");
71
72  LoadParam<ParticleEmitter>(root, "size", this, &ParticleEmitter::setSize)
73    .describe("How big the emitter is (no effect on dot-emitters)");
74
75  LoadParam<ParticleEmitter>(root, "rate", this, &ParticleEmitter::setEmissionRate)
76    .describe("How many particles should be emittet from this emitter");
77
78  LoadParam<ParticleEmitter>(root, "emission-velocity", this, &ParticleEmitter::setEmissionVelocity)
79    .describe("How fast the particles are emittet (their initial speed)");
80 
81  LoadParam<ParticleEmitter>(root, "spread", this, &ParticleEmitter::setSpread)
82    .describe("The angle the particles are emitted from (angle, deviation)");
83
84}
85
86/**
87   \brief this start the emitter
88*/
89void ParticleEmitter::start() {}
90
91
92/**
93   \brief this stops the emitter
94*/
95void ParticleEmitter::stop() {}
96
97
98
99
100/* these are Animation interfaces: so you can change spec values as you want */
101
102/**
103   \param type the new Type of this emitter
104*/
105void ParticleEmitter::setType(EMITTER_TYPE type)
106{
107  this->type = type;
108}
109
110/**
111   \param the type of emitter
112*/
113void ParticleEmitter::setType(const char* type)
114{
115  if (!strcmp(type, "plane"))
116    this->type = EMITTER_PLANE;
117  else if (!strcmp(type, "cube"))
118    this->type = EMITTER_CUBE;
119  else if (!strcmp(type, "sphere"))
120    this->type = EMITTER_SPHERE;
121  else
122    this->type = EMITTER_DOT;
123}
124
125
126void ParticleEmitter::setSize(float emitterSize)
127{
128  if (emitterSize > 0.0)
129    this->emitterSize = emitterSize;
130  else
131    emitterSize = 0.0;
132}
133
134/**
135   \brief set the emission rate
136   \param sets the number of particles emitted per second
137
138   if you want to change the value of this variable during emission time (to make it more dynamic)
139   you may want to use the animation class
140*/
141void ParticleEmitter::setEmissionRate(float emissionRate)
142{
143  if (emissionRate > 0.0)
144    this->emissionRate = emissionRate;
145  else
146    this->emissionRate = 0.0;
147}
148
149/**
150   \brief set the angle of the emitter
151   \param angle around the direction in which there are particles to be emitted
152   \param randomAngle A random spread-angle, the +- randomness of this option
153
154   if you want to change the value of this variable during emission time (to make it more dynamic)
155   you may want to use the animation class
156*/
157void ParticleEmitter::setSpread(float angle, float randomAngle)
158{
159  this->angle = angle;
160  this->randomAngle = randomAngle;
161}
162
163/**
164   \brief sets the velocity of all particles emitted
165   \param velocity The starting velocity of the emitted particles
166   \param random A random starting velocity, the +- randomness of this option
167
168   if you want to change the value of this variable during emission time (to make it more dynamic)
169   you may want to use the animation class
170*/
171void ParticleEmitter::setEmissionVelocity(float velocity, float randomVelocity)
172{
173  this->velocity = velocity;
174  this->randomVelocity = randomVelocity;
175}
176
177/**
178   \brief this set the time to life of a particle, after which it will die
179   \param the time to live in seconds
180
181   if you want to change the value of this variable during emission time (to make it more dynamic)
182   you may want to use the animation class
183*/
184
185void ParticleEmitter::tick(float dt, ParticleSystem* system)
186{
187  if (likely(dt > 0.0 && this->emissionRate > 0.0))
188  {
189    // saving the time
190    float count = (dt+this->saveTime) * this->emissionRate;
191    this->saveTime = modff(count, &count) / this->emissionRate;
192    PRINTF(5)("emitting %f particles, saving %f seconds for the next round\n", count, this->saveTime); 
193   
194    if (likely(count > 0))
195      {
196        Vector inheritVelocity = this->getVelocity() * system->inheritSpeed;
197        for (int i = 0; i < count; i++)
198          // emmits from EMITTER_DOT,
199          {
200            Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
201            randDir.normalize();
202            randDir = (this->getAbsDir()*Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->direction);
203            Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
204
205            // this should spread the Particles evenly. if the Emitter is moved around quickly
206            Vector equalSpread = this->getVelocity() * rand()/RAND_MAX * dt;
207            Vector extension; // the Vector for different fields.
208
209            if (this->type & 2)
210              {
211                extension = Vector(this->emitterSize * ((float)rand()/RAND_MAX -.5), 0, this->emitterSize * ((float)rand()/RAND_MAX - .5));
212                extension = this->getAbsDir().apply(extension);
213              }
214            else if (this->type & 8)
215              {
216                extension = Vector((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * this->emitterSize;
217              }
218
219            system->addParticle(this->getAbsCoor() + extension - equalSpread, velocityV);
220           
221          }
222      }
223  }
224}
225
226/**
227   \brief outputs some nice debug information
228*/
229void ParticleEmitter::debug(void)
230{
231
232}
Note: See TracBrowser for help on using the repository browser.