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