Panda3D

particleSystemManager.cxx

00001 // Filename: particleSystemManager.cxx
00002 // Created by:  charles (28Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "particleSystemManager.h"
00016 #include "particleSystem.h"
00017 
00018 #include "pandabase.h"
00019 #include "physicsManager.h"
00020 #include "clockObject.h"
00021 #include "pStatTimer.h"
00022 
00023 #include <algorithm>
00024 
00025 PStatCollector ParticleSystemManager::_do_particles_collector("App:Particles:Do Particles");
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //    Function : ParticleSystemManager
00029 //      Access : public
00030 // Description : default constructor
00031 ////////////////////////////////////////////////////////////////////
00032 ParticleSystemManager::
00033 ParticleSystemManager(int every_nth_frame) :
00034   _nth_frame(every_nth_frame), _cur_frame(0) {
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //    Function : ParticleSystemManager
00039 //      Access : Public, Virtual
00040 // Description : Destructor
00041 ////////////////////////////////////////////////////////////////////
00042 ParticleSystemManager::
00043 ~ParticleSystemManager() {
00044 }
00045 
00046 ////////////////////////////////////////////////////////////////////
00047 //    Function : remove_particlesystem
00048 //      Access : public
00049 // Description : removes a ps from the maintenance list
00050 ////////////////////////////////////////////////////////////////////
00051 void ParticleSystemManager::
00052 remove_particlesystem(ParticleSystem *ps) {
00053   plist< PT(ParticleSystem) >::iterator found;
00054 
00055   PT(ParticleSystem) ptps = ps;
00056   found = find(_ps_list.begin(), _ps_list.end(), ptps);
00057 
00058   if (found == _ps_list.end())
00059     return;
00060 
00061   _ps_list.erase(found);
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //    Function : do_particles
00066 //      Access : public
00067 // Description : does an update and render for each ps in the list.
00068 //               this is probably the one you want to use.  Rendering
00069 //               is the expensive operation, and particles REALLY
00070 //               should at least be updated every frame, so nth_frame
00071 //               stepping applies only to rendering.
00072 ////////////////////////////////////////////////////////////////////
00073 void ParticleSystemManager::
00074 do_particles(PN_stdfloat dt) {
00075   //  cout << "ParticlesystemManager::doparticles entering." << endl;
00076   PStatTimer t1(_do_particles_collector);
00077 
00078   plist< PT(ParticleSystem) >::iterator cur;
00079 
00080   bool render_due = false;
00081 
00082   _cur_frame++;
00083 
00084   if (_cur_frame >= _nth_frame) {
00085     _cur_frame = 0;
00086     render_due = true;
00087   }
00088 
00089   cur = _ps_list.begin();
00090 
00091   //  cout << "PSM::do_particles on a vector of size " << _ps_list.size() << endl;
00092   //  int cs = 0;
00093 
00094   while (cur != _ps_list.end()) {
00095     ParticleSystem *cur_ps = *cur;
00096 
00097     // update this system
00098     if (cur_ps->get_active_system_flag() == true) {
00099       //      cout << "  system " << cs++ << endl;
00100       //      cout << "  count is: " << cur_ps->get_render_parent()->get_ref_count() << endl;
00101       cur_ps->update(dt);
00102 
00103       // Handle age:
00104       if (cur_ps->get_system_grows_older_flag() == true) {
00105         PN_stdfloat age = cur_ps->get_system_age() + dt;
00106         cur_ps->set_system_age(age);
00107 
00108         // handle death
00109         if (age >= cur_ps->get_system_lifespan()) {
00110           plist< PT(ParticleSystem) >::iterator kill = cur;
00111           ++cur;
00112 
00113           _ps_list.erase(kill);
00114           render_due = false;
00115         }
00116       }
00117 
00118       // handle render
00119       if (render_due) {
00120         cur_ps->render();
00121       }
00122     }
00123 
00124     if (cur != _ps_list.end()) {
00125       ++cur;
00126     }
00127   }
00128   //  cout << "PSM::do_particles finished." << endl;
00129   //  cout << "ParticleSystemManager::doparticles exiting." << endl;
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //    Function : do_particles
00134 //      Access : public
00135 // Description : does an update and an optional render for a specific
00136 //               ps.  Since rendering is the expensive operation, multiple
00137 //               updates could be applied before calling the final render.
00138 ////////////////////////////////////////////////////////////////////
00139 void ParticleSystemManager::
00140 do_particles(PN_stdfloat dt, ParticleSystem *ps, bool do_render) {
00141   if (ps->get_active_system_flag() == true) {
00142     ps->update(dt);
00143     // Handle age:
00144     if (ps->get_system_grows_older_flag() == true) {
00145       PN_stdfloat age = ps->get_system_age() + dt;
00146       ps->set_system_age(age);
00147     }
00148     
00149     // handle render
00150     if (do_render) {
00151       ps->render();
00152     }
00153   }
00154 }
00155 
00156 ////////////////////////////////////////////////////////////////////
00157 //     Function : output
00158 //       Access : Public
00159 //  Description : Write a string representation of this instance to
00160 //                <out>.
00161 ////////////////////////////////////////////////////////////////////
00162 void ParticleSystemManager::
00163 output(ostream &out) const {
00164   #ifndef NDEBUG //[
00165   out<<"ParticleSystemManager";
00166   #endif //] NDEBUG
00167 }
00168 
00169 ////////////////////////////////////////////////////////////////////
00170 //     Function : write_ps_list
00171 //       Access : Public
00172 //  Description : Write a string representation of this instance to
00173 //                <out>.
00174 ////////////////////////////////////////////////////////////////////
00175 void ParticleSystemManager::
00176 write_ps_list(ostream &out, int indent) const {
00177   #ifndef NDEBUG //[
00178   out.width(indent);
00179   out<<""<<"_ps_list ("<<_ps_list.size()<<" systems)\n";
00180   for (plist< PT(ParticleSystem) >::const_iterator i=_ps_list.begin();
00181        i != _ps_list.end();
00182        ++i) {
00183     (*i)->write(out, indent+2);
00184   }
00185   #endif //] NDEBUG
00186 }
00187 
00188 ////////////////////////////////////////////////////////////////////
00189 //     Function : write
00190 //       Access : Public
00191 //  Description : Write a string representation of this instance to
00192 //                <out>.
00193 ////////////////////////////////////////////////////////////////////
00194 void ParticleSystemManager::
00195 write(ostream &out, int indent) const {
00196   #ifndef NDEBUG //[
00197   out.width(indent); out<<""; out<<"ParticleSystemManager:\n";
00198   out.width(indent+2); out<<""; out<<"_nth_frame "<<_nth_frame<<"\n";
00199   out.width(indent+2); out<<""; out<<"_cur_frame "<<_cur_frame<<"\n";
00200   write_ps_list(out, indent+2);
00201   #endif //] NDEBUG
00202 }
 All Classes Functions Variables Enumerations