Panda3D
|
00001 // Filename: geomParticleRenderer.cxx 00002 // Created by: charles (05Jul00) 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 "geomParticleRenderer.h" 00016 #include "baseParticle.h" 00017 00018 #include "transformState.h" 00019 #include "colorScaleAttrib.h" 00020 #include "colorAttrib.h" 00021 #include "pStatTimer.h" 00022 00023 PStatCollector GeomParticleRenderer::_render_collector("App:Particles:Geom:Render"); 00024 00025 //////////////////////////////////////////////////////////////////// 00026 // Function : GeomParticleRenderer 00027 // Access : public 00028 // Description : constructor 00029 //////////////////////////////////////////////////////////////////// 00030 00031 GeomParticleRenderer:: 00032 GeomParticleRenderer(ParticleRendererAlphaMode am, PandaNode *geom_node) : 00033 BaseParticleRenderer(am), 00034 _geom_node(geom_node), 00035 _color_interpolation_manager(new ColorInterpolationManager(LColor(1.0f,1.0f,1.0f,1.0f))), 00036 _pool_size(0), 00037 _initial_x_scale(1.0f), 00038 _final_x_scale(1.0f), 00039 _initial_y_scale(1.0f), 00040 _final_y_scale(1.0f), 00041 _initial_z_scale(1.0f), 00042 _final_z_scale(1.0f), 00043 _animate_x_ratio(false), 00044 _animate_y_ratio(false), 00045 _animate_z_ratio(false) 00046 { 00047 if (_geom_node.is_null()) 00048 _geom_node = new PandaNode("empty"); 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function : GeomParticleRenderer 00053 // Access : public 00054 // Description : copy constructor 00055 //////////////////////////////////////////////////////////////////// 00056 00057 GeomParticleRenderer:: 00058 GeomParticleRenderer(const GeomParticleRenderer& copy) : 00059 BaseParticleRenderer(copy), 00060 _pool_size(0), 00061 _initial_x_scale(copy._initial_x_scale), 00062 _final_x_scale(copy._final_x_scale), 00063 _initial_y_scale(copy._initial_y_scale), 00064 _final_y_scale(copy._final_y_scale), 00065 _initial_z_scale(copy._initial_z_scale), 00066 _final_z_scale(copy._final_z_scale), 00067 _animate_x_ratio(copy._animate_x_ratio), 00068 _animate_y_ratio(copy._animate_y_ratio), 00069 _animate_z_ratio(copy._animate_z_ratio) 00070 { 00071 _geom_node = copy._geom_node; 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function : ~GeomParticleRenderer 00076 // Access : public 00077 // Description : destructor 00078 //////////////////////////////////////////////////////////////////// 00079 00080 GeomParticleRenderer:: 00081 ~GeomParticleRenderer() { 00082 kill_nodes(); 00083 } 00084 00085 //////////////////////////////////////////////////////////////////// 00086 // Function : make_copy 00087 // Access : public 00088 // Description : dynamic copying 00089 //////////////////////////////////////////////////////////////////// 00090 00091 BaseParticleRenderer *GeomParticleRenderer:: 00092 make_copy() { 00093 return new GeomParticleRenderer(*this); 00094 } 00095 00096 //////////////////////////////////////////////////////////////////// 00097 // Function : init_geoms 00098 // Access : private 00099 // Description : links the child nodes to the parent stuff 00100 //////////////////////////////////////////////////////////////////// 00101 void GeomParticleRenderer:: 00102 init_geoms() { 00103 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function : resize_pool 00108 // Access : private 00109 // Description : handles renderer-size resizing. 00110 //////////////////////////////////////////////////////////////////// 00111 00112 void GeomParticleRenderer:: 00113 resize_pool(int new_size) { 00114 kill_nodes(); 00115 00116 // now repopulate the vector with a bunch of NULLS, representing 00117 // potential instances of the _geom_node. 00118 00119 int i; 00120 for (i = 0; i < new_size; i++) { 00121 _node_vector.push_back(NULL); 00122 } 00123 00124 _pool_size = new_size; 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function : kill_nodes 00129 // Access : private 00130 //////////////////////////////////////////////////////////////////// 00131 00132 void GeomParticleRenderer:: 00133 kill_nodes() { 00134 pvector< PT(PandaNode) >::iterator vec_iter = _node_vector.begin(); 00135 00136 PandaNode *render_node = get_render_node(); 00137 for (; vec_iter != _node_vector.end(); vec_iter++) { 00138 PandaNode *node = *vec_iter; 00139 if (node != (PandaNode *)NULL) { 00140 render_node->remove_child(node); 00141 } 00142 } 00143 00144 _node_vector.erase(_node_vector.begin(), _node_vector.end()); 00145 } 00146 00147 //////////////////////////////////////////////////////////////////// 00148 // Function : birth_particle 00149 // Access : Private, virtual 00150 // Description : child birth 00151 //////////////////////////////////////////////////////////////////// 00152 00153 void GeomParticleRenderer:: 00154 birth_particle(int index) { 00155 if (_node_vector[index] == (PandaNode *)NULL) { 00156 PandaNode *node = new PandaNode(""); 00157 get_render_node()->add_child(node); 00158 node->add_child(_geom_node); 00159 _node_vector[index] = node; 00160 } 00161 } 00162 00163 //////////////////////////////////////////////////////////////////// 00164 // Function : kill_particle 00165 // Access : Private, virtual 00166 // Description : child kill 00167 //////////////////////////////////////////////////////////////////// 00168 00169 void GeomParticleRenderer:: 00170 kill_particle(int index) { 00171 if (_node_vector[index] != (PandaNode *)NULL) { 00172 get_render_node()->remove_child(_node_vector[index]); 00173 _node_vector[index] = (PandaNode *)NULL; 00174 } 00175 } 00176 00177 //////////////////////////////////////////////////////////////////// 00178 // Function : render 00179 // Access : private 00180 // Description : sets the transitions on each arc 00181 //////////////////////////////////////////////////////////////////// 00182 00183 void GeomParticleRenderer:: 00184 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) { 00185 PStatTimer t1(_render_collector); 00186 00187 BaseParticle *cur_particle; 00188 int i, remaining_particles = ttl_particles; 00189 00190 pvector< PT(PandaNode) >::iterator cur_node_iter = _node_vector.begin(); 00191 00192 // run through the particle vector 00193 00194 for (i = 0; i < (int)po_vector.size(); i++) { 00195 PandaNode *cur_node; 00196 00197 cur_particle = (BaseParticle *) po_vector[i].p(); 00198 cur_node = *cur_node_iter; 00199 00200 if (cur_particle->get_alive()) { 00201 // living particle 00202 if (cur_node == (PandaNode *)NULL) { 00203 birth_particle(i); 00204 cur_node = *cur_node_iter; 00205 } 00206 nassertv(cur_node != (PandaNode *)NULL); 00207 00208 cur_node->set_state(_render_state); 00209 00210 PN_stdfloat t = cur_particle->get_parameterized_age(); 00211 LColor c = _color_interpolation_manager->generateColor(t); 00212 00213 if ((_alpha_mode != PR_ALPHA_NONE)) { 00214 PN_stdfloat alpha_scalar; 00215 00216 if(_alpha_mode == PR_ALPHA_USER) { 00217 alpha_scalar = get_user_alpha(); 00218 } else { 00219 alpha_scalar = t; 00220 if (_alpha_mode == PR_ALPHA_OUT) 00221 alpha_scalar = 1.0f - alpha_scalar; 00222 else if (_alpha_mode == PR_ALPHA_IN_OUT) 00223 alpha_scalar = 2.0f * min(alpha_scalar, 1.0f - alpha_scalar); 00224 alpha_scalar *= get_user_alpha(); 00225 } 00226 00227 c[3] *= alpha_scalar; 00228 cur_node->set_attrib(ColorScaleAttrib::make 00229 (LColor(1.0f, 1.0f, 1.0f, c[3]))); 00230 } 00231 00232 cur_node->set_attrib(ColorAttrib::make_flat(c), 0); 00233 00234 // animate scale 00235 PN_stdfloat current_x_scale = _initial_x_scale; 00236 PN_stdfloat current_y_scale = _initial_y_scale; 00237 PN_stdfloat current_z_scale = _initial_z_scale; 00238 00239 if (_animate_x_ratio || _animate_y_ratio || _animate_z_ratio) { 00240 if (_animate_x_ratio) { 00241 current_x_scale = (_initial_x_scale + 00242 (t * (_final_x_scale - _initial_x_scale))); 00243 } 00244 if (_animate_y_ratio) { 00245 current_y_scale = (_initial_y_scale + 00246 (t * (_final_y_scale - _initial_y_scale))); 00247 } 00248 if (_animate_z_ratio) { 00249 current_z_scale = (_initial_z_scale + 00250 (t * (_final_z_scale - _initial_z_scale))); 00251 } 00252 } 00253 00254 cur_node->set_transform(TransformState::make_pos_quat_scale 00255 (cur_particle->get_position(), 00256 cur_particle->get_orientation(), 00257 LVecBase3(current_x_scale, current_y_scale, current_z_scale))); 00258 00259 // maybe get out early if possible. 00260 00261 remaining_particles--; 00262 00263 if (remaining_particles == 0) 00264 break; 00265 } 00266 00267 cur_node_iter++; 00268 } 00269 } 00270 00271 //////////////////////////////////////////////////////////////////// 00272 // Function : output 00273 // Access : Public 00274 // Description : Write a string representation of this instance to 00275 // <out>. 00276 //////////////////////////////////////////////////////////////////// 00277 void GeomParticleRenderer:: 00278 output(ostream &out) const { 00279 #ifndef NDEBUG //[ 00280 out<<"GeomParticleRenderer"; 00281 #endif //] NDEBUG 00282 } 00283 00284 //////////////////////////////////////////////////////////////////// 00285 // Function : write_linear_forces 00286 // Access : Public 00287 // Description : Write a string representation of this instance to 00288 // <out>. 00289 //////////////////////////////////////////////////////////////////// 00290 void GeomParticleRenderer:: 00291 write_linear_forces(ostream &out, int indent) const { 00292 #ifndef NDEBUG //[ 00293 out.width(indent); 00294 out<<""<<"_node_vector ("<<_node_vector.size()<<" forces)\n"; 00295 for (pvector< PT(PandaNode) >::const_iterator i=_node_vector.begin(); 00296 i != _node_vector.end(); 00297 ++i) { 00298 (*i)->write(out, indent+2); 00299 } 00300 #endif //] NDEBUG 00301 } 00302 00303 //////////////////////////////////////////////////////////////////// 00304 // Function : write 00305 // Access : Public 00306 // Description : Write a string representation of this instance to 00307 // <out>. 00308 //////////////////////////////////////////////////////////////////// 00309 void GeomParticleRenderer:: 00310 write(ostream &out, int indent) const { 00311 #ifndef NDEBUG //[ 00312 out.width(indent); out<<""; out<<"GeomParticleRenderer:\n"; 00313 out.width(indent+2); out<<""; out<<"_geom_node "<<_geom_node<<"\n"; 00314 out.width(indent+2); out<<""; out<<"_pool_size "<<_pool_size<<"\n"; 00315 00316 out.width(indent+2); out<<""; out<<"_initial_x_scale "<<_initial_x_scale<<"\n"; 00317 out.width(indent+2); out<<""; out<<"_final_x_scale "<<_final_x_scale<<"\n"; 00318 out.width(indent+2); out<<""; out<<"_initial_y_scale "<<_initial_y_scale<<"\n"; 00319 out.width(indent+2); out<<""; out<<"_final_y_scale "<<_final_y_scale<<"\n"; 00320 out.width(indent+2); out<<""; out<<"_initial_z_scale "<<_initial_z_scale<<"\n"; 00321 out.width(indent+2); out<<""; out<<"_final_z_scale "<<_final_z_scale<<"\n"; 00322 out.width(indent+2); out<<""; out<<"_animate_x_ratio "<<_animate_x_ratio<<"\n"; 00323 out.width(indent+2); out<<""; out<<"_animate_y_ratio "<<_animate_y_ratio<<"\n"; 00324 out.width(indent+2); out<<""; out<<"_animate_z_ratio "<<_animate_z_ratio<<"\n"; 00325 00326 write_linear_forces(out, indent+2); 00327 BaseParticleRenderer::write(out, indent+2); 00328 #endif //] NDEBUG 00329 }