Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: some minor cleanup, of the mess i made with AutoMake-sh

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