Panda3D
pointParticleRenderer.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 pointParticleRenderer.cxx
10  * @author charles
11  * @date 2000-06-20
12  */
13 
14 #include "pointParticleRenderer.h"
15 #include "boundingSphere.h"
16 #include "geomNode.h"
17 #include "geom.h"
18 #include "geomVertexWriter.h"
19 #include "indent.h"
20 #include "pStatTimer.h"
21 
22 PStatCollector PointParticleRenderer::_render_collector("App:Particles:Point:Render");
23 
24 /**
25  * special constructor
26  */
28 PointParticleRenderer(ParticleRendererAlphaMode am,
29  PN_stdfloat point_size,
30  PointParticleBlendType bt,
31  ParticleRendererBlendMethod bm,
32  const LColor& sc, const LColor& ec) :
34  _start_color(sc), _end_color(ec),
35  _blend_type(bt), _blend_method(bm)
36 {
37  set_point_size(point_size);
38  resize_pool(0);
39 }
40 
41 /**
42  * Copy constructor
43  */
47 {
48  _blend_type = copy._blend_type;
49  _blend_method = copy._blend_method;
50  _start_color = copy._start_color;
51  _end_color = copy._end_color;
52  _point_size = copy._point_size;
53  _thick = copy._thick;
54  resize_pool(0);
55 }
56 
57 /**
58  * Simple destructor
59  */
62 }
63 
64 /**
65  * for spawning systems from dead particles
66  */
69  return new PointParticleRenderer(*this);
70 }
71 
72 /**
73  * reallocate the space for the vertex and color pools
74  */
75 void PointParticleRenderer::
76 resize_pool(int new_size) {
77  if (new_size == _max_pool_size)
78  return;
79 
80  _max_pool_size = new_size;
81 
82  init_geoms();
83 }
84 
85 /**
86  * On-construction initialization
87  */
88 void PointParticleRenderer::
89 init_geoms() {
90  _vdata = new GeomVertexData
91  ("point_particles", GeomVertexFormat::get_v3cp(),
92  Geom::UH_stream);
93  PT(Geom) geom = new Geom(_vdata);
94  _point_primitive = geom;
95  _points = new GeomPoints(Geom::UH_stream);
96  geom->add_primitive(_points);
97 
98  GeomNode *render_node = get_render_node();
99  render_node->remove_all_geoms();
100  render_node->add_geom(_point_primitive, _render_state->add_attrib(_thick));
101 }
102 
103 /**
104  * child birth
105  */
106 void PointParticleRenderer::
107 birth_particle(int) {
108 }
109 
110 /**
111  * child kill
112  */
113 void PointParticleRenderer::
114 kill_particle(int) {
115 }
116 
117 /**
118  * Generates the point color based on the render_type
119  */
120 LColor PointParticleRenderer::
121 create_color(const BaseParticle *p) {
122  LColor color;
123  PN_stdfloat life_t, vel_t;
124  PN_stdfloat parameterized_age = 1.0f;
125  bool have_alpha_t = false;
126 
127  switch (_blend_type) {
128  case PP_ONE_COLOR:
129  // Constant solid color
130  color = _start_color;
131  break;
132 
133  case PP_BLEND_LIFE:
134  // Blending colors based on life
135  parameterized_age = p->get_parameterized_age();
136  life_t = parameterized_age;
137  have_alpha_t = true;
138 
139  if (_blend_method == PP_BLEND_CUBIC) {
140  life_t = CUBIC_T(life_t);
141  }
142 
143  color = LERP(life_t, _start_color, _end_color);
144  break;
145 
146  case PP_BLEND_VEL:
147  // Blending colors based on vel
148  vel_t = p->get_parameterized_vel();
149 
150  if (_blend_method == PP_BLEND_CUBIC) {
151  vel_t = CUBIC_T(vel_t);
152  }
153 
154  color = LERP(vel_t, _start_color, _end_color);
155  break;
156  }
157 
158  // Handle alpha channel
159  if (_alpha_mode != PR_ALPHA_NONE) {
160  if (_alpha_mode == PR_ALPHA_USER) {
161  parameterized_age = 1.0;
162  } else {
163  if (!have_alpha_t) {
164  parameterized_age = p->get_parameterized_age();
165  }
166 
167  if (_alpha_mode == PR_ALPHA_OUT) {
168  parameterized_age = 1.0f - parameterized_age;
169  } else if (_alpha_mode == PR_ALPHA_IN_OUT) {
170  parameterized_age = 2.0f * std::min(parameterized_age,
171  1.0f - parameterized_age);
172  }
173  }
174  color[3] = parameterized_age * get_user_alpha();
175  }
176 
177  return color;
178 }
179 
180 /**
181  * renders the particle system out to a GeomNode
182  */
183 void PointParticleRenderer::
184 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
185  PStatTimer t1(_render_collector);
186 
187  BaseParticle *cur_particle;
188 
189  int remaining_particles = ttl_particles;
190  int i;
191 
192  GeomVertexWriter vertex(_vdata, InternalName::get_vertex());
193  GeomVertexWriter color(_vdata, InternalName::get_color());
194 
195  // init the aabb
196 
197  _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
198  _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
199 
200  // run through every filled slot
201 
202  for (i = 0; i < (int)po_vector.size(); i++) {
203  cur_particle = (BaseParticle *) po_vector[i].p();
204 
205  if (!cur_particle->get_alive())
206  continue;
207 
208  LPoint3 position = cur_particle->get_position();
209 
210  // x aabb adjust
211 
212  if (position[0] > _aabb_max[0])
213  _aabb_max[0] = position[0];
214  else if (position[0] < _aabb_min[0])
215  _aabb_min[0] = position[0];
216 
217  // y aabb adjust
218 
219  if (position[1] > _aabb_max[1])
220  _aabb_max[1] = position[1];
221  else if (position[1] < _aabb_min[1])
222  _aabb_min[1] = position[1];
223 
224  // z aabb adjust
225 
226  if (position[2] > _aabb_max[2])
227  _aabb_max[2] = position[2];
228  else if (position[2] < _aabb_min[2])
229  _aabb_min[2] = position[2];
230 
231  // stuff it into the arrays
232 
233  vertex.add_data3(position);
234  color.add_data4(create_color(cur_particle));
235 
236  // maybe jump out early?
237 
238  remaining_particles--;
239  if (remaining_particles == 0)
240  break;
241  }
242 
243  _points->clear_vertices();
244  _points->add_next_vertices(ttl_particles);
245 
246  // done filling geompoint node, now do the bb stuff
247 
248  LPoint3 aabb_center = _aabb_min + ((_aabb_max - _aabb_min) * 0.5f);
249  PN_stdfloat radius = (aabb_center - _aabb_min).length();
250 
251  BoundingSphere sphere(aabb_center, radius);
252  _point_primitive->set_bounds(&sphere);
253  get_render_node()->mark_internal_bounds_stale();
254 }
255 
256 /**
257  * Write a string representation of this instance to <out>.
258  */
260 output(std::ostream &out) const {
261  #ifndef NDEBUG //[
262  out<<"PointParticleRenderer";
263  #endif //] NDEBUG
264 }
265 
266 /**
267  * Write a string representation of this instance to <out>.
268  */
270 write(std::ostream &out, int indent_level) const {
271  indent(out, indent_level) << "PointParticleRenderer:\n";
272  indent(out, indent_level + 2) << "_start_color "<<_start_color<<"\n";
273  indent(out, indent_level + 2) << "_end_color "<<_end_color<<"\n";
274  indent(out, indent_level + 2) << "_point_size "<<_point_size<<"\n";
275  indent(out, indent_level + 2) << "_point_primitive "<<_point_primitive<<"\n";
276  indent(out, indent_level + 2) << "_max_pool_size "<<_max_pool_size<<"\n";
277  indent(out, indent_level + 2) << "_blend_type "<<_blend_type<<"\n";
278  indent(out, indent_level + 2) << "_blend_method "<<_blend_method<<"\n";
279  indent(out, indent_level + 2) << "_aabb_min "<<_aabb_min<<"\n";
280  indent(out, indent_level + 2) << "_aabb_max "<<_aabb_max<<"\n";
281  BaseParticleRenderer::write(out, indent_level + 2);
282 }
GeomNode * get_render_node() const
Query the geomnode pointer.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write(std::ostream &out, int indent_level=0) const
Write a string representation of this instance to <out>.
virtual void write(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
Defines a series of disconnected points.
Definition: geomPoints.h:23
static const GeomVertexFormat * get_v3cp()
Returns a standard vertex format with a packed color and a 3-component vertex position.
This defines a bounding sphere, consisting of a center and a radius.
A body on which physics will be applied.
Definition: physicsObject.h:27
PointParticleRenderer(const PointParticleRenderer &copy)
Copy constructor.
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.
virtual BaseParticleRenderer * make_copy()
for spawning systems from dead particles
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.
Pure virtual particle renderer base class.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
virtual ~PointParticleRenderer()
Simple destructor.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
Definition: geom.h:54
Simple point/point particle renderer.
PN_stdfloat get_user_alpha() const
gets alpha for "user" alpha mode
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An individual, physically-modelable particle abstract base class.
Definition: baseParticle.h:23
LPoint3 get_position() const
Position Query.
virtual void output(std::ostream &out) const
Write a string representation of this instance to <out>.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:34
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
Definition: geomNode.cxx:584
void remove_all_geoms()
Removes all the geoms from the node at once.
Definition: geomNode.I:126