Panda3D
lineParticleRenderer.cxx
1 // Filename: lineParticleRenderer.cxx
2 // Created by: darren (06Oct00)
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 "lineParticleRenderer.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 LineParticleRenderer::_render_collector("App:Particles:Line:Render");
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function : LineParticleRenderer
27 // Access : Public
28 // Description : Default Constructor
29 ////////////////////////////////////////////////////////////////////
30 
33  _head_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)),
34  _tail_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)) {
35 
36  _line_scale_factor = 1.0f;
37 
38  resize_pool(0);
39 }
40 
41 ////////////////////////////////////////////////////////////////////
42 // Function : LineParticleRenderer
43 // Access : Public
44 // Description : Constructor
45 ////////////////////////////////////////////////////////////////////
46 
49  const LColor& tail,
50  ParticleRendererAlphaMode alpha_mode) :
51  BaseParticleRenderer(alpha_mode),
52  _head_color(head), _tail_color(tail)
53 {
54  resize_pool(0);
55 }
56 
57 ////////////////////////////////////////////////////////////////////
58 // Function : LineParticleRenderer
59 // Access : Public
60 // Description : Copy Constructor
61 ////////////////////////////////////////////////////////////////////
62 
65  BaseParticleRenderer(copy) {
66  _head_color = copy._head_color;
67  _tail_color = copy._tail_color;
68 
69  resize_pool(0);
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function : ~LineParticleRenderer
74 // Access : Public
75 // Description : Destructor
76 ////////////////////////////////////////////////////////////////////
77 
80 }
81 
82 ////////////////////////////////////////////////////////////////////
83 // Function : make copy
84 // Access : Public
85 // Description : child virtual for spawning systems
86 ////////////////////////////////////////////////////////////////////
87 
90  return new LineParticleRenderer(*this);
91 }
92 
93 ////////////////////////////////////////////////////////////////////
94 // Function : birth_particle
95 // Access : Private, virtual
96 // Description : child birth
97 ////////////////////////////////////////////////////////////////////
98 
99 void LineParticleRenderer::
100 birth_particle(int) {
101 }
102 
103 ////////////////////////////////////////////////////////////////////
104 // Function : kill_particle
105 // Access : Private, virtual
106 // Description : child kill
107 ////////////////////////////////////////////////////////////////////
108 
109 void LineParticleRenderer::
110 kill_particle(int) {
111 }
112 
113 ////////////////////////////////////////////////////////////////////
114 // Function : resize_pool
115 // Access : private
116 // Description : resizes the render pool. Reference counting
117 // makes this easy.
118 ////////////////////////////////////////////////////////////////////
119 
120 void LineParticleRenderer::
121 resize_pool(int new_size) {
122  _max_pool_size = new_size;
123 
124  init_geoms();
125 }
126 
127 ////////////////////////////////////////////////////////////////////
128 // Function : init_geoms
129 // Access : private
130 // Description : initializes the geomnodes
131 ////////////////////////////////////////////////////////////////////
132 
133 void LineParticleRenderer::
134 init_geoms() {
135  _vdata = new GeomVertexData
136  ("line_particles", GeomVertexFormat::get_v3cp(),
137  Geom::UH_stream);
138  PT(Geom) geom = new Geom(_vdata);
139  _line_primitive = geom;
140  _lines = new GeomLines(Geom::UH_stream);
141  geom->add_primitive(_lines);
142 
143  GeomNode *render_node = get_render_node();
144  render_node->remove_all_geoms();
145  render_node->add_geom(_line_primitive, _render_state);
146 }
147 
148 ////////////////////////////////////////////////////////////////////
149 // Function : render
150 // Access : private
151 // Description : populates the GeomLine
152 ////////////////////////////////////////////////////////////////////
153 
154 void LineParticleRenderer::
155 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
156  PStatTimer t1(_render_collector);
157 
158  if (!ttl_particles)
159  return;
160 
161  BaseParticle *cur_particle;
162 
163  int remaining_particles = ttl_particles;
164  int i;
165 
166  GeomVertexWriter vertex(_vdata, InternalName::get_vertex());
167  GeomVertexWriter color(_vdata, InternalName::get_color());
168  _lines->clear_vertices();
169 
170  // init the aabb
171 
172  _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
173  _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
174 
175  // run through the array
176 
177  for (i = 0; i < (int)po_vector.size(); i++) {
178  cur_particle = (BaseParticle *) po_vector[i].p();
179 
180  if (cur_particle->get_alive() == false)
181  continue;
182 
183  LPoint3 position = cur_particle->get_position();
184 
185  // adjust the aabb
186 
187  if (position[0] > _aabb_max[0])
188  _aabb_max[0] = position[0];
189  if (position[0] < _aabb_min[0])
190  _aabb_min[0] = position[0];
191 
192  if (position[1] > _aabb_max[1])
193  _aabb_max[1] = position[1];
194  if (position[1] < _aabb_min[1])
195  _aabb_min[1] = position[1];
196 
197  if (position[2] > _aabb_max[2])
198  _aabb_max[2] = position[2];
199  if (position[2] < _aabb_min[2])
200  _aabb_min[2] = position[2];
201 
202  // draw the particle.
203 
204  LColor head_color = _head_color;
205  LColor tail_color = _tail_color;
206 
207  // handle alpha
208 
209  if (_alpha_mode != PR_ALPHA_NONE) {
210 
211  PN_stdfloat alpha;
212 
213  if (_alpha_mode == PR_ALPHA_USER) {
214  alpha = get_user_alpha();
215  } else {
216  alpha = cur_particle->get_parameterized_age();
217  if (_alpha_mode == PR_ALPHA_OUT)
218  alpha = 1.0f - alpha;
219  else if (_alpha_mode == PR_ALPHA_IN_OUT)
220  alpha = 2.0f * min(alpha, 1.0f - alpha);
221  }
222 
223  head_color[3] = alpha;
224  tail_color[3] = alpha;
225  }
226 
227  // one line from current position to last position
228 
229  vertex.add_data3(position);
230  LPoint3 last_position = position +
231  (cur_particle->get_last_position() - position) * _line_scale_factor;
232  vertex.add_data3(last_position);
233  color.add_data4(head_color);
234  color.add_data4(tail_color);
235  _lines->add_next_vertices(2);
236  _lines->close_primitive();
237 
238  remaining_particles--;
239  if (remaining_particles == 0)
240  break;
241  }
242 
243  // done filling geomline node, now do the bb stuff
244 
245  LPoint3 aabb_center = (_aabb_min + _aabb_max) * 0.5f;
246  PN_stdfloat radius = (aabb_center - _aabb_min).length();
247 
248  BoundingSphere sphere(aabb_center, radius);
249  _line_primitive->set_bounds(&sphere);
250  get_render_node()->mark_internal_bounds_stale();
251 }
252 
253 ////////////////////////////////////////////////////////////////////
254 // Function : output
255 // Access : Public
256 // Description : Write a string representation of this instance to
257 // <out>.
258 ////////////////////////////////////////////////////////////////////
260 output(ostream &out) const {
261  #ifndef NDEBUG //[
262  out<<"LineParticleRenderer";
263  #endif //] NDEBUG
264 }
265 
266 ////////////////////////////////////////////////////////////////////
267 // Function : write
268 // Access : Public
269 // Description : Write a string representation of this instance to
270 // <out>.
271 ////////////////////////////////////////////////////////////////////
273 write(ostream &out, int indent_level) const {
274  indent(out, indent_level) << "LineParticleRenderer:\n";
275  indent(out, indent_level + 2) << "_head_color "<<_head_color<<"\n";
276  indent(out, indent_level + 2) << "_tail_color "<<_tail_color<<"\n";
277  indent(out, indent_level + 2) << "_line_primitive "<<_line_primitive<<"\n";
278  indent(out, indent_level + 2) << "_max_pool_size "<<_max_pool_size<<"\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...
virtual BaseParticleRenderer * make_copy()
child virtual for spawning systems
LPoint3 get_last_position() const
Get the position of the physics object at the start of the most recent do_physics.
virtual void output(ostream &out) const
Write a string representation of this instance to <out>.
This defines a bounding sphere, consisting of a center and a radius.
A body on which physics will be applied.
Definition: physicsObject.h:29
virtual ~LineParticleRenderer()
Destructor.
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. ...
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. ...
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
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.
LineParticleRenderer()
Default Constructor.
renders a line from last position to current position – good for rain, sparks, etc.
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