Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-11-16 13:53:44 +0000
committerStijn Buys <ingar@osirion.org>2008-11-16 13:53:44 +0000
commit315a8c2dff9b76ac5e1ebbef265f13ac19d65e3d (patch)
treedec6de0bcf7f19dd95b7121f27b185da67cee4e2 /src/render/particles.cc
parent28ba97bdd8fb6ca352dc49dba01a66bd155ad523 (diff)
engine trails
Diffstat (limited to 'src/render/particles.cc')
-rw-r--r--src/render/particles.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/render/particles.cc b/src/render/particles.cc
new file mode 100644
index 0000000..94a3a07
--- /dev/null
+++ b/src/render/particles.cc
@@ -0,0 +1,144 @@
+/*
+ render/particles.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "render/particles.h"
+#include "render/camera.h"
+#include "render/gl.h"
+#include "render/draw.h"
+#include "render/textures.h"
+
+#include "core/application.h"
+namespace render {
+
+/* ---- class Particle --------------------------------------------- */
+
+Particle::Particle(const math::Vector3f &location, float time) : particle_location(location)
+{
+ particle_time = time;
+}
+
+Particle::Particle(const math::Vector3f &location, const math::Vector3f &up, const math::Vector3f &left, float time) : particle_location(location), particle_up(up), particle_left(left)
+{
+ particle_time = time;
+}
+
+/* ---- class ParticleStream --------------------------------------- */
+
+ParticleStream::ParticleStream(const math::Vector3f &location, const math::Color &color, float radius, size_t texture, core::EntityControlable *entity, bool oriented) : particles_location(location), particles_color(color)
+{
+ particles_texture = texture;
+ particles_entity = entity;
+ if (!entity) {
+ particles_oriented = false;
+ } else {
+ particles_oriented = oriented;
+ }
+
+ particles_radius = radius;
+
+ particles_timeout = 1.5f; // a particles lives for 3 seconds
+ particles_eject = 0.02f; // a particle is ejected every 0.2 seconds
+
+ particles_last_eject = 0; // timestamp of the last eject
+}
+
+ParticleStream::~ParticleStream()
+{
+ for (Particles::iterator it = particles_stream.begin(); it != particles_stream.end(); it++) {
+ delete (*it);
+ }
+ particles_stream.clear();
+}
+
+void ParticleStream::draw() {
+ float now = core::application()->time();
+
+ // remove dead particles
+ Particles::iterator it = particles_stream.begin();
+ while ((it != particles_stream.end()) && ((*it)->time() + particles_timeout <= now)) {
+ delete (*it);
+ particles_stream.erase(it);
+ it = particles_stream.begin();
+ }
+
+ // add new particles
+ if (particles_last_eject + particles_eject <= now) {
+ if (particles_entity) {
+ float u = 0;
+ if ((particles_entity->eventstate() == core::Entity::ImpulseInitiate ) || (particles_entity->eventstate() == core::Entity::Impulse)) {
+ u = 1.0f;
+ } else if(particles_entity->eventstate() == core::Entity::Normal) {
+ u = particles_entity->thrust();
+ }
+ if (u > 0.0f) {
+ math::Vector3f l(particles_entity->location() + (particles_entity->axis() * location()));
+ Particle *p = 0;
+ if (particles_oriented) {
+ p = new Particle(l, particles_entity->axis().up(), particles_entity->axis().left(), now);
+ } else {
+ p = new Particle(l, now);
+ }
+ particles_stream.push_back(p);
+ }
+ } else {
+ particles_stream.push_back(new Particle(location(), now));
+ }
+ particles_last_eject = now;
+ }
+
+ math::Vector3f quad[4];
+
+ if (particles_stream.size()) {
+ Textures::bind(particles_texture);
+ gl::begin(gl::Quads);
+
+ for (Particles::reverse_iterator rit = particles_stream.rbegin(); rit != particles_stream.rend(); rit++) {
+ Particle *particle = (*rit);
+
+ if (particles_oriented) {
+ quad[0].assign(particle->up() - particle->left());
+ quad[1].assign(particle->up() + particle->left());
+ quad[2].assign(particle->up() * -1 + particle->left());
+ quad[3].assign(particle->up() * -1 - particle->left());
+ } else {
+ quad[0].assign(Camera::axis().up() - Camera::axis().left());
+ quad[1].assign(Camera::axis().up() + Camera::axis().left());
+ quad[2].assign(Camera::axis().up() * -1 + Camera::axis().left());
+ quad[3].assign(Camera::axis().up() * -1 - Camera::axis().left());
+ }
+
+ float t = now - particle->time();
+ float f = 0;
+
+ if (t < particles_timeout * 0.1f) {
+ f = t / (0.1f * particles_timeout);
+ } else {
+ t = t - particles_timeout * 0.1f;
+ f = t / (0.9f * particles_timeout);
+ f = 1.0 - f;
+ }
+
+ f *= f;
+ float radius = particles_radius * f;
+ particles_color.a = f;
+ gl::color(particles_color);
+
+ glTexCoord2f(0,1);
+ gl::vertex(particle->location() + quad[0] * radius);
+ glTexCoord2f(0,0);
+ gl::vertex(particle->location() + quad[1] * radius);
+ glTexCoord2f(1,0);
+ gl::vertex(particle->location() + quad[2] * radius);
+ glTexCoord2f(1,1);
+ gl::vertex(particle->location() + quad[3] * radius);
+ Stats::quads++;
+ }
+
+ gl::end();
+ }
+}
+
+} // namespace render