Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/particleEngine: now the particles are much nicer :)

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