Panda3D
 All Classes Functions Variables Enumerations
geomParticleRenderer.cxx
1 // Filename: geomParticleRenderer.cxx
2 // Created by: charles (05Jul00)
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 "geomParticleRenderer.h"
16 #include "baseParticle.h"
17 
18 #include "transformState.h"
19 #include "colorScaleAttrib.h"
20 #include "colorAttrib.h"
21 #include "pStatTimer.h"
22 
23 PStatCollector GeomParticleRenderer::_render_collector("App:Particles:Geom:Render");
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function : GeomParticleRenderer
27 // Access : public
28 // Description : constructor
29 ////////////////////////////////////////////////////////////////////
30 
32 GeomParticleRenderer(ParticleRendererAlphaMode am, PandaNode *geom_node) :
34  _geom_node(geom_node),
35  _color_interpolation_manager(new ColorInterpolationManager(LColor(1.0f,1.0f,1.0f,1.0f))),
36  _pool_size(0),
37  _initial_x_scale(1.0f),
38  _final_x_scale(1.0f),
39  _initial_y_scale(1.0f),
40  _final_y_scale(1.0f),
41  _initial_z_scale(1.0f),
42  _final_z_scale(1.0f),
43  _animate_x_ratio(false),
44  _animate_y_ratio(false),
45  _animate_z_ratio(false)
46 {
47  if (_geom_node.is_null())
48  _geom_node = new PandaNode("empty");
49 }
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function : GeomParticleRenderer
53 // Access : public
54 // Description : copy constructor
55 ////////////////////////////////////////////////////////////////////
56 
59  BaseParticleRenderer(copy),
60  _pool_size(0),
61  _initial_x_scale(copy._initial_x_scale),
62  _final_x_scale(copy._final_x_scale),
63  _initial_y_scale(copy._initial_y_scale),
64  _final_y_scale(copy._final_y_scale),
65  _initial_z_scale(copy._initial_z_scale),
66  _final_z_scale(copy._final_z_scale),
67  _animate_x_ratio(copy._animate_x_ratio),
68  _animate_y_ratio(copy._animate_y_ratio),
69  _animate_z_ratio(copy._animate_z_ratio)
70 {
71  _geom_node = copy._geom_node;
72 }
73 
74 ////////////////////////////////////////////////////////////////////
75 // Function : ~GeomParticleRenderer
76 // Access : public
77 // Description : destructor
78 ////////////////////////////////////////////////////////////////////
79 
82  kill_nodes();
83 }
84 
85 ////////////////////////////////////////////////////////////////////
86 // Function : make_copy
87 // Access : public
88 // Description : dynamic copying
89 ////////////////////////////////////////////////////////////////////
90 
93  return new GeomParticleRenderer(*this);
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function : init_geoms
98 // Access : private
99 // Description : links the child nodes to the parent stuff
100 ////////////////////////////////////////////////////////////////////
101 void GeomParticleRenderer::
102 init_geoms() {
103 
104 }
105 
106 ////////////////////////////////////////////////////////////////////
107 // Function : resize_pool
108 // Access : private
109 // Description : handles renderer-size resizing.
110 ////////////////////////////////////////////////////////////////////
111 
112 void GeomParticleRenderer::
113 resize_pool(int new_size) {
114  kill_nodes();
115 
116  // now repopulate the vector with a bunch of NULLS, representing
117  // potential instances of the _geom_node.
118 
119  int i;
120  for (i = 0; i < new_size; i++) {
121  _node_vector.push_back(NULL);
122  }
123 
124  _pool_size = new_size;
125 }
126 
127 ////////////////////////////////////////////////////////////////////
128 // Function : kill_nodes
129 // Access : private
130 ////////////////////////////////////////////////////////////////////
131 
132 void GeomParticleRenderer::
133 kill_nodes() {
134  pvector< PT(PandaNode) >::iterator vec_iter = _node_vector.begin();
135 
136  PandaNode *render_node = get_render_node();
137  for (; vec_iter != _node_vector.end(); vec_iter++) {
138  PandaNode *node = *vec_iter;
139  if (node != (PandaNode *)NULL) {
140  render_node->remove_child(node);
141  }
142  }
143 
144  _node_vector.erase(_node_vector.begin(), _node_vector.end());
145 }
146 
147 ////////////////////////////////////////////////////////////////////
148 // Function : birth_particle
149 // Access : Private, virtual
150 // Description : child birth
151 ////////////////////////////////////////////////////////////////////
152 
153 void GeomParticleRenderer::
154 birth_particle(int index) {
155  if (_node_vector[index] == (PandaNode *)NULL) {
156  PandaNode *node = new PandaNode("");
157  get_render_node()->add_child(node);
158  node->add_child(_geom_node);
159  _node_vector[index] = node;
160  }
161 }
162 
163 ////////////////////////////////////////////////////////////////////
164 // Function : kill_particle
165 // Access : Private, virtual
166 // Description : child kill
167 ////////////////////////////////////////////////////////////////////
168 
169 void GeomParticleRenderer::
170 kill_particle(int index) {
171  if (_node_vector[index] != (PandaNode *)NULL) {
172  get_render_node()->remove_child(_node_vector[index]);
173  _node_vector[index] = (PandaNode *)NULL;
174  }
175 }
176 
177 ////////////////////////////////////////////////////////////////////
178 // Function : render
179 // Access : private
180 // Description : sets the transitions on each arc
181 ////////////////////////////////////////////////////////////////////
182 
183 void GeomParticleRenderer::
184 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
185  PStatTimer t1(_render_collector);
186 
187  BaseParticle *cur_particle;
188  int i, remaining_particles = ttl_particles;
189 
190  pvector< PT(PandaNode) >::iterator cur_node_iter = _node_vector.begin();
191 
192  // run through the particle vector
193 
194  for (i = 0; i < (int)po_vector.size(); i++) {
195  PandaNode *cur_node;
196 
197  cur_particle = (BaseParticle *) po_vector[i].p();
198  cur_node = *cur_node_iter;
199 
200  if (cur_particle->get_alive()) {
201  // living particle
202  if (cur_node == (PandaNode *)NULL) {
203  birth_particle(i);
204  cur_node = *cur_node_iter;
205  }
206  nassertv(cur_node != (PandaNode *)NULL);
207 
208  cur_node->set_state(_render_state);
209 
210  PN_stdfloat t = cur_particle->get_parameterized_age();
211  LColor c = _color_interpolation_manager->generateColor(t);
212 
213  if ((_alpha_mode != PR_ALPHA_NONE)) {
214  PN_stdfloat alpha_scalar;
215 
216  if(_alpha_mode == PR_ALPHA_USER) {
217  alpha_scalar = get_user_alpha();
218  } else {
219  alpha_scalar = t;
220  if (_alpha_mode == PR_ALPHA_OUT)
221  alpha_scalar = 1.0f - alpha_scalar;
222  else if (_alpha_mode == PR_ALPHA_IN_OUT)
223  alpha_scalar = 2.0f * min(alpha_scalar, 1.0f - alpha_scalar);
224  alpha_scalar *= get_user_alpha();
225  }
226 
227  c[3] *= alpha_scalar;
228  cur_node->set_attrib(ColorScaleAttrib::make
229  (LColor(1.0f, 1.0f, 1.0f, c[3])));
230  }
231 
232  cur_node->set_attrib(ColorAttrib::make_flat(c), 0);
233 
234  // animate scale
235  PN_stdfloat current_x_scale = _initial_x_scale;
236  PN_stdfloat current_y_scale = _initial_y_scale;
237  PN_stdfloat current_z_scale = _initial_z_scale;
238 
239  if (_animate_x_ratio || _animate_y_ratio || _animate_z_ratio) {
240  if (_animate_x_ratio) {
241  current_x_scale = (_initial_x_scale +
242  (t * (_final_x_scale - _initial_x_scale)));
243  }
244  if (_animate_y_ratio) {
245  current_y_scale = (_initial_y_scale +
246  (t * (_final_y_scale - _initial_y_scale)));
247  }
248  if (_animate_z_ratio) {
249  current_z_scale = (_initial_z_scale +
250  (t * (_final_z_scale - _initial_z_scale)));
251  }
252  }
253 
254  cur_node->set_transform(TransformState::make_pos_quat_scale
255  (cur_particle->get_position(),
256  cur_particle->get_orientation(),
257  LVecBase3(current_x_scale, current_y_scale, current_z_scale)));
258 
259  // maybe get out early if possible.
260 
261  remaining_particles--;
262 
263  if (remaining_particles == 0)
264  break;
265  }
266 
267  cur_node_iter++;
268  }
269 }
270 
271 ////////////////////////////////////////////////////////////////////
272 // Function : output
273 // Access : Public
274 // Description : Write a string representation of this instance to
275 // <out>.
276 ////////////////////////////////////////////////////////////////////
278 output(ostream &out) const {
279  #ifndef NDEBUG //[
280  out<<"GeomParticleRenderer";
281  #endif //] NDEBUG
282 }
283 
284 ////////////////////////////////////////////////////////////////////
285 // Function : write_linear_forces
286 // Access : Public
287 // Description : Write a string representation of this instance to
288 // <out>.
289 ////////////////////////////////////////////////////////////////////
291 write_linear_forces(ostream &out, int indent) const {
292  #ifndef NDEBUG //[
293  out.width(indent);
294  out<<""<<"_node_vector ("<<_node_vector.size()<<" forces)\n";
295  for (pvector< PT(PandaNode) >::const_iterator i=_node_vector.begin();
296  i != _node_vector.end();
297  ++i) {
298  (*i)->write(out, indent+2);
299  }
300  #endif //] NDEBUG
301 }
302 
303 ////////////////////////////////////////////////////////////////////
304 // Function : write
305 // Access : Public
306 // Description : Write a string representation of this instance to
307 // <out>.
308 ////////////////////////////////////////////////////////////////////
310 write(ostream &out, int indent) const {
311  #ifndef NDEBUG //[
312  out.width(indent); out<<""; out<<"GeomParticleRenderer:\n";
313  out.width(indent+2); out<<""; out<<"_geom_node "<<_geom_node<<"\n";
314  out.width(indent+2); out<<""; out<<"_pool_size "<<_pool_size<<"\n";
315 
316  out.width(indent+2); out<<""; out<<"_initial_x_scale "<<_initial_x_scale<<"\n";
317  out.width(indent+2); out<<""; out<<"_final_x_scale "<<_final_x_scale<<"\n";
318  out.width(indent+2); out<<""; out<<"_initial_y_scale "<<_initial_y_scale<<"\n";
319  out.width(indent+2); out<<""; out<<"_final_y_scale "<<_final_y_scale<<"\n";
320  out.width(indent+2); out<<""; out<<"_initial_z_scale "<<_initial_z_scale<<"\n";
321  out.width(indent+2); out<<""; out<<"_final_z_scale "<<_final_z_scale<<"\n";
322  out.width(indent+2); out<<""; out<<"_animate_x_ratio "<<_animate_x_ratio<<"\n";
323  out.width(indent+2); out<<""; out<<"_animate_y_ratio "<<_animate_y_ratio<<"\n";
324  out.width(indent+2); out<<""; out<<"_animate_z_ratio "<<_animate_z_ratio<<"\n";
325 
326  write_linear_forces(out, indent+2);
327  BaseParticleRenderer::write(out, indent+2);
328  #endif //] NDEBUG
329 }
GeomParticleRenderer(ParticleRendererAlphaMode am=PR_ALPHA_NONE, PandaNode *geom_node=(PandaNode *) NULL)
constructor
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
LPoint3 get_position() const
Position Query.
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
void remove_child(int child_index, Thread *current_thread=Thread::get_current_thread())
Removes the nth child from the node.
Definition: pandaNode.cxx:697
virtual void output(ostream &out) const
Write a string representation of this instance to &lt;out&gt;.
virtual void write(ostream &out, int indent=0) const
Write a string representation of this instance to &lt;out&gt;.
PN_stdfloat get_user_alpha() const
gets alpha for &quot;user&quot; alpha mode
A body on which physics will be applied.
Definition: physicsObject.h:29
LOrientation get_orientation() const
get current orientation.
GeomNode * get_render_node() const
Query the geomnode pointer.
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 vector.
Definition: pvector.h:39
A lightweight class that represents a single element that may be timed and/or counted via stats...
Pure virtual particle renderer base class.
void set_state(const RenderState *state, Thread *current_thread=Thread::get_current_thread())
Sets the complete RenderState that will be applied to all nodes at this level and below...
Definition: pandaNode.cxx:1216
High level class for color interpolation.
void set_attrib(const RenderAttrib *attrib, int override=0)
Adds the indicated render attribute to the scene graph on this node.
Definition: pandaNode.cxx:1107
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
An individual, physically-modelable particle abstract base class.
Definition: baseParticle.h:26
virtual void write_linear_forces(ostream &out, int indent=0) const
Write a string representation of this instance to &lt;out&gt;.
virtual void write(ostream &out, int indent=0) const
Write a string representation of this instance to &lt;out&gt;.
virtual ~GeomParticleRenderer()
destructor
virtual BaseParticleRenderer * make_copy()
dynamic copying
void add_child(PandaNode *child_node, int sort=0, Thread *current_thread=Thread::get_current_thread())
Adds a new child to the node.
Definition: pandaNode.cxx:654
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that will be applied to this node and below.
Definition: pandaNode.cxx:1267