Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more std::string

File size: 12.6 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 "class_list.h"
21
22#include "debug.h"
23#include "stdlibincl.h"
24#include "util/loading/load_param.h"
25
26using namespace std;
27
28/**
29 *  standard constructor
30*/
31ParticleEngine::ParticleEngine ()
32{
33   this->setClassID(CL_PARTICLE_ENGINE, "ParticleEngine");
34   this->setName("ParticleEngine");
35
36   this->systemList = new tList<ParticleSystem>;
37   this->emitterList = new tList<ParticleEmitter>;
38   this->connectionList = new tList<ParticleConnection>;
39}
40
41/**
42 *  the singleton reference to this class
43*/
44ParticleEngine* ParticleEngine::singletonRef = NULL;
45
46/**
47 *  deletes all the system, emitters, connections and Lists
48*/
49ParticleEngine::~ParticleEngine ()
50{
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
54  // delete all remaining systems
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//
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;
74   delete this->emitterList;
75
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
82  ParticleEngine::singletonRef = NULL;
83}
84
85/**
86  \brief loads the ParticleEngines settings and connections between particles and emitters
87* @param root the XML-element to load this from.
88 */
89void ParticleEngine::loadParams(const TiXmlElement* root)
90{
91  LOAD_PARAM_START_CYCLE(root, element);
92  {
93    LoadParam_CYCLE(element, "connect", this, ParticleEngine, addConnection)
94        .describe("connects an Emitter to a System (emitterName, systemName)");
95  }
96  LOAD_PARAM_END_CYCLE(element);
97}
98
99/**
100 *  Adds a System to the System list.
101
102   this is done automatically when creating a ParticleSystem
103*/
104void ParticleEngine::addSystem(ParticleSystem* system)
105{
106  this->systemList->add(system);
107}
108
109/**
110 *  Adds an emitter to the emitterList
111
112   this is done automatically when creating a ParticleEmitter
113*/
114void ParticleEngine::addEmitter(ParticleEmitter* emitter)
115{
116  this->emitterList->add(emitter);
117}
118
119/**
120* @brief Connects a ParticleSystem to a ParticleSystem thus emitting Particles.
121* @param emitter the Emitter to connect to the System
122* @param system the System to connect to the Emitter
123*/
124void ParticleEngine::addConnection(const std::string& emitter, const std::string& system)
125{
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);
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.c_str(), system.c_str());
135    if (tmpEmit == NULL)
136      PRINTF(2)("System %s not found in the List of emitters, not connecting to %s\n", system.c_str(), emitter.c_str());
137  }
138}
139
140/**
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
144*/
145void ParticleEngine::addConnection(ParticleEmitter* emitter, ParticleSystem* system)
146{
147  // look, if we have already added this connection
148  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
149  ParticleConnection* tmpConnection = tmpConIt->firstElement();
150  while(tmpConnection)
151    {
152      if (tmpConnection->emitter == emitter && tmpConnection->system == system)
153        {
154          PRINTF(2)("Connection between Emitter and System already exists.\n");
155          delete tmpConIt;
156          return;
157        }
158
159      tmpConnection = tmpConIt->nextElement();
160    }
161  delete tmpConIt;
162
163
164
165  ParticleConnection* tmpCon = new ParticleConnection;
166  tmpCon->emitter = emitter;
167  tmpCon->system = system;
168
169  this->connectionList->add(tmpCon);
170}
171
172/**
173 *  Removes a system from the systemList and also removes all Connections to the System
174 * @param system The ParticleSystem to delete
175*/
176bool ParticleEngine::removeSystem(ParticleSystem* system)
177{
178  // remove any connections, that have this system within
179  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
180  ParticleConnection* tmpConnection = tmpConIt->firstElement();
181  while(tmpConnection != NULL)
182    {
183      if (tmpConnection->system == system)
184        this->breakConnection(tmpConnection);
185      tmpConnection = tmpConIt->nextElement();
186    }
187  delete tmpConIt;
188
189  // remove the System from the systemList.
190  this->systemList->remove(system);
191}
192
193/**
194 *  removes an emitter from the emitterList and also from all Connections it is attached to.
195 * @param emitter the ParticleEmitter to remove.
196*/
197bool ParticleEngine::removeEmitter(ParticleEmitter* emitter)
198{
199  // remove any connections, that have this emitter within
200  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
201  ParticleConnection* tmpConnection = tmpConIt->firstElement();
202  while(tmpConnection != NULL)
203    {
204      if (tmpConnection->emitter == emitter)
205        this->breakConnection(tmpConnection);
206      tmpConnection = tmpConIt->nextElement();
207    }
208  delete tmpConIt;
209
210  // remove the emitter from the emitterList
211  this->emitterList->remove(emitter);
212}
213
214
215/**
216 *  removes a Connection between an Emitter and a System
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
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
232 *
233 * only if both system and emitter are in the connection the Connection will be broken
234*/
235bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
236{
237  // look, if we have already added this connection
238  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
239  ParticleConnection* tmpConnection = tmpConIt->firstElement();
240  while(tmpConnection)
241    {
242    if (tmpConnection->emitter == emitter && tmpConnection->system == system)
243      {
244        this->breakConnection(tmpConnection);
245        delete tmpConIt;
246        return true;
247      }
248    tmpConnection = tmpConIt->nextElement();
249    }
250  delete tmpConIt;
251  return false;
252}
253
254/**
255 *  removes a Connection between an Emitter and a System
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)
260{
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;
276}
277
278
279/**
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/**
304 *  this function ticks all the ParticleSystems, so an animation will flow
305 * @param dt passed since last tick
306*/
307void ParticleEngine::tick(float dt)
308{
309  // ticks all the ParticleSystems
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;
318
319  // add new Particles to each System connected to an Emitter.
320  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
321  ParticleConnection* tmpConnection = tmpConIt->firstElement();
322  while(tmpConnection)
323    {
324      tmpConnection->emitter->tick(dt, tmpConnection->system);
325      tmpConnection = tmpConIt->nextElement();
326    }
327  delete tmpConIt;
328}
329
330/**
331 *  draws all the systems and their Particles.
332*/
333void ParticleEngine::draw() const
334{
335  /*
336  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
337  ParticleSystem* tmpSys = tmpIt->firstElement();
338  while(tmpSys)
339    {
340      tmpSys->draw();
341      tmpSys = tmpIt->nextElement();
342    }
343  delete tmpIt;*/
344
345}
346
347/**
348 * @param number the n-th system to return
349 * @returns the system called by number or NULL if not found
350*/
351ParticleSystem* ParticleEngine::getSystemByNumber(unsigned int number) const
352{
353  int count = 0;
354  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
355  ParticleSystem* tmpSys = tmpIt->firstElement();
356  while(tmpSys)
357    {
358      count++;
359      if ( count == number)
360        {
361          delete tmpIt;
362          return tmpSys;
363        }
364      tmpSys = tmpIt->nextElement();
365    }
366  delete tmpIt;
367  return NULL;
368}
369
370/**
371 * @param number the n-th emitter to return
372 * @returns the emitter called by number or NULL if not found
373*/
374ParticleEmitter* ParticleEngine::getEmitterByNumber(unsigned int number) const
375{
376  int count = 0;
377  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
378  ParticleEmitter* tmpEmit = tmpIt->firstElement();
379  while(tmpEmit)
380    {
381      count++;
382      if ( count == number)
383        {
384          delete tmpIt;
385          return tmpEmit;
386        }
387      tmpEmit = tmpIt->nextElement();
388    }
389  delete tmpIt;
390  return NULL;
391}
392
393/**
394 *  outputs some nice debug information
395*/
396void ParticleEngine::debug()
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",
403  this->emitterList->getSize(), this->systemList->getSize(), this->connectionList->getSize());
404
405  if (this->connectionList->getSize() > 0)
406  {
407    PRINT(0)(" Connections:\n");
408    PRINT(0)(" -----------------------------------\n");
409
410    tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
411    ParticleConnection* tmpConnection = tmpConIt->firstElement();
412    while(tmpConnection)
413    {
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  }
419
420  if (this->systemList->getSize() > 0)
421  {
422    tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
423    ParticleSystem* tmpSys = tmpIt->firstElement();
424    while(tmpSys)
425    {
426      tmpSys->debug();
427      tmpSys = tmpIt->nextElement();
428    }
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();
438    ParticleEmitter* tmpEmit = tmpIt->firstElement();
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  }
450
451  PRINT(0)("+--------------------------------PE-+\n");
452
453}
454
Note: See TracBrowser for help on using the repository browser.