Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: setClassID implemented in all files

File size: 7.8 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->setClassID(CL_PARTICLE_EMITTER, "ParticleEmitter");
37  this->type = EMITTER_DOT;
38  this->emitterSize = 1.0;
39  this->direction = direction;
40  this->setInheritSpeed(0);
41  this->setSpread(angle);
42  this->setEmissionRate(emissionRate);
43  this->setEmissionVelocity(velocity);
44}
45
46/**
47   \brief constructs and loads a ParticleEmitter from a XML-element
48   \param root the XML-element to load from
49*/
50ParticleEmitter::ParticleEmitter(const TiXmlElement* root)
51{
52   this->setClassID(CL_PARTICLE_EMITTER, "ParticleEmitter");
53
54   this->saveTime = 0.0;
55
56   if (root)
57     this->loadParams(root);
58
59   ParticleEngine::getInstance()->addEmitter(this);
60}
61
62/**
63   \brief standard destructor
64
65   removes the EmitterSystem from the ParticleEngine
66*/
67ParticleEmitter::~ParticleEmitter ()
68{
69  ParticleEngine::getInstance()->removeEmitter(this);
70}
71
72/**
73   \brief loads a ParticleEmitter from a XML-element
74   \param root the XML-element to load from
75*/
76void ParticleEmitter::loadParams(const TiXmlElement* root)
77{
78  static_cast<PNode*>(this)->loadParams(root);
79
80  LoadParam<ParticleEmitter>(root, "type", this, &ParticleEmitter::setType)
81    .describe("What type of emitter is this [dot, plane, cube, sphere].");
82
83  LoadParam<ParticleEmitter>(root, "size", this, &ParticleEmitter::setSize)
84    .describe("How big the emitter is (no effect on dot-emitters)");
85
86  LoadParam<ParticleEmitter>(root, "rate", this, &ParticleEmitter::setEmissionRate)
87    .describe("How many particles should be emittet from this emitter");
88
89  LoadParam<ParticleEmitter>(root, "inherit-speed", this, &ParticleEmitter::setInheritSpeed)
90    .describe("the extent, the speed of the emitter has on the particles");
91
92  LoadParam<ParticleEmitter>(root, "emission-velocity", this, &ParticleEmitter::setEmissionVelocity)
93    .describe("How fast the particles are emittet (their initial speed)");
94
95  LoadParam<ParticleEmitter>(root, "spread", this, &ParticleEmitter::setSpread)
96    .describe("The angle the particles are emitted from (angle, deviation)");
97}
98
99/**
100   \brief this start the emitter
101*/
102void ParticleEmitter::start() {}
103
104
105/**
106   \brief this stops the emitter
107*/
108void ParticleEmitter::stop() {}
109
110
111
112
113/* these are Animation interfaces: so you can change spec values as you want */
114
115/**
116   \param type the new Type of this emitter
117*/
118void ParticleEmitter::setType(EMITTER_TYPE type)
119{
120  this->type = type;
121}
122
123/**
124   \brief sets the type of emitter
125   \param type the type as a const char*
126   dot: EMITTER_DOT, plane: EMITTER_PLANE, cube: EMITTER_CUBE, sphere, EMITTER_SPHERE;
127*/
128void ParticleEmitter::setType(const char* type)
129{
130  if (!strcmp(type, "plane"))
131    this->type = EMITTER_PLANE;
132  else if (!strcmp(type, "cube"))
133    this->type = EMITTER_CUBE;
134  else if (!strcmp(type, "sphere"))
135    this->type = EMITTER_SPHERE;
136  else
137    this->type = EMITTER_DOT;
138}
139
140/**
141   \brief sets a new size to the emitter
142*/
143void ParticleEmitter::setSize(float emitterSize)
144{
145  if (emitterSize > 0.0)
146    this->emitterSize = emitterSize;
147  else
148    emitterSize = 0.0;
149}
150
151/**
152   \brief set the emission rate
153   \param emissionRate: sets the number of particles emitted per second
154
155   if you want to change the value of this variable during emission time (to make it more dynamic)
156   you may want to use the animation class
157*/
158void ParticleEmitter::setEmissionRate(float emissionRate)
159{
160  if (emissionRate > 0.0)
161    this->emissionRate = emissionRate;
162  else
163    this->emissionRate = 0.0;
164}
165
166/**
167   \brief how much of the speed from the ParticleEmitter should flow onto the ParticleSystem
168   \param value a Value between zero and one
169
170   if you want to change the value of this variable during emission time (to make it more dynamic)
171   you may want to use the animation class
172*/
173void ParticleEmitter::setInheritSpeed(float value)
174{
175  if (unlikely(value > 1.0))
176    this->inheritSpeed = 1;
177  else if (unlikely(value < 0.0))
178    this->inheritSpeed = 0;
179  else
180    this->inheritSpeed = value;
181}
182
183/**
184   \brief set the angle of the emitter
185   \param angle around the direction in which there are particles to be emitted
186   \param randomAngle A random spread-angle, the +- randomness of this option
187
188   if you want to change the value of this variable during emission time (to make it more dynamic)
189   you may want to use the animation class
190*/
191void ParticleEmitter::setSpread(float angle, float randomAngle)
192{
193  this->angle = angle;
194  this->randomAngle = randomAngle;
195}
196
197/**
198   \brief sets the velocity of all particles emitted
199   \param velocity The starting velocity of the emitted particles
200   \param randomVelocity A random starting velocity, the +- randomness of this option
201
202   if you want to change the value of this variable during emission time (to make it more dynamic)
203   you may want to use the animation class
204*/
205void ParticleEmitter::setEmissionVelocity(float velocity, float randomVelocity)
206{
207  this->velocity = velocity;
208  this->randomVelocity = randomVelocity;
209}
210
211/**
212   \brief this set the time to life of a particle, after which it will die
213   \param dt: the time to live in seconds
214   \param system: the system into which to emitt
215
216   if you want to change the value of this variable during emission time (to make it more dynamic)
217   you may want to use the animation class
218*/
219
220void ParticleEmitter::tick(float dt, ParticleSystem* system)
221{
222  if (likely(dt > 0.0 && this->emissionRate > 0.0))
223  {
224    // saving the time
225    float count = (dt+this->saveTime) * this->emissionRate;
226    this->saveTime = modff(count, &count) / this->emissionRate;
227    PRINTF(5)("emitting %f particles, saving %f seconds for the next round\n", count, this->saveTime);
228
229    if (likely(count > 0))
230      {
231        Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
232        for (int i = 0; i < count; i++)
233          // emmits from EMITTER_DOT,
234          {
235            Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
236            randDir.normalize();
237            randDir = (this->getAbsDir()*Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->direction);
238            Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
239
240            // this should spread the Particles evenly. if the Emitter is moved around quickly
241            Vector equalSpread = this->getVelocity() * rand()/RAND_MAX * dt;
242            Vector extension; // the Vector for different fields.
243
244            if (this->type & 2)
245              {
246                extension = Vector(this->emitterSize * ((float)rand()/RAND_MAX -.5), 0, this->emitterSize * ((float)rand()/RAND_MAX - .5));
247                extension = this->getAbsDir().apply(extension);
248              }
249            else if (this->type & 8)
250              {
251                extension = Vector((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * this->emitterSize;
252              }
253
254            system->addParticle(this->getAbsCoor() + extension - equalSpread, velocityV);
255
256          }
257      }
258  }
259}
260
261/**
262   \brief outputs some nice debug information
263*/
264void ParticleEmitter::debug(void)
265{
266  PRINT(0)(" Emitter %s\n", this->getName());
267}
Note: See TracBrowser for help on using the repository browser.