00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "geomParticleRenderer.h"
00016 #include "baseParticle.h"
00017
00018 #include "transformState.h"
00019 #include "colorScaleAttrib.h"
00020 #include "colorAttrib.h"
00021 #include "pStatTimer.h"
00022
00023 PStatCollector GeomParticleRenderer::_render_collector("App:Particles:Geom:Render");
00024
00025
00026
00027
00028
00029
00030
00031 GeomParticleRenderer::
00032 GeomParticleRenderer(ParticleRendererAlphaMode am, PandaNode *geom_node) :
00033 BaseParticleRenderer(am),
00034 _geom_node(geom_node),
00035 _color_interpolation_manager(new ColorInterpolationManager(LColor(1.0f,1.0f,1.0f,1.0f))),
00036 _pool_size(0),
00037 _initial_x_scale(1.0f),
00038 _final_x_scale(1.0f),
00039 _initial_y_scale(1.0f),
00040 _final_y_scale(1.0f),
00041 _initial_z_scale(1.0f),
00042 _final_z_scale(1.0f),
00043 _animate_x_ratio(false),
00044 _animate_y_ratio(false),
00045 _animate_z_ratio(false)
00046 {
00047 if (_geom_node.is_null())
00048 _geom_node = new PandaNode("empty");
00049 }
00050
00051
00052
00053
00054
00055
00056
00057 GeomParticleRenderer::
00058 GeomParticleRenderer(const GeomParticleRenderer& copy) :
00059 BaseParticleRenderer(copy),
00060 _pool_size(0),
00061 _initial_x_scale(copy._initial_x_scale),
00062 _final_x_scale(copy._final_x_scale),
00063 _initial_y_scale(copy._initial_y_scale),
00064 _final_y_scale(copy._final_y_scale),
00065 _initial_z_scale(copy._initial_z_scale),
00066 _final_z_scale(copy._final_z_scale),
00067 _animate_x_ratio(copy._animate_x_ratio),
00068 _animate_y_ratio(copy._animate_y_ratio),
00069 _animate_z_ratio(copy._animate_z_ratio)
00070 {
00071 _geom_node = copy._geom_node;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 GeomParticleRenderer::
00081 ~GeomParticleRenderer() {
00082 kill_nodes();
00083 }
00084
00085
00086
00087
00088
00089
00090
00091 BaseParticleRenderer *GeomParticleRenderer::
00092 make_copy() {
00093 return new GeomParticleRenderer(*this);
00094 }
00095
00096
00097
00098
00099
00100
00101 void GeomParticleRenderer::
00102 init_geoms() {
00103
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 void GeomParticleRenderer::
00113 resize_pool(int new_size) {
00114 kill_nodes();
00115
00116
00117
00118
00119 int i;
00120 for (i = 0; i < new_size; i++) {
00121 _node_vector.push_back(NULL);
00122 }
00123
00124 _pool_size = new_size;
00125 }
00126
00127
00128
00129
00130
00131
00132 void GeomParticleRenderer::
00133 kill_nodes() {
00134 pvector< PT(PandaNode) >::iterator vec_iter = _node_vector.begin();
00135
00136 PandaNode *render_node = get_render_node();
00137 for (; vec_iter != _node_vector.end(); vec_iter++) {
00138 PandaNode *node = *vec_iter;
00139 if (node != (PandaNode *)NULL) {
00140 render_node->remove_child(node);
00141 }
00142 }
00143
00144 _node_vector.erase(_node_vector.begin(), _node_vector.end());
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 void GeomParticleRenderer::
00154 birth_particle(int index) {
00155 if (_node_vector[index] == (PandaNode *)NULL) {
00156 PandaNode *node = new PandaNode("");
00157 get_render_node()->add_child(node);
00158 node->add_child(_geom_node);
00159 _node_vector[index] = node;
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 void GeomParticleRenderer::
00170 kill_particle(int index) {
00171 if (_node_vector[index] != (PandaNode *)NULL) {
00172 get_render_node()->remove_child(_node_vector[index]);
00173 _node_vector[index] = (PandaNode *)NULL;
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182
00183 void GeomParticleRenderer::
00184 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
00185 PStatTimer t1(_render_collector);
00186
00187 BaseParticle *cur_particle;
00188 int i, remaining_particles = ttl_particles;
00189
00190 pvector< PT(PandaNode) >::iterator cur_node_iter = _node_vector.begin();
00191
00192
00193
00194 for (i = 0; i < (int)po_vector.size(); i++) {
00195 PandaNode *cur_node;
00196
00197 cur_particle = (BaseParticle *) po_vector[i].p();
00198 cur_node = *cur_node_iter;
00199
00200 if (cur_particle->get_alive()) {
00201
00202 if (cur_node == (PandaNode *)NULL) {
00203 birth_particle(i);
00204 cur_node = *cur_node_iter;
00205 }
00206 nassertv(cur_node != (PandaNode *)NULL);
00207
00208 cur_node->set_state(_render_state);
00209
00210 PN_stdfloat t = cur_particle->get_parameterized_age();
00211 LColor c = _color_interpolation_manager->generateColor(t);
00212
00213 if ((_alpha_mode != PR_ALPHA_NONE)) {
00214 PN_stdfloat alpha_scalar;
00215
00216 if(_alpha_mode == PR_ALPHA_USER) {
00217 alpha_scalar = get_user_alpha();
00218 } else {
00219 alpha_scalar = t;
00220 if (_alpha_mode == PR_ALPHA_OUT)
00221 alpha_scalar = 1.0f - alpha_scalar;
00222 else if (_alpha_mode == PR_ALPHA_IN_OUT)
00223 alpha_scalar = 2.0f * min(alpha_scalar, 1.0f - alpha_scalar);
00224 alpha_scalar *= get_user_alpha();
00225 }
00226
00227 c[3] *= alpha_scalar;
00228 cur_node->set_attrib(ColorScaleAttrib::make
00229 (LColor(1.0f, 1.0f, 1.0f, c[3])));
00230 }
00231
00232 cur_node->set_attrib(ColorAttrib::make_flat(c), 0);
00233
00234
00235 PN_stdfloat current_x_scale = _initial_x_scale;
00236 PN_stdfloat current_y_scale = _initial_y_scale;
00237 PN_stdfloat current_z_scale = _initial_z_scale;
00238
00239 if (_animate_x_ratio || _animate_y_ratio || _animate_z_ratio) {
00240 if (_animate_x_ratio) {
00241 current_x_scale = (_initial_x_scale +
00242 (t * (_final_x_scale - _initial_x_scale)));
00243 }
00244 if (_animate_y_ratio) {
00245 current_y_scale = (_initial_y_scale +
00246 (t * (_final_y_scale - _initial_y_scale)));
00247 }
00248 if (_animate_z_ratio) {
00249 current_z_scale = (_initial_z_scale +
00250 (t * (_final_z_scale - _initial_z_scale)));
00251 }
00252 }
00253
00254 cur_node->set_transform(TransformState::make_pos_quat_scale
00255 (cur_particle->get_position(),
00256 cur_particle->get_orientation(),
00257 LVecBase3(current_x_scale, current_y_scale, current_z_scale)));
00258
00259
00260
00261 remaining_particles--;
00262
00263 if (remaining_particles == 0)
00264 break;
00265 }
00266
00267 cur_node_iter++;
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 void GeomParticleRenderer::
00278 output(ostream &out) const {
00279 #ifndef NDEBUG //[
00280 out<<"GeomParticleRenderer";
00281 #endif //] NDEBUG
00282 }
00283
00284
00285
00286
00287
00288
00289
00290 void GeomParticleRenderer::
00291 write_linear_forces(ostream &out, int indent) const {
00292 #ifndef NDEBUG //[
00293 out.width(indent);
00294 out<<""<<"_node_vector ("<<_node_vector.size()<<" forces)\n";
00295 for (pvector< PT(PandaNode) >::const_iterator i=_node_vector.begin();
00296 i != _node_vector.end();
00297 ++i) {
00298 (*i)->write(out, indent+2);
00299 }
00300 #endif //] NDEBUG
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 void GeomParticleRenderer::
00310 write(ostream &out, int indent) const {
00311 #ifndef NDEBUG //[
00312 out.width(indent); out<<""; out<<"GeomParticleRenderer:\n";
00313 out.width(indent+2); out<<""; out<<"_geom_node "<<_geom_node<<"\n";
00314 out.width(indent+2); out<<""; out<<"_pool_size "<<_pool_size<<"\n";
00315
00316 out.width(indent+2); out<<""; out<<"_initial_x_scale "<<_initial_x_scale<<"\n";
00317 out.width(indent+2); out<<""; out<<"_final_x_scale "<<_final_x_scale<<"\n";
00318 out.width(indent+2); out<<""; out<<"_initial_y_scale "<<_initial_y_scale<<"\n";
00319 out.width(indent+2); out<<""; out<<"_final_y_scale "<<_final_y_scale<<"\n";
00320 out.width(indent+2); out<<""; out<<"_initial_z_scale "<<_initial_z_scale<<"\n";
00321 out.width(indent+2); out<<""; out<<"_final_z_scale "<<_final_z_scale<<"\n";
00322 out.width(indent+2); out<<""; out<<"_animate_x_ratio "<<_animate_x_ratio<<"\n";
00323 out.width(indent+2); out<<""; out<<"_animate_y_ratio "<<_animate_y_ratio<<"\n";
00324 out.width(indent+2); out<<""; out<<"_animate_z_ratio "<<_animate_z_ratio<<"\n";
00325
00326 write_linear_forces(out, indent+2);
00327 BaseParticleRenderer::write(out, indent+2);
00328 #endif //] NDEBUG
00329 }