Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4506 was 4478, checked in by bensch, 20 years ago

orxonox/trunk: particles documented

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