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-04-16 21:06:49 +0000
committerStijn Buys <ingar@osirion.org>2013-04-16 21:06:49 +0000
commit2c8331414db790824df9e9e2ea6e25ad7aa39b99 (patch)
tree387bd65dc1d0c6fde5942dce0591c430a6eb9053
parentc625314940a3e41c28aff7a311ccd7ad2d0bf8d7 (diff)
Support for 'colorsecond' in particle scripts, have trail style particles use a single texture for the entire length instead of repeating it.
-rw-r--r--src/render/particle.cc2
-rw-r--r--src/render/particle.h24
-rw-r--r--src/render/particleejector.cc76
-rw-r--r--src/render/particleejectorscript.cc4
-rw-r--r--src/render/particleejectorscript.h54
-rw-r--r--src/render/particlesystemscript.cc6
6 files changed, 118 insertions, 48 deletions
diff --git a/src/render/particle.cc b/src/render/particle.cc
index 5925ba5..6774cde 100644
--- a/src/render/particle.cc
+++ b/src/render/particle.cc
@@ -19,7 +19,6 @@ Particle::Particle(const math::Vector3f &location, const unsigned long timestamp
particle_speed = 0.0f;
particle_radius = 0.0f;
- particle_alpha = 0.0f;
}
@@ -31,7 +30,6 @@ Particle::Particle(const math::Vector3f &location, const math::Axis &axis, const
particle_speed = 0.0f;
particle_radius = 0.0f;
- particle_alpha = 0.0f;
}
} //namespace render
diff --git a/src/render/particle.h b/src/render/particle.h
index c259dbc..742a03a 100644
--- a/src/render/particle.h
+++ b/src/render/particle.h
@@ -59,11 +59,11 @@ public:
}
/**
- * @brief alpha value of the particle
+ * @brief color of the particle
* */
- const float alpha() const
+ const math::Color color() const
{
- return particle_alpha;
+ return particle_color;
}
/**
@@ -130,11 +130,19 @@ public:
}
/**
- * @brief set the alpha value of the particle
+ * @brief set the color of the particle
* */
- inline void set_alpha(const float alpha)
+ inline void set_color(const math::Color color)
{
- particle_alpha = alpha;
+ particle_color.assign(color);
+ }
+
+ /**
+ * @brief return a reference to the color of the particle
+ * */
+ math::Color & get_color()
+ {
+ return particle_color;
}
/**
@@ -148,9 +156,9 @@ public:
protected:
math::Vector3f particle_location;
+ math::Color particle_color;
math::Axis particle_axis;
- float particle_radius;
- float particle_alpha;
+ float particle_radius;
float particle_rotation;
float particle_speed;
unsigned long particle_timestamp;
diff --git a/src/render/particleejector.cc b/src/render/particleejector.cc
index 29a255d..5fae7d1 100644
--- a/src/render/particleejector.cc
+++ b/src/render/particleejector.cc
@@ -82,7 +82,10 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat
Particle *particle = new Particle(particle_location, particle_axis, now);
particle->set_radius(radius_vec()[0]);
- particle->set_alpha(alpha_vec()[0]);
+
+ particle->set_color(color());
+ particle->get_color().a = alpha_vec()[0];
+
particle->set_rotation(math::randomf(2.0f * M_PI));
particle->set_speed(math::randomf(speed_vec()[0], speed_vec()[1]));
particles().push_front(particle);
@@ -90,7 +93,8 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat
if (type() == Streak) {
Particle *tail = new Particle(particle_location, particle_axis, now);
tail->set_radius(radius_vec()[0]);
- tail->set_alpha(alpha_vec()[0]);
+ tail->set_color(color());
+ tail->get_color().a = alpha_vec()[0];
tail->set_rotation(particle->rotation());
tail->set_speed(math::randomf(tailspeed_vec()[0], tailspeed_vec()[1]));
particles().push_front(tail);
@@ -115,20 +119,32 @@ void ParticleEjector::frame(const float seconds, const math::Vector3f & ps_locat
// apply velocity
particle->get_location() += (particle->axis().forward() * particle->speed() * seconds);
- // set particle radius_vec and alpha_vec
+ // interpolate particle radius, color and alpha
const float age = (float) (now - particle->timestamp());
const float halflife = offset() * (float) lifespan();
+ float t;
if (age < halflife) {
- const float t = age / halflife;
+ t = age / halflife;
particle->set_radius((1.0f - t) * radius_vec()[0] + t * radius_vec()[1]);
- particle->set_alpha((1.0f - t) * alpha_vec()[0] + t * alpha_vec()[1]);
+ particle->get_color().a = ((1.0f - t) * alpha_vec()[0] + t * alpha_vec()[1]);
+
+ t *= 0.5f;
+
} else {
- const float t = (age - halflife) / ((float) lifespan() - halflife);
+ t = (age - halflife) / ((float) lifespan() - halflife);
particle->set_radius((1.0f - t) * radius_vec()[1] + t * radius_vec()[2]);
- particle->set_alpha((1.0f - t) * alpha_vec()[1] + t * alpha_vec()[2]);
+ particle->get_color().a = ((1.0f - t) * alpha_vec()[1] + t * alpha_vec()[2]);
+
+ t = 0.5f + t * 0.5f;
+ }
+
+ if (color_interpolated()) {
+ particle->get_color().r = color().r * (1.0f - t) + color_second().r * t;
+ particle->get_color().g = color().g * (1.0f - t) + color_second().g * t;
+ particle->get_color().b = color().b * (1.0f - t) + color_second().b * t;
}
}
@@ -183,8 +199,6 @@ void ParticleEjectorSprite::draw(const math::Vector3f & ps_location, const math:
quad[2].assign((Camera::axis().up() * -1 + Camera::axis().left()));
quad[3].assign((Camera::axis().up() * -1 - Camera::axis().left()));
- math::Color c(color());
-
for (Particles::iterator it = particles().begin(); it != particles().end(); it++) {
Particle *particle = (*it);
@@ -194,8 +208,7 @@ void ParticleEjectorSprite::draw(const math::Vector3f & ps_location, const math:
math::Vector3f l(attached() ? ps_location + ps_axis * particle->location() : particle->location());
const float r = particle->radius();
- c.a = particle->alpha();
- gl::color(c);
+ gl::color(particle->color());
glTexCoord2f(0, 1);
gl::vertex(l + rotation * quad[0] * r);
@@ -226,7 +239,7 @@ void ParticleEjectorFlare::draw(const math::Vector3f & ps_location, const math::
{
Textures::bind(texture());
gl::begin(gl::Quads);
- math::Color c(color());
+
for (Particles::iterator it = particles().begin(); it != particles().end(); it++) {
Particle *particle = (*it);
@@ -234,8 +247,7 @@ void ParticleEjectorFlare::draw(const math::Vector3f & ps_location, const math::
math::Axis particle_axis(attached() ? ps_axis * particle->axis() : particle->axis());
const float r = particle->radius();
- c.a = particle->alpha();
- gl::color(c);
+ gl::color(particle->color());
glTexCoord2f(0, 1);
gl::vertex(particle_location + (particle_axis.up() - particle_axis.left()) * r);
@@ -268,7 +280,7 @@ void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::
return;
}
- (*particles().rbegin())->set_alpha(0.0f);
+ (*particles().rbegin())->get_color().a = (0.0f);
Particles::iterator first = particles().begin();
Particles::iterator next = first;
@@ -277,9 +289,7 @@ void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::
Textures::bind(texture());
gl::begin(gl::Quads);
- math::Color c(color());
- c.a = (*first)->alpha();
- gl::color(c);
+ gl::color((*first)->color());
//math::Vector3f first_location(attached() ? ps_location + ps_axis * (*first)->location() : (*first)->location());
math::Vector3f first_normal(math::crossproduct(((*first)->location() - ps_location), ((*first)->location() - Camera::eye())));
@@ -287,14 +297,17 @@ void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::
math::Vector3f next_normal(first_normal);
+ const float length = (float) particles().size();
+ float position = 1.0f;
+
glTexCoord2f(1, 0);
gl::vertex(ps_location - first_normal * (*first)->radius());
glTexCoord2f(0, 0);
gl::vertex(ps_location + first_normal * (*first)->radius());
- glTexCoord2f(0, 1);
+ glTexCoord2f(0, position / length);
gl::vertex((*first)->location() + next_normal * (*first)->radius());
- glTexCoord2f(1, 1);
+ glTexCoord2f(1, position / length);
gl::vertex((*first)->location() - next_normal * (*first)->radius());
Stats::quads++;
@@ -302,20 +315,20 @@ void ParticleEjectorTrail::draw(const math::Vector3f & ps_location, const math::
next_normal.assign(math::crossproduct(((*next)->location() - (*first)->location()), ((*next)->location() - Camera::eye())));
next_normal.normalize();
- c.a = (*first)->alpha();
- gl::color(c);
+ gl::color((*first)->color());
- glTexCoord2f(1, 0);
+ glTexCoord2f(1, position / length);
gl::vertex((*first)->location() - first_normal * (*first)->radius());
- glTexCoord2f(0, 0);
+ glTexCoord2f(0, position / length);
gl::vertex((*first)->location() + first_normal * (*first)->radius());
- c.a = (*next)->alpha();
- gl::color(c);
+ gl::color((*next)->color());
- glTexCoord2f(0, 1);
+ position += 1.0f;
+
+ glTexCoord2f(0, position / length);
gl::vertex((*next)->location() + next_normal * (*next)->radius());
- glTexCoord2f(1, 1);
+ glTexCoord2f(1, position / length);
gl::vertex((*next)->location() - next_normal * (*next)->radius());
Stats::quads++;
@@ -352,7 +365,6 @@ void ParticleEjectorStreak::draw(const math::Vector3f & ps_location, const math:
Particles::iterator next = first;
math::Vector3f normal;
- math::Color c(color());
Textures::bind(texture());
gl::begin(gl::Quads);
@@ -368,16 +380,14 @@ void ParticleEjectorStreak::draw(const math::Vector3f & ps_location, const math:
normal.assign(math::crossproduct((first_location - Camera::eye()), (next_location - Camera::eye())));
normal.normalize();
- c.a = (*first)->alpha();
- gl::color(c);
+ gl::color((*first)->color());
glTexCoord2f(1, 0);
gl::vertex(first_location - normal * (*first)->radius());
glTexCoord2f(0, 0);
gl::vertex(first_location + normal * (*first)->radius());
- c.a = (*next)->alpha();
- gl::color(c);
+ gl::color((*next)->color());
glTexCoord2f(0, 1);
gl::vertex(next_location + normal * (*next)->radius());
diff --git a/src/render/particleejectorscript.cc b/src/render/particleejectorscript.cc
index b2c84bc..250eb20 100644
--- a/src/render/particleejectorscript.cc
+++ b/src/render/particleejectorscript.cc
@@ -28,6 +28,8 @@ ParticleEjectorScript::ParticleEjectorScript()
script_spawn_radius = 0.0f;
script_attached = false;
script_scaled = false;
+
+ script_color_interpolated = false;
}
ParticleEjectorScript::ParticleEjectorScript(const ParticleEjectorScript &other)
@@ -48,6 +50,7 @@ ParticleEjectorScript::ParticleEjectorScript(const ParticleEjectorScript &other)
script_cull = other.cull();
script_attached = other.attached();
script_scaled = other.scaled();
+ script_color_interpolated = other.color_interpolated();
script_texture.assign(other.texture());
script_axis.assign(other.axis());
@@ -56,6 +59,7 @@ ParticleEjectorScript::ParticleEjectorScript(const ParticleEjectorScript &other)
script_speed_vec.assign(other.speed_vec());
script_tailspeed_vec.assign(other.tailspeed_vec());
script_color.assign(other.color());
+ script_color_second.assign(other.color_second());
}
ParticleEjectorScript::~ParticleEjectorScript()
diff --git a/src/render/particleejectorscript.h b/src/render/particleejectorscript.h
index 535458e..ef2be4c 100644
--- a/src/render/particleejectorscript.h
+++ b/src/render/particleejectorscript.h
@@ -126,6 +126,14 @@ public:
}
/**
+ * @brief true if particle color is interpolated between color() and color_second()
+ * */
+ inline const bool color_interpolated() const
+ {
+ return script_color_interpolated;
+ }
+
+ /**
* @brief ejector particles and speed are scaled according to modelscale
* */
inline const bool scaled() const
@@ -156,6 +164,14 @@ public:
}
/**
+ * @brief secondary color used to render ejected particles
+ * */
+ inline const math::Color &color_second() const
+ {
+ return script_color_second;
+ }
+
+ /**
* @brief radius vector for ejected particles, start, middle, end
* The radius is interpolated depending on the age and lifespan of the particle
* */
@@ -249,13 +265,21 @@ public:
}
/**
- * @brief return a reference to particle color
+ * @brief return a reference to primary particle color
* */
inline math::Color &get_color()
{
return script_color;
}
+ /**
+ * @brief return a reference to secondary particle color
+ * */
+ inline math::Color &get_color_second()
+ {
+ return script_color_second;
+ }
+
/**
* @brief set the ejector type
* */
@@ -408,19 +432,35 @@ public:
script_attached = attached;
}
+ /**
+ * @brief set to true to interpolate particle color between color() and color_second()
+ * */
+ inline void set_color_interpolated(const bool color_interpolated)
+ {
+ script_color_interpolated = color_interpolated;
+ }
+
inline void set_scaled(const bool scaled)
{
script_scaled = scaled;
}
/**
- * @brief set the particle color
+ * @brief set the particle color at the begin of lifespan
* */
inline void set_color(const math::Color &color)
{
script_color.assign(color);
}
+ /**
+ * @brief set the particle color at the end of lifespane
+ * */
+ inline void set_color_second(const math::Color &color_second)
+ {
+ script_color_second.assign(color_second);
+ }
+
private:
/// type of ejector
Type script_type;
@@ -450,9 +490,15 @@ private:
/// spawn radius
float script_spawn_radius;
- /// color of ejected particles
+ /// color of ejected particles at start of lifespan
math::Color script_color;
-
+
+ /// color of ejected particles at end of lifespan
+ math::Color script_color_second;
+
+ /// true of the particle color has to be interpolated betwoon color and color_second
+ bool script_color_interpolated;
+
/// particles have entity primary color
bool script_entity;
/// particles have entity secondary color
diff --git a/src/render/particlesystemscript.cc b/src/render/particlesystemscript.cc
index f78fa88..03ce86e 100644
--- a/src/render/particlesystemscript.cc
+++ b/src/render/particlesystemscript.cc
@@ -214,11 +214,15 @@ ParticleSystemScript *ParticleSystemScript::load(const std::string &label)
} else if (inifile.got_key_long("timeout", l)) {
ejector->set_timeout((unsigned long) l);
- continue;
+ continue;
} else if (inifile.got_key_color("color", ejector->get_color())) {
continue;
+ } else if (inifile.got_key_color("colorsecond", ejector->get_color_second())) {
+ ejector->set_color_interpolated(true);
+ continue;
+
} else if (inifile.got_key_bool("engine", b)) {
ejector->set_engine(b);
continue;