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