Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/particles.cc')
-rw-r--r--src/render/particles.cc361
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);