Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: made include more local. stdincl.h not in base_object.h anymore

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