Panda3D
|
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 }