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