Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: inheritSpeed now property of particle_emitter. system not friend emitter anymore

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