Panda3D
sparkleParticleRenderer.cxx
1 // Filename: sparkleParticleRenderer.cxx
2 // Created by: charles (27Jun00)
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 "sparkleParticleRenderer.h"
16 #include "boundingSphere.h"
17 #include "geomNode.h"
18 #include "geom.h"
19 #include "geomVertexWriter.h"
20 #include "indent.h"
21 #include "pStatTimer.h"
22 
23 PStatCollector SparkleParticleRenderer::_render_collector("App:Particles:Sparkle:Render");
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function : SparkleParticleRenderer
27 // Access : Public
28 // Description : Default Constructor
29 ////////////////////////////////////////////////////////////////////
32  BaseParticleRenderer(PR_ALPHA_NONE),
33  _center_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)),
34  _edge_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)),
35  _birth_radius(0.1f), _death_radius(0.1f)
36 {
37  resize_pool(0);
38 }
39 
40 ////////////////////////////////////////////////////////////////////
41 // Function : SparkleParticleRenderer
42 // Access : Public
43 // Description : Constructor
44 ////////////////////////////////////////////////////////////////////
46 SparkleParticleRenderer(const LColor& center, const LColor& edge,
47  PN_stdfloat birth_radius, PN_stdfloat death_radius,
48  SparkleParticleLifeScale life_scale,
49  ParticleRendererAlphaMode alpha_mode) :
50  BaseParticleRenderer(alpha_mode),
51  _center_color(center), _edge_color(edge), _birth_radius(birth_radius),
52  _death_radius(death_radius), _life_scale(life_scale)
53 {
54  resize_pool(0);
55 }
56 
57 ////////////////////////////////////////////////////////////////////
58 // Function : SparkleParticleRenderer
59 // Access : Public
60 // Description : Copy Constructor
61 ////////////////////////////////////////////////////////////////////
64  BaseParticleRenderer(copy) {
65  _center_color = copy._center_color;
66  _edge_color = copy._edge_color;
67  _birth_radius = copy._birth_radius;
68  _death_radius = copy._death_radius;
69  _life_scale = copy._life_scale;
70 
71  resize_pool(0);
72 }
73 
74 ////////////////////////////////////////////////////////////////////
75 // Function : ~SparkleParticleRenderer
76 // Access : Public
77 // Description : Destructor
78 ////////////////////////////////////////////////////////////////////
81 }
82 
83 ////////////////////////////////////////////////////////////////////
84 // Function : make copy
85 // Access : Public
86 // Description : child virtual for spawning systems
87 ////////////////////////////////////////////////////////////////////
90  return new SparkleParticleRenderer(*this);
91 }
92 
93 ////////////////////////////////////////////////////////////////////
94 // Function : birth_particle
95 // Access : Private, virtual
96 // Description : child birth
97 ////////////////////////////////////////////////////////////////////
98 void SparkleParticleRenderer::
99 birth_particle(int) {
100 }
101 
102 ////////////////////////////////////////////////////////////////////
103 // Function : kill_particle
104 // Access : Private, virtual
105 // Description : child kill
106 ////////////////////////////////////////////////////////////////////
107 void SparkleParticleRenderer::
108 kill_particle(int) {
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function : resize_pool
113 // Access : private
114 // Description : resizes the render pool. Reference counting
115 // makes this easy.
116 ////////////////////////////////////////////////////////////////////
117 void SparkleParticleRenderer::
118 resize_pool(int new_size) {
119  _max_pool_size = new_size;
120 
121  init_geoms();
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function : init_geoms
126 // Access : private
127 // Description : initializes the geomnodes
128 ////////////////////////////////////////////////////////////////////
129 void SparkleParticleRenderer::
130 init_geoms() {
131  _vdata = new GeomVertexData
132  ("sparkle_particles", GeomVertexFormat::get_v3cp(),
133  Geom::UH_stream);
134  PT(Geom) geom = new Geom(_vdata);
135  _line_primitive = geom;
136  _lines = new GeomLines(Geom::UH_stream);
137  geom->add_primitive(_lines);
138 
139  GeomNode *render_node = get_render_node();
140  render_node->remove_all_geoms();
141  render_node->add_geom(_line_primitive, _render_state);
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function : render
146 // Access : private
147 // Description : populates the GeomLine
148 ////////////////////////////////////////////////////////////////////
149 void SparkleParticleRenderer::
150 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
151  PStatTimer t1(_render_collector);
152  if (!ttl_particles) {
153  return;
154  }
155 
156  BaseParticle *cur_particle;
157 
158  int remaining_particles = ttl_particles;
159  int i;
160 
161  GeomVertexWriter vertex(_vdata, InternalName::get_vertex());
162  GeomVertexWriter color(_vdata, InternalName::get_color());
163  _lines->clear_vertices();
164 
165  // init the aabb
166 
167  _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
168  _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
169 
170  // run through the array
171 
172  for (i = 0; i < (int)po_vector.size(); i++) {
173  cur_particle = (BaseParticle *) po_vector[i].p();
174 
175  if (cur_particle->get_alive() == false) {
176  continue;
177  }
178 
179  LPoint3 position = cur_particle->get_position();
180 
181  // adjust the aabb
182 
183  if (position[0] > _aabb_max[0])
184  _aabb_max[0] = position[0];
185  else if (position[0] < _aabb_min[0])
186  _aabb_min[0] = position[0];
187 
188  if (position[1] > _aabb_max[1])
189  _aabb_max[1] = position[1];
190  else if (position[1] < _aabb_min[1])
191  _aabb_min[1] = position[1];
192 
193  if (position[2] > _aabb_max[2])
194  _aabb_max[2] = position[2];
195  else if (position[2] < _aabb_min[2])
196  _aabb_min[2] = position[2];
197 
198  // draw the particle.
199 
200  PN_stdfloat radius = get_radius(cur_particle);
201  PN_stdfloat neg_radius = -radius;
202  PN_stdfloat alpha;
203 
204  LColor center_color = _center_color;
205  LColor edge_color = _edge_color;
206 
207  // handle alpha
208 
209  if (_alpha_mode != PR_ALPHA_NONE) {
210  if(_alpha_mode == PR_ALPHA_USER) {
211  alpha = get_user_alpha();
212  } else {
213  alpha = cur_particle->get_parameterized_age();
214  if (_alpha_mode == PR_ALPHA_OUT)
215  alpha = 1.0f - alpha;
216  else if (_alpha_mode == PR_ALPHA_IN_OUT)
217  alpha = 2.0f * min(alpha, 1.0f - alpha);
218 
219  alpha *= get_user_alpha();
220  }
221 
222  center_color[3] = alpha;
223  edge_color[3] = alpha;
224  }
225 
226  // 6 lines coming from the center point.
227 
228  vertex.add_data3(position);
229  vertex.add_data3(position + LVertex(radius, 0.0f, 0.0f));
230  vertex.add_data3(position);
231  vertex.add_data3(position + LVertex(neg_radius, 0.0f, 0.0f));
232  vertex.add_data3(position);
233  vertex.add_data3(position + LVertex(0.0f, radius, 0.0f));
234  vertex.add_data3(position);
235  vertex.add_data3(position + LVertex(0.0f, neg_radius, 0.0f));
236  vertex.add_data3(position);
237  vertex.add_data3(position + LVertex(0.0f, 0.0f, radius));
238  vertex.add_data3(position);
239  vertex.add_data3(position + LVertex(0.0f, 0.0f, neg_radius));
240 
241  color.add_data4(center_color);
242  color.add_data4(edge_color);
243  color.add_data4(center_color);
244  color.add_data4(edge_color);
245  color.add_data4(center_color);
246  color.add_data4(edge_color);
247  color.add_data4(center_color);
248  color.add_data4(edge_color);
249  color.add_data4(center_color);
250  color.add_data4(edge_color);
251  color.add_data4(center_color);
252  color.add_data4(edge_color);
253 
254  _lines->add_next_vertices(2);
255  _lines->close_primitive();
256  _lines->add_next_vertices(2);
257  _lines->close_primitive();
258  _lines->add_next_vertices(2);
259  _lines->close_primitive();
260  _lines->add_next_vertices(2);
261  _lines->close_primitive();
262  _lines->add_next_vertices(2);
263  _lines->close_primitive();
264  _lines->add_next_vertices(2);
265  _lines->close_primitive();
266 
267  remaining_particles--;
268  if (remaining_particles == 0) {
269  break;
270  }
271  }
272 
273  // done filling geomline node, now do the bb stuff
274 
275  LPoint3 aabb_center = _aabb_min + ((_aabb_max - _aabb_min) * 0.5f);
276  PN_stdfloat radius = (aabb_center - _aabb_min).length();
277 
278  BoundingSphere sphere(aabb_center, radius);
279  _line_primitive->set_bounds(&sphere);
280  get_render_node()->mark_internal_bounds_stale();
281 }
282 
283 ////////////////////////////////////////////////////////////////////
284 // Function : output
285 // Access : Public
286 // Description : Write a string representation of this instance to
287 // <out>.
288 ////////////////////////////////////////////////////////////////////
290 output(ostream &out) const {
291  #ifndef NDEBUG //[
292  out<<"SparkleParticleRenderer";
293  #endif //] NDEBUG
294 }
295 
296 ////////////////////////////////////////////////////////////////////
297 // Function : write
298 // Access : Public
299 // Description : Write a string representation of this instance to
300 // <out>.
301 ////////////////////////////////////////////////////////////////////
303 write(ostream &out, int indent_level) const {
304  indent(out, indent_level) << "SparkleParticleRenderer:\n";
305  indent(out, indent_level + 2) << "_center_color "<<_center_color<<"\n";
306  indent(out, indent_level + 2) << "_edge_color "<<_edge_color<<"\n";
307  indent(out, indent_level + 2) << "_birth_radius "<<_birth_radius<<"\n";
308  indent(out, indent_level + 2) << "_death_radius "<<_death_radius<<"\n";
309  indent(out, indent_level + 2) << "_line_primitive "<<_line_primitive<<"\n";
310  indent(out, indent_level + 2) << "_max_pool_size "<<_max_pool_size<<"\n";
311  indent(out, indent_level + 2) << "_life_scale "<<_life_scale<<"\n";
312  indent(out, indent_level + 2) << "_aabb_min "<<_aabb_min<<"\n";
313  indent(out, indent_level + 2) << "_aabb_max "<<_aabb_max<<"\n";
314  BaseParticleRenderer::write(out, indent_level + 2);
315 }
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...
SparkleParticleRenderer()
Default Constructor.
This defines a bounding sphere, consisting of a center and a radius.
A body on which physics will be applied.
Definition: physicsObject.h:29
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:34
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row. ...
virtual void output(ostream &out) const
Write a string representation of this instance to <out>.
virtual ~SparkleParticleRenderer()
Destructor.
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.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition: geom.h:58
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
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:25
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
pretty sparkly things.
virtual void write(ostream &out, int indent_level=0) const
Write a string representation of this instance to <out>.
An individual, physically-modelable particle abstract base class.
Definition: baseParticle.h:26
LPoint3 get_position() const
Position Query.
virtual void write(ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:37
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
Definition: geomNode.cxx:642
void remove_all_geoms()
Removes all the geoms from the node at once.
Definition: geomNode.I:159