Panda3D
 All Classes Functions Variables Enumerations
pointParticleRenderer.cxx
00001 // Filename: pointParticleRenderer.cxx
00002 // Created by:  charles (20Jun00)
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 "pointParticleRenderer.h"
00016 #include "boundingSphere.h"
00017 #include "geomNode.h"
00018 #include "geom.h"
00019 #include "geomVertexWriter.h"
00020 #include "indent.h"
00021 #include "pStatTimer.h"
00022 
00023 PStatCollector PointParticleRenderer::_render_collector("App:Particles:Point:Render");
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //    Function : PointParticleRenderer
00027 //      Access : Public
00028 // Description : special constructor
00029 ////////////////////////////////////////////////////////////////////
00030 
00031 PointParticleRenderer::
00032 PointParticleRenderer(ParticleRendererAlphaMode am,
00033                       PN_stdfloat point_size,
00034                       PointParticleBlendType bt,
00035                       ParticleRendererBlendMethod bm,
00036                       const LColor& sc, const LColor& ec) :
00037   BaseParticleRenderer(am),
00038   _start_color(sc), _end_color(ec),
00039   _blend_type(bt), _blend_method(bm)
00040 {
00041   set_point_size(point_size);
00042   resize_pool(0);
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //    Function : PointParticleRenderer
00047 //      Access : Public
00048 // Description : Copy constructor
00049 ////////////////////////////////////////////////////////////////////
00050 
00051 PointParticleRenderer::
00052 PointParticleRenderer(const PointParticleRenderer& copy) :
00053   BaseParticleRenderer(copy)
00054 {
00055   _blend_type = copy._blend_type;
00056   _blend_method = copy._blend_method;
00057   _start_color = copy._start_color;
00058   _end_color = copy._end_color;
00059   _point_size = copy._point_size;
00060   _thick = copy._thick;
00061   resize_pool(0);
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //    Function : ~PointParticleRenderer
00066 //      Access : Public
00067 // Description : Simple destructor
00068 ////////////////////////////////////////////////////////////////////
00069 
00070 PointParticleRenderer::
00071 ~PointParticleRenderer() {
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //    Function : make_copy
00076 //      Access : Public
00077 // Description : for spawning systems from dead particles
00078 ////////////////////////////////////////////////////////////////////
00079 
00080 BaseParticleRenderer *PointParticleRenderer::
00081 make_copy() {
00082   return new PointParticleRenderer(*this);
00083 }
00084 
00085 ////////////////////////////////////////////////////////////////////
00086 //    Function : resize_pool
00087 //      Access : Public
00088 // Description : reallocate the space for the vertex and color
00089 //               pools
00090 ////////////////////////////////////////////////////////////////////
00091 
00092 void PointParticleRenderer::
00093 resize_pool(int new_size) {
00094   if (new_size == _max_pool_size)
00095     return;
00096 
00097   _max_pool_size = new_size;
00098 
00099   init_geoms();
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //    Function : init_geoms
00104 //      Access : Private
00105 // Description : On-construction initialization
00106 ////////////////////////////////////////////////////////////////////
00107 
00108 void PointParticleRenderer::
00109 init_geoms() {
00110   _vdata = new GeomVertexData
00111     ("point_particles", GeomVertexFormat::get_v3cp(),
00112      Geom::UH_stream);
00113   PT(Geom) geom = new Geom(_vdata);
00114   _point_primitive = geom;
00115   _points = new GeomPoints(Geom::UH_stream);
00116   geom->add_primitive(_points);
00117   
00118   GeomNode *render_node = get_render_node();
00119   render_node->remove_all_geoms();
00120   render_node->add_geom(_point_primitive, _render_state->add_attrib(_thick));
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //    Function : birth_particle
00125 //      Access : Private, virtual
00126 // Description : child birth
00127 ////////////////////////////////////////////////////////////////////
00128 
00129 void PointParticleRenderer::
00130 birth_particle(int) {
00131 }
00132 
00133 ////////////////////////////////////////////////////////////////////
00134 //    Function : kill_particle
00135 //      Access : Private, virtual
00136 // Description : child kill
00137 ////////////////////////////////////////////////////////////////////
00138 
00139 void PointParticleRenderer::
00140 kill_particle(int) {
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //    Function : create_color
00145 //      Access : Private
00146 // Description : Generates the point color based on the render_type
00147 ////////////////////////////////////////////////////////////////////
00148 
00149 LColor PointParticleRenderer::
00150 create_color(const BaseParticle *p) {
00151   LColor color;
00152   PN_stdfloat life_t, vel_t;
00153   PN_stdfloat parameterized_age = 1.0f;
00154   bool have_alpha_t = false;
00155 
00156   switch (_blend_type) {
00157 
00158     //// Constant solid color
00159 
00160   case PP_ONE_COLOR:
00161     color = _start_color;
00162     break;
00163 
00164     //// Blending colors based on life
00165 
00166   case PP_BLEND_LIFE:
00167     parameterized_age = p->get_parameterized_age();
00168     life_t = parameterized_age;
00169     have_alpha_t = true;
00170 
00171     if (_blend_method == PP_BLEND_CUBIC)
00172       life_t = CUBIC_T(life_t);
00173     
00174     color = LERP(life_t, _start_color, _end_color);
00175     
00176     break;
00177     
00178     //// Blending colors based on vel
00179 
00180   case PP_BLEND_VEL:
00181     vel_t = p->get_parameterized_vel();
00182 
00183     if (_blend_method == PP_BLEND_CUBIC)
00184       vel_t = CUBIC_T(vel_t);
00185 
00186     color = LERP(vel_t, _start_color, _end_color);
00187 
00188     break;
00189   }
00190 
00191   // handle alpha channel
00192 
00193   if(_alpha_mode != PR_ALPHA_NONE) {
00194     if(_alpha_mode == PR_ALPHA_USER) {
00195       parameterized_age = 1.0;
00196     } else {
00197       if(!have_alpha_t)
00198         parameterized_age = p->get_parameterized_age();
00199 
00200       if(_alpha_mode==PR_ALPHA_OUT) {
00201         parameterized_age = 1.0f - parameterized_age;
00202       } else if(_alpha_mode==PR_ALPHA_IN_OUT) {
00203         parameterized_age = 2.0f * min(parameterized_age, 
00204                                       1.0f - parameterized_age);
00205       }
00206     }
00207     color[3] = parameterized_age * get_user_alpha();
00208   }
00209 
00210   return color;
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //    Function : render
00215 //      Access : Public
00216 // Description : renders the particle system out to a GeomNode
00217 ////////////////////////////////////////////////////////////////////
00218 
00219 void PointParticleRenderer::
00220 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
00221   PStatTimer t1(_render_collector);
00222 
00223   BaseParticle *cur_particle;
00224 
00225   int remaining_particles = ttl_particles;
00226   int i;
00227 
00228   GeomVertexWriter vertex(_vdata, InternalName::get_vertex());
00229   GeomVertexWriter color(_vdata, InternalName::get_color());
00230 
00231   // init the aabb
00232 
00233   _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
00234   _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
00235 
00236   // run through every filled slot
00237 
00238   for (i = 0; i < (int)po_vector.size(); i++) {
00239     cur_particle = (BaseParticle *) po_vector[i].p();
00240 
00241     if (!cur_particle->get_alive())
00242       continue;
00243 
00244     LPoint3 position = cur_particle->get_position();
00245 
00246     // x aabb adjust
00247 
00248     if (position[0] > _aabb_max[0])
00249       _aabb_max[0] = position[0];
00250     else if (position[0] < _aabb_min[0])
00251       _aabb_min[0] = position[0];
00252 
00253     // y aabb adjust
00254 
00255     if (position[1] > _aabb_max[1])
00256       _aabb_max[1] = position[1];
00257     else if (position[1] < _aabb_min[1])
00258       _aabb_min[1] = position[1];
00259 
00260     // z aabb adjust
00261 
00262     if (position[2] > _aabb_max[2])
00263       _aabb_max[2] = position[2];
00264     else if (position[2] < _aabb_min[2])
00265       _aabb_min[2] = position[2];
00266 
00267     // stuff it into the arrays
00268 
00269     vertex.add_data3(position);
00270     color.add_data4(create_color(cur_particle));
00271 
00272     // maybe jump out early?
00273 
00274     remaining_particles--;
00275     if (remaining_particles == 0)
00276       break;
00277   }
00278 
00279   _points->clear_vertices();
00280   _points->add_next_vertices(ttl_particles);
00281 
00282   // done filling geompoint node, now do the bb stuff
00283 
00284   LPoint3 aabb_center = _aabb_min + ((_aabb_max - _aabb_min) * 0.5f);
00285   PN_stdfloat radius = (aabb_center - _aabb_min).length();
00286 
00287   BoundingSphere sphere(aabb_center, radius);
00288   _point_primitive->set_bounds(&sphere);
00289   get_render_node()->mark_internal_bounds_stale();
00290 }
00291 
00292 ////////////////////////////////////////////////////////////////////
00293 //     Function : output
00294 //       Access : Public
00295 //  Description : Write a string representation of this instance to
00296 //                <out>.
00297 ////////////////////////////////////////////////////////////////////
00298 void PointParticleRenderer::
00299 output(ostream &out) const {
00300   #ifndef NDEBUG //[
00301   out<<"PointParticleRenderer";
00302   #endif //] NDEBUG
00303 }
00304 
00305 ////////////////////////////////////////////////////////////////////
00306 //     Function : write
00307 //       Access : Public
00308 //  Description : Write a string representation of this instance to
00309 //                <out>.
00310 ////////////////////////////////////////////////////////////////////
00311 void PointParticleRenderer::
00312 write(ostream &out, int indent_level) const {
00313   indent(out, indent_level) << "PointParticleRenderer:\n";
00314   indent(out, indent_level + 2) << "_start_color "<<_start_color<<"\n";
00315   indent(out, indent_level + 2) << "_end_color "<<_end_color<<"\n";
00316   indent(out, indent_level + 2) << "_point_size "<<_point_size<<"\n";
00317   indent(out, indent_level + 2) << "_point_primitive "<<_point_primitive<<"\n";
00318   indent(out, indent_level + 2) << "_max_pool_size "<<_max_pool_size<<"\n";
00319   indent(out, indent_level + 2) << "_blend_type "<<_blend_type<<"\n";
00320   indent(out, indent_level + 2) << "_blend_method "<<_blend_method<<"\n";
00321   indent(out, indent_level + 2) << "_aabb_min "<<_aabb_min<<"\n";
00322   indent(out, indent_level + 2) << "_aabb_max "<<_aabb_max<<"\n";
00323   BaseParticleRenderer::write(out, indent_level + 2);
00324 }
 All Classes Functions Variables Enumerations