Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/particleEngine: some minor fixes

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      tickPart->position = tickPart->position + tickPart->velocity;
187      tickPart->radius += tickPart->radiusIt * dt;
188
189      // many more to come
190
191
192      if (this->conserve < 1.0)
193        tickPart->velocity = tickPart->velocity * this->conserve;
194      // find out if we have to delete tickPart
195      if ((tickPart->timeToLive -= dt) <= 0)
196        {
197          // remove the particle from the list
198          if (likely(prevPart != NULL))
199            {
200              prevPart->next = tickPart->next;
201              delete tickPart;
202              tickPart = prevPart->next;
203            }
204          else
205            {
206              prevPart = NULL;
207              this->particles = tickPart->next;
208              delete tickPart;
209              tickPart = this->particles;
210            }
211          --this->count;
212        }
213      else
214        {     
215          prevPart = tickPart;
216          tickPart = tickPart->next;
217        }
218    }
219}
220
221/**
222   \brief draws all the Particles of this System
223*/
224void ParticleSystem::draw(void)
225{
226  //  material->select();
227
228
229  glMatrixMode(GL_MODELVIEW);
230  //  glDisable(GL_LIGHTING);
231  material->select();
232  glPushAttrib(GL_ENABLE_BIT);
233  glDisable(GL_DEPTH_TEST);
234  glDisable(GL_CULL_FACE);
235  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
236  glEnable(GL_TEXTURE_2D);
237
238  /* This allows alpha blending of 2D textures with the scene */
239  glEnable(GL_BLEND);
240  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
241
242
243  Particle* drawPart = particles;
244  if (likely(drawPart != NULL))
245    {
246      glBegin(GL_POINTS);
247      while (likely(drawPart != NULL))
248        {
249          // draw in DOT mode
250          glPushMatrix();
251          glTranslatef(drawPart->position.x, drawPart->position.y, drawPart->position.z);
252          glScalef(drawPart->radius, drawPart->radius, drawPart->radius);
253          glCallList(*this->glID);
254         
255          //              glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z);
256          drawPart = drawPart->next;
257          glPopMatrix();
258        }
259      glEnd();
260    }
261  glPopAttrib();
262
263}
264
265/**
266   \brief adds a new Particle to the System
267   \param position the position where the particle gets emitted.
268   \param velocity the Starting velocity of the particle.
269   \param data some more data given by the emitter
270*/
271void ParticleSystem::addParticle(const Vector& position, const Vector& velocity, unsigned int data)
272{
273  if (this->count <= this->maxCount)
274    {
275      // if it is the first Particle
276      if (unlikely(particles == NULL))
277        {
278          this->particles = new Particle;
279          this->particles->next = NULL;
280        }
281      // filling the List from the beginning
282      else
283        {
284          Particle* tmpPart = new Particle;
285          tmpPart->next = this->particles;
286          this->particles = tmpPart;
287        }
288     
289      particles->timeToLive = this->lifeSpan + (float)(random()/RAND_MAX)* this->randomLifeSpan;
290      particles->position = position;
291      particles->velocity = velocity;
292
293      //  particle->rotation = ; //! \todo rotation is once again something to be done.
294      particles->mass = this->initialMass + (random()/RAND_MAX -.5)* this->randomInitialMass;
295      particles->radius = this->startRadius + (random()/RAND_MAX-.5)*this->randomStartRadius;
296     
297      particles->radiusIt = (this->endRadius + (random()/RAND_MAX-.5)*this->randomEndRadius - particles->radius) / particles->timeToLive;
298
299      ++this->count;
300    }
301  else
302    PRINTF(4)("maximum count of particles reached not adding any more\n");
303}
304
305/**
306   \brief outputs some nice debug information
307*/
308void ParticleSystem::debug(void)
309{
310  PRINT(0)("  ParticleSystem %s\n", this->name);
311  PRINT(0)("  ParticleCount: %d, maximumCount: %d :: filled %d%%\n", this->count, this->maxCount, 100*this->count/this->maxCount);
312}
Note: See TracBrowser for help on using the repository browser.