Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Connection-Removing in the Particle-Class

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