Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/particleEngine/src/lib/graphics/particles/particle_system.cc @ 4129

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

orxonox/branches/particleEngine: particles should get spread evenly if Emitter moves

File size: 8.5 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: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PARTICLE
17
18#include "particle_system.h"
19
20#include "particle_emitter.h"
21#include "particle_engine.h"
22#include "compiler.h"
23#include "material.h"
24
25using namespace std;
26
27/**
28   \brief standard constructor
29   \param count the Count of particles in the System
30   \param type The Type of the ParticleSystem
31
32   \todo this constructor is not jet implemented - do it
33*/
34ParticleSystem::ParticleSystem (unsigned int maxCount, PARTICLE_TYPE type)
35{
36   this->setClassName ("ParticleSystem");
37   this->name = NULL;
38   this->maxCount = maxCount;
39   this->count = 0;
40   this->particleType = type;
41   this->particles = NULL;
42   this->deadList = NULL;
43   this->setConserve(.8);
44   this->setLifeSpan(.1);
45   this->setInheritSpeed(0);
46   this->glID = NULL;
47   this->setRadius(1.0, 1.0, 0.0);
48   this->setType(PARTICLE_SPRITE, 1);
49   ParticleEngine::getInstance()->addSystem(this);
50}
51
52
53/**
54   \brief standard deconstructor
55*/
56ParticleSystem::~ParticleSystem() 
57{
58  // delete what has to be deleted here
59   ParticleEngine::getInstance()->removeSystem(this);
60
61   // deleting all the living Particles
62   while (this->particles)
63     {
64       Particle* tmpDelPart = this->particles;
65       this->particles = this->particles->next;
66       delete tmpDelPart;
67     }
68
69   // deleting all the dead particles
70   while (this->deadList)
71     {
72       Particle* tmpDelPart = this->deadList;
73       this->deadList = this->deadList->next;
74       delete tmpDelPart;
75     }
76}
77
78/**
79   \brief sets the Name of the Particle System
80   \param name the Name of the System
81*/
82void ParticleSystem::setName(const char* name)
83{
84  if (this->name)
85    delete this->name;
86  this->name = new char[strlen(name)+1];
87  strcpy(this->name, name);
88}
89
90/**
91   \returns the Name of the ParticleSystem
92*/
93const char* ParticleSystem::getName(void) const
94{
95  return this->name;
96}
97
98/**
99   \todo this will be different
100*/
101void ParticleSystem::setType(PARTICLE_TYPE particleType, int count)
102{
103  this->particleType = particleType;
104  this->dialectCount = count;
105  if (glID != NULL)
106    delete glID;
107
108  glID = new GLuint[count];
109  for (int i = 0; i< count; i++)
110    glID[i] = 0;
111
112  glID[0] = glGenLists(count);
113 
114  material = new Material("transperencyMap");
115  material->setDiffuseMap("pictures/radialTransparency.png");
116  //  material->setTransparency(.5);
117
118  glNewList(glID[0], GL_COMPILE);
119  glBegin(GL_TRIANGLE_STRIP);
120  glTexCoord2f(1, 1);
121  glVertex3f(0.0, .5, .5);
122  glTexCoord2f(1, 0);
123  glVertex3f(0.0, -.5, .5);
124  glTexCoord2f(0, 1);
125  glVertex3f(0.0, .5, -.5);
126  glTexCoord2f(0, 0);
127  glVertex3f(0.0, -.5, -.5);
128  glEnd();
129  glEndList();
130}
131
132// setting properties
133void ParticleSystem::setMaterial(Material* material)
134{
135  this->material = material;
136}
137
138
139
140/**
141   \brief how much of the speed from the ParticleEmitter should flow onto the ParticleSystem
142   \param value a Value between zero and one
143
144   
145   if you want to change the value of this variable during emission time (to make it more dynamic)
146   you may want to use the animation class
147*/
148void ParticleSystem::setInheritSpeed(float value)
149{
150  if (unlikely(value > 1.0))
151    this->inheritSpeed = 1;
152  else if (unlikely(value < 0.0))
153    this->inheritSpeed = 0;
154  else
155    this->inheritSpeed = value;
156}
157
158/**
159   \brief Sets the lifespan of newly created particles
160*/   
161void ParticleSystem::setLifeSpan(float lifeSpan, float randomLifeSpan)
162{
163  this->lifeSpan = lifeSpan;
164  this->randomLifeSpan = randomLifeSpan;
165}
166
167/**
168   \brief sets the radius of newly created particles
169*/
170void ParticleSystem::setRadius(float startRadius, float endRadius, float randomStartRadius, float randomEndRadius)
171{
172  this->startRadius = startRadius;
173  this->endRadius = endRadius;
174  this->randomStartRadius = randomStartRadius;
175  this->randomEndRadius = randomEndRadius;
176}
177
178/**
179   \brief sets the conserve Factor of newly created particles
180*/
181void ParticleSystem::setConserve(float conserve)
182{
183  if (conserve > 1.0)
184    this->conserve = 1.0;
185  else if (conserve < 0.0)
186    this->conserve = 0.0;
187  else
188    this->conserve = conserve;
189}
190
191/**
192   \brief ticks the system.
193   \param dt the time to tick all the Particles of the System
194
195   this is used to get all the particles some motion
196*/
197void ParticleSystem::tick(float dt)
198{
199  Particle* tickPart = particles;  // the particle to Tick
200  Particle* prevPart = NULL;       //
201  while (likely(tickPart != NULL))
202    {
203      tickPart->position = tickPart->position + tickPart->velocity;
204      tickPart->radius += tickPart->radiusIt * dt;
205
206      // many more to come
207
208
209      if (this->conserve < 1.0)
210        tickPart->velocity = tickPart->velocity * this->conserve;
211      // find out if we have to delete tickPart
212      if ((tickPart->timeToLive -= dt) <= 0)
213        {
214          // remove the particle from the list
215          if (likely(prevPart != NULL))
216            {
217              prevPart->next = tickPart->next;
218              tickPart->next = this->deadList;
219              this->deadList = tickPart;
220              tickPart = prevPart->next;
221            }
222          else
223            {
224              prevPart = NULL;
225              this->particles = tickPart->next;
226              tickPart->next = this->deadList;
227              this->deadList = tickPart;
228              tickPart = this->particles;
229            }
230          --this->count;
231        }
232      else
233        {     
234          prevPart = tickPart;
235          tickPart = tickPart->next;
236        }
237    }
238}
239
240/**
241   \brief draws all the Particles of this System
242*/
243void ParticleSystem::draw(void)
244{
245  //  material->select();
246
247
248  glMatrixMode(GL_MODELVIEW);
249  //  glDisable(GL_LIGHTING);
250  material->select(); 
251  glDisable(GL_DEPTH_TEST);
252 Particle* drawPart = particles;
253  if (likely(drawPart != NULL))
254    {
255      //draw in DOT mode
256      //      glBegin(GL_POINTS);
257      while (likely(drawPart != NULL))
258        {
259          glPushMatrix();
260          glTranslatef(drawPart->position.x, drawPart->position.y, drawPart->position.z);
261          glScalef(drawPart->radius, drawPart->radius, drawPart->radius);
262          glCallList(*this->glID);
263         
264          //glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z);
265          drawPart = drawPart->next;
266          glPopMatrix();
267        }
268      //      glEnd();
269    }
270  //  glEnable(GL_LIGHTING);
271  glEnable(GL_DEPTH_TEST);
272}
273
274/**
275   \brief adds a new Particle to the System
276   \param position the position where the particle gets emitted.
277   \param velocity the Starting velocity of the particle.
278   \param data some more data given by the emitter
279*/
280void ParticleSystem::addParticle(const Vector& position, const Vector& velocity, unsigned int data)
281{
282  if (this->count <= this->maxCount)
283    {
284      // if it is the first Particle
285      if (unlikely(particles == NULL))
286        {
287          if (likely(deadList != NULL))
288            {
289              this->particles = this->deadList;
290              deadList = deadList->next;
291            }
292          else
293            {
294              PRINTF(5)("Generating new Particle\n");
295              this->particles = new Particle;
296            }
297          this->particles->next = NULL;
298        }
299      // filling the List from the beginning
300      else
301        {
302          Particle* tmpPart;
303          if (likely(deadList != NULL))
304            {
305              tmpPart = this->deadList;
306              deadList = deadList->next;
307            }
308          else
309            {
310              PRINTF(5)("Generating new Particle\n");
311              tmpPart = new Particle;
312            }
313          tmpPart->next = this->particles;
314          this->particles = tmpPart;
315        }
316     
317      particles->timeToLive = this->lifeSpan + (float)(rand()/RAND_MAX)* this->randomLifeSpan;
318      particles->position = position;
319      particles->velocity = velocity;
320
321      //  particle->rotation = ; //! \todo rotation is once again something to be done.
322      particles->mass = this->initialMass + (rand()/RAND_MAX -.5)* this->randomInitialMass;
323      particles->radius = this->startRadius + (rand()/RAND_MAX-.5)*this->randomStartRadius;
324     
325      particles->radiusIt = (this->endRadius + (rand()/RAND_MAX-.5)*this->randomEndRadius - particles->radius) / particles->timeToLive;
326
327      ++this->count;
328    }
329  else
330    PRINTF(5)("maximum count of particles reached not adding any more\n");
331}
332
333/**
334   \brief outputs some nice debug information
335*/
336void ParticleSystem::debug(void)
337{
338  PRINT(0)("  ParticleSystem %s\n", this->name);
339  PRINT(0)("  ParticleCount: %d, maximumCount: %d :: filled %d%%\n", this->count, this->maxCount, 100*this->count/this->maxCount);
340  if (deadList)
341    {
342      PRINT(0)("  - ParticleDeadList is used: ");
343      int i = 1;
344      Particle* tmpPart = this->deadList;
345      while (tmpPart = tmpPart->next) ++i;
346      PRINT(0)("count: %d\n", i);
347    }
348}
Note: See TracBrowser for help on using the repository browser.