Panda3D
particleSystemManager.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file particleSystemManager.cxx
10  * @author charles
11  * @date 2000-06-28
12  */
13 
14 #include "particleSystemManager.h"
15 #include "particleSystem.h"
16 
17 #include "pandabase.h"
18 #include "physicsManager.h"
19 #include "clockObject.h"
20 #include "pStatTimer.h"
21 
22 #include <algorithm>
23 
24 PStatCollector ParticleSystemManager::_do_particles_collector("App:Particles:Do Particles");
25 
26 /**
27  * default constructor
28  */
30 ParticleSystemManager(int every_nth_frame) :
31  _nth_frame(every_nth_frame), _cur_frame(0) {
32 }
33 
34 /**
35  * Destructor
36  */
39 }
40 
41 /**
42  * removes a ps from the maintenance list
43  */
46  plist< PT(ParticleSystem) >::iterator found;
47 
48  PT(ParticleSystem) ptps = ps;
49  found = find(_ps_list.begin(), _ps_list.end(), ptps);
50 
51  if (found == _ps_list.end())
52  return;
53 
54  _ps_list.erase(found);
55 }
56 
57 /**
58  * does an update and render for each ps in the list. this is probably the
59  * one you want to use. Rendering is the expensive operation, and particles
60  * REALLY should at least be updated every frame, so nth_frame stepping
61  * applies only to rendering.
62  */
64 do_particles(PN_stdfloat dt) {
65  // cout << "ParticlesystemManager::doparticles entering." << endl;
66  PStatTimer t1(_do_particles_collector);
67 
68  plist< PT(ParticleSystem) >::iterator cur;
69 
70  bool render_due = false;
71 
72  _cur_frame++;
73 
74  if (_cur_frame >= _nth_frame) {
75  _cur_frame = 0;
76  render_due = true;
77  }
78 
79  cur = _ps_list.begin();
80 
81  // cout << "PSM::do_particles on a vector of size " << _ps_list.size() <<
82  // endl; int cs = 0;
83 
84  while (cur != _ps_list.end()) {
85  ParticleSystem *cur_ps = *cur;
86 
87  // update this system
88  if (cur_ps->get_active_system_flag() == true) {
89  // cout << " system " << cs++ << endl; cout << " count is: " <<
90  // cur_ps->get_render_parent()->get_ref_count() << endl;
91  cur_ps->update(dt);
92 
93  // Handle age:
94  if (cur_ps->get_system_grows_older_flag() == true) {
95  PN_stdfloat age = cur_ps->get_system_age() + dt;
96  cur_ps->set_system_age(age);
97 
98  // handle death
99  if (age >= cur_ps->get_system_lifespan()) {
100  plist< PT(ParticleSystem) >::iterator kill = cur;
101  ++cur;
102 
103  _ps_list.erase(kill);
104  render_due = false;
105  }
106  }
107 
108  // handle render
109  if (render_due) {
110  cur_ps->render();
111  }
112  }
113 
114  if (cur != _ps_list.end()) {
115  ++cur;
116  }
117  }
118  // cout << "PSM::do_particles finished." << endl; cout <<
119  // "ParticleSystemManager::doparticles exiting." << endl;
120 }
121 
122 /**
123  * does an update and an optional render for a specific ps. Since rendering
124  * is the expensive operation, multiple updates could be applied before
125  * calling the final render.
126  */
128 do_particles(PN_stdfloat dt, ParticleSystem *ps, bool do_render) {
129  if (ps->get_active_system_flag() == true) {
130  ps->update(dt);
131  // Handle age:
132  if (ps->get_system_grows_older_flag() == true) {
133  PN_stdfloat age = ps->get_system_age() + dt;
134  ps->set_system_age(age);
135  }
136 
137  // handle render
138  if (do_render) {
139  ps->render();
140  }
141  }
142 }
143 
144 /**
145  * Write a string representation of this instance to <out>.
146  */
148 output(std::ostream &out) const {
149  #ifndef NDEBUG //[
150  out<<"ParticleSystemManager";
151  #endif //] NDEBUG
152 }
153 
154 /**
155  * Write a string representation of this instance to <out>.
156  */
158 write_ps_list(std::ostream &out, int indent) const {
159  #ifndef NDEBUG //[
160  out.width(indent);
161  out<<""<<"_ps_list ("<<_ps_list.size()<<" systems)\n";
162  for (plist< PT(ParticleSystem) >::const_iterator i=_ps_list.begin();
163  i != _ps_list.end();
164  ++i) {
165  (*i)->write(out, indent+2);
166  }
167  #endif //] NDEBUG
168 }
169 
170 /**
171  * Write a string representation of this instance to <out>.
172  */
174 write(std::ostream &out, int indent) const {
175  #ifndef NDEBUG //[
176  out.width(indent); out<<""; out<<"ParticleSystemManager:\n";
177  out.width(indent+2); out<<""; out<<"_nth_frame "<<_nth_frame<<"\n";
178  out.width(indent+2); out<<""; out<<"_cur_frame "<<_cur_frame<<"\n";
179  write_ps_list(out, indent+2);
180  #endif //] NDEBUG
181 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void remove_particlesystem(ParticleSystem *ps)
removes a ps from the maintenance list
void do_particles(PN_stdfloat dt)
does an update and render for each ps in the list.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void output(std::ostream &out) const
Write a string representation of this instance to <out>.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:30
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL list.
Definition: plist.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
A lightweight class that represents a single element that may be timed and/or counted via stats.
Contains and manages a particle system.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
virtual void write_ps_list(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
ParticleSystemManager(int every_nth_frame=1)
default constructor
void update(PN_stdfloat dt)
Updates the particle system.
void render()
Populates an attached GeomNode structure with the particle geometry for rendering.
virtual ~ParticleSystemManager()
Destructor.