Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cd_old/src/lib/particles/particle_emitter.cc @ 7422

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

trunk: new interface to ParticleEmitters

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_GRAPHICS
17
18#include "particle_emitter.h"
19
20#include "particle_system.h"
21
22#include "load_param.h"
23#include "debug.h"
24#include "stdlibincl.h"
25
26using namespace std;
27
28/**
29 *  standard constructor
30*/
31ParticleEmitter::ParticleEmitter(float emissionRate, float velocity, float angle)
32{
33  this->setClassID(CL_PARTICLE_EMITTER, "ParticleEmitter");
34
35  this->system = NULL;
36
37  this->setInheritSpeed(PARTICLE_EMITTER_DEFAULT_INHERIT_SPEED);
38  this->setEmissionMomentum(0);
39  this->setSpread(angle);
40  this->setEmissionRate(emissionRate);
41  this->setEmissionVelocity(velocity);
42
43  this->saveTime = 0.0;
44}
45
46/**
47 *  standard destructor
48
49   removes the EmitterSystem from the ParticleEngine
50*/
51ParticleEmitter::~ParticleEmitter ()
52{
53  this->setSystem(NULL);
54}
55
56/**
57 *  loads a ParticleEmitter from a XML-element
58 * @param root the XML-element to load from
59*/
60void ParticleEmitter::loadParams(const TiXmlElement* root)
61{
62  PNode::loadParams(root);
63
64  LoadParam(root, "rate", this, ParticleEmitter, setEmissionRate)
65    .describe("How many particles should be emittet from this emitter");
66
67  LoadParam(root, "inherit-speed", this, ParticleEmitter, setInheritSpeed)
68    .describe("the extent, the speed of the emitter has on the particles");
69
70  LoadParam(root, "emission-velocity", this, ParticleEmitter, setEmissionVelocity)
71    .describe("How fast the particles are emittet (their initial speed)");
72
73  LoadParam(root, "emission-momentum", this, ParticleEmitter, setEmissionMomentum)
74      .describe("How fast the particles rotation is at emissiontime (their initial momentum)");
75
76  LoadParam(root, "spread", this, ParticleEmitter, setSpread)
77    .describe("The angle the particles are emitted from (angle, deviation)");
78}
79
80void ParticleEmitter::setSystem(ParticleSystem* system)
81{
82  if (system != NULL)
83    system->addEmitter(this);
84  else if (this->system != NULL)
85    this->system->removeEmitter(this);
86}
87
88/**
89 *  this start the emitter
90*/
91void ParticleEmitter::start() {}
92
93
94/**
95 *  this stops the emitter
96*/
97void ParticleEmitter::stop() {}
98
99
100/**
101 *  set the emission rate
102 * @param emissionRate: sets the number of particles emitted per second
103
104   if you want to change the value of this variable during emission time (to make it more dynamic)
105   you may want to use the animation class
106*/
107void ParticleEmitter::setEmissionRate(float emissionRate)
108{
109  if (emissionRate > 0.0)
110    this->emissionRate = emissionRate;
111  else
112    this->emissionRate = 0.0;
113}
114
115/**
116 *  how much of the speed from the ParticleEmitter should flow onto the ParticleSystem
117 * @param value a Value between zero and one
118
119   if you want to change the value of this variable during emission time (to make it more dynamic)
120   you may want to use the animation class
121*/
122void ParticleEmitter::setInheritSpeed(float value)
123{
124  if (unlikely(value > 1.0))
125    this->inheritSpeed = 1;
126  else if (unlikely(value < 0.0))
127    this->inheritSpeed = 0;
128  else
129    this->inheritSpeed = value;
130}
131
132/**
133 *  set the angle of the emitter
134 * @param angle around the direction in which there are particles to be emitted
135 * @param randomAngle A random spread-angle, the +- randomness of this option
136
137   if you want to change the value of this variable during emission time (to make it more dynamic)
138   you may want to use the animation class
139*/
140void ParticleEmitter::setSpread(float angle, float randomAngle)
141{
142  this->angle = angle;
143  this->randomAngle = randomAngle;
144}
145
146/**
147 *  sets the initial velocity of all particles emitted
148 * @param velocity The starting velocity of the emitted particles
149 * @param randomVelocity A random starting velocity, the +- randomness of this option
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::setEmissionVelocity(float velocity, float randomVelocity)
155{
156  this->velocity = velocity;
157  this->randomVelocity = randomVelocity;
158}
159
160/**
161 *  sets the initial Momentum of all particles emitted
162 * @param momentum the new Momentum (just a float for being not too complicated).
163 * @param randomMomentum variation from the given value.
164 */
165void ParticleEmitter::setEmissionMomentum(float momentum, float randomMomentum)
166{
167  this->momentum = momentum;
168  this->momentumRandom = randomMomentum;
169}
170
171/**
172 *  this set the time to life of a particle, after which it will die
173 * @param dt: the time to live in seconds
174 * @param system: the system into which to emitt
175
176   if you want to change the value of this variable during emission time (to make it more dynamic)
177   you may want to use the animation class
178*/
179void ParticleEmitter::tick(float dt)
180{
181  assert (this->system != NULL);
182  if (likely(dt > 0.0 && this->emissionRate > 0.0))
183  {
184    // saving the time (particles only partly emitted in this timestep)
185    float count = (dt+this->saveTime) * this->emissionRate;
186    this->saveTime = modff(count, &count) / this->emissionRate;
187    PRINTF(5)("emitting %f particles, saving %f seconds for the next timestep\n", count, this->saveTime);
188
189    if (likely(count > 0.0f))
190    {
191      this->emitParticles((unsigned int)count);
192
193/*      Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
194      for (int i = 0; i < (int)count; i++)
195      {
196        Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
197        randDir.normalize();
198        randDir = (this->getAbsDir()*Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->direction);
199        Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
200
201        // this should spread the Particles evenly. if the Emitter is moved around quickly
202        Vector equalSpread = this->getVelocity() * rand()/RAND_MAX * dt;
203        Vector extension; // the Vector for different fields.
204
205//         if (this->type & EMITTER_PLANE)
206//         {
207//           extension = Vector(this->emitterSize * ((float)rand()/RAND_MAX -.5), 0, this->emitterSize * ((float)rand()/RAND_MAX - .5));
208//           extension = this->getAbsDir().apply(extension);
209//         }
210//         else if (this->type & EMITTER_CUBE)
211//         {
212//           extension = Vector((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * this->emitterSize;
213//         }
214
215
216        // ROTATIONAL CALCULATION (this must not be done for all types of particles.)
217        randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
218        randDir.normalize();
219        Quaternion orient = Quaternion(M_PI, randDir);
220        Quaternion moment = Quaternion(this->momentum + this->momentumRandom, randDir);
221
222        this->system->addParticle(this->getAbsCoor() + extension - equalSpread, velocityV, orient, moment);
223      } */
224    }
225  }
226}
227
228/**
229 *  outputs some nice debug information
230*/
231void ParticleEmitter::debug() const
232{
233  PRINT(0)(" ParticleEmitter %s::%s\n", this->getClassName(), this->getName());
234  PRINT(0)("  EmissionRate: %f, Speed: %f, SpreadAngle: %f\n", this->getEmissionRate(), this->getEmissionVelocity(), this->getSpread());
235}
Note: See TracBrowser for help on using the repository browser.