00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00027
00028
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
00042
00043
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
00059
00060
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
00076
00077
00078
00079 SparkleParticleRenderer::
00080 ~SparkleParticleRenderer() {
00081 }
00082
00083
00084
00085
00086
00087
00088 BaseParticleRenderer *SparkleParticleRenderer::
00089 make_copy() {
00090 return new SparkleParticleRenderer(*this);
00091 }
00092
00093
00094
00095
00096
00097
00098 void SparkleParticleRenderer::
00099 birth_particle(int) {
00100 }
00101
00102
00103
00104
00105
00106
00107 void SparkleParticleRenderer::
00108 kill_particle(int) {
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 void SparkleParticleRenderer::
00118 resize_pool(int new_size) {
00119 _max_pool_size = new_size;
00120
00121 init_geoms();
00122 }
00123
00124
00125
00126
00127
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
00146
00147
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
00166
00167 _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
00168 _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
00169
00170
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
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
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
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
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
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
00285
00286
00287
00288
00289 void SparkleParticleRenderer::
00290 output(ostream &out) const {
00291 #ifndef NDEBUG //[
00292 out<<"SparkleParticleRenderer";
00293 #endif //] NDEBUG
00294 }
00295
00296
00297
00298
00299
00300
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 }