Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more std::string

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