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>2013-01-20 21:37:11 +0000
committerStijn Buys <ingar@osirion.org>2013-01-20 21:37:11 +0000
commitd4f9da2f3c19511b028da2569d7b6a8d1371e135 (patch)
treee1bba0d8dd3b15169612f865612d3fca6475639a /src/render/particlesystemscript.cc
parent4feff2411d1b703a3b93d8a342112bd998b1ffed (diff)
Major overhaul of the particle system back-end, support multiple ejectors per particle system.
Diffstat (limited to 'src/render/particlesystemscript.cc')
-rw-r--r--src/render/particlesystemscript.cc313
1 files changed, 313 insertions, 0 deletions
diff --git a/src/render/particlesystemscript.cc b/src/render/particlesystemscript.cc
new file mode 100644
index 0000000..98c0a2d
--- /dev/null
+++ b/src/render/particlesystemscript.cc
@@ -0,0 +1,313 @@
+/*
+ render/particlesystemscript.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/particlesystemscript.h"
+#include "render/textures.h"
+
+namespace render
+{
+
+/* ---- static ParticleSystemScript registry ---------------------------------- */
+
+ParticleSystemScript::Registry ParticleSystemScript::script_registry;
+
+void ParticleSystemScript::list()
+{
+
+ for (Registry::const_iterator it = script_registry.begin(); it != script_registry.end(); ++it) {
+
+ const ParticleSystemScript *script = (*it).second;
+ std::string strval;
+
+ for (Ejectors::const_iterator eit = script->script_ejectors.begin(); eit != script->script_ejectors.end(); ++eit) {
+ const ParticleEjectorScript *ejector = (*eit);
+
+ switch (ejector->type()) {
+ case ParticleEjectorScript::Flame:
+ strval.append(" flame");
+ break;
+ case ParticleEjectorScript::Flare:
+ strval.append(" flare");
+ break;
+ case ParticleEjectorScript::Jet:
+ strval.append(" jet");
+ break;
+ case ParticleEjectorScript::Spray:
+ strval.append(" spray");
+ break;
+ case ParticleEjectorScript::Trail:
+ strval.append(" trail");
+ break;
+ }
+ }
+ con_print << " " << script->label() << strval << " " << script->script_ejectors.size() << " " << aux::plural("ejector", script->script_ejectors.size()) << std::endl;
+ }
+ con_print << script_registry.size() << " particle scripts" << std::endl;
+}
+
+void ParticleSystemScript::clear()
+{
+ for (Registry::iterator it = script_registry.begin(); it != script_registry.end(); it++) {
+ delete(*it).second;
+ (*it).second = 0;
+ }
+ script_registry.clear();
+}
+
+ParticleSystemScript *ParticleSystemScript::find(const std::string &label)
+{
+ Registry::iterator it = script_registry.find(label);
+
+ if (it != script_registry.end()) {
+ return (*it).second;
+ } else {
+ return 0;
+ }
+}
+
+ParticleSystemScript *ParticleSystemScript::load(const std::string &label)
+{
+ ParticleSystemScript *script = find(label);
+ if (script) {
+ return script;
+ }
+
+ filesystem::IniFile inifile;
+ inifile.open("particles/" + label);
+ if (!inifile.is_open()) {
+ con_warn << "Could not open " << inifile.name() << std::endl;
+ return 0;
+ }
+
+ ParticleEjectorScript *ejector = 0;
+ std::string strval;
+ float pitch, yaw, roll = 0.0f;
+ float f;
+ bool b;
+ long l;
+
+ while (inifile.getline()) {
+
+ if (inifile.got_section()) {
+
+ if (inifile.got_section("particles")) {
+ if (!script) {
+ script = new ParticleSystemScript(label);
+ script_registry[script->label()] = script;
+ }
+ ejector = 0;
+ continue;
+ } else if (inifile.got_section("ejector")) {
+ if (script) {
+ ejector = script->add_ejector();
+ } else {
+ inifile.unknown_error("ejector section without particles section");
+ }
+ } else {
+ inifile.unknown_section();
+ }
+
+ } else if (inifile.got_key()) {
+
+ if (inifile.in_section("particles")) {
+ inifile.unknown_key();
+
+ } else if (inifile.in_section("ejector") && ejector) {
+
+ if (inifile.got_key_string("type", strval)) {
+ aux::to_label(strval);
+ if (strval.compare("jet") == 0) {
+ ejector->set_type(ParticleEjectorScript::Jet);
+ } 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("spray") == 0) {
+ ejector->set_type(ParticleEjectorScript::Spray);
+ } else if (strval.compare("flare") == 0) {
+ ejector->set_type(ParticleEjectorScript::Flare);
+ } 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_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("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_bool("thrust", b)) {
+ ejector->set_thrust(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_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 {
+ 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_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();
+ }
+ }
+ }
+ }
+
+ inifile.close();
+
+#ifdef HAVE_DEBUG_MESSAGES
+ if (script) {
+ strval.clear();
+ for (Ejectors::const_iterator eit = script->script_ejectors.begin(); eit != script->script_ejectors.end(); ++eit) {
+ const ParticleEjectorScript *ejector = (*eit);
+
+ switch (ejector->type()) {
+ case ParticleEjectorScript::Flame:
+ strval.append(" flame");
+ break;
+ case ParticleEjectorScript::Flare:
+ strval.append(" flare");
+ break;
+ case ParticleEjectorScript::Jet:
+ strval.append(" jet");
+ break;
+ case ParticleEjectorScript::Spray:
+ strval.append(" spray");
+ break;
+ case ParticleEjectorScript::Trail:
+ strval.append(" trail");
+ break;
+ }
+ }
+ con_debug << " " << script->label() << strval << " " << script->script_ejectors.size() << " " << aux::plural("ejector", script->script_ejectors.size()) << std::endl;
+ }
+#endif
+ return script;
+}
+
+/* ---- class ParticleSystemScript --------------------------------------- */
+
+ParticleSystemScript::ParticleSystemScript(const std::string & label) : script_label(label)
+{
+
+}
+
+ParticleSystemScript::~ParticleSystemScript()
+{
+ for (Ejectors::iterator it = script_ejectors.begin(); it != script_ejectors.end(); ++it)
+ {
+ delete (*it);
+ (*it) = 0;
+ }
+ script_ejectors.clear();
+}
+
+ParticleEjectorScript *ParticleSystemScript::add_ejector()
+{
+ ParticleEjectorScript *ejector = new ParticleEjectorScript();
+ script_ejectors.push_back(ejector);
+ return ejector;
+}
+
+} \ No newline at end of file