From f096586dac6e6c0e083e23afafc99731bf2ba642 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 27 Jan 2013 09:41:25 +0000 Subject: Added support for particles minimum/maximum speed, renamed [ejector] sections in particle ini files, resolved the issue where only 1 particle per frame could be ejected. --- src/render/draw.cc | 31 +--- src/render/particleejector.cc | 11 +- src/render/particleejectorscript.cc | 3 +- src/render/particleejectorscript.h | 23 ++- src/render/particlesystem.cc | 5 + src/render/particlesystemscript.cc | 297 +++++++++++++++++++----------------- src/render/renderext.cc | 3 +- 7 files changed, 187 insertions(+), 186 deletions(-) (limited to 'src/render') diff --git a/src/render/draw.cc b/src/render/draw.cc index 0d77c7b..87c25e2 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -932,6 +932,8 @@ void draw_model_lights(model::Model *model, const float scale, } // draw the quad + + // FIXME add random per-light rotation gl::color(color); gl::texcoord(1, 0); @@ -1087,36 +1089,7 @@ void draw_pass_model_fx(float elapsed) // draw particle systems if (draw_particles && ext_render(entity)->particles().size()) { - /* - gl::disable(GL_CULL_FACE); - - model::Cull current_cull = model::CullNone; - - for (RenderExt::ParticleSystems::iterator it = ext_render(entity)->particles().begin(); it != ext_render(entity)->particles().end(); it++) { - ParticleSystem *particlesystem = (*it); - - if (current_cull != particlesystem->cull()) { - if (particlesystem->cull() == model::CullNone) { - gl::disable(GL_CULL_FACE); - current_cull = model::CullNone; - } else { - if (current_cull == model::CullNone) { - gl::enable(GL_CULL_FACE); - } - - if (particlesystem->cull() == model::CullBack) { - gl::cullface(GL_BACK); - current_cull = model::CullBack; - } else { - gl::cullface(GL_FRONT); - current_cull = model::CullFront; - } - } - } - particlesystem->draw(elapsed); - } - */ for (RenderExt::ParticleSystems::iterator it = ext_render(entity)->particles().begin(); it != ext_render(entity)->particles().end(); ++it) { (*it)->draw(elapsed); } diff --git a/src/render/particleejector.cc b/src/render/particleejector.cc index 92b8d8f..9ee9cc8 100644 --- a/src/render/particleejector.cc +++ b/src/render/particleejector.cc @@ -47,12 +47,11 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat it = particles().rbegin(); } + ejector_last_eject += (unsigned long) (1000.0f * seconds); + // add new particles if (ejector_enabled) { - // FIXME currently, only one particle per frame is ejected - // particle ejection rate should be independent of framerate, but we run into issues - // of the particle systems not rendered - if (ejector_last_eject + interval() <= now) { + while (ejector_last_eject > interval()) { math::Vector3f particle_location; math::Axis particle_axis; if (!attached()) { @@ -75,9 +74,9 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat particle->set_radius(radius_vec()[0]); particle->set_alpha(alpha_vec()[0]); particle->set_rotation(math::randomf(2.0f * M_PI)); - particle->set_speed(speed()); + particle->set_speed(math::randomf(speed_vec()[0], speed_vec()[1])); particles().push_front(particle); - ejector_last_eject = now; + ejector_last_eject -= interval(); } } else { ejector_last_eject = 0; diff --git a/src/render/particleejectorscript.cc b/src/render/particleejectorscript.cc index a37ab9d..1eb1eff 100644 --- a/src/render/particleejectorscript.cc +++ b/src/render/particleejectorscript.cc @@ -17,7 +17,6 @@ ParticleEjectorScript::ParticleEjectorScript() script_cone = 0.0f; script_offset = 0.5f; script_lifespan = 1000; - script_speed = 0; script_acceleration = 0.0f; script_entity = false; script_entity_second = false; @@ -37,7 +36,6 @@ ParticleEjectorScript::ParticleEjectorScript(const ParticleEjectorScript &other) script_spawn_radius = other.spawn_radius(); script_offset = other.offset(); script_lifespan = other.lifespan(); - script_speed = other.speed(); script_acceleration = other.acceleration(); script_entity = other.entity(); script_entity_second = other.entity_second(); @@ -51,6 +49,7 @@ ParticleEjectorScript::ParticleEjectorScript(const ParticleEjectorScript &other) script_axis.assign(other.axis()); script_radius_vec.assign(other.radius_vec()); script_alpha_vec.assign(other.alpha_vec()); + script_speed_vec.assign(other.speed_vec()); script_color.assign(other.color()); } diff --git a/src/render/particleejectorscript.h b/src/render/particleejectorscript.h index e7c135f..731dbe2 100644 --- a/src/render/particleejectorscript.h +++ b/src/render/particleejectorscript.h @@ -9,6 +9,7 @@ #include "math/axis.h" #include "math/color.h" +#include "math/vector2f.h" #include "math/vector3f.h" #include "model/model.h" @@ -159,11 +160,11 @@ public: } /** - * @brief speed of ejected particles, in gameunits per second + * @brief minimum and maximum speed of ejected particles, in gameunits per second * */ - inline const float speed() const + inline const math::Vector2f & speed_vec() const { - return script_speed; + return script_speed_vec; } /** @@ -209,6 +210,14 @@ public: return script_alpha_vec; } + /** + * @brief return a reference to the speed vector + * */ + inline math::Vector2f &get_speed_vec() + { + return script_speed_vec; + } + /** * @brief return a reference to particle color * */ @@ -236,9 +245,9 @@ public: /** * @brief set the speed of ejected particles, in gameunits per second * */ - inline void set_speed(const float speed) + inline void set_speed_vec(const math::Vector2f &speed_vec) { - script_speed = speed; + script_speed_vec.assign(speed_vec); } /** @@ -387,8 +396,8 @@ private: /// particle radius vector: 0.0 - middle - 1.0 math::Vector3f script_radius_vec; - /// speed of ejected particles, in gameunits per second - float script_speed; + /// minimum and maximum speed of ejected particles, in gameunits per second + math::Vector2f script_speed_vec; /// acceleration of ejected particles, in gameunits per second squared float script_acceleration; /// spawn radius diff --git a/src/render/particlesystem.cc b/src/render/particlesystem.cc index 8fe0e13..518a5f7 100644 --- a/src/render/particlesystem.cc +++ b/src/render/particlesystem.cc @@ -48,6 +48,11 @@ ParticleSystem::ParticleSystem(const ParticleSystemScript *script, const core::E } if (ejector) { + // safety values + if (!ejector->interval()) { + ejector->set_interval(1000); + } + ejectors().push_back(ejector); if (entity) { diff --git a/src/render/particlesystemscript.cc b/src/render/particlesystemscript.cc index 7344aab..2f90f1b 100644 --- a/src/render/particlesystemscript.cc +++ b/src/render/particlesystemscript.cc @@ -100,9 +100,38 @@ ParticleSystemScript *ParticleSystemScript::load(const std::string &label) } ejector = 0; continue; - } else if (inifile.got_section("ejector")) { + } else if (inifile.got_section("sprites")) { if (script) { ejector = script->add_ejector(); + ejector->set_type(ParticleEjectorScript::Sprite); + } else { + inifile.unknown_error("ejector section without particles section"); + } + } else if (inifile.got_section("flares")) { + if (script) { + ejector = script->add_ejector(); + ejector->set_type(ParticleEjectorScript::Flare); + } else { + inifile.unknown_error("ejector section without particles section"); + } + } else if (inifile.got_section("trail")) { + if (script) { + ejector = script->add_ejector(); + ejector->set_type(ParticleEjectorScript::Trail); + } else { + inifile.unknown_error("ejector section without particles section"); + } + } else if (inifile.got_section("flame")) { + if (script) { + ejector = script->add_ejector(); + ejector->set_type(ParticleEjectorScript::Flame); + } else { + inifile.unknown_error("ejector section without particles section"); + } + } else if (inifile.got_section("streak")) { + if (script) { + ejector = script->add_ejector(); + ejector->set_type(ParticleEjectorScript::Streak); } else { inifile.unknown_error("ejector section without particles section"); } @@ -115,153 +144,139 @@ ParticleSystemScript *ParticleSystemScript::load(const std::string &label) if (inifile.in_section("particles")) { inifile.unknown_key(); - } else if (inifile.in_section("ejector") && ejector) { + } else if (script) { + + if (inifile.in_section("sprites") || inifile.in_section("flares") || inifile.in_section("trail") || inifile.in_section("flame") || inifile.in_section("streak")) { + + if (inifile.got_key_string("cull", strval)) { + aux::to_label(strval); + if (strval.compare("none") == 0) { + ejector->set_cull(model::CullNone); + } else if (strval.compare("back") == 0) { + ejector->set_cull(model::CullBack); + } else if (strval.compare("front") == 0) { + ejector->set_cull(model::CullFront); + } else { + inifile.unknown_value(); + } + continue; - if (inifile.got_key_string("type", strval)) { - aux::to_label(strval); - if (strval.compare("sprite") == 0) { - ejector->set_type(ParticleEjectorScript::Sprite); - } else if (strval.compare("flare") == 0) { - ejector->set_type(ParticleEjectorScript::Flare); - } else if (strval.compare("trail") == 0) { - ejector->set_type(ParticleEjectorScript::Trail); - } else if (strval.compare("flame") == 0) { - ejector->set_type(ParticleEjectorScript::Flame); - } else if (strval.compare("streak") == 0) { - ejector->set_type(ParticleEjectorScript::Streak); - } else { - inifile.unknown_value(); - } - continue; - - } else if (inifile.got_key_string("cull", strval)) { - aux::to_label(strval); - if (strval.compare("none") == 0) { - ejector->set_cull(model::CullNone); - } else if (strval.compare("back") == 0) { - ejector->set_cull(model::CullBack); - } else if (strval.compare("front") == 0) { - ejector->set_cull(model::CullFront); - } else { - inifile.unknown_value(); - } - continue; + } else if (inifile.got_key_string("texture", strval)) { + ejector->set_texture("textures/" + strval); + Textures::load(ejector->texture()); + continue; + + } else if (inifile.got_key_vector2f_opt("speed", ejector->get_speed_vec())) { + // convert speed from meters/second to game units/second + ejector->get_speed_vec() *= 0.01f; + continue; + + } else if (inifile.got_key_float("acceleration", f)) { + // convert speed from meters/second to game units/second + ejector->set_acceleration(f * 0.01f); + continue; + + } else if (inifile.got_key_float("offset", f)) { + math::clamp(f, 0.0f, 1.0f); + ejector->set_offset(f); + continue; + + } else if (inifile.got_key_vector3f_opt("alpha", ejector->get_alpha_vec())) { + math::clamp(ejector->get_alpha_vec()[0], 0.0f, 1.0f); + math::clamp(ejector->get_alpha_vec()[1], 0.0f, 1.0f); + math::clamp(ejector->get_alpha_vec()[2], 0.0f, 1.0f); + continue; + + } else if (inifile.got_key_vector3f_opt("radius", ejector->get_radius_vec())) { + ejector->get_radius_vec() *= model::SCALE; + continue; + + } else if (inifile.got_key_float("spawnradius", f)) { + ejector->set_spawn_radius(f * model::SCALE); + continue; + + } else if (inifile.got_key_float("cone", f)) { + ejector->set_cone(f); + continue; + + } else if (inifile.got_key_long("interval", l)) { + ejector->set_interval((unsigned long) l); + continue; + + } else if (inifile.got_key_long("lifespan", l)) { + ejector->set_lifespan((unsigned long) l); + continue; + + } else if (inifile.got_key_color("color", ejector->get_color())) { + continue; + + } else if (inifile.got_key_bool("engine", b)) { + ejector->set_engine(b); + continue; - } else if (inifile.got_key_string("texture", strval)) { - ejector->set_texture("textures/" + strval); - Textures::load(ejector->texture()); - continue; - - } else if (inifile.got_key_float("speed", f)) { - // convert speed from meters/second to game units/second - ejector->set_speed(f * 0.01f); - continue; - - } else if (inifile.got_key_float("acceleration", f)) { - // convert speed from meters/second to game units/second - ejector->set_acceleration(f * 0.01f); - continue; + } else if (inifile.got_key_bool("thrust", b)) { + 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; + + } else if (inifile.got_key_bool("entitysecond", b)) { + ejector->set_entity_second(b); + continue; + + } else if (inifile.got_key_bool("entitythird", b)) { + if (b) { + ejector->set_entity(true); + ejector->set_entity_second(true); + } + continue; + + } else if (inifile.got_key_bool("attached", b)) { + ejector->set_attached(b); + continue; + + } else if (inifile.got_key_float("angle", yaw)) { - } else if (inifile.got_key_float("offset", f)) { - math::clamp(f, 0.0f, 1.0f); - ejector->set_offset(f); - continue; - - } else if (inifile.got_key_vector3f_opt("alpha", ejector->get_alpha_vec())) { - math::clamp(ejector->get_alpha_vec()[0], 0.0f, 1.0f); - math::clamp(ejector->get_alpha_vec()[1], 0.0f, 1.0f); - math::clamp(ejector->get_alpha_vec()[2], 0.0f, 1.0f); - continue; - - } else if (inifile.got_key_vector3f_opt("radius", ejector->get_radius_vec())) { - ejector->get_radius_vec() *= model::SCALE; - continue; - - } else if (inifile.got_key_float("spawnradius", f)) { - ejector->set_spawn_radius(f * model::SCALE); - continue; - - } else if (inifile.got_key_float("cone", f)) { - ejector->set_cone(f); - continue; - - } else if (inifile.got_key_long("interval", l)) { - ejector->set_interval((unsigned long) l); - continue; - - } else if (inifile.got_key_long("lifespan", l)) { - ejector->set_lifespan((unsigned long) l); - continue; - - } else if (inifile.got_key_color("color", ejector->get_color())) { - continue; - - } else if (inifile.got_key_bool("engine", b)) { - ejector->set_engine(b); - continue; + if (yaw == model::ANGLEUP) { + ejector->get_axis().change_pitch(-90.0f); + } else if (yaw == model::ANGLEDOWN) { + ejector->get_axis().change_pitch(90.0f); + } else { + ejector->get_axis().change_direction(yaw); + } + continue; + + } else if (inifile.got_key("angles")) { + + std::istringstream str(inifile.value()); + if (str >> pitch >> yaw >> roll) { + ejector->get_axis().assign(yaw, pitch, roll); + } else { + inifile.unknown_value(); + } + continue; - } else if (inifile.got_key_bool("thrust", b)) { - 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; - - } else if (inifile.got_key_bool("entitysecond", b)) { - ejector->set_entity_second(b); - continue; - - } else if (inifile.got_key_bool("entitythird", b)) { - if (b) { - ejector->set_entity(true); - ejector->set_entity_second(true); - } - 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) { - ejector->get_axis().change_pitch(-90.0f); - } else if (yaw == model::ANGLEDOWN) { - ejector->get_axis().change_pitch(90.0f); - } else { + } else if (inifile.got_key_float("pitch", pitch)) { + ejector->get_axis().change_pitch(-pitch); + continue; + + } else if (inifile.got_key_float("yaw", yaw)) { ejector->get_axis().change_direction(yaw); - } - continue; - - } else if (inifile.got_key("angles")) { - - std::istringstream str(inifile.value()); - if (str >> pitch >> yaw >> roll) { - ejector->get_axis().assign(yaw, pitch, roll); + continue; + + } else if (inifile.got_key_float("roll", roll)) { + ejector->get_axis().change_roll(-roll); + continue; + } else { - inifile.unknown_value(); + inifile.unknown_key(); } - continue; - - } else if (inifile.got_key_float("pitch", pitch)) { - ejector->get_axis().change_pitch(-pitch); - continue; - - } else if (inifile.got_key_float("yaw", yaw)) { - ejector->get_axis().change_direction(yaw); - continue; - - } else if (inifile.got_key_float("roll", roll)) { - ejector->get_axis().change_roll(-roll); - continue; - - } else { - inifile.unknown_key(); } } } diff --git a/src/render/renderext.cc b/src/render/renderext.cc index 25e0cab..6730aba 100644 --- a/src/render/renderext.cc +++ b/src/render/renderext.cc @@ -111,8 +111,9 @@ void RenderExt::frame(float elapsed) state_power = true; state_thrust = 0.0f; - if (!state_visible) + if (!state_visible) { return; + } int state = core::Entity::Normal; -- cgit v1.2.3