diff options
Diffstat (limited to 'src/libjin/graphics/particles/je_particle.cpp')
-rw-r--r-- | src/libjin/graphics/particles/je_particle.cpp | 154 |
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); } } |