00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pointParticleRenderer.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 PointParticleRenderer::_render_collector("App:Particles:Point:Render");
00024
00025
00026
00027
00028
00029
00030
00031 PointParticleRenderer::
00032 PointParticleRenderer(ParticleRendererAlphaMode am,
00033 PN_stdfloat point_size,
00034 PointParticleBlendType bt,
00035 ParticleRendererBlendMethod bm,
00036 const LColor& sc, const LColor& ec) :
00037 BaseParticleRenderer(am),
00038 _start_color(sc), _end_color(ec),
00039 _blend_type(bt), _blend_method(bm)
00040 {
00041 set_point_size(point_size);
00042 resize_pool(0);
00043 }
00044
00045
00046
00047
00048
00049
00050
00051 PointParticleRenderer::
00052 PointParticleRenderer(const PointParticleRenderer& copy) :
00053 BaseParticleRenderer(copy)
00054 {
00055 _blend_type = copy._blend_type;
00056 _blend_method = copy._blend_method;
00057 _start_color = copy._start_color;
00058 _end_color = copy._end_color;
00059 _point_size = copy._point_size;
00060 _thick = copy._thick;
00061 resize_pool(0);
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 PointParticleRenderer::
00071 ~PointParticleRenderer() {
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 BaseParticleRenderer *PointParticleRenderer::
00081 make_copy() {
00082 return new PointParticleRenderer(*this);
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092 void PointParticleRenderer::
00093 resize_pool(int new_size) {
00094 if (new_size == _max_pool_size)
00095 return;
00096
00097 _max_pool_size = new_size;
00098
00099 init_geoms();
00100 }
00101
00102
00103
00104
00105
00106
00107
00108 void PointParticleRenderer::
00109 init_geoms() {
00110 _vdata = new GeomVertexData
00111 ("point_particles", GeomVertexFormat::get_v3cp(),
00112 Geom::UH_stream);
00113 PT(Geom) geom = new Geom(_vdata);
00114 _point_primitive = geom;
00115 _points = new GeomPoints(Geom::UH_stream);
00116 geom->add_primitive(_points);
00117
00118 GeomNode *render_node = get_render_node();
00119 render_node->remove_all_geoms();
00120 render_node->add_geom(_point_primitive, _render_state->add_attrib(_thick));
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 void PointParticleRenderer::
00130 birth_particle(int) {
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 void PointParticleRenderer::
00140 kill_particle(int) {
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 LColor PointParticleRenderer::
00150 create_color(const BaseParticle *p) {
00151 LColor color;
00152 PN_stdfloat life_t, vel_t;
00153 PN_stdfloat parameterized_age = 1.0f;
00154 bool have_alpha_t = false;
00155
00156 switch (_blend_type) {
00157
00158
00159
00160 case PP_ONE_COLOR:
00161 color = _start_color;
00162 break;
00163
00164
00165
00166 case PP_BLEND_LIFE:
00167 parameterized_age = p->get_parameterized_age();
00168 life_t = parameterized_age;
00169 have_alpha_t = true;
00170
00171 if (_blend_method == PP_BLEND_CUBIC)
00172 life_t = CUBIC_T(life_t);
00173
00174 color = LERP(life_t, _start_color, _end_color);
00175
00176 break;
00177
00178
00179
00180 case PP_BLEND_VEL:
00181 vel_t = p->get_parameterized_vel();
00182
00183 if (_blend_method == PP_BLEND_CUBIC)
00184 vel_t = CUBIC_T(vel_t);
00185
00186 color = LERP(vel_t, _start_color, _end_color);
00187
00188 break;
00189 }
00190
00191
00192
00193 if(_alpha_mode != PR_ALPHA_NONE) {
00194 if(_alpha_mode == PR_ALPHA_USER) {
00195 parameterized_age = 1.0;
00196 } else {
00197 if(!have_alpha_t)
00198 parameterized_age = p->get_parameterized_age();
00199
00200 if(_alpha_mode==PR_ALPHA_OUT) {
00201 parameterized_age = 1.0f - parameterized_age;
00202 } else if(_alpha_mode==PR_ALPHA_IN_OUT) {
00203 parameterized_age = 2.0f * min(parameterized_age,
00204 1.0f - parameterized_age);
00205 }
00206 }
00207 color[3] = parameterized_age * get_user_alpha();
00208 }
00209
00210 return color;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 void PointParticleRenderer::
00220 render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
00221 PStatTimer t1(_render_collector);
00222
00223 BaseParticle *cur_particle;
00224
00225 int remaining_particles = ttl_particles;
00226 int i;
00227
00228 GeomVertexWriter vertex(_vdata, InternalName::get_vertex());
00229 GeomVertexWriter color(_vdata, InternalName::get_color());
00230
00231
00232
00233 _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
00234 _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
00235
00236
00237
00238 for (i = 0; i < (int)po_vector.size(); i++) {
00239 cur_particle = (BaseParticle *) po_vector[i].p();
00240
00241 if (!cur_particle->get_alive())
00242 continue;
00243
00244 LPoint3 position = cur_particle->get_position();
00245
00246
00247
00248 if (position[0] > _aabb_max[0])
00249 _aabb_max[0] = position[0];
00250 else if (position[0] < _aabb_min[0])
00251 _aabb_min[0] = position[0];
00252
00253
00254
00255 if (position[1] > _aabb_max[1])
00256 _aabb_max[1] = position[1];
00257 else if (position[1] < _aabb_min[1])
00258 _aabb_min[1] = position[1];
00259
00260
00261
00262 if (position[2] > _aabb_max[2])
00263 _aabb_max[2] = position[2];
00264 else if (position[2] < _aabb_min[2])
00265 _aabb_min[2] = position[2];
00266
00267
00268
00269 vertex.add_data3(position);
00270 color.add_data4(create_color(cur_particle));
00271
00272
00273
00274 remaining_particles--;
00275 if (remaining_particles == 0)
00276 break;
00277 }
00278
00279 _points->clear_vertices();
00280 _points->add_next_vertices(ttl_particles);
00281
00282
00283
00284 LPoint3 aabb_center = _aabb_min + ((_aabb_max - _aabb_min) * 0.5f);
00285 PN_stdfloat radius = (aabb_center - _aabb_min).length();
00286
00287 BoundingSphere sphere(aabb_center, radius);
00288 _point_primitive->set_bounds(&sphere);
00289 get_render_node()->mark_internal_bounds_stale();
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 void PointParticleRenderer::
00299 output(ostream &out) const {
00300 #ifndef NDEBUG //[
00301 out<<"PointParticleRenderer";
00302 #endif //] NDEBUG
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 void PointParticleRenderer::
00312 write(ostream &out, int indent_level) const {
00313 indent(out, indent_level) << "PointParticleRenderer:\n";
00314 indent(out, indent_level + 2) << "_start_color "<<_start_color<<"\n";
00315 indent(out, indent_level + 2) << "_end_color "<<_end_color<<"\n";
00316 indent(out, indent_level + 2) << "_point_size "<<_point_size<<"\n";
00317 indent(out, indent_level + 2) << "_point_primitive "<<_point_primitive<<"\n";
00318 indent(out, indent_level + 2) << "_max_pool_size "<<_max_pool_size<<"\n";
00319 indent(out, indent_level + 2) << "_blend_type "<<_blend_type<<"\n";
00320 indent(out, indent_level + 2) << "_blend_method "<<_blend_method<<"\n";
00321 indent(out, indent_level + 2) << "_aabb_min "<<_aabb_min<<"\n";
00322 indent(out, indent_level + 2) << "_aabb_max "<<_aabb_max<<"\n";
00323 BaseParticleRenderer::write(out, indent_level + 2);
00324 }