From 266d0d2cf6648509650bdd490c8e9c64be75b92e Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 21 Jan 2013 18:37:59 +0000 Subject: Added attached property to draw particle systems in entity space instead of world space, corrected several bugs in the initial particle system implementation, added impulse key to have particle systems react on impulse drive. --- src/render/particleejector.cc | 69 +++++++++++++++++++++---------------- src/render/particleejector.h | 6 ++-- src/render/particleejectorscript.cc | 6 +++- src/render/particleejectorscript.h | 67 +++++++++++++++++++++++++++-------- src/render/particlesystem.cc | 39 ++++++++++++++++----- src/render/particlesystemscript.cc | 8 +++++ 6 files changed, 138 insertions(+), 57 deletions(-) (limited to 'src/render') diff --git a/src/render/particleejector.cc b/src/render/particleejector.cc index 5b26d59..091743d 100644 --- a/src/render/particleejector.cc +++ b/src/render/particleejector.cc @@ -48,29 +48,36 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat } // add new particles - if ( (ejector_enabled) && (ejector_last_eject + interval() <= now) ) - { - math::Vector3f particle_location(ps_location); - math::Axis particle_axis(ps_axis * axis()); - - if (cone() > 0) { - particle_axis.change_roll(math::randomf(360.0f)); - particle_axis.change_pitch(math::randomf(cone()) - (cone() * 0.5f) ); - } - if (spawn_radius() > 0) { - // FIXME find a faster formula - math::Axis random_axis(ps_axis); - random_axis.change_roll(math::randomf(360.0f)); - random_axis.change_pitch(math::randomf(180.0f)); - particle_location += random_axis.forward() * spawn_radius(); + if (ejector_enabled) { + if (ejector_last_eject + interval() <= now) { + math::Vector3f particle_location; + math::Axis particle_axis; + if (!attached()) { + particle_location.assign(ps_location); + particle_axis.assign(ps_axis); + } + + if (cone() > 0) { + particle_axis.change_roll(math::randomf(360.0f)); + particle_axis.change_pitch(math::randomf(cone()) - (cone() * 0.5f) ); + } + if (spawn_radius() > 0) { + // FIXME find a faster formula + math::Axis random_axis(ps_axis); + random_axis.change_roll(math::randomf(360.0f)); + random_axis.change_pitch(math::randomf(180.0f)); + particle_location += random_axis.forward() * spawn_radius(); + } + + Particle *particle = new Particle(particle_location, particle_axis.forward() * speed(), now); + particle->set_radius(radius_vec()[0]); + particle->set_alpha(alpha_vec()[0]); + + particles().push_front(particle); + ejector_last_eject = now; } - - Particle *particle = new Particle(particle_location, particle_axis.forward() * speed(), now); - particle->set_radius(radius_vec()[0]); - particle->set_alpha(alpha_vec()[0]); - - particles().push_front(particle); - ejector_last_eject = now; + } else { + ejector_last_eject = 0; } for (Particles::iterator it = particles().begin(); it != particles().end(); ++it) { @@ -115,11 +122,11 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat } if (particles().size()) { - draw(ps_location); + draw(ps_location, ps_axis); } } -void ParticleEjector::draw(const math::Vector3f & ps_location) +void ParticleEjector::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis) { } @@ -136,7 +143,7 @@ ParticleEjectorSpray::~ParticleEjectorSpray() } -void ParticleEjectorSpray::draw(const math::Vector3f & ps_location) +void ParticleEjectorSpray::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis) { math::Vector3f quad[4]; Textures::bind(texture()); @@ -152,19 +159,20 @@ void ParticleEjectorSpray::draw(const math::Vector3f & ps_location) for (Particles::iterator it = particles().begin(); it != particles().end(); it++) { Particle *particle = (*it); + math::Vector3f l(attached() ? ps_location + ps_axis * particle->location() : particle->location()); const float r = particle->radius(); c.a = particle->alpha(); gl::color(c); glTexCoord2f(0, 1); - gl::vertex(particle->location() + quad[0] * r); + gl::vertex(l + quad[0] * r); glTexCoord2f(0, 0); - gl::vertex(particle->location() + quad[1] * r); + gl::vertex(l + quad[1] * r); glTexCoord2f(1, 0); - gl::vertex(particle->location() + quad[2] * r); + gl::vertex(l + quad[2] * r); glTexCoord2f(1, 1); - gl::vertex(particle->location() + quad[3] * r); + gl::vertex(l + quad[3] * r); Stats::quads++; } gl::end(); @@ -182,7 +190,7 @@ ParticleEjectorTrail::~ParticleEjectorTrail() } -void ParticleEjectorTrail::draw(const math::Vector3f & ps_location) +void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::Axis & ps_axis) { if (!particles().size()) { return; @@ -201,6 +209,7 @@ void ParticleEjectorTrail::draw(const math::Vector3f & ps_location) c.a = (*first)->alpha(); gl::color(c); + //math::Vector3f first_location(attached() ? ps_location + ps_axis * (*first)->location() : (*first)->location()); math::Vector3f first_normal(math::crossproduct(((*first)->location() - ps_location), ((*first)->location() - Camera::eye()))); first_normal.normalize(); diff --git a/src/render/particleejector.h b/src/render/particleejector.h index f626f26..9e090d9 100644 --- a/src/render/particleejector.h +++ b/src/render/particleejector.h @@ -66,7 +66,7 @@ protected: return ejector_particles; } - virtual void draw(const math::Vector3f & ps_location); + virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis); private: unsigned long ejector_last_eject; @@ -83,7 +83,7 @@ public: virtual ~ParticleEjectorSpray(); protected: - virtual void draw(const math::Vector3f & ps_location); + virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis); }; /** @@ -95,7 +95,7 @@ public: virtual ~ParticleEjectorTrail(); protected: - virtual void draw(const math::Vector3f & ps_location); + virtual void draw(const math::Vector3f & ps_location, const math::Axis & ps_axis); }; } // namespace render diff --git a/src/render/particleejectorscript.cc b/src/render/particleejectorscript.cc index 4c9b6c9..3609b9e 100644 --- a/src/render/particleejectorscript.cc +++ b/src/render/particleejectorscript.cc @@ -21,9 +21,11 @@ ParticleEjectorScript::ParticleEjectorScript() script_entity = false; script_entity_second = false; script_engine = false; + script_impulse = false; script_thrust = false; script_cull = model::CullNone; script_spawn_radius = 0.0f; + script_attached = false; } ParticleEjectorScript::ParticleEjectorScript(const ParticleEjectorScript &other) @@ -31,15 +33,17 @@ ParticleEjectorScript::ParticleEjectorScript(const ParticleEjectorScript &other) script_type = other.type(); script_interval = other.interval(); script_cone = other.cone(); + script_spawn_radius = other.spawn_radius(); script_offset = other.offset(); script_lifespan = other.lifespan(); script_speed = other.speed(); script_entity = other.entity(); script_entity_second = other.entity_second(); script_engine = other.engine(); + script_impulse = other.impulse(); script_thrust = other.thrust(); script_cull = other.cull(); - script_spawn_radius = other.spawn_radius(); + script_attached = other.attached(); script_texture.assign(other.texture()); script_axis.assign(other.axis()); diff --git a/src/render/particleejectorscript.h b/src/render/particleejectorscript.h index a538bb5..5a79cc8 100644 --- a/src/render/particleejectorscript.h +++ b/src/render/particleejectorscript.h @@ -45,13 +45,6 @@ public: return script_axis; } - /** - * @brief true of the ejector reacts on thrust - * */ - inline bool thrust() const { - return script_thrust; - } - inline const unsigned int interval() const { return script_interval; @@ -68,39 +61,63 @@ public: /** * @brief offset defines the interpolation midpoint for alpha and radius ranges, default 0.5f * */ - inline float offset() const { + inline const float offset() const { return script_offset; } /** * @brief lifespan of ejected particles, in milliseconds * */ - inline unsigned long lifespan() const { + inline const unsigned long lifespan() const { return script_lifespan; } /** * @brief true if engine color is to be applied to ejected particles * */ - inline bool engine() const { + inline const bool engine() const { return script_engine; } /** * @brief true if entity primary color is to be applied to ejected particles * */ - inline bool entity() const + inline const bool entity() const { return script_entity; } + /** + * @brief true for a thrust activated ejector + * */ + inline const bool thrust() const + { + return script_thrust; + } + + /** + * @brief true for a thrust impulse ejector + * */ + inline const bool impulse() const + { + return script_impulse; + } + /** * @brief true if entity secondary color is to be applied to ejected particles * */ - inline bool entity_second() const + inline const bool entity_second() const { return script_entity_second; } + + /** + * @brief true if particles are drawn in model coordinates + * */ + inline const bool attached() const + { + return script_attached; + } /** * @brief name of the texture used to render ejected particles @@ -305,13 +322,29 @@ public: } /** - * @brief make ejector react on thruster setting + * @brief enable or disable thrust activated ejector * */ inline void set_thrust(const bool use_thrust) { script_thrust = use_thrust; } + /** + * @brief enable or disable impulse activated ejector + * */ + inline void set_impulse(const bool use_impulse) + { + script_impulse = use_impulse; + } + + /** + * @brief ejector particles are drawn in entity coordinates + * */ + inline void set_attached(const bool attached) + { + script_attached = attached; + } + /** * @brief set the particle color * */ @@ -353,9 +386,13 @@ private: bool script_entity_second; /// particles jave engine color bool script_engine; - /// ejector reacts on engine thrust + /// thrust activated ejector bool script_thrust; - + /// impulse activated ejector + bool script_impulse; + /// ejector is attached to entity coordinates + bool script_attached; + /// texture to render particles with std::string script_texture; /// texture cull diff --git a/src/render/particlesystem.cc b/src/render/particlesystem.cc index ff9c720..920d77c 100644 --- a/src/render/particlesystem.cc +++ b/src/render/particlesystem.cc @@ -4,6 +4,7 @@ the terms of the GNU General Public License version 2 */ +#include "render/gl.h" #include "render/particlesystem.h" namespace render { @@ -121,23 +122,45 @@ void ParticleSystem::draw(const float seconds) math::Axis current_axis(entity() ? entity()->axis() * axis() : axis()); for (Ejectors::iterator it = ejectors().begin(); it != ejectors().end(); ++it) { - + + ParticleEjector *ejector = (*it); + if (entity()) { bool ejector_active = true; + if (entity()->type() == core::Entity::Controlable) { + const core::EntityControlable *controlable = static_cast(entity()); - if ((*it)->thrust()) { - // thrust activated - const core::EntityControlable *controlable = static_cast(entity()); - if ( controlable->thrust() == 0.0f ) { - ejector_active = false; + if (ejector->impulse() || ejector->thrust()) { + ejector_active = false; + + switch (controlable->state()) { + case core::Entity::Impulse: + case core::Entity::ImpulseInitiate: + if (ejector->impulse() || ejector->thrust()) { + ejector_active = true; + } + break; + + case core::Entity::Normal: + if (ejector->thrust()) { + if (controlable->thrust() > 0.0f) { + ejector_active = true; + } + } + break; + + default: + ejector_active = false; + break; } - (*it)->enable(ejector_active); + ejector->enable(ejector_active); } } } - (*it)->frame(seconds, current_location, current_axis); + (*it)->frame(seconds, current_location, current_axis * ejector->axis()); + } } diff --git a/src/render/particlesystemscript.cc b/src/render/particlesystemscript.cc index 98c0a2d..866fce1 100644 --- a/src/render/particlesystemscript.cc +++ b/src/render/particlesystemscript.cc @@ -199,6 +199,10 @@ ParticleSystemScript *ParticleSystemScript::load(const std::string &label) ejector->set_thrust(b); continue; + } else if (inifile.got_key_bool("impulse", b)) { + ejector->set_impulse(b); + continue; + } else if (inifile.got_key_bool("entity", b)) { ejector->set_entity(b); continue; @@ -214,6 +218,10 @@ ParticleSystemScript *ParticleSystemScript::load(const std::string &label) } continue; + } else if (inifile.got_key_bool("attached", b)) { + ejector->set_attached(b); + continue; + } else if (inifile.got_key_float("angle", yaw)) { if (yaw == model::ANGLEUP) { -- cgit v1.2.3