Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: reimplemented the list functions, as i did before in revision 5110.
This time, i looked out for the bugs, and i think i found one

@patrick: i know, that you do not want to code at the moment… :/ → see mail

File size: 12.1 KB
RevLine 
[4597]1/*
[3655]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
[3938]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PARTICLE
[3655]17
[3924]18#include "particle_engine.h"
[3655]19
[3931]20#include "particle_system.h"
21#include "particle_emitter.h"
22
[3930]23#include "list.h"
[4381]24#include "debug.h"
25#include "stdlibincl.h"
[4726]26#include "load_param.h"
[3930]27
[3655]28using namespace std;
29
30/**
[4836]31 *  standard constructor
[3655]32*/
[4597]33ParticleEngine::ParticleEngine ()
[3655]34{
[4320]35   this->setClassID(CL_PARTICLE_ENGINE, "ParticleEngine");
[4597]36   this->setName("ParticleEngine");
[3655]37
[3931]38   this->systemList = new tList<ParticleSystem>;
[3935]39   this->emitterList = new tList<ParticleEmitter>;
[3932]40   this->connectionList = new tList<ParticleConnection>;
[3655]41}
42
43/**
[4836]44 *  the singleton reference to this class
[3655]45*/
[3923]46ParticleEngine* ParticleEngine::singletonRef = NULL;
[3655]47
48/**
[4836]49 *  deletes all the system, emitters, connections and Lists
[3655]50*/
[4597]51ParticleEngine::~ParticleEngine ()
[3655]52{
[5115]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
[3945]55  // delete all remaining systems
[5115]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;
[3930]76
[3945]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
[3923]83  ParticleEngine::singletonRef = NULL;
[3655]84}
[3931]85
[3945]86/**
[4726]87  \brief loads the ParticleEngines settings and connections between particles and emitters
[4836]88* @param root the XML-element to load this from.
[4726]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/**
[4836]102 *  Adds a System to the System list.
[3945]103
104   this is done automatically when creating a ParticleSystem
105*/
[3932]106void ParticleEngine::addSystem(ParticleSystem* system)
107{
108  this->systemList->add(system);
109}
110
[3945]111/**
[4836]112 *  Adds an emitter to the emitterList
[3945]113
114   this is done automatically when creating a ParticleEmitter
115*/
[3935]116void ParticleEngine::addEmitter(ParticleEmitter* emitter)
117{
118  this->emitterList->add(emitter);
119}
[3932]120
[3931]121/**
[4726]122  \brief Connects a ParticleSystem to a ParticleSystem thus emitting Particles.
[4836]123* @param emitter the Emitter to connect to the System
124* @param system the System to connect to the Emitter
[4726]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/**
[4836]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
[3932]146*/
147void ParticleEngine::addConnection(ParticleEmitter* emitter, ParticleSystem* system)
148{
[3937]149  // look, if we have already added this connection
150  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5115]151  ParticleConnection* tmpConnection = tmpConIt->firstElement();
[3937]152  while(tmpConnection)
153    {
154      if (tmpConnection->emitter == emitter && tmpConnection->system == system)
[4597]155        {
156          PRINTF(2)("Connection between Emitter and System already added\n");
157          delete tmpConIt;
158          return;
159        }
160
[3937]161      tmpConnection = tmpConIt->nextElement();
162    }
163  delete tmpConIt;
164
165
[4597]166
[3932]167  ParticleConnection* tmpCon = new ParticleConnection;
168  tmpCon->emitter = emitter;
169  tmpCon->system = system;
170
171  this->connectionList->add(tmpCon);
172}
173
[3945]174/**
[4836]175 *  Removes a system from the systemList and also removes all Connections to the System
176 * @param system The ParticleSystem to delete
[3945]177*/
[3935]178bool ParticleEngine::removeSystem(ParticleSystem* system)
179{
[3943]180  // remove any connections, that have this system within
181  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5115]182  ParticleConnection* tmpConnection = tmpConIt->firstElement();
[3943]183  while(tmpConnection)
184    {
185      if (tmpConnection->system == system)
[4597]186        this->breakConnection(tmpConnection);
[3943]187      tmpConnection = tmpConIt->nextElement();
188    }
189  delete tmpConIt;
190
191  // remove the System from the systemList.
[3935]192  this->systemList->remove(system);
193}
194
[3945]195/**
[4836]196 *  removes an emitter from the emitterList and also from all Connections it is attached to.
197 * @param emitter the ParticleEmitter to remove.
[3945]198*/
[3935]199bool ParticleEngine::removeEmitter(ParticleEmitter* emitter)
200{
[3943]201  // remove any connections, that have this emitter within
202  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5115]203  ParticleConnection* tmpConnection = tmpConIt->firstElement();
[3943]204  while(tmpConnection)
205    {
206      if (tmpConnection->emitter == emitter)
[4597]207        this->breakConnection(tmpConnection);
[3943]208      tmpConnection = tmpConIt->nextElement();
209    }
210  delete tmpConIt;
211
212  // remove the emitter from the emitterList
[3935]213  this->emitterList->remove(emitter);
214}
215
[3945]216/**
[4836]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
[3935]221
[3945]222   only if both system and emitter are in the connection the Connection will be broken
223*/
[3943]224bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
225{
226  // look, if we have already added this connection
227  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5115]228  ParticleConnection* tmpConnection = tmpConIt->firstElement();
[3943]229  while(tmpConnection)
230    {
[3945]231    if (tmpConnection->emitter == emitter && tmpConnection->system == system)
232      {
[4597]233        this->breakConnection(tmpConnection);
234        delete tmpConIt;
235        return true;
[3945]236      }
237    tmpConnection = tmpConIt->nextElement();
[3943]238    }
[3945]239  delete tmpConIt;
240  return false;
[3943]241}
242
[3945]243/**
[4836]244 *  removes a Connection between an Emitter and a System
245 * @param connection the connection to remove
[3945]246
247   \see bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
248*/
[3943]249bool ParticleEngine::breakConnection(ParticleConnection* connection)
250{
251  this->connectionList->remove(connection);
[3945]252  return true;
[3943]253}
254
255
[3932]256/**
[4836]257 *  this function ticks all the ParticleSystems, so an animation will flow
258 * @param dt passed since last tick
[3931]259*/
260void ParticleEngine::tick(float dt)
261{
[4176]262  // ticks all the ParticleSystems
263  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5115]264  ParticleSystem* tmpSys = tmpIt->firstElement();
[4176]265  while(tmpSys)
266    {
267      tmpSys->tick(dt);
268      tmpSys = tmpIt->nextElement();
269    }
270  delete tmpIt;
271
[3945]272  // add new Particles to each System connected to an Emitter.
[3932]273  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5115]274  ParticleConnection* tmpConnection = tmpConIt->firstElement();
[3932]275  while(tmpConnection)
276    {
277      tmpConnection->emitter->tick(dt, tmpConnection->system);
278      tmpConnection = tmpConIt->nextElement();
279    }
280  delete tmpConIt;
[3931]281}
[3932]282
[3945]283/**
[4836]284 *  draws all the systems and their Particles.
[3945]285*/
[4349]286void ParticleEngine::draw() const
[3932]287{
288  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5115]289  ParticleSystem* tmpSys = tmpIt->firstElement();
[3932]290  while(tmpSys)
291    {
[4349]292      tmpSys->draw();
[3932]293      tmpSys = tmpIt->nextElement();
294    }
295  delete tmpIt;
296
297}
[3944]298
299/**
[4836]300 * @param systemName the name of the system to search for
301 * @returns the system called by systemName or NULL if not found
[4338]302*/
303ParticleSystem* ParticleEngine::getSystemByName(const char* systemName) const
304{
305  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5115]306  ParticleSystem* tmpSys = tmpIt->firstElement();
[4338]307  while(tmpSys)
308    {
309      if (!strcmp(systemName, tmpSys->getName()))
[4597]310        {
311          delete tmpIt;
312          return tmpSys;
313        }
[4338]314      tmpSys = tmpIt->nextElement();
315    }
316  delete tmpIt;
317  return NULL;
318}
319
320/**
[4836]321 * @param number the n-th system to return
322 * @returns the system called by number or NULL if not found
[4338]323*/
324ParticleSystem* ParticleEngine::getSystemByNumber(unsigned int number) const
325{
326  int count = 0;
327  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5115]328  ParticleSystem* tmpSys = tmpIt->firstElement();
[4338]329  while(tmpSys)
330    {
331      count++;
332      if ( count == number)
[4597]333        {
334          delete tmpIt;
335          return tmpSys;
336        }
[4338]337      tmpSys = tmpIt->nextElement();
338    }
339  delete tmpIt;
340  return NULL;
341}
342
343/**
[4836]344 * @param emitterName the name of the emitter to search for
345 * @returns the emitter called by emitterName or NULL if not found
[4338]346*/
347ParticleEmitter* ParticleEngine::getEmitterByName(const char* emitterName) const
348{
349  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
[5115]350  ParticleEmitter* tmpEmit = tmpIt->firstElement();
[4338]351  while(tmpEmit)
352    {
353      if (!strcmp(emitterName, tmpEmit->getName()))
[4597]354        {
355          delete tmpIt;
356          return tmpEmit;
357        }
[4338]358      tmpEmit = tmpIt->nextElement();
359    }
360  delete tmpIt;
361  return NULL;
362}
363
364
365/**
[4836]366 * @param number the n-th emitter to return
367 * @returns the emitter called by number or NULL if not found
[4338]368*/
369ParticleEmitter* ParticleEngine::getEmitterByNumber(unsigned int number) const
370{
371  int count = 0;
372  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
[5115]373  ParticleEmitter* tmpEmit = tmpIt->firstElement();
[4338]374  while(tmpEmit)
375    {
376      count++;
377      if ( count == number)
[4597]378        {
379          delete tmpIt;
380          return tmpEmit;
381        }
[4338]382      tmpEmit = tmpIt->nextElement();
383    }
384  delete tmpIt;
385  return NULL;
386}
387
388/**
[4836]389 *  outputs some nice debug information
[3944]390*/
[4746]391void ParticleEngine::debug()
[3944]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",
[4639]398  this->emitterList->getSize(), this->systemList->getSize(), this->connectionList->getSize());
399
[3944]400  if (this->connectionList->getSize() > 0)
[4639]401  {
402    PRINT(0)(" Connections:\n");
403    PRINT(0)(" -----------------------------------\n");
404
405    tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5115]406    ParticleConnection* tmpConnection = tmpConIt->firstElement();
[4639]407    while(tmpConnection)
[3944]408    {
[4639]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  }
[3944]414
415  if (this->systemList->getSize() > 0)
[4639]416  {
417    tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5115]418    ParticleSystem* tmpSys = tmpIt->firstElement();
[4639]419    while(tmpSys)
[3944]420    {
[4639]421      tmpSys->debug();
422      tmpSys = tmpIt->nextElement();
[3944]423    }
[4639]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();
[5115]433    ParticleEmitter* tmpEmit = tmpIt->firstElement();
[4639]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  }
[3944]445
446  PRINT(0)("+--------------------------------PE-+\n");
447
448}
Note: See TracBrowser for help on using the repository browser.