diff options
Diffstat (limited to 'src/render/particles.cc')
-rw-r--r-- | src/render/particles.cc | 361 |
1 files changed, 227 insertions, 134 deletions
diff --git a/src/render/particles.cc b/src/render/particles.cc index 610c49a..86847c3 100644 --- a/src/render/particles.cc +++ b/src/render/particles.cc @@ -30,47 +30,56 @@ Particle::Particle(const math::Vector3f &location, const math::Axis &axis, float /* ---- static ParticleScript registry ---------------------------------- */ -ParticleScript::Registry ParticleScript::particles_registry; +ParticleScript::Registry ParticleScript::particlescript_registry; void ParticleScript::list() { - std::string str; - for (Registry::iterator it = particles_registry.begin(); it != particles_registry.end(); it++) { + + for (Registry::const_iterator it = particlescript_registry.begin(); it != particlescript_registry.end(); it++) { - ParticleScript *script = (*it).second; - switch (script->type()) { - case Flame: - str.assign("flame"); - break; - case Jet: - str.assign("jet"); - break; - case Spray: - str.assign("spray"); - break; - case Trail: - str.assign("trail"); - break; + const ParticleScript *script = (*it).second; + + std::string strval; + size_t count = 0; + while (script) { + + switch (script->type()) { + case Flame: + strval.append(" flame"); + break; + case Jet: + strval.append(" jet"); + break; + case Spray: + strval.append(" spray"); + break; + case Trail: + strval.append(" trail"); + break; + } + + count++; + script = script->next(); } - con_print << " " << script->label() << " " << str << std::endl; - con_print << particles_registry.size() << " particle scripts" << std::endl; + con_print << " " << (*it).second->label() << strval << " " << count << " " << aux::plural("ejector", count) << std::endl; + con_print << particlescript_registry.size() << " particle scripts" << std::endl; } } void ParticleScript::clear() { - for (Registry::iterator it = particles_registry.begin(); it != particles_registry.end(); it++) { + for (Registry::iterator it = particlescript_registry.begin(); it != particlescript_registry.end(); it++) { delete(*it).second; (*it).second = 0; } - particles_registry.clear(); + particlescript_registry.clear(); } ParticleScript *ParticleScript::find(const std::string &label) { - Registry::iterator it = particles_registry.find(label); + Registry::iterator it = particlescript_registry.find(label); - if (it != particles_registry.end()) { + if (it != particlescript_registry.end()) { return (*it).second; } else { return 0; @@ -79,9 +88,9 @@ ParticleScript *ParticleScript::find(const std::string &label) ParticleScript *ParticleScript::load(const std::string &label) { - ParticleScript *script = find(label); - if (script) - return script; + ParticleScript *parent_script = find(label); + if (parent_script) + return parent_script; filesystem::IniFile inifile; @@ -92,15 +101,23 @@ ParticleScript *ParticleScript::load(const std::string &label) return 0; } - script = new ParticleScript(label); - con_debug << " " << inifile.name() << std::endl; - + ParticleScript *script = 0; std::string strval; + float pitch, yaw, roll = 0.0f; while (inifile.getline()) { if (inifile.got_section()) { + if (inifile.got_section("particles")) { + if (script) { + script->particlescript_next = new ParticleScript(std::string()); + script = script->particlescript_next; + } else { + script = new ParticleScript(label); + particlescript_registry[script->label()] = script; + parent_script = script; + } continue; } else { inifile.unknown_section(); @@ -113,34 +130,85 @@ ParticleScript *ParticleScript::load(const std::string &label) if (inifile.got_key_string("type", strval)) { aux::to_label(strval); if (strval.compare("flame") == 0) { - script->particles_type = ParticleScript::Flame; + script->particlescript_type = ParticleScript::Flame; } else if (strval.compare("jet") == 0) { - script->particles_type = ParticleScript::Jet; + script->particlescript_type = ParticleScript::Jet; } else if (strval.compare("trail") == 0) { - script->particles_type = ParticleScript::Trail; + script->particlescript_type = ParticleScript::Trail; } else { inifile.unknown_value(); } continue; - } else if (inifile.got_key_string("texture", script->particles_texture)) { + + } else if (inifile.got_key_string("cull", strval)) { + aux::to_label(strval); + if (strval.compare("none") == 0) { + script->particlescript_cull = model::CullNone; + } else if (strval.compare("back") == 0) { + script->particlescript_cull = model::CullBack; + } else if (strval.compare("front") == 0) { + script->particlescript_cull = model::CullFront; + } else { + inifile.unknown_value(); + } + continue; + + } else if (inifile.got_key_string("texture", script->particlescript_texture)) { Textures::load("textures/" + script->texture()); continue; - } else if (inifile.got_key_float("speed", script->particles_speed)) { + } else if (inifile.got_key_float("speed", script->particlescript_speed)) { + continue; + } else if (inifile.got_key_float("offset", script->particlescript_offset)) { + math::clamp(script->particlescript_offset, 0.0f, 1.0f); continue; - } else if (inifile.got_key_float("offset", script->particles_offset)) { - math::clamp(script->particles_offset, 0.0f, 1.0f); + } else if (inifile.got_key_float("alpha", script->particlescript_alpha)) { continue; - } else if (inifile.got_key_float("alpha", script->particles_alpha)) { + } else if (inifile.got_key_float("radius", script->particlescript_radius)) { + script->particlescript_radius *= model::SCALE; continue; - } else if (inifile.got_key_float("radius", script->particles_radius)) { - script->particles_radius *= model::SCALE; + } else if (inifile.got_key_float("eject", script->particlescript_eject)) { continue; - } else if (inifile.got_key_float("eject", script->particles_eject)) { + } else if (inifile.got_key_float("timeout", script->particlescript_timeout)) { continue; - } else if (inifile.got_key_float("timeout", script->particles_timeout)) { + } else if (inifile.got_key_color("color", script->particlescript_color)) { continue; - } else if (inifile.got_key_color("color", script->particles_color)) { + + } else if (inifile.got_key_float("angle", yaw)) { + + if (yaw == model::ANGLEUP) { + script->particlescript_axis.change_pitch(-90.0f); + } else if (yaw == model::ANGLEDOWN) { + script->particlescript_axis.change_pitch(90.0f); + } else { + script->particlescript_axis.change_direction(yaw); + } + continue; + + } else if (inifile.got_key("angles")) { + + std::istringstream str(inifile.value()); + if (str >> pitch >> yaw >> roll) { + script->particlescript_axis.clear(); + script->particlescript_axis.change_pitch(-pitch); + script->particlescript_axis.change_direction(yaw); + script->particlescript_axis.change_roll(-roll); + } else { + inifile.unknown_value(); + } + continue; + + } else if (inifile.got_key_float("pitch", pitch)) { + script->particlescript_axis.change_pitch(-pitch); + continue; + + } else if (inifile.got_key_float("yaw", yaw)) { + script->particlescript_axis.change_direction(yaw); continue; + + } else if (inifile.got_key_float("roll", roll)) { + script->particlescript_axis.change_roll(-roll); + continue; + } else { inifile.unkown_key(); } @@ -149,67 +217,92 @@ ParticleScript *ParticleScript::load(const std::string &label) } inifile.close(); + + strval.clear(); + + size_t count = 0; + for (script = parent_script; script != 0; script = script->particlescript_next) { + switch (script->type()) { + case Flame: + strval.append(" flame"); + break; + case Jet: + strval.append(" jet"); + break; + case Spray: + strval.append(" spray"); + break; + case Trail: + strval.append(" trail"); + break; + } + count++; + } + con_debug << " " << inifile.name() << strval << " " << count << " " << aux::plural("ejector", count) << std::endl; - particles_registry[script->label()] = script; - - return script; + return parent_script; } /* ---- class ParticleScript --------------------------------------- */ -ParticleScript::ParticleScript(const std::string label) : particles_label(label) +ParticleScript::ParticleScript(const std::string & label) : particlescript_label(label) { - particles_radius = 1.0f; - particles_alpha = 1.0f; + particlescript_radius = 1.0f; + particlescript_alpha = 1.0f; - particles_speed = 0.0f; - particles_timeout = 2.0f; - particles_eject = 0.25f; + particlescript_speed = 0.0f; + particlescript_timeout = 2.0f; + particlescript_eject = 0.25f; - particles_offset = 0.1f; + particlescript_offset = 0.1f; - particles_color.assign(1.0f, 1.0f); + particlescript_color.assign(1.0f, 1.0f); + + particlescript_next = 0; + + particlescript_cull = model::CullNone; } ParticleScript::~ParticleScript() { + if (particlescript_next) { + delete particlescript_next; + } } /* ---- class ParticleSystem --------------------------------------- */ -ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) +ParticleSystem::ParticleSystem(const ParticleScript *script, const core::Entity *entity, const model::Particles *modelclass) { + particlesystem_script = script; particlesystem_entity = entity; + particlesystem_modelclass = modelclass; + particlesystem_last_eject = 0; // timestamp of the last eject - - particlesystem_script = script; - particlesystem_texture = 0; particlesystem_cull = model::CullNone; - - particlesystem_modelclass = modelclass; - + particlesystem_texture = 0; + particlesystem_radius = 1.0f; + if (particlesystem_script) { particlesystem_texture = Textures::load("textures/" + particlesystem_script->texture()); - - // map entity radius overrules script value - if (modelclass->radius()) - particlesystem_radius = modelclass->radius(); - else - particlesystem_radius = particlesystem_script->radius(); - - color.assign(particlesystem_script->color()); + particlesystem_radius = particlesystem_script->radius(); + particlesystem_cull = particlesystem_script->cull(); + particlesystem_color.assign(particlesystem_script->color()); + particlesystem_axis.assign(particlesystem_script->axis()); } if (particlesystem_modelclass) { particlesystem_location.assign(modelclass->location()); + if (modelclass->entity()) { - color.assign(entity->color()); + particlesystem_color.assign(entity->color()); } if (modelclass->engine()) { - color.assign(entity->model()->enginecolor()); + // FIXME if not modelclass->has_color(); + particlesystem_color.assign(entity->model()->enginecolor()); } - particlesystem_axis.assign(modelclass->axis()); -// particlesystem_cull = particlesystem_modelclass->cull(); + particlesystem_axis.assign(modelclass->axis() * particlesystem_axis); + particlesystem_radius *= particlesystem_modelclass->scale(); } @@ -234,11 +327,11 @@ void ParticleSystem::clear() particlesystem_stream.clear(); } -void ParticleSystem::draw(float elapsed) +void ParticleSystem::draw(const float elapsed) { if (particlesystem_entity->type() == core::Entity::Controlable) { - core::EntityControlable *ec = static_cast<core::EntityControlable *>(particlesystem_entity); - if (ec->state() == core::Entity::Docked) { + const core::EntityControlable *controlable = static_cast<const core::EntityControlable *>(particlesystem_entity); + if (controlable->state() == core::Entity::Docked) { if (particlesystem_stream.size()) clear(); return; @@ -266,13 +359,13 @@ void ParticleSystem::draw(float elapsed) ejector_active = true; } else { if (particlesystem_entity->type() == core::Entity::Dynamic) { - core::EntityDynamic *ed = static_cast<core::EntityDynamic *>(particlesystem_entity); + const core::EntityDynamic *ed = static_cast<const core::EntityDynamic *>(particlesystem_entity); if (ed->speed()) { ejector_active = true; } } else if (particlesystem_entity->type() == core::Entity::Controlable) { - core::EntityControlable *ec = static_cast<core::EntityControlable *>(particlesystem_entity); - if ((ec->thrust() > 0.0f) || (ec->state() == core::Entity::ImpulseInitiate) || (ec->state() == core::Entity::Impulse)) { + const core::EntityControlable *controlable = static_cast<const core::EntityControlable *>(particlesystem_entity); + if ((controlable->thrust() > 0.0f) || (controlable->state() == core::Entity::ImpulseInitiate) || (controlable->state() == core::Entity::Impulse)) { ejector_active = true; } } @@ -287,15 +380,15 @@ void ParticleSystem::draw(float elapsed) /* ---- class Jet -------------------------------------------------- */ -Jet::Jet(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : - ParticleSystem(script, entity, modelclass) +Jet::Jet(const ParticleScript *script, const core::Entity *entity, const model::Particles *modelclass) : + ParticleSystem(script, entity, modelclass) { } Jet::~Jet() {} -void Jet::draw(float elapsed) +void Jet::draw(const float elapsed) { if (!particlesystem_script) return; @@ -329,8 +422,8 @@ void Jet::draw(float elapsed) f *= f; float radius = particlesystem_radius * f; - color.a = f * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = f * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, 1); gl::vertex(particle->location() + quad[0] * radius); @@ -348,15 +441,15 @@ void Jet::draw(float elapsed) } /* ---- class Spray ------------------------------------------------ */ -Spray::Spray(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : - ParticleSystem(script, entity, modelclass) +Spray::Spray(const ParticleScript *script, const core::Entity *entity, const model::Particles *modelclass) : + ParticleSystem(script, entity, modelclass) { } Spray::~Spray() {} -void Spray::draw(float elapsed) +void Spray::draw(const float elapsed) { if (!particlesystem_script) return; @@ -390,8 +483,8 @@ void Spray::draw(float elapsed) f *= f; float radius = particlesystem_radius * f; - color.a = f * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = f * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, 1); gl::vertex(particle->location() + quad[0] * radius); @@ -411,15 +504,15 @@ void Spray::draw(float elapsed) /* ---- class Trail ------------------------------------------------ */ -Trail::Trail(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : - ParticleSystem(script, entity, modelclass) +Trail::Trail(const ParticleScript *script, const core::Entity *entity, const model::Particles *modelclass) : + ParticleSystem(script, entity, modelclass) { } Trail::~Trail() {} -void Trail::draw(float elapsed) +void Trail::draw(const float elapsed) { if (!particlesystem_script) @@ -447,16 +540,16 @@ void Trail::draw(float elapsed) tp = (now - (*first)->time()) / particlesystem_script->timeout(); if (tp > 0) { - color.a = 0.0f; - gl::color(color); + particlesystem_color.a = 0.0f; + gl::color(particlesystem_color); glTexCoord2f(1, 0); gl::vertex(ejector_location); glTexCoord2f(0, 0); gl::vertex(ejector_location); - color.a = fp; - gl::color(color); + particlesystem_color.a = fp; + gl::color(particlesystem_color); glTexCoord2f(0, 1); gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_radius * fp); @@ -480,16 +573,16 @@ void Trail::draw(float elapsed) } t = (now - (*next)->time()) / particlesystem_script->timeout(); - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(1, 0); gl::vertex((*first)->location() - (*first)->axis().left() * particlesystem_radius * fp); glTexCoord2f(0, 0); gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_radius * fp); - color.a = f * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = f * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, 1); gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_radius * f); @@ -510,15 +603,15 @@ void Trail::draw(float elapsed) /* ---- class Flame ------------------------------------------------ */ -Flame::Flame(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : - ParticleSystem(script, entity, modelclass) +Flame::Flame(const ParticleScript *script, const core::Entity *entity, const model::Particles *modelclass) : + ParticleSystem(script, entity, modelclass) { } Flame::~Flame() {} -void Flame::draw(float elapsed) +void Flame::draw(const float elapsed) { if (!particlesystem_script) @@ -547,60 +640,60 @@ void Flame::draw(float elapsed) Stream::iterator next = first; if (tp > 0) { - color.a = 0; - gl::color(color); + particlesystem_color.a = 0; + gl::color(particlesystem_color); glTexCoord2f(1, 0); gl::vertex(ejector_location); glTexCoord2f(0, 0); gl::vertex(ejector_location); - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, tp); gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_radius * fp); glTexCoord2f(1, tp); gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_radius * fp); Stats::quads++; - color.a = 0; - gl::color(color); + particlesystem_color.a = 0; + gl::color(particlesystem_color); glTexCoord2f(1, 0); gl::vertex(ejector_location); glTexCoord2f(0, 0); gl::vertex(ejector_location); - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, tp); gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_radius * fp); glTexCoord2f(1, tp); gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_radius * fp); Stats::quads++; - color.a = 0; - gl::color(color); + particlesystem_color.a = 0; + gl::color(particlesystem_color); glTexCoord2f(1, 0); gl::vertex(ejector_location); glTexCoord2f(0, 0); gl::vertex(ejector_location); - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, tp); gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_radius * fp); glTexCoord2f(1, tp); gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_radius * fp); Stats::quads++; - color.a = 0; - gl::color(color); + particlesystem_color.a = 0; + gl::color(particlesystem_color); glTexCoord2f(1, 0); gl::vertex(ejector_location); glTexCoord2f(0, 0); gl::vertex(ejector_location); - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, tp); gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_radius * fp); glTexCoord2f(1, tp); @@ -622,60 +715,60 @@ void Flame::draw(float elapsed) } t = (now - (*next)->time()) / particlesystem_script->timeout(); - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(1, tp); gl::vertex((*first)->location() + (*first)->axis().up() * particlesystem_radius * fp); glTexCoord2f(0, tp); gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_radius * fp); - color.a = f * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = f * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, t); gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_radius * f); glTexCoord2f(1, t); gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_radius * f); Stats::quads++; - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(1, tp); gl::vertex((*first)->location() - (*first)->axis().left() * particlesystem_radius * fp); glTexCoord2f(0, tp); gl::vertex((*first)->location() + (*first)->axis().up() * particlesystem_radius * fp); - color.a = f * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = f * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, t); gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_radius * f); glTexCoord2f(1, t); gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_radius * f); Stats::quads++; - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(1, tp); gl::vertex((*first)->location() - (*first)->axis().up() * particlesystem_radius * fp); glTexCoord2f(0, tp); gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_radius * fp); - color.a = f * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = f * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, t); gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_radius * f); glTexCoord2f(1, t); gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_radius * f); Stats::quads++; - color.a = fp * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = fp * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(1, tp); gl::vertex((*first)->location() - (*first)->axis().left() * particlesystem_radius * fp); glTexCoord2f(0, tp); gl::vertex((*first)->location() - (*first)->axis().up() * particlesystem_radius * fp); - color.a = f * particlesystem_script->alpha(); - gl::color(color); + particlesystem_color.a = f * particlesystem_script->alpha(); + gl::color(particlesystem_color); glTexCoord2f(0, t); gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_radius * f); glTexCoord2f(1, t); |