Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: reverted the last steps, because they created a huge pack of seg-faults

File size: 11.9 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{
[3945]53  // delete all remaining systems
54  tIterator<ParticleSystem>* sysIt = this->systemList->getIterator();
[5111]55  ParticleSystem* tmpSys = sysIt->nextElement();
[3945]56  while(tmpSys)
57    {
58      delete tmpSys;
59      tmpSys = sysIt->nextElement();
60    }
61  delete sysIt;
[3931]62  delete this->systemList;
[3930]63
[3945]64  // delete all remaining emitters
65  tIterator<ParticleEmitter>* emitIt = this->emitterList->getIterator();
[5111]66  ParticleEmitter* tmpEmit = emitIt->nextElement();
[3945]67  while(tmpEmit)
68    {
69      delete tmpEmit;
70      tmpEmit = emitIt->nextElement();
71    }
72  delete emitIt;
73  delete this->emitterList;
[3930]74
[3945]75  // there should be no more Connections
76  if (this->connectionList->getSize() == 0)
77    delete this->connectionList;
78  else
79    PRINTF(2)("The Connection List is not empty. This should not happen.\n");
80
[3923]81  ParticleEngine::singletonRef = NULL;
[3655]82}
[3931]83
[3945]84/**
[4726]85  \brief loads the ParticleEngines settings and connections between particles and emitters
[4836]86* @param root the XML-element to load this from.
[4726]87 */
88void ParticleEngine::loadParams(const TiXmlElement* root)
89{
90  const TiXmlElement* element = root->FirstChildElement();
91  while( element != NULL)
92  {
93    LoadParam<ParticleEngine>(element, "connect", this, &ParticleEngine::addConnection, true)
94        .describe("connects an Emitter to a System (emitterName, systemName)");
95    element = element->NextSiblingElement();
96  }
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/**
[4726]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*/
124void ParticleEngine::addConnection(const char* emitter, const char* system)
125{
126  ParticleEmitter* tmpEmit = this->getEmitterByName(emitter);
127  ParticleSystem* tmpSys = this->getSystemByName(system);
128
129  if (tmpEmit != NULL && tmpSys != NULL)
130    this->addConnection(tmpEmit, tmpSys);
131  else
132  {
133    if (tmpEmit == NULL)
134      PRINTF(2)("Emitter %s not found in the List of emitters, not connecting to %s\n", emitter, system);
135    if (tmpEmit == NULL)
136      PRINTF(2)("System %s not found in the List of emitters, not connecting to %s\n", system, emitter);
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();
[5111]149  ParticleConnection* tmpConnection = tmpConIt->nextElement();
[3937]150  while(tmpConnection)
151    {
152      if (tmpConnection->emitter == emitter && tmpConnection->system == system)
[4597]153        {
154          PRINTF(2)("Connection between Emitter and System already added\n");
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();
[5111]180  ParticleConnection* tmpConnection = tmpConIt->nextElement();
[3943]181  while(tmpConnection)
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();
[5111]201  ParticleConnection* tmpConnection = tmpConIt->nextElement();
[3943]202  while(tmpConnection)
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
[3945]214/**
[4836]215 *  removes a Connection between an Emitter and a System
216 * @param emitter The emitter of the connection to remove
217 * @param system The system of the connection to remove
218 * @returns true, if the connection was broken, false if the conntection was not found
[3935]219
[3945]220   only if both system and emitter are in the connection the Connection will be broken
221*/
[3943]222bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
223{
224  // look, if we have already added this connection
225  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5111]226  ParticleConnection* tmpConnection = tmpConIt->nextElement();
[3943]227  while(tmpConnection)
228    {
[3945]229    if (tmpConnection->emitter == emitter && tmpConnection->system == system)
230      {
[4597]231        this->breakConnection(tmpConnection);
232        delete tmpConIt;
233        return true;
[3945]234      }
235    tmpConnection = tmpConIt->nextElement();
[3943]236    }
[3945]237  delete tmpConIt;
238  return false;
[3943]239}
240
[3945]241/**
[4836]242 *  removes a Connection between an Emitter and a System
243 * @param connection the connection to remove
[3945]244
245   \see bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
246*/
[3943]247bool ParticleEngine::breakConnection(ParticleConnection* connection)
248{
249  this->connectionList->remove(connection);
[3945]250  return true;
[3943]251}
252
253
[3932]254/**
[4836]255 *  this function ticks all the ParticleSystems, so an animation will flow
256 * @param dt passed since last tick
[3931]257*/
258void ParticleEngine::tick(float dt)
259{
[4176]260  // ticks all the ParticleSystems
261  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5111]262  ParticleSystem* tmpSys = tmpIt->nextElement();
[4176]263  while(tmpSys)
264    {
265      tmpSys->tick(dt);
266      tmpSys = tmpIt->nextElement();
267    }
268  delete tmpIt;
269
[3945]270  // add new Particles to each System connected to an Emitter.
[3932]271  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5111]272  ParticleConnection* tmpConnection = tmpConIt->nextElement();
[3932]273  while(tmpConnection)
274    {
275      tmpConnection->emitter->tick(dt, tmpConnection->system);
276      tmpConnection = tmpConIt->nextElement();
277    }
278  delete tmpConIt;
[3931]279}
[3932]280
[3945]281/**
[4836]282 *  draws all the systems and their Particles.
[3945]283*/
[4349]284void ParticleEngine::draw() const
[3932]285{
286  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5111]287  ParticleSystem* tmpSys = tmpIt->nextElement();
[3932]288  while(tmpSys)
289    {
[4349]290      tmpSys->draw();
[3932]291      tmpSys = tmpIt->nextElement();
292    }
293  delete tmpIt;
294
295}
[3944]296
297/**
[4836]298 * @param systemName the name of the system to search for
299 * @returns the system called by systemName or NULL if not found
[4338]300*/
301ParticleSystem* ParticleEngine::getSystemByName(const char* systemName) const
302{
303  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5111]304  ParticleSystem* tmpSys = tmpIt->nextElement();
[4338]305  while(tmpSys)
306    {
307      if (!strcmp(systemName, tmpSys->getName()))
[4597]308        {
309          delete tmpIt;
310          return tmpSys;
311        }
[4338]312      tmpSys = tmpIt->nextElement();
313    }
314  delete tmpIt;
315  return NULL;
316}
317
318/**
[4836]319 * @param number the n-th system to return
320 * @returns the system called by number or NULL if not found
[4338]321*/
322ParticleSystem* ParticleEngine::getSystemByNumber(unsigned int number) const
323{
324  int count = 0;
325  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5111]326  ParticleSystem* tmpSys = tmpIt->nextElement();
[4338]327  while(tmpSys)
328    {
329      count++;
330      if ( count == number)
[4597]331        {
332          delete tmpIt;
333          return tmpSys;
334        }
[4338]335      tmpSys = tmpIt->nextElement();
336    }
337  delete tmpIt;
338  return NULL;
339}
340
341/**
[4836]342 * @param emitterName the name of the emitter to search for
343 * @returns the emitter called by emitterName or NULL if not found
[4338]344*/
345ParticleEmitter* ParticleEngine::getEmitterByName(const char* emitterName) const
346{
347  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
[5111]348  ParticleEmitter* tmpEmit = tmpIt->nextElement();
[4338]349  while(tmpEmit)
350    {
351      if (!strcmp(emitterName, tmpEmit->getName()))
[4597]352        {
353          delete tmpIt;
354          return tmpEmit;
355        }
[4338]356      tmpEmit = tmpIt->nextElement();
357    }
358  delete tmpIt;
359  return NULL;
360}
361
362
363/**
[4836]364 * @param number the n-th emitter to return
365 * @returns the emitter called by number or NULL if not found
[4338]366*/
367ParticleEmitter* ParticleEngine::getEmitterByNumber(unsigned int number) const
368{
369  int count = 0;
370  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
[5111]371  ParticleEmitter* tmpEmit = tmpIt->nextElement();
[4338]372  while(tmpEmit)
373    {
374      count++;
375      if ( count == number)
[4597]376        {
377          delete tmpIt;
378          return tmpEmit;
379        }
[4338]380      tmpEmit = tmpIt->nextElement();
381    }
382  delete tmpIt;
383  return NULL;
384}
385
386/**
[4836]387 *  outputs some nice debug information
[3944]388*/
[4746]389void ParticleEngine::debug()
[3944]390{
391  PRINT(0)("+-----------------------------------+\n");
392  PRINT(0)("+ PARTICLE-ENGINE DEBUG INFORMATION +\n");
393  PRINT(0)("+-----------------------------------+\n");
394  PRINT(0)(" Reference: %p\n", ParticleEngine::singletonRef);
395  PRINT(0)(" Count: Emitters: %d; Systems: %d, Connections: %d\n",
[4639]396  this->emitterList->getSize(), this->systemList->getSize(), this->connectionList->getSize());
397
[3944]398  if (this->connectionList->getSize() > 0)
[4639]399  {
400    PRINT(0)(" Connections:\n");
401    PRINT(0)(" -----------------------------------\n");
402
403    tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
[5111]404    ParticleConnection* tmpConnection = tmpConIt->nextElement();
[4639]405    while(tmpConnection)
[3944]406    {
[4639]407      PRINT(0)(" Emitter '%s' emitts into System '%s'\n", tmpConnection->emitter->getName(), tmpConnection->system->getName());
408      tmpConnection = tmpConIt->nextElement();
409    }
410    delete tmpConIt;
411  }
[3944]412
413  if (this->systemList->getSize() > 0)
[4639]414  {
415    tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
[5111]416    ParticleSystem* tmpSys = tmpIt->nextElement();
[4639]417    while(tmpSys)
[3944]418    {
[4639]419      tmpSys->debug();
420      tmpSys = tmpIt->nextElement();
[3944]421    }
[4639]422    delete tmpIt;
423  }
424  else
425  {
426    PRINT(0)("NO SYSTEMS\n");
427  }
428  if (this->emitterList->getSize() > 0)
429  {
430    tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
[5111]431    ParticleEmitter* tmpEmit = tmpIt->nextElement();
[4639]432    while(tmpEmit)
433    {
434      tmpEmit->debug();
435      tmpEmit = tmpIt->nextElement();
436    }
437    delete tmpIt;
438  }
439  else
440  {
441    PRINTF(0)("NO EMITTERS\n");
442  }
[3944]443
444  PRINT(0)("+--------------------------------PE-+\n");
445
446}
Note: See TracBrowser for help on using the repository browser.