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>2008-12-07 14:48:54 +0000
committerStijn Buys <ingar@osirion.org>2008-12-07 14:48:54 +0000
commit11229dcfef77baab5a7a3893a7c6281fbc5f7211 (patch)
tree54fa65dc37ffa35b486c1b7e76afe26ef2318859
parent7de62efc14d0e0f037051bd887c96f28fd9a3215 (diff)
flame particle systems
-rw-r--r--src/model/classes.cc2
-rw-r--r--src/model/classes.h14
-rw-r--r--src/model/map.cc6
-rw-r--r--src/render/particles.cc214
-rw-r--r--src/render/particles.h18
-rw-r--r--src/render/renderext.cc7
6 files changed, 245 insertions, 16 deletions
diff --git a/src/model/classes.cc b/src/model/classes.cc
index 4042c38..06ebda3 100644
--- a/src/model/classes.cc
+++ b/src/model/classes.cc
@@ -43,6 +43,8 @@ Flare::~Flare()
Particles::Particles() :
particles_location()
{
+ particles_entity = false;
+ particles_engine = false;
}
Particles::Particles(math::Vector3f const & location) :
diff --git a/src/model/classes.h b/src/model/classes.h
index 175070a..a0e9d1f 100644
--- a/src/model/classes.h
+++ b/src/model/classes.h
@@ -147,15 +147,21 @@ public:
return particles_script;
}
- inline const float radius() const
+ inline bool entity() const
+ {
+ return particles_entity;
+ }
+
+ inline bool engine() const
{
- return particles_radius;
+ return particles_engine;
}
-
std::string particles_script;
math::Vector3f particles_location;
math::Axis particles_axis;
- float particles_radius;
+
+ bool particles_entity;
+ bool particles_engine;
};
/* ---- class Dock ------------------------------------------------- */
diff --git a/src/model/map.cc b/src/model/map.cc
index 618fd51..f2c519f 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -989,7 +989,11 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_float("roll", angle)) {
particles->particles_axis.change_roll(angle);
-/*
+
+ } else if (mapfile.got_key_int("spawnflags", u)) {
+ particles->particles_entity = spawnflag_isset(u, 2);
+ particles->particles_engine = spawnflag_isset(u, 4);
+/*
} else if (mapfile.got_key_float("radius", particles->particles_radius)) {
particles->particles_radius *= LIGHTSCALE;
*/
diff --git a/src/render/particles.cc b/src/render/particles.cc
index c232ca1..f9271ab 100644
--- a/src/render/particles.cc
+++ b/src/render/particles.cc
@@ -112,6 +112,9 @@ void ParticleScript::init()
continue;
} else if (inifile.got_key_float("speed", script->particles_speed)) {
continue;
+ } else if (inifile.got_key_float("offset", script->particles_offset)) {
+ math::clamp(script->particles_offset, 0.0f, 1.0f);
+ continue;
} else if (inifile.got_key_float("alpha", script->particles_alpha)) {
continue;
} else if (inifile.got_key_float("radius", script->particles_radius)) {
@@ -159,6 +162,8 @@ ParticleScript::ParticleScript()
particles_timeout = 2.0f;
particles_eject = 0.25f;
+ particles_offset = 0.1f;
+
particles_color.assign(1.0f, 1.0f);
}
@@ -168,8 +173,7 @@ ParticleScript::~ParticleScript()
/* ---- class ParticleSystem --------------------------------------- */
-ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, const math::Vector3f &location) :
- particlesystem_location(location)
+ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, model::Particles *modelclass)
{
particlesystem_entity = entity;
particlesystem_last_eject = 0; // timestamp of the last eject
@@ -177,10 +181,24 @@ ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, con
particlesystem_script = script;
particlesystem_texture = 0;
+ particlesystem_modelclass = modelclass;
+
if (particlesystem_script) {
particlesystem_texture = Textures::load("textures/" + particlesystem_script->texture());
+
+ radius = particlesystem_script->radius();
color.assign(particlesystem_script->color());
}
+
+ if (particlesystem_modelclass) {
+ particlesystem_location.assign(modelclass->location());
+ if (modelclass->entity()) {
+ color.assign(entity->color());
+ }
+ if (modelclass->engine()) {
+ color.assign(entity->model()->enginecolor());
+ }
+ }
}
ParticleSystem::~ParticleSystem()
@@ -249,8 +267,8 @@ void ParticleSystem::draw(float elapsed)
/* ---- class Jet -------------------------------------------------- */
-Jet::Jet(ParticleScript *script, core::Entity *entity, const math::Vector3f &location) :
- ParticleSystem(script, entity, location) {
+Jet::Jet(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) :
+ ParticleSystem(script, entity, modelclass) {
}
Jet::~Jet()
@@ -309,8 +327,8 @@ void Jet::draw(float elapsed) {
/* ---- class Trail ------------------------------------------------ */
-Trail::Trail(ParticleScript *script, core::Entity *entity, const math::Vector3f &location) :
- ParticleSystem(script, entity, location) {
+Trail::Trail(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) :
+ ParticleSystem(script, entity, modelclass) {
}
Trail::~Trail()
@@ -340,6 +358,7 @@ void Trail::draw(float elapsed) {
fp = tp / (0.9f * particlesystem_script->timeout());
fp = 1.0 - fp;
}
+ tp = (now - (*first)->time()) / particlesystem_script->timeout();
if (tp > 0) {
color.a = 0.0f;
@@ -373,6 +392,7 @@ void Trail::draw(float elapsed) {
f = t / (0.9f * particlesystem_script->timeout());
f = 1.0 - f;
}
+ t = (now - (*next)->time()) / particlesystem_script->timeout();
color.a = fp * particlesystem_script->alpha();
gl::color(color);
@@ -402,4 +422,186 @@ void Trail::draw(float elapsed) {
}
}
+/* ---- class Flame ------------------------------------------------ */
+
+Flame::Flame(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) :
+ ParticleSystem(script, entity, modelclass) {
+}
+
+Flame::~Flame()
+{}
+
+void Flame::draw(float elapsed) {
+
+ if (!particlesystem_script)
+ return;
+
+ ParticleSystem::draw(elapsed);
+
+ if (particlesystem_stream.size() > 1) {
+
+ Textures::bind(particlesystem_texture);
+ gl::begin(gl::Quads);
+
+ Stream::iterator first = particlesystem_stream.begin();
+
+ float tp = now - (*first)->time();
+ float fp = 0;
+
+ if (tp < particlesystem_script->timeout() * particlesystem_script->offset()) {
+ fp = tp / (particlesystem_script->offset() * particlesystem_script->timeout());
+ } else {
+ tp = tp - particlesystem_script->timeout() * particlesystem_script->offset();
+ fp = tp / ((1.0f - particlesystem_script->offset()) * particlesystem_script->timeout());
+ fp = 1.0 - fp;
+ }
+ tp = (now - (*first)->time()) / particlesystem_script->timeout();
+
+ Stream::iterator next = first;
+ if (tp > 0) {
+ color.a = 0;
+ gl::color(color);
+ glTexCoord2f(1,0);
+ gl::vertex(ejector_location);
+ glTexCoord2f(0,0);
+ gl::vertex(ejector_location);
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,tp);
+ gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * fp);
+ glTexCoord2f(1,tp);
+ gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * fp);
+ Stats::quads++;
+
+ color.a = 0;
+ gl::color(color);
+ glTexCoord2f(1,0);
+ gl::vertex(ejector_location);
+ glTexCoord2f(0,0);
+ gl::vertex(ejector_location);
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,tp);
+ gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * fp);
+ glTexCoord2f(1,tp);
+ gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * fp);
+ Stats::quads++;
+
+ color.a = 0;
+ gl::color(color);
+ glTexCoord2f(1,0);
+ gl::vertex(ejector_location);
+ glTexCoord2f(0,0);
+ gl::vertex(ejector_location);
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,tp);
+ gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * fp);
+ glTexCoord2f(1,tp);
+ gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * fp);
+ Stats::quads++;
+
+ color.a = 0;
+ gl::color(color);
+ glTexCoord2f(1,0);
+ gl::vertex(ejector_location);
+ glTexCoord2f(0,0);
+ gl::vertex(ejector_location);
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,tp);
+ gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * fp);
+ glTexCoord2f(1,tp);
+ gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * fp);
+ Stats::quads++;
+ }
+
+ for (next++; next != particlesystem_stream.end(); next++) {
+
+ float t = now - (*next)->time();
+ float f = 0;
+
+ if (t < particlesystem_script->timeout() * particlesystem_script->offset()) {
+ f = t / (particlesystem_script->offset() * particlesystem_script->timeout());
+ } else {
+ t = t - particlesystem_script->timeout() * particlesystem_script->offset();
+ f = t / ((1.0f - particlesystem_script->offset()) * particlesystem_script->timeout());
+ f = 1.0 - f;
+ }
+ t = (now - (*next)->time()) / particlesystem_script->timeout();
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(1,tp);
+ gl::vertex((*first)->location() + (*first)->axis().up() * particlesystem_script->radius() * fp);
+ glTexCoord2f(0,tp);
+ gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_script->radius() * fp);
+
+ color.a = f * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,t);
+ gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * f);
+ glTexCoord2f(1,t);
+ gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * f);
+ Stats::quads++;
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(1,tp);
+ gl::vertex((*first)->location() - (*first)->axis().left() * particlesystem_script->radius() * fp);
+ glTexCoord2f(0,tp);
+ gl::vertex((*first)->location() + (*first)->axis().up() * particlesystem_script->radius() * fp);
+
+ color.a = f * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,t);
+ gl::vertex((*next)->location() + (*next)->axis().up() * particlesystem_script->radius() * f);
+ glTexCoord2f(1,t);
+ gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * f);
+ Stats::quads++;
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(1,tp);
+ gl::vertex((*first)->location() - (*first)->axis().up() * particlesystem_script->radius() * fp);
+ glTexCoord2f(0,tp);
+ gl::vertex((*first)->location() + (*first)->axis().left() * particlesystem_script->radius() * fp);
+
+ color.a = f * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,t);
+ gl::vertex((*next)->location() + (*next)->axis().left() * particlesystem_script->radius() * f);
+ glTexCoord2f(1,t);
+ gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * f);
+ Stats::quads++;
+
+ color.a = fp * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(1,tp);
+ gl::vertex((*first)->location() - (*first)->axis().left() * particlesystem_script->radius() * fp);
+ glTexCoord2f(0,tp);
+ gl::vertex((*first)->location() - (*first)->axis().up() * particlesystem_script->radius() * fp);
+
+ color.a = f * particlesystem_script->alpha();
+ gl::color(color);
+ glTexCoord2f(0,t);
+ gl::vertex((*next)->location() - (*next)->axis().up() * particlesystem_script->radius() * f);
+ glTexCoord2f(1,t);
+ gl::vertex((*next)->location() - (*next)->axis().left() * particlesystem_script->radius() * f);
+ Stats::quads++;
+
+ first = next;
+ fp = f;
+ tp = t;
+ }
+
+
+ gl::end();
+ }
+}
+
} // namespace render
diff --git a/src/render/particles.h b/src/render/particles.h
index 0044832..9c9d44b 100644
--- a/src/render/particles.h
+++ b/src/render/particles.h
@@ -13,6 +13,7 @@
#include "math/color.h"
#include "math/vector3f.h"
#include "core/entity.h"
+#include "model/classes.h"
namespace render {
@@ -64,6 +65,8 @@ public:
inline float alpha() const { return particles_alpha; }
+ inline float offset() const { return particles_offset; }
+
static ParticleScript *find(const std::string &label);
static void init();
@@ -84,6 +87,7 @@ private:
float particles_eject;
float particles_speed;
float particles_alpha;
+ float particles_offset;
typedef std::map<std::string, ParticleScript *> Registry;
@@ -95,7 +99,7 @@ private:
/// abstract base class for a particle system attached to an entity
class ParticleSystem {
public:
- ParticleSystem(ParticleScript *script, core::Entity *entity, const math::Vector3f &location);
+ ParticleSystem(ParticleScript *script, core::Entity *entity, model::Particles *modelclass);
virtual ~ParticleSystem();
/// index of the texture to use
@@ -136,8 +140,11 @@ protected:
math::Vector3f ejector_location;
bool ejector_active;
+ float radius;
float now;
math::Color color;
+
+ model::Particles *particlesystem_modelclass;
};
/* ---- class Flame ------------------------------------------------ */
@@ -145,6 +152,11 @@ protected:
/// flame style particles, like engine flames
class Flame : public ParticleSystem
{
+public:
+ Flame(ParticleScript *script, core::Entity *entity, model::Particles *modelclass);
+ virtual ~Flame();
+
+ virtual void draw(float elapsed);
};
/* ---- class Jet -------------------------------------------------- */
@@ -153,7 +165,7 @@ class Flame : public ParticleSystem
class Jet : public ParticleSystem
{
public:
- Jet(ParticleScript *script, core::Entity *entity, const math::Vector3f &location);
+ Jet(ParticleScript *script, core::Entity *entity, model::Particles *modelclass);
virtual ~Jet();
virtual void draw(float elapsed);
@@ -165,7 +177,7 @@ public:
class Trail : public ParticleSystem
{
public:
- Trail(ParticleScript *script, core::Entity *entity, const math::Vector3f &location);
+ Trail(ParticleScript *script, core::Entity *entity, model::Particles *modelclass);
virtual ~Trail();
virtual void draw(float elapsed);
diff --git a/src/render/renderext.cc b/src/render/renderext.cc
index 0fa6796..d2d5a71 100644
--- a/src/render/renderext.cc
+++ b/src/render/renderext.cc
@@ -60,11 +60,14 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re
ParticleScript *script = ParticleScript::find(particlesystem->script());
if (script) {
if (script->type() == render::ParticleScript::Trail) {
- Trail *trail = new Trail(script, entity, particlesystem->location());
+ Trail *trail = new Trail(script, entity, particlesystem);
state_particles.push_back(trail);
} else if (script->type() == render::ParticleScript::Jet) {
- Jet *jet = new Jet(script, entity, particlesystem->location());
+ Jet *jet = new Jet(script, entity, particlesystem);
state_particles.push_back(jet);
+ } else if (script->type() == render::ParticleScript::Flame) {
+ Flame *flame = new Flame(script, entity, particlesystem);
+ state_particles.push_back(flame);
}
} else {
con_warn << "Could not find particle system '" << particlesystem->script() << "'" << std::endl;