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