Panda3D

geomParticleRenderer.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 geomParticleRenderer.cxx
10 * @author charles
11 * @date 2000-07-05
12 */
13
14 #include "geomParticleRenderer.h"
15 #include "baseParticle.h"
16
17 #include "transformState.h"
18 #include "colorScaleAttrib.h"
19 #include "colorAttrib.h"
20 #include "pStatTimer.h"
21
22 PStatCollector GeomParticleRenderer::_render_collector("App:Particles:Geom:Render");
23
24 /**
25 * constructor
26 */
27
28 GeomParticleRenderer::
29 GeomParticleRenderer(ParticleRendererAlphaMode am, PandaNode *geom_node) :
30 BaseParticleRenderer(am),
31 _geom_node(geom_node),
32 _color_interpolation_manager(new ColorInterpolationManager(LColor(1.0f,1.0f,1.0f,1.0f))),
33 _pool_size(0),
34 _initial_x_scale(1.0f),
35 _final_x_scale(1.0f),
36 _initial_y_scale(1.0f),
37 _final_y_scale(1.0f),
38 _initial_z_scale(1.0f),
39 _final_z_scale(1.0f),
40 _animate_x_ratio(false),
41 _animate_y_ratio(false),
42 _animate_z_ratio(false)
43 {
44 if (_geom_node.is_null())
45 _geom_node = new PandaNode("empty");
46 }
47
48 /**
49 * copy constructor
50 */
51
52 GeomParticleRenderer::
53 GeomParticleRenderer(const GeomParticleRenderer& copy) :
54 BaseParticleRenderer(copy),
55 _pool_size(0),
56 _initial_x_scale(copy._initial_x_scale),
57 _final_x_scale(copy._final_x_scale),
58 _initial_y_scale(copy._initial_y_scale),
59 _final_y_scale(copy._final_y_scale),
60 _initial_z_scale(copy._initial_z_scale),
61 _final_z_scale(copy._final_z_scale),
62 _animate_x_ratio(copy._animate_x_ratio),
63 _animate_y_ratio(copy._animate_y_ratio),
64 _animate_z_ratio(copy._animate_z_ratio)
65 {
66 _geom_node = copy._geom_node;
67 }
68
69 /**
70 * destructor
71 */
72
73 GeomParticleRenderer::
74 ~GeomParticleRenderer() {
75 kill_nodes();
76 }
77
78 /**
79 * dynamic copying
80 */
81
82 BaseParticleRenderer *GeomParticleRenderer::
83 make_copy() {
84 return new GeomParticleRenderer(*this);
85 }
86
87 /**
88 * links the child nodes to the parent stuff
89 */
90 void GeomParticleRenderer::
91 init_geoms() {
92
93 }
94
95 /**
96 * handles renderer-size resizing.
97 */
98
99 void GeomParticleRenderer::
100 resize_pool(int new_size) {
101 kill_nodes();
102
103 // now repopulate the vector with a bunch of NULLS, representing potential
104 // instances of the _geom_node.
105
106 int i;
107 for (i = 0; i < new_size; i++) {
108 _node_vector.push_back(nullptr);
109 }
110
111 _pool_size = new_size;
112 }
113
114 /**
115
116 */
117
118 void GeomParticleRenderer::
119 kill_nodes() {
120 pvector< PT(PandaNode) >::iterator vec_iter = _node_vector.begin();
121
122 PandaNode *render_node = get_render_node();
123 for (; vec_iter != _node_vector.end(); vec_iter++) {
124 PandaNode *node = *vec_iter;
125 if (node != nullptr) {
126 render_node->remove_child(node);
127 }
128 }
129
130 _node_vector.erase(_node_vector.begin(), _node_vector.end());
131 }
132
133 /**
134 * child birth
135 */
136
137 void GeomParticleRenderer::
138 birth_particle(int index) {
139 if (_node_vector[index] == nullptr) {
140 PandaNode *node = new PandaNode("");
141 get_render_node()->add_child(node);
142 node->add_child(_geom_node);
143 _node_vector[index] = node;
144 }
145 }
146
147 /**
148 * child kill
149 */
150
151 void GeomParticleRenderer::
152 kill_particle(int index) {
153 if (_node_vector[index] != nullptr) {
154 get_render_node()->remove_child(_node_vector[index]);
155 _node_vector[index] = nullptr;
156 }
157 }
158
159 /**
160 * sets the transitions on each arc
161 */
162
163 void GeomParticleRenderer::
164 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
165 PStatTimer t1(_render_collector);
166
167 BaseParticle *cur_particle;
168 int i, remaining_particles = ttl_particles;
169
170 pvector< PT(PandaNode) >::iterator cur_node_iter = _node_vector.begin();
171
172 // run through the particle vector
173
174 for (i = 0; i < (int)po_vector.size(); i++) {
175 PandaNode *cur_node;
176
177 cur_particle = (BaseParticle *) po_vector[i].p();
178 cur_node = *cur_node_iter;
179
180 if (cur_particle->get_alive()) {
181 // living particle
182 if (cur_node == nullptr) {
183 birth_particle(i);
184 cur_node = *cur_node_iter;
185 }
186 nassertv(cur_node != nullptr);
187
188 cur_node->set_state(_render_state);
189
190 PN_stdfloat t = cur_particle->get_parameterized_age();
191 LColor c = _color_interpolation_manager->generateColor(t);
192
193 if ((_alpha_mode != PR_ALPHA_NONE)) {
194 PN_stdfloat alpha_scalar;
195
196 if(_alpha_mode == PR_ALPHA_USER) {
197 alpha_scalar = get_user_alpha();
198 } else {
199 alpha_scalar = t;
200 if (_alpha_mode == PR_ALPHA_OUT)
201 alpha_scalar = 1.0f - alpha_scalar;
202 else if (_alpha_mode == PR_ALPHA_IN_OUT)
203 alpha_scalar = 2.0f * std::min(alpha_scalar, 1.0f - alpha_scalar);
204 alpha_scalar *= get_user_alpha();
205 }
206
207 c[3] *= alpha_scalar;
208 cur_node->set_attrib(ColorScaleAttrib::make
209 (LColor(1.0f, 1.0f, 1.0f, c[3])));
210 }
211
212 cur_node->set_attrib(ColorAttrib::make_flat(c), 0);
213
214 // animate scale
215 PN_stdfloat current_x_scale = _initial_x_scale;
216 PN_stdfloat current_y_scale = _initial_y_scale;
217 PN_stdfloat current_z_scale = _initial_z_scale;
218
219 if (_animate_x_ratio || _animate_y_ratio || _animate_z_ratio) {
220 if (_animate_x_ratio) {
221 current_x_scale = (_initial_x_scale +
222 (t * (_final_x_scale - _initial_x_scale)));
223 }
224 if (_animate_y_ratio) {
225 current_y_scale = (_initial_y_scale +
226 (t * (_final_y_scale - _initial_y_scale)));
227 }
228 if (_animate_z_ratio) {
229 current_z_scale = (_initial_z_scale +
230 (t * (_final_z_scale - _initial_z_scale)));
231 }
232 }
233
234 cur_node->set_transform(TransformState::make_pos_quat_scale
235 (cur_particle->get_position(),
236 cur_particle->get_orientation(),
237 LVecBase3(current_x_scale, current_y_scale, current_z_scale)));
238
239 // maybe get out early if possible.
240
241 remaining_particles--;
242
243 if (remaining_particles == 0)
244 break;
245 }
246
247 cur_node_iter++;
248 }
249 }
250
251 /**
252 * Write a string representation of this instance to <out>.
253 */
254 void GeomParticleRenderer::
255 output(std::ostream &out) const {
256 #ifndef NDEBUG //[
257 out<<"GeomParticleRenderer";
258 #endif //] NDEBUG
259 }
260
261 /**
262 * Write a string representation of this instance to <out>.
263 */
264 void GeomParticleRenderer::
265 write_linear_forces(std::ostream &out, int indent) const {
266 #ifndef NDEBUG //[
267 out.width(indent);
268 out<<""<<"_node_vector ("<<_node_vector.size()<<" forces)\n";
269 for (pvector< PT(PandaNode) >::const_iterator i=_node_vector.begin();
270 i != _node_vector.end();
271 ++i) {
272 (*i)->write(out, indent+2);
273 }
274 #endif //] NDEBUG
275 }
276
277 /**
278 * Write a string representation of this instance to <out>.
279 */
280 void GeomParticleRenderer::
281 write(std::ostream &out, int indent) const {
282 #ifndef NDEBUG //[
283 out.width(indent); out<<""; out<<"GeomParticleRenderer:\n";
284 out.width(indent+2); out<<""; out<<"_geom_node "<<_geom_node<<"\n";
285 out.width(indent+2); out<<""; out<<"_pool_size "<<_pool_size<<"\n";
286
287 out.width(indent+2); out<<""; out<<"_initial_x_scale "<<_initial_x_scale<<"\n";
288 out.width(indent+2); out<<""; out<<"_final_x_scale "<<_final_x_scale<<"\n";
289 out.width(indent+2); out<<""; out<<"_initial_y_scale "<<_initial_y_scale<<"\n";
290 out.width(indent+2); out<<""; out<<"_final_y_scale "<<_final_y_scale<<"\n";
291 out.width(indent+2); out<<""; out<<"_initial_z_scale "<<_initial_z_scale<<"\n";
292 out.width(indent+2); out<<""; out<<"_final_z_scale "<<_final_z_scale<<"\n";
293 out.width(indent+2); out<<""; out<<"_animate_x_ratio "<<_animate_x_ratio<<"\n";
294 out.width(indent+2); out<<""; out<<"_animate_y_ratio "<<_animate_y_ratio<<"\n";
295 out.width(indent+2); out<<""; out<<"_animate_z_ratio "<<_animate_z_ratio<<"\n";
296
297 write_linear_forces(out, indent+2);
298 BaseParticleRenderer::write(out, indent+2);
299 #endif //] NDEBUG
300 }
baseParticle.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BaseParticleRenderer
Pure virtual particle renderer base class.
Definition: baseParticleRenderer.h:32
BaseParticleRenderer::get_render_node
GeomNode * get_render_node() const
Query the geomnode pointer.
Definition: baseParticleRenderer.I:18
BaseParticleRenderer::get_user_alpha
PN_stdfloat get_user_alpha() const
gets alpha for "user" alpha mode
Definition: baseParticleRenderer.I:59
BaseParticleRenderer::write
virtual void write(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
Definition: baseParticleRenderer.cxx:92
BaseParticle
An individual, physically-modelable particle abstract base class.
Definition: baseParticle.h:23
ColorInterpolationManager
High level class for color interpolation.
Definition: colorInterpolationManager.h:269
GeomParticleRenderer
Definition: geomParticleRenderer.h:26
GeomParticleRenderer::~GeomParticleRenderer
virtual ~GeomParticleRenderer()
destructor
Definition: geomParticleRenderer.cxx:74
GeomParticleRenderer::write
virtual void write(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
Definition: geomParticleRenderer.cxx:281
GeomParticleRenderer::make_copy
virtual BaseParticleRenderer * make_copy()
dynamic copying
Definition: geomParticleRenderer.cxx:83
GeomParticleRenderer::write_linear_forces
virtual void write_linear_forces(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
Definition: geomParticleRenderer.cxx:265
GeomParticleRenderer::GeomParticleRenderer
GeomParticleRenderer(ParticleRendererAlphaMode am=PR_ALPHA_NONE, PandaNode *geom_node=nullptr)
constructor
Definition: geomParticleRenderer.cxx:29
GeomParticleRenderer::output
virtual void output(std::ostream &out) const
Write a string representation of this instance to <out>.
Definition: geomParticleRenderer.cxx:255
PStatCollector
A lightweight class that represents a single element that may be timed and/or counted via stats.
Definition: pStatCollector.h:43
PStatTimer
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:30
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
PandaNode::remove_child
void remove_child(int child_index, Thread *current_thread=Thread::get_current_thread())
Removes the nth child from the node.
Definition: pandaNode.cxx:564
PandaNode::set_state
set_state
Sets the complete RenderState that will be applied to all nodes at this level and below.
Definition: pandaNode.h:173
PandaNode::set_transform
set_transform
Sets the transform that will be applied to this node and below.
Definition: pandaNode.h:183
PandaNode::set_attrib
void set_attrib(const RenderAttrib *attrib, int override=0)
Adds the indicated render attribute to the scene graph on this node.
Definition: pandaNode.cxx:938
PhysicsObject
A body on which physics will be applied.
Definition: physicsObject.h:27
PhysicsObject::get_position
get_position
Position Query.
Definition: physicsObject.h:105
PhysicsObject::get_orientation
get_orientation
get current orientation.
Definition: physicsObject.h:111
pvector
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
colorAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
colorScaleAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomParticleRenderer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
pStatTimer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
transformState.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.