Panda3D
 All Classes Functions Variables Enumerations
sparkleParticleRenderer.cxx
00001 // Filename: sparkleParticleRenderer.cxx
00002 // Created by:  charles (27Jun00)
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 "sparkleParticleRenderer.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 SparkleParticleRenderer::_render_collector("App:Particles:Sparkle:Render");
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //    Function : SparkleParticleRenderer
00027 //      Access : Public
00028 // Description : Default Constructor
00029 ////////////////////////////////////////////////////////////////////
00030 SparkleParticleRenderer::
00031 SparkleParticleRenderer() :
00032   BaseParticleRenderer(PR_ALPHA_NONE),
00033   _center_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)),
00034   _edge_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)),
00035   _birth_radius(0.1f), _death_radius(0.1f)
00036 {
00037   resize_pool(0);
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //    Function : SparkleParticleRenderer
00042 //      Access : Public
00043 // Description : Constructor
00044 ////////////////////////////////////////////////////////////////////
00045 SparkleParticleRenderer::
00046 SparkleParticleRenderer(const LColor& center, const LColor& edge,
00047                         PN_stdfloat birth_radius, PN_stdfloat death_radius,
00048                         SparkleParticleLifeScale life_scale,
00049                         ParticleRendererAlphaMode alpha_mode) :
00050   BaseParticleRenderer(alpha_mode),
00051   _center_color(center), _edge_color(edge), _birth_radius(birth_radius),
00052   _death_radius(death_radius), _life_scale(life_scale)
00053 {
00054   resize_pool(0);
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //    Function : SparkleParticleRenderer
00059 //      Access : Public
00060 // Description : Copy Constructor
00061 ////////////////////////////////////////////////////////////////////
00062 SparkleParticleRenderer::
00063 SparkleParticleRenderer(const SparkleParticleRenderer& copy) :
00064   BaseParticleRenderer(copy) {
00065   _center_color = copy._center_color;
00066   _edge_color = copy._edge_color;
00067   _birth_radius = copy._birth_radius;
00068   _death_radius = copy._death_radius;
00069   _life_scale = copy._life_scale;
00070 
00071   resize_pool(0);
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //    Function : ~SparkleParticleRenderer
00076 //      Access : Public
00077 // Description : Destructor
00078 ////////////////////////////////////////////////////////////////////
00079 SparkleParticleRenderer::
00080 ~SparkleParticleRenderer() {
00081 }
00082 
00083 ////////////////////////////////////////////////////////////////////
00084 //    Function : make copy
00085 //      Access : Public
00086 // Description : child virtual for spawning systems
00087 ////////////////////////////////////////////////////////////////////
00088 BaseParticleRenderer *SparkleParticleRenderer::
00089 make_copy() {
00090   return new SparkleParticleRenderer(*this);
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //    Function : birth_particle
00095 //      Access : Private, virtual
00096 // Description : child birth
00097 ////////////////////////////////////////////////////////////////////
00098 void SparkleParticleRenderer::
00099 birth_particle(int) {
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //    Function : kill_particle
00104 //      Access : Private, virtual
00105 // Description : child kill
00106 ////////////////////////////////////////////////////////////////////
00107 void SparkleParticleRenderer::
00108 kill_particle(int) {
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //    Function : resize_pool
00113 //      Access : private
00114 // Description : resizes the render pool.  Reference counting
00115 //               makes this easy.
00116 ////////////////////////////////////////////////////////////////////
00117 void SparkleParticleRenderer::
00118 resize_pool(int new_size) {
00119   _max_pool_size = new_size;
00120 
00121   init_geoms();
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //    Function : init_geoms
00126 //      Access : private
00127 // Description : initializes the geomnodes
00128 ////////////////////////////////////////////////////////////////////
00129 void SparkleParticleRenderer::
00130 init_geoms() {
00131   _vdata = new GeomVertexData
00132     ("sparkle_particles", GeomVertexFormat::get_v3cp(),
00133      Geom::UH_stream);
00134   PT(Geom) geom = new Geom(_vdata);
00135   _line_primitive = geom;
00136   _lines = new GeomLines(Geom::UH_stream);
00137   geom->add_primitive(_lines);
00138 
00139   GeomNode *render_node = get_render_node();
00140   render_node->remove_all_geoms();
00141   render_node->add_geom(_line_primitive, _render_state);
00142 }
00143 
00144 ////////////////////////////////////////////////////////////////////
00145 //    Function : render
00146 //      Access : private
00147 // Description : populates the GeomLine
00148 ////////////////////////////////////////////////////////////////////
00149 void SparkleParticleRenderer::
00150 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
00151   PStatTimer t1(_render_collector);
00152   if (!ttl_particles) {
00153     return;
00154   }
00155 
00156   BaseParticle *cur_particle;
00157 
00158   int remaining_particles = ttl_particles;
00159   int i;
00160 
00161   GeomVertexWriter vertex(_vdata, InternalName::get_vertex());
00162   GeomVertexWriter color(_vdata, InternalName::get_color());
00163   _lines->clear_vertices();
00164 
00165   // init the aabb
00166 
00167   _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
00168   _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
00169 
00170   // run through the array
00171 
00172   for (i = 0; i < (int)po_vector.size(); i++) {
00173     cur_particle = (BaseParticle *) po_vector[i].p();
00174 
00175     if (cur_particle->get_alive() == false) {
00176       continue;
00177     }
00178 
00179     LPoint3 position = cur_particle->get_position();
00180 
00181     // adjust the aabb
00182 
00183     if (position[0] > _aabb_max[0])
00184       _aabb_max[0] = position[0];
00185     else if (position[0] < _aabb_min[0])
00186       _aabb_min[0] = position[0];
00187 
00188     if (position[1] > _aabb_max[1])
00189       _aabb_max[1] = position[1];
00190     else if (position[1] < _aabb_min[1])
00191       _aabb_min[1] = position[1];
00192 
00193     if (position[2] > _aabb_max[2])
00194       _aabb_max[2] = position[2];
00195     else if (position[2] < _aabb_min[2])
00196       _aabb_min[2] = position[2];
00197 
00198     // draw the particle.
00199 
00200     PN_stdfloat radius = get_radius(cur_particle);
00201     PN_stdfloat neg_radius = -radius;
00202     PN_stdfloat alpha;
00203 
00204     LColor center_color = _center_color;
00205     LColor edge_color = _edge_color;
00206 
00207     // handle alpha
00208 
00209     if (_alpha_mode != PR_ALPHA_NONE) {
00210       if(_alpha_mode == PR_ALPHA_USER) {
00211         alpha = get_user_alpha();
00212       } else {
00213         alpha = cur_particle->get_parameterized_age();
00214         if (_alpha_mode == PR_ALPHA_OUT)
00215           alpha = 1.0f - alpha;
00216         else if (_alpha_mode == PR_ALPHA_IN_OUT)
00217           alpha = 2.0f * min(alpha, 1.0f - alpha);
00218 
00219         alpha *= get_user_alpha();
00220       }
00221 
00222       center_color[3] = alpha;
00223       edge_color[3] = alpha;
00224     }
00225 
00226     // 6 lines coming from the center point.
00227 
00228     vertex.add_data3(position);
00229     vertex.add_data3(position + LVertex(radius, 0.0f, 0.0f));
00230     vertex.add_data3(position);
00231     vertex.add_data3(position + LVertex(neg_radius, 0.0f, 0.0f));
00232     vertex.add_data3(position);
00233     vertex.add_data3(position + LVertex(0.0f, radius, 0.0f));
00234     vertex.add_data3(position);
00235     vertex.add_data3(position + LVertex(0.0f, neg_radius, 0.0f));
00236     vertex.add_data3(position);
00237     vertex.add_data3(position + LVertex(0.0f, 0.0f, radius));
00238     vertex.add_data3(position);
00239     vertex.add_data3(position + LVertex(0.0f, 0.0f, neg_radius));
00240 
00241     color.add_data4(center_color);
00242     color.add_data4(edge_color);
00243     color.add_data4(center_color);
00244     color.add_data4(edge_color);
00245     color.add_data4(center_color);
00246     color.add_data4(edge_color);
00247     color.add_data4(center_color);
00248     color.add_data4(edge_color);
00249     color.add_data4(center_color);
00250     color.add_data4(edge_color);
00251     color.add_data4(center_color);
00252     color.add_data4(edge_color);
00253     
00254     _lines->add_next_vertices(2);
00255     _lines->close_primitive();
00256     _lines->add_next_vertices(2);
00257     _lines->close_primitive();
00258     _lines->add_next_vertices(2);
00259     _lines->close_primitive();
00260     _lines->add_next_vertices(2);
00261     _lines->close_primitive();
00262     _lines->add_next_vertices(2);
00263     _lines->close_primitive();
00264     _lines->add_next_vertices(2);
00265     _lines->close_primitive();
00266     
00267     remaining_particles--;
00268     if (remaining_particles == 0) {
00269       break;
00270     }
00271   }
00272 
00273   // done filling geomline node, now do the bb stuff
00274 
00275   LPoint3 aabb_center = _aabb_min + ((_aabb_max - _aabb_min) * 0.5f);
00276   PN_stdfloat radius = (aabb_center - _aabb_min).length();
00277 
00278   BoundingSphere sphere(aabb_center, radius);
00279   _line_primitive->set_bounds(&sphere);
00280   get_render_node()->mark_internal_bounds_stale();
00281 }
00282 
00283 ////////////////////////////////////////////////////////////////////
00284 //     Function : output
00285 //       Access : Public
00286 //  Description : Write a string representation of this instance to
00287 //                <out>.
00288 ////////////////////////////////////////////////////////////////////
00289 void SparkleParticleRenderer::
00290 output(ostream &out) const {
00291   #ifndef NDEBUG //[
00292   out<<"SparkleParticleRenderer";
00293   #endif //] NDEBUG
00294 }
00295 
00296 ////////////////////////////////////////////////////////////////////
00297 //     Function : write
00298 //       Access : Public
00299 //  Description : Write a string representation of this instance to
00300 //                <out>.
00301 ////////////////////////////////////////////////////////////////////
00302 void SparkleParticleRenderer::
00303 write(ostream &out, int indent_level) const {
00304   indent(out, indent_level) << "SparkleParticleRenderer:\n";
00305   indent(out, indent_level + 2) << "_center_color "<<_center_color<<"\n";
00306   indent(out, indent_level + 2) << "_edge_color "<<_edge_color<<"\n";
00307   indent(out, indent_level + 2) << "_birth_radius "<<_birth_radius<<"\n";
00308   indent(out, indent_level + 2) << "_death_radius "<<_death_radius<<"\n";
00309   indent(out, indent_level + 2) << "_line_primitive "<<_line_primitive<<"\n";
00310   indent(out, indent_level + 2) << "_max_pool_size "<<_max_pool_size<<"\n";
00311   indent(out, indent_level + 2) << "_life_scale "<<_life_scale<<"\n";
00312   indent(out, indent_level + 2) << "_aabb_min "<<_aabb_min<<"\n";
00313   indent(out, indent_level + 2) << "_aabb_max "<<_aabb_max<<"\n";
00314   BaseParticleRenderer::write(out, indent_level + 2);
00315 }
 All Classes Functions Variables Enumerations