Panda3D
|
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 }