// Filename: particleSystemManager.cxx // Created by: charles (28Jun00) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // // All use of this software is subject to the terms of the revised BSD // license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #include "particleSystemManager.h" #include "particleSystem.h" #include "pandabase.h" #include "physicsManager.h" #include "clockObject.h" #include "pStatTimer.h" #include PStatCollector ParticleSystemManager::_do_particles_collector("App:Particles:Do Particles"); //////////////////////////////////////////////////////////////////// // Function : ParticleSystemManager // Access : public // Description : default constructor //////////////////////////////////////////////////////////////////// ParticleSystemManager:: ParticleSystemManager(int every_nth_frame) : _nth_frame(every_nth_frame), _cur_frame(0) { } //////////////////////////////////////////////////////////////////// // Function : ParticleSystemManager // Access : Public, Virtual // Description : Destructor //////////////////////////////////////////////////////////////////// ParticleSystemManager:: ~ParticleSystemManager() { } //////////////////////////////////////////////////////////////////// // Function : remove_particlesystem // Access : public // Description : removes a ps from the maintenance list //////////////////////////////////////////////////////////////////// void ParticleSystemManager:: remove_particlesystem(ParticleSystem *ps) { plist< PT(ParticleSystem) >::iterator found; PT(ParticleSystem) ptps = ps; found = find(_ps_list.begin(), _ps_list.end(), ptps); if (found == _ps_list.end()) return; _ps_list.erase(found); } //////////////////////////////////////////////////////////////////// // Function : do_particles // Access : public // Description : does an update and render for each ps in the list. // this is probably the one you want to use. Rendering // is the expensive operation, and particles REALLY // should at least be updated every frame, so nth_frame // stepping applies only to rendering. //////////////////////////////////////////////////////////////////// void ParticleSystemManager:: do_particles(PN_stdfloat dt) { // cout << "ParticlesystemManager::doparticles entering." << endl; PStatTimer t1(_do_particles_collector); plist< PT(ParticleSystem) >::iterator cur; bool render_due = false; _cur_frame++; if (_cur_frame >= _nth_frame) { _cur_frame = 0; render_due = true; } cur = _ps_list.begin(); // cout << "PSM::do_particles on a vector of size " << _ps_list.size() << endl; // int cs = 0; while (cur != _ps_list.end()) { ParticleSystem *cur_ps = *cur; // update this system if (cur_ps->get_active_system_flag() == true) { // cout << " system " << cs++ << endl; // cout << " count is: " << cur_ps->get_render_parent()->get_ref_count() << endl; cur_ps->update(dt); // Handle age: if (cur_ps->get_system_grows_older_flag() == true) { PN_stdfloat age = cur_ps->get_system_age() + dt; cur_ps->set_system_age(age); // handle death if (age >= cur_ps->get_system_lifespan()) { plist< PT(ParticleSystem) >::iterator kill = cur; ++cur; _ps_list.erase(kill); render_due = false; } } // handle render if (render_due) { cur_ps->render(); } } if (cur != _ps_list.end()) { ++cur; } } // cout << "PSM::do_particles finished." << endl; // cout << "ParticleSystemManager::doparticles exiting." << endl; } //////////////////////////////////////////////////////////////////// // Function : do_particles // Access : public // Description : does an update and an optional render for a specific // ps. Since rendering is the expensive operation, multiple // updates could be applied before calling the final render. //////////////////////////////////////////////////////////////////// void ParticleSystemManager:: do_particles(PN_stdfloat dt, ParticleSystem *ps, bool do_render) { if (ps->get_active_system_flag() == true) { ps->update(dt); // Handle age: if (ps->get_system_grows_older_flag() == true) { PN_stdfloat age = ps->get_system_age() + dt; ps->set_system_age(age); } // handle render if (do_render) { ps->render(); } } } //////////////////////////////////////////////////////////////////// // Function : output // Access : Public // Description : Write a string representation of this instance to // . //////////////////////////////////////////////////////////////////// void ParticleSystemManager:: output(ostream &out) const { #ifndef NDEBUG //[ out<<"ParticleSystemManager"; #endif //] NDEBUG } //////////////////////////////////////////////////////////////////// // Function : write_ps_list // Access : Public // Description : Write a string representation of this instance to // . //////////////////////////////////////////////////////////////////// void ParticleSystemManager:: write_ps_list(ostream &out, int indent) const { #ifndef NDEBUG //[ out.width(indent); out<<""<<"_ps_list ("<<_ps_list.size()<<" systems)\n"; for (plist< PT(ParticleSystem) >::const_iterator i=_ps_list.begin(); i != _ps_list.end(); ++i) { (*i)->write(out, indent+2); } #endif //] NDEBUG } //////////////////////////////////////////////////////////////////// // Function : write // Access : Public // Description : Write a string representation of this instance to // . //////////////////////////////////////////////////////////////////// void ParticleSystemManager:: write(ostream &out, int indent) const { #ifndef NDEBUG //[ out.width(indent); out<<""; out<<"ParticleSystemManager:\n"; out.width(indent+2); out<<""; out<<"_nth_frame "<<_nth_frame<<"\n"; out.width(indent+2); out<<""; out<<"_cur_frame "<<_cur_frame<<"\n"; write_ps_list(out, indent+2); #endif //] NDEBUG }