Panda3D
sparkleParticleRenderer.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 sparkleParticleRenderer.cxx
10  * @author charles
11  * @date 2000-06-27
12  */
13 
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 SparkleParticleRenderer::_render_collector("App:Particles:Sparkle:Render");
23 
24 /**
25  * Default Constructor
26  */
29  BaseParticleRenderer(PR_ALPHA_NONE),
30  _center_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)),
31  _edge_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)),
32  _birth_radius(0.1f), _death_radius(0.1f)
33 {
34  resize_pool(0);
35 }
36 
37 /**
38  * Constructor
39  */
41 SparkleParticleRenderer(const LColor& center, const LColor& edge,
42  PN_stdfloat birth_radius, PN_stdfloat death_radius,
43  SparkleParticleLifeScale life_scale,
44  ParticleRendererAlphaMode alpha_mode) :
45  BaseParticleRenderer(alpha_mode),
46  _center_color(center), _edge_color(edge), _birth_radius(birth_radius),
47  _death_radius(death_radius), _life_scale(life_scale)
48 {
49  resize_pool(0);
50 }
51 
52 /**
53  * Copy Constructor
54  */
57  BaseParticleRenderer(copy) {
58  _center_color = copy._center_color;
59  _edge_color = copy._edge_color;
60  _birth_radius = copy._birth_radius;
61  _death_radius = copy._death_radius;
62  _life_scale = copy._life_scale;
63 
64  resize_pool(0);
65 }
66 
67 /**
68  * Destructor
69  */
72 }
73 
74 /**
75  * child virtual for spawning systems
76  */
79  return new SparkleParticleRenderer(*this);
80 }
81 
82 /**
83  * child birth
84  */
85 void SparkleParticleRenderer::
86 birth_particle(int) {
87 }
88 
89 /**
90  * child kill
91  */
92 void SparkleParticleRenderer::
93 kill_particle(int) {
94 }
95 
96 /**
97  * resizes the render pool. Reference counting makes this easy.
98  */
99 void SparkleParticleRenderer::
100 resize_pool(int new_size) {
101  _max_pool_size = new_size;
102 
103  init_geoms();
104 }
105 
106 /**
107  * initializes the geomnodes
108  */
109 void SparkleParticleRenderer::
110 init_geoms() {
111  _vdata = new GeomVertexData
112  ("sparkle_particles", GeomVertexFormat::get_v3cp(),
113  Geom::UH_stream);
114  PT(Geom) geom = new Geom(_vdata);
115  _line_primitive = geom;
116  _lines = new GeomLines(Geom::UH_stream);
117  geom->add_primitive(_lines);
118 
119  GeomNode *render_node = get_render_node();
120  render_node->remove_all_geoms();
121  render_node->add_geom(_line_primitive, _render_state);
122 }
123 
124 /**
125  * populates the GeomLine
126  */
127 void SparkleParticleRenderer::
128 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
129  PStatTimer t1(_render_collector);
130  if (!ttl_particles) {
131  return;
132  }
133 
134  BaseParticle *cur_particle;
135 
136  int remaining_particles = ttl_particles;
137  int i;
138 
139  GeomVertexWriter vertex(_vdata, InternalName::get_vertex());
140  GeomVertexWriter color(_vdata, InternalName::get_color());
141  _lines->clear_vertices();
142 
143  // init the aabb
144 
145  _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
146  _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
147 
148  // run through the array
149 
150  for (i = 0; i < (int)po_vector.size(); i++) {
151  cur_particle = (BaseParticle *) po_vector[i].p();
152 
153  if (cur_particle->get_alive() == false) {
154  continue;
155  }
156 
157  LPoint3 position = cur_particle->get_position();
158 
159  // adjust the aabb
160 
161  if (position[0] > _aabb_max[0])
162  _aabb_max[0] = position[0];
163  else if (position[0] < _aabb_min[0])
164  _aabb_min[0] = position[0];
165 
166  if (position[1] > _aabb_max[1])
167  _aabb_max[1] = position[1];
168  else if (position[1] < _aabb_min[1])
169  _aabb_min[1] = position[1];
170 
171  if (position[2] > _aabb_max[2])
172  _aabb_max[2] = position[2];
173  else if (position[2] < _aabb_min[2])
174  _aabb_min[2] = position[2];
175 
176  // draw the particle.
177 
178  PN_stdfloat radius = get_radius(cur_particle);
179  PN_stdfloat neg_radius = -radius;
180  PN_stdfloat alpha;
181 
182  LColor center_color = _center_color;
183  LColor edge_color = _edge_color;
184 
185  // handle alpha
186 
187  if (_alpha_mode != PR_ALPHA_NONE) {
188  if(_alpha_mode == PR_ALPHA_USER) {
189  alpha = get_user_alpha();
190  } else {
191  alpha = cur_particle->get_parameterized_age();
192  if (_alpha_mode == PR_ALPHA_OUT)
193  alpha = 1.0f - alpha;
194  else if (_alpha_mode == PR_ALPHA_IN_OUT)
195  alpha = 2.0f * std::min(alpha, 1.0f - alpha);
196 
197  alpha *= get_user_alpha();
198  }
199 
200  center_color[3] = alpha;
201  edge_color[3] = alpha;
202  }
203 
204  // 6 lines coming from the center point.
205 
206  vertex.add_data3(position);
207  vertex.add_data3(position + LVertex(radius, 0.0f, 0.0f));
208  vertex.add_data3(position);
209  vertex.add_data3(position + LVertex(neg_radius, 0.0f, 0.0f));
210  vertex.add_data3(position);
211  vertex.add_data3(position + LVertex(0.0f, radius, 0.0f));
212  vertex.add_data3(position);
213  vertex.add_data3(position + LVertex(0.0f, neg_radius, 0.0f));
214  vertex.add_data3(position);
215  vertex.add_data3(position + LVertex(0.0f, 0.0f, radius));
216  vertex.add_data3(position);
217  vertex.add_data3(position + LVertex(0.0f, 0.0f, neg_radius));
218 
219  color.add_data4(center_color);
220  color.add_data4(edge_color);
221  color.add_data4(center_color);
222  color.add_data4(edge_color);
223  color.add_data4(center_color);
224  color.add_data4(edge_color);
225  color.add_data4(center_color);
226  color.add_data4(edge_color);
227  color.add_data4(center_color);
228  color.add_data4(edge_color);
229  color.add_data4(center_color);
230  color.add_data4(edge_color);
231 
232  _lines->add_next_vertices(2);
233  _lines->close_primitive();
234  _lines->add_next_vertices(2);
235  _lines->close_primitive();
236  _lines->add_next_vertices(2);
237  _lines->close_primitive();
238  _lines->add_next_vertices(2);
239  _lines->close_primitive();
240  _lines->add_next_vertices(2);
241  _lines->close_primitive();
242  _lines->add_next_vertices(2);
243  _lines->close_primitive();
244 
245  remaining_particles--;
246  if (remaining_particles == 0) {
247  break;
248  }
249  }
250 
251  // done filling geomline node, now do the bb stuff
252 
253  LPoint3 aabb_center = _aabb_min + ((_aabb_max - _aabb_min) * 0.5f);
254  PN_stdfloat radius = (aabb_center - _aabb_min).length();
255 
256  BoundingSphere sphere(aabb_center, radius);
257  _line_primitive->set_bounds(&sphere);
258  get_render_node()->mark_internal_bounds_stale();
259 }
260 
261 /**
262  * Write a string representation of this instance to <out>.
263  */
265 output(std::ostream &out) const {
266  #ifndef NDEBUG //[
267  out<<"SparkleParticleRenderer";
268  #endif //] NDEBUG
269 }
270 
271 /**
272  * Write a string representation of this instance to <out>.
273  */
275 write(std::ostream &out, int indent_level) const {
276  indent(out, indent_level) << "SparkleParticleRenderer:\n";
277  indent(out, indent_level + 2) << "_center_color "<<_center_color<<"\n";
278  indent(out, indent_level + 2) << "_edge_color "<<_edge_color<<"\n";
279  indent(out, indent_level + 2) << "_birth_radius "<<_birth_radius<<"\n";
280  indent(out, indent_level + 2) << "_death_radius "<<_death_radius<<"\n";
281  indent(out, indent_level + 2) << "_line_primitive "<<_line_primitive<<"\n";
282  indent(out, indent_level + 2) << "_max_pool_size "<<_max_pool_size<<"\n";
283  indent(out, indent_level + 2) << "_life_scale "<<_life_scale<<"\n";
284  indent(out, indent_level + 2) << "_aabb_min "<<_aabb_min<<"\n";
285  indent(out, indent_level + 2) << "_aabb_max "<<_aabb_max<<"\n";
286  BaseParticleRenderer::write(out, indent_level + 2);
287 }
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.
SparkleParticleRenderer()
Default Constructor.
virtual void write(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
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
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 ~SparkleParticleRenderer()
Destructor.
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.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
Definition: geom.h:54
virtual BaseParticleRenderer * make_copy()
child virtual for spawning systems
PN_stdfloat get_user_alpha() const
gets alpha for "user" alpha mode
Defines a series of disconnected line segments.
Definition: geomLines.h:23
pretty sparkly things.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An individual, physically-modelable particle abstract base class.
Definition: baseParticle.h:23
virtual void output(std::ostream &out) const
Write a string representation of this instance to <out>.
LPoint3 get_position() const
Position Query.
virtual void write(std::ostream &out, int indent_level=0) 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