Panda3D
particleSystemManager.cxx
1 // Filename: particleSystemManager.cxx
2 // Created by: charles (28Jun00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "particleSystemManager.h"
16 #include "particleSystem.h"
17 
18 #include "pandabase.h"
19 #include "physicsManager.h"
20 #include "clockObject.h"
21 #include "pStatTimer.h"
22 
23 #include <algorithm>
24 
25 PStatCollector ParticleSystemManager::_do_particles_collector("App:Particles:Do Particles");
26 
27 ////////////////////////////////////////////////////////////////////
28 // Function : ParticleSystemManager
29 // Access : public
30 // Description : default constructor
31 ////////////////////////////////////////////////////////////////////
33 ParticleSystemManager(int every_nth_frame) :
34  _nth_frame(every_nth_frame), _cur_frame(0) {
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function : ParticleSystemManager
39 // Access : Public, Virtual
40 // Description : Destructor
41 ////////////////////////////////////////////////////////////////////
44 }
45 
46 ////////////////////////////////////////////////////////////////////
47 // Function : remove_particlesystem
48 // Access : public
49 // Description : removes a ps from the maintenance list
50 ////////////////////////////////////////////////////////////////////
54 
55  PT(ParticleSystem) ptps = ps;
56  found = find(_ps_list.begin(), _ps_list.end(), ptps);
57 
58  if (found == _ps_list.end())
59  return;
60 
61  _ps_list.erase(found);
62 }
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function : do_particles
66 // Access : public
67 // Description : does an update and render for each ps in the list.
68 // this is probably the one you want to use. Rendering
69 // is the expensive operation, and particles REALLY
70 // should at least be updated every frame, so nth_frame
71 // stepping applies only to rendering.
72 ////////////////////////////////////////////////////////////////////
74 do_particles(PN_stdfloat dt) {
75  // cout << "ParticlesystemManager::doparticles entering." << endl;
76  PStatTimer t1(_do_particles_collector);
77 
79 
80  bool render_due = false;
81 
82  _cur_frame++;
83 
84  if (_cur_frame >= _nth_frame) {
85  _cur_frame = 0;
86  render_due = true;
87  }
88 
89  cur = _ps_list.begin();
90 
91  // cout << "PSM::do_particles on a vector of size " << _ps_list.size() << endl;
92  // int cs = 0;
93 
94  while (cur != _ps_list.end()) {
95  ParticleSystem *cur_ps = *cur;
96 
97  // update this system
98  if (cur_ps->get_active_system_flag() == true) {
99  // cout << " system " << cs++ << endl;
100  // cout << " count is: " << cur_ps->get_render_parent()->get_ref_count() << endl;
101  cur_ps->update(dt);
102 
103  // Handle age:
104  if (cur_ps->get_system_grows_older_flag() == true) {
105  PN_stdfloat age = cur_ps->get_system_age() + dt;
106  cur_ps->set_system_age(age);
107 
108  // handle death
109  if (age >= cur_ps->get_system_lifespan()) {
111  ++cur;
112 
113  _ps_list.erase(kill);
114  render_due = false;
115  }
116  }
117 
118  // handle render
119  if (render_due) {
120  cur_ps->render();
121  }
122  }
123 
124  if (cur != _ps_list.end()) {
125  ++cur;
126  }
127  }
128  // cout << "PSM::do_particles finished." << endl;
129  // cout << "ParticleSystemManager::doparticles exiting." << endl;
130 }
131 
132 ////////////////////////////////////////////////////////////////////
133 // Function : do_particles
134 // Access : public
135 // Description : does an update and an optional render for a specific
136 // ps. Since rendering is the expensive operation, multiple
137 // updates could be applied before calling the final render.
138 ////////////////////////////////////////////////////////////////////
140 do_particles(PN_stdfloat dt, ParticleSystem *ps, bool do_render) {
141  if (ps->get_active_system_flag() == true) {
142  ps->update(dt);
143  // Handle age:
144  if (ps->get_system_grows_older_flag() == true) {
145  PN_stdfloat age = ps->get_system_age() + dt;
146  ps->set_system_age(age);
147  }
148 
149  // handle render
150  if (do_render) {
151  ps->render();
152  }
153  }
154 }
155 
156 ////////////////////////////////////////////////////////////////////
157 // Function : output
158 // Access : Public
159 // Description : Write a string representation of this instance to
160 // <out>.
161 ////////////////////////////////////////////////////////////////////
163 output(ostream &out) const {
164  #ifndef NDEBUG //[
165  out<<"ParticleSystemManager";
166  #endif //] NDEBUG
167 }
168 
169 ////////////////////////////////////////////////////////////////////
170 // Function : write_ps_list
171 // Access : Public
172 // Description : Write a string representation of this instance to
173 // <out>.
174 ////////////////////////////////////////////////////////////////////
176 write_ps_list(ostream &out, int indent) const {
177  #ifndef NDEBUG //[
178  out.width(indent);
179  out<<""<<"_ps_list ("<<_ps_list.size()<<" systems)\n";
180  for (plist< PT(ParticleSystem) >::const_iterator i=_ps_list.begin();
181  i != _ps_list.end();
182  ++i) {
183  (*i)->write(out, indent+2);
184  }
185  #endif //] NDEBUG
186 }
187 
188 ////////////////////////////////////////////////////////////////////
189 // Function : write
190 // Access : Public
191 // Description : Write a string representation of this instance to
192 // <out>.
193 ////////////////////////////////////////////////////////////////////
195 write(ostream &out, int indent) const {
196  #ifndef NDEBUG //[
197  out.width(indent); out<<""; out<<"ParticleSystemManager:\n";
198  out.width(indent+2); out<<""; out<<"_nth_frame "<<_nth_frame<<"\n";
199  out.width(indent+2); out<<""; out<<"_cur_frame "<<_cur_frame<<"\n";
200  write_ps_list(out, indent+2);
201  #endif //] NDEBUG
202 }
void remove_particlesystem(ParticleSystem *ps)
removes a ps from the maintenance list
virtual void output(ostream &out) const
Write a string representation of this instance to <out>.
void do_particles(PN_stdfloat dt)
does an update and render for each ps in the list.
virtual void write_ps_list(ostream &out, int indent=0) 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:34
This is our own Panda specialization on the default STL list.
Definition: plist.h:38
virtual void write(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.
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.