Panda3D
 All Classes Functions Variables Enumerations
geomParticleRenderer.cxx
00001 // Filename: geomParticleRenderer.cxx
00002 // Created by:  charles (05Jul00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
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 //    Function : GeomParticleRenderer
00027 //      Access : public
00028 // Description : constructor
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 //    Function : GeomParticleRenderer
00053 //      Access : public
00054 // Description : copy constructor
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 //    Function : ~GeomParticleRenderer
00076 //      Access : public
00077 // Description : destructor
00078 ////////////////////////////////////////////////////////////////////
00079 
00080 GeomParticleRenderer::
00081 ~GeomParticleRenderer() {
00082   kill_nodes();
00083 }
00084 
00085 ////////////////////////////////////////////////////////////////////
00086 //    Function : make_copy
00087 //      Access : public
00088 // Description : dynamic copying
00089 ////////////////////////////////////////////////////////////////////
00090 
00091 BaseParticleRenderer *GeomParticleRenderer::
00092 make_copy() {
00093   return new GeomParticleRenderer(*this);
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //    Function : init_geoms
00098 //      Access : private
00099 // Description : links the child nodes to the parent stuff
00100 ////////////////////////////////////////////////////////////////////
00101 void GeomParticleRenderer::
00102 init_geoms() {
00103 
00104 }
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //    Function : resize_pool
00108 //      Access : private
00109 // Description : handles renderer-size resizing.
00110 ////////////////////////////////////////////////////////////////////
00111 
00112 void GeomParticleRenderer::
00113 resize_pool(int new_size) {
00114   kill_nodes();
00115 
00116   // now repopulate the vector with a bunch of NULLS, representing
00117   // potential instances of the _geom_node.
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 //  Function : kill_nodes
00129 //    Access : private
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 //    Function : birth_particle
00149 //      Access : Private, virtual
00150 // Description : child birth
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 //    Function : kill_particle
00165 //      Access : Private, virtual
00166 // Description : child kill
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 //    Function : render
00179 //      Access : private
00180 // Description : sets the transitions on each arc
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   // run through the particle vector
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       // living particle
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       // animate scale
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       // maybe get out early if possible.
00260 
00261       remaining_particles--;
00262 
00263       if (remaining_particles == 0)
00264         break;
00265     }
00266 
00267     cur_node_iter++;
00268   }
00269 }
00270 
00271 ////////////////////////////////////////////////////////////////////
00272 //     Function : output
00273 //       Access : Public
00274 //  Description : Write a string representation of this instance to
00275 //                <out>.
00276 ////////////////////////////////////////////////////////////////////
00277 void GeomParticleRenderer::
00278 output(ostream &out) const {
00279   #ifndef NDEBUG //[
00280   out<<"GeomParticleRenderer";
00281   #endif //] NDEBUG
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function : write_linear_forces
00286 //       Access : Public
00287 //  Description : Write a string representation of this instance to
00288 //                <out>.
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 //     Function : write
00305 //       Access : Public
00306 //  Description : Write a string representation of this instance to
00307 //                <out>.
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 }
 All Classes Functions Variables Enumerations