Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4438 was 4437, checked in by bensch, 20 years ago

orxonox/trunk: ParticleEmitter now loadable

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