Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/particles/particle_engine.cc @ 4349

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

orxonox/trunk: ParticleEngine now has a draw-function, that makes sense

File size: 10.4 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: ...
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PARTICLE
17
18#include "particle_engine.h"
19
20#include "particle_system.h"
21#include "particle_emitter.h"
22
23#include "list.h"
24
25using namespace std;
26
27/**
28   \brief standard constructor
29*/
30ParticleEngine::ParticleEngine () 
31{
32   this->setClassID(CL_PARTICLE_ENGINE, "ParticleEngine");
33
34   this->systemList = new tList<ParticleSystem>;
35   this->emitterList = new tList<ParticleEmitter>;
36   this->connectionList = new tList<ParticleConnection>;
37}
38
39/**
40   \brief the singleton reference to this class
41*/
42ParticleEngine* ParticleEngine::singletonRef = NULL;
43
44/**
45   \returns a Pointer to this Class
46*/
47ParticleEngine* ParticleEngine::getInstance(void)
48{
49  if (!ParticleEngine::singletonRef)
50    ParticleEngine::singletonRef = new ParticleEngine();
51  return ParticleEngine::singletonRef;
52}
53
54/**
55   \brief deletes all the system, emitters, connections and Lists
56*/
57ParticleEngine::~ParticleEngine () 
58{
59  // delete all remaining systems
60  tIterator<ParticleSystem>* sysIt = this->systemList->getIterator();
61  ParticleSystem* tmpSys = sysIt->nextElement();
62  while(tmpSys)
63    {
64      delete tmpSys;
65      tmpSys = sysIt->nextElement();
66    }
67  delete sysIt;
68  delete this->systemList;
69
70  // delete all remaining emitters
71  tIterator<ParticleEmitter>* emitIt = this->emitterList->getIterator();
72  ParticleEmitter* tmpEmit = emitIt->nextElement();
73  while(tmpEmit)
74    {
75      delete tmpEmit;
76      tmpEmit = emitIt->nextElement();
77    }
78  delete emitIt;
79  delete this->emitterList;
80
81  // there should be no more Connections
82  if (this->connectionList->getSize() == 0)
83    delete this->connectionList;
84  else
85    PRINTF(2)("The Connection List is not empty. This should not happen.\n");
86
87  ParticleEngine::singletonRef = NULL;
88}
89
90/**
91   \brief Adds a System to the System list.
92
93   this is done automatically when creating a ParticleSystem
94*/
95void ParticleEngine::addSystem(ParticleSystem* system)
96{
97  this->systemList->add(system);
98}
99
100/**
101   \brief Adds an emitter to the emitterList
102
103   this is done automatically when creating a ParticleEmitter
104*/
105void ParticleEngine::addEmitter(ParticleEmitter* emitter)
106{
107  this->emitterList->add(emitter);
108}
109
110/**
111   \brief Connects a ParticleSystem to a ParticleSystem thus emitting Particles.
112   \param emitter the Emitter to connect to the System
113   \param system the System to connect to the Emitter
114*/
115void ParticleEngine::addConnection(ParticleEmitter* emitter, ParticleSystem* system)
116{
117  // look, if we have already added this connection
118  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
119  ParticleConnection* tmpConnection = tmpConIt->nextElement();
120  while(tmpConnection)
121    {
122      if (tmpConnection->emitter == emitter && tmpConnection->system == system)
123        {
124          PRINTF(2)("Connection between Emitter and System already added\n");
125          delete tmpConIt;
126          return;
127        }
128     
129      tmpConnection = tmpConIt->nextElement();
130    }
131  delete tmpConIt;
132 
133
134
135  ParticleConnection* tmpCon = new ParticleConnection;
136  tmpCon->emitter = emitter;
137  tmpCon->system = system;
138
139  this->connectionList->add(tmpCon);
140}
141
142/**
143   \brief Removes a system from the systemList and also removes all Connections to the System
144   \param system The ParticleSystem to delete
145*/
146bool ParticleEngine::removeSystem(ParticleSystem* system)
147{
148  // remove any connections, that have this system within
149  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
150  ParticleConnection* tmpConnection = tmpConIt->nextElement();
151  while(tmpConnection)
152    {
153      if (tmpConnection->system == system)
154        this->breakConnection(tmpConnection);
155      tmpConnection = tmpConIt->nextElement();
156    }
157  delete tmpConIt;
158
159  // remove the System from the systemList.
160  this->systemList->remove(system);
161}
162
163/**
164   \brief removes an emitter from the emitterList and also from all Connections it is attached to.
165   \param emitter the ParticleEmitter to remove.
166*/
167bool ParticleEngine::removeEmitter(ParticleEmitter* emitter)
168{
169  // remove any connections, that have this emitter within
170  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
171  ParticleConnection* tmpConnection = tmpConIt->nextElement();
172  while(tmpConnection)
173    {
174      if (tmpConnection->emitter == emitter)
175        this->breakConnection(tmpConnection);
176      tmpConnection = tmpConIt->nextElement();
177    }
178  delete tmpConIt;
179
180  // remove the emitter from the emitterList
181  this->emitterList->remove(emitter);
182}
183
184/**
185   \brief removes a Connection between an Emitter and a System
186   \param emitter The emitter of the connection to remove
187   \param system The system of the connection to remove
188   \returns true, if the connection was broken, false if the conntection was not found
189
190   only if both system and emitter are in the connection the Connection will be broken
191*/
192bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
193{
194  // look, if we have already added this connection
195  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
196  ParticleConnection* tmpConnection = tmpConIt->nextElement();
197  while(tmpConnection)
198    {
199    if (tmpConnection->emitter == emitter && tmpConnection->system == system)
200      {
201        this->breakConnection(tmpConnection);
202        delete tmpConIt;
203        return true;
204      }
205    tmpConnection = tmpConIt->nextElement();
206    }
207  delete tmpConIt;
208  return false;
209}
210
211/**
212   \brief removes a Connection between an Emitter and a System
213   \param connection the connection to remove
214
215   \see bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
216*/
217bool ParticleEngine::breakConnection(ParticleConnection* connection)
218{
219  this->connectionList->remove(connection);
220  return true;
221}
222
223
224/**
225   \brief this function ticks all the ParticleSystems, so an animation will flow
226   \param dt passed since last tick
227*/
228void ParticleEngine::tick(float dt)
229{
230  // ticks all the ParticleSystems
231  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
232  ParticleSystem* tmpSys = tmpIt->nextElement();
233  while(tmpSys)
234    {
235      tmpSys->tick(dt);
236      tmpSys = tmpIt->nextElement();
237    }
238  delete tmpIt;
239
240  // add new Particles to each System connected to an Emitter.
241  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
242  ParticleConnection* tmpConnection = tmpConIt->nextElement();
243  while(tmpConnection)
244    {
245      tmpConnection->emitter->tick(dt, tmpConnection->system);
246      tmpConnection = tmpConIt->nextElement();
247    }
248  delete tmpConIt;
249}
250
251/**
252   \brief draws all the systems and their Particles.
253   \param dt the time passed in seconds (since the last Frame)
254*/
255void ParticleEngine::draw() const
256{
257  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
258  ParticleSystem* tmpSys = tmpIt->nextElement();
259  while(tmpSys)
260    {
261      tmpSys->draw();
262      tmpSys = tmpIt->nextElement();
263    }
264  delete tmpIt;
265
266}
267
268/**
269   \param systemName the name of the system to search for
270   \returns the system called by systemName or NULL if not found
271*/
272ParticleSystem* ParticleEngine::getSystemByName(const char* systemName) const
273{
274  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
275  ParticleSystem* tmpSys = tmpIt->nextElement();
276  while(tmpSys)
277    {
278      if (!strcmp(systemName, tmpSys->getName()))
279        {
280          delete tmpIt;
281          return tmpSys;
282        }
283      tmpSys = tmpIt->nextElement();
284    }
285  delete tmpIt;
286  return NULL;
287}
288
289/**
290   \param number the n-th system to return
291   \returns the system called by number or NULL if not found
292*/
293ParticleSystem* ParticleEngine::getSystemByNumber(unsigned int number) const
294{
295  int count = 0;
296  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
297  ParticleSystem* tmpSys = tmpIt->nextElement();
298  while(tmpSys)
299    {
300      count++;
301      if ( count == number)
302        {
303          delete tmpIt;
304          return tmpSys;
305        }
306      tmpSys = tmpIt->nextElement();
307    }
308  delete tmpIt;
309  return NULL;
310}
311
312/**
313   \param emitterName the name of the emitter to search for
314   \returns the emitter called by emitterName or NULL if not found
315*/
316ParticleEmitter* ParticleEngine::getEmitterByName(const char* emitterName) const
317{
318  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
319  ParticleEmitter* tmpEmit = tmpIt->nextElement();
320  while(tmpEmit)
321    {
322      if (!strcmp(emitterName, tmpEmit->getName()))
323        {
324          delete tmpIt;
325          return tmpEmit;
326        }
327      tmpEmit = tmpIt->nextElement();
328    }
329  delete tmpIt;
330  return NULL;
331}
332
333
334/**
335   \param number the n-th emitter to return
336   \returns the emitter called by number or NULL if not found
337*/
338ParticleEmitter* ParticleEngine::getEmitterByNumber(unsigned int number) const
339{
340  int count = 0;
341  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
342  ParticleEmitter* tmpEmit = tmpIt->nextElement();
343  while(tmpEmit)
344    {
345      count++;
346      if ( count == number)
347        {
348          delete tmpIt;
349          return tmpEmit;
350        }
351      tmpEmit = tmpIt->nextElement();
352    }
353  delete tmpIt;
354  return NULL;
355}
356
357/**
358   \brief outputs some nice debug information
359*/
360void ParticleEngine::debug(void)
361{
362  PRINT(0)("+-----------------------------------+\n");
363  PRINT(0)("+ PARTICLE-ENGINE DEBUG INFORMATION +\n");
364  PRINT(0)("+-----------------------------------+\n");
365  PRINT(0)(" Reference: %p\n", ParticleEngine::singletonRef);
366  PRINT(0)(" Count: Emitters: %d; Systems: %d, Connections: %d\n",
367            this->emitterList->getSize(), this->systemList->getSize(), this->connectionList->getSize());
368  if (this->connectionList->getSize() > 0)
369    {
370      PRINT(0)(" Connections:\n");
371      PRINT(0)(" -----------------------------------\n");
372
373      tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
374      ParticleConnection* tmpConnection = tmpConIt->nextElement();
375      while(tmpConnection)
376        {
377          PRINT(0)(" Emitter '%s' emitts into System '%s'\n", tmpConnection->emitter->getName(), tmpConnection->system->getName());
378          tmpConnection = tmpConIt->nextElement();
379        }
380      delete tmpConIt;
381    }
382  if (this->systemList->getSize() > 0)
383    {
384      tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
385      ParticleSystem* tmpSys = tmpIt->nextElement();
386      while(tmpSys)
387        {
388          tmpSys->debug();
389          tmpSys = tmpIt->nextElement();
390        }
391      delete tmpIt;
392    }
393
394  PRINT(0)("+--------------------------------PE-+\n");
395
396}
Note: See TracBrowser for help on using the repository browser.