Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: changed all getInstances into inline functions to save some (minor) time

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