aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/graphics/particles/je_particle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/graphics/particles/je_particle.cpp')
-rw-r--r--src/libjin/graphics/particles/je_particle.cpp154
1 files changed, 129 insertions, 25 deletions
diff --git a/src/libjin/graphics/particles/je_particle.cpp b/src/libjin/graphics/particles/je_particle.cpp
index 1fa8bc2..761f166 100644
--- a/src/libjin/graphics/particles/je_particle.cpp
+++ b/src/libjin/graphics/particles/je_particle.cpp
@@ -1,4 +1,6 @@
+#include "../../common/je_array.hpp"
#include "../../math/je_math.h"
+#include "../../math/je_random.h"
#include "../je_sprite.h"
@@ -13,57 +15,158 @@ namespace JinEngine
namespace Particles
{
- Particle::Particle(const Sprite* spr)
- : sprite(spr)
+ static RandomGenerator rng(0xEA44944);
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ScaledRangedValue
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ScaledRangedValue::ScaledRangedValue(Percentage* points, uint n)
+ {
+ for (int i = 0; i < n; ++i)
+ {
+ float x = points[2 * i].value;
+ float y = points[2 * i + 1].value;
+ addPoint(x, y);
+ }
+ }
+
+ void ScaledRangedValue::set(Math::Percentage* points, uint n)
+ {
+ clear();
+ for (int i = 0; i < n; ++i)
+ {
+ float x = points[2 * i].value;
+ float y = points[2 * i + 1].value;
+ addPoint(x, y);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // GradientColorValue
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ GradientColorValue::GradientColorValue()
+ : mCount(0)
+ {
+ }
+
+ void GradientColorValue::addColor(Color col, Percentage time)
+ {
+ mColors.push_back(col);
+ mTimeline.push_back(time);
+ ++mCount;
+ }
+
+ Color GradientColorValue::getColor(Percentage time)
+ {
+ int endIndex = -1;
+ int n = mCount;
+ for (int i = 1; i < n; i++) {
+ Percentage t = mTimeline[i];
+ if (t.value > time.value) {
+ endIndex = i;
+ break;
+ }
+ }
+ if (endIndex == -1) return mColors[n - 1];
+ int startIndex = endIndex - 1;
+ Color& startValue = mColors[startIndex];
+ Color& endValue = mColors[endIndex];
+ float t = time.value;
+ float start = mTimeline[startIndex].value;
+ float end = mTimeline[endIndex].value;
+ Color c;
+ c.r = startValue.r + (endValue.r - startValue.r) * ((t - start) / (end - start));
+ c.g = startValue.g + (endValue.g - startValue.g) * ((t - start) / (end - start));
+ c.b = startValue.b + (endValue.b - startValue.b) * ((t - start) / (end - start));
+ c.a = startValue.a + (endValue.a - startValue.a) * ((t - start) / (end - start));
+ return c;
+ }
+
+ void GradientColorValue::insertColor(uint i, Color col, Math::Percentage time)
+ {
+ mColors.insert(mColors.begin() + i, col);
+ mTimeline.insert(mTimeline.begin() + i, time);
+ ++mCount;
+ }
+
+ void GradientColorValue::removeColor(uint i)
+ {
+ mColors.erase(mColors.begin() + i);
+ mTimeline.erase(mTimeline.begin() + i);
+ --mCount;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ Particle::Particle()
{
reset();
}
void Particle::reset()
{
+ updateFlags = ParticleUpdateMask::NONE;
transform.set(0, 0, 1, 1, 0, 0, 0);
lifeTime = 1.0f;
life = 0.0f;
- speed.set(0, 0);
+ velocity.set(0, 0);
linearAcceleration.set(0, 0);
radialAcceleration = 0.0f;
angularSpeed = 0;
- scaleBegin = 1;
- scaleEnd = 1;
color = Color::WHITE;
- colorStart = Color::WHITE;
- colorEnd = Color::WHITE;
alive = true;
+ spriteIndex = 0;
}
void Particle::update(float dt)
{
float t = life / lifeTime;
- // Lerp color.
- color.r = lerp<int>(colorStart.r, colorEnd.r, t);
- color.g = lerp<int>(colorStart.g, colorEnd.g, t);
- color.b = lerp<int>(colorStart.b, colorEnd.b, t);
- color.a = lerp<int>(colorStart.a, colorEnd.a, t);
- // Lerp scale.
- Vector2<float> scale = transform.getScale();
- scale.x = lerp<float>(scaleBegin, scaleEnd, t);
- scale.y = scale.x;
- transform.setScale(scale.x, scale.y);
- // Calculate position.
- speed += linearAcceleration * dt;
- transform.move(speed * dt);
- // Calculate rotation.
- angularSpeed += radialAcceleration * dt;
- transform.rotate(angularSpeed * dt);
- // Update life time.
+ if ((updateFlags & UPDATE_COLOR) != 0)
+ color = def->colorDef.overTime.value.getColor(t);
+ if ((updateFlags & UPDATE_SCALE) != 0)
+ {
+ // Lerp scale.
+ float scale = def->scaleDef.overTime.value.getValue(t);
+ transform.setScale(scale, scale);
+ }
+ if ((updateFlags & UPDATE_POSITION) != 0)
+ {
+ // Calculate position.
+ if((updateFlags & UPDATE_VELOCITY) != 0)
+ velocity += linearAcceleration * dt;
+ transform.move(velocity * dt);
+ }
+ if ((updateFlags & UPDATE_ROTATION) != 0)
+ {
+ // Calculate rotation.
+ angularSpeed += radialAcceleration * dt;
+ transform.rotate(angularSpeed * dt);
+ }
+ if ((updateFlags & UPDATE_SPRITE) != 0)
+ {
+ int n = def->spritesDef.sprites.size();
+ if (def->spritesDef.mode == SpriteMode::ANIMATED)
+ spriteIndex = lerp<int>(0, n - 1, t);
+ else
+ spriteIndex = rng.rand(0, n);
+ }
life += dt;
alive = life < lifeTime;
}
void Particle::render()
{
+ // Set blend.
+ OpenGL::BlendMode blend = gl.getBlendMode();
+ if(def->blendDef.additive)
+ gl.setBlendMode(OpenGL::BlendMode::ADDITIVE);
Color c = gl.getColor();
gl.setColor(color);
+ const Sprite* sprite = def->spritesDef.sprites[spriteIndex];
if (sprite != nullptr)
{
Vector2<float>& position = transform.getPosition();
@@ -71,7 +174,8 @@ namespace JinEngine
float r = transform.getRotation();
sprite->render(position.x, position.y, scale.x, scale.y, r);
}
- gl.getColor();
+ gl.setColor(c);
+ gl.setBlendMode(blend);
}
}