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
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
22PStatCollector PointParticleRenderer::_render_collector("App:Particles:Point:Render");
23
24/**
25 * special constructor
26 */
28PointParticleRenderer(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 */
68make_copy() {
69 return new PointParticleRenderer(*this);
70}
71
72/**
73 * reallocate the space for the vertex and color pools
74 */
75void PointParticleRenderer::
76resize_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 */
88void PointParticleRenderer::
89init_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 */
106void PointParticleRenderer::
107birth_particle(int) {
108}
109
110/**
111 * child kill
112 */
113void PointParticleRenderer::
114kill_particle(int) {
115}
116
117/**
118 * Generates the point color based on the render_type
119 */
120LColor PointParticleRenderer::
121create_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 */
183void PointParticleRenderer::
184render(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 */
260output(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 */
270write(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}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Pure virtual particle renderer base class.
GeomNode * get_render_node() const
Query the geomnode pointer.
PN_stdfloat get_user_alpha() const
gets alpha for "user" alpha mode
virtual void write(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
An individual, physically-modelable particle abstract base class.
Definition: baseParticle.h:23
This defines a bounding sphere, consisting of a center and a radius.
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:594
void remove_all_geoms()
Removes all the geoms from the node at once.
Definition: geomNode.I:126
Defines a series of disconnected points.
Definition: geomPoints.h:23
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
static const GeomVertexFormat * get_v3cp()
Returns a standard vertex format with a packed color and a 3-component vertex position.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A container for geometry primitives.
Definition: geom.h:54
A lightweight class that represents a single element that may be timed and/or counted via stats.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:30
A body on which physics will be applied.
Definition: physicsObject.h:27
get_position
Position Query.
Simple point/point particle renderer.
virtual void write(std::ostream &out, int indent_level=0) const
Write a string representation of this instance to <out>.
virtual ~PointParticleRenderer()
Simple destructor.
PointParticleRenderer(const PointParticleRenderer &copy)
Copy constructor.
virtual void output(std::ostream &out) const
Write a string representation of this instance to <out>.
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
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: dcindent.cxx:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.