00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00027
00028
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
00043
00044
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
00059
00060
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
00074
00075
00076
00077
00078 LineParticleRenderer::
00079 ~LineParticleRenderer() {
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 BaseParticleRenderer *LineParticleRenderer::
00089 make_copy() {
00090 return new LineParticleRenderer(*this);
00091 }
00092
00093
00094
00095
00096
00097
00098
00099 void LineParticleRenderer::
00100 birth_particle(int) {
00101 }
00102
00103
00104
00105
00106
00107
00108
00109 void LineParticleRenderer::
00110 kill_particle(int) {
00111 }
00112
00113
00114
00115
00116
00117
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
00129
00130
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
00150
00151
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
00171
00172 _aabb_min.set(99999.0f, 99999.0f, 99999.0f);
00173 _aabb_max.set(-99999.0f, -99999.0f, -99999.0f);
00174
00175
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
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
00203
00204 LColor head_color = _head_color;
00205 LColor tail_color = _tail_color;
00206
00207
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
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
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
00255
00256
00257
00258
00259 void LineParticleRenderer::
00260 output(ostream &out) const {
00261 #ifndef NDEBUG //[
00262 out<<"LineParticleRenderer";
00263 #endif //] NDEBUG
00264 }
00265
00266
00267
00268
00269
00270
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 }