aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/graphics/particles/particle_system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/graphics/particles/particle_system.cpp')
-rw-r--r--src/libjin/graphics/particles/particle_system.cpp266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/libjin/graphics/particles/particle_system.cpp b/src/libjin/graphics/particles/particle_system.cpp
new file mode 100644
index 0000000..984f42b
--- /dev/null
+++ b/src/libjin/graphics/particles/particle_system.cpp
@@ -0,0 +1,266 @@
+#include <stdarg.h>
+
+#include "../../utils/log.h"
+
+#include "particle_system.h"
+
+namespace JinEngine
+{
+ namespace Graphics
+ {
+ namespace Particles
+ {
+
+ ParticleSystem::ParticleSystem(uint maxCount)
+ : mEmitter(*this)
+ , mParticlePool(maxCount, sizeof(Particle))
+ {
+ }
+
+ ParticleSystem::ParticleSystem(const ParticleSystemDef& def)
+ : mDef(def)
+ , mEmitter(*this)
+ , mParticlePool(def.maxParticleCount, sizeof(Particle))
+ {
+ }
+
+ ParticleSystem::~ParticleSystem()
+ {
+ }
+
+ void ParticleSystem::setPosition(float x, float y)
+ {
+ mPosition.x() = x;
+ mPosition.y() = y;
+ }
+
+ void ParticleSystem::update(float dt)
+ {
+ mEmitter.update(dt);
+ for (int i = 0; i < mAliveParticles.size(); ++i)
+ {
+ Particle* p = mAliveParticles[i];
+ if (p->alive == false)
+ {
+ recycle(i, p);
+ --i;
+ }
+ else
+ {
+ p->update(dt);
+ }
+ }
+ }
+
+ void ParticleSystem::render()
+ {
+ for (Particle* p : mAliveParticles)
+ p->render();
+ }
+
+ Particle* ParticleSystem::claim()
+ {
+ Particle* p = new (mParticlePool.GetNextWithoutInitializing()) Particle();
+ mAliveParticles.push_back(p);
+ //jin_log_info("particle count %d", mAliveParticles.size());
+ return p;
+ }
+
+ void ParticleSystem::recycle(int i, Particle* p)
+ {
+ if (i >= mAliveParticles.size())
+ return;
+ mAliveParticles.erase(mAliveParticles.begin() + i);
+ mParticlePool.Delete(p);
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle Emitter modification.
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ParticleSystem::setEmitRate(float floor, float ceil)
+ {
+ mDef.emitterDef.emitRateDef.enableRandom = true;
+ mDef.emitterDef.emitRateDef.rate.random.floor = floor;
+ mDef.emitterDef.emitRateDef.rate.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitRate(float rate)
+ {
+ mDef.emitterDef.emitRateDef.enableRandom = false;
+ mDef.emitterDef.emitRateDef.rate.rate = rate;
+ }
+
+ void ParticleSystem::setEmitForce(float floor, float ceil)
+ {
+ mDef.emitterDef.forceDef.enableRandom = true;
+ mDef.emitterDef.forceDef.force.random.floor = floor;
+ mDef.emitterDef.forceDef.force.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitForce(float force)
+ {
+ mDef.emitterDef.forceDef.enableRandom = false;
+ mDef.emitterDef.forceDef.force.force = force;
+ }
+
+ void ParticleSystem::setEmitDirection(float floor, float ceil)
+ {
+ mDef.emitterDef.directionDef.enableRandom = true;
+ mDef.emitterDef.directionDef.direction.random.floor = floor;
+ mDef.emitterDef.directionDef.direction.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitDirection(float dir)
+ {
+ mDef.emitterDef.directionDef.enableRandom = false;
+ mDef.emitterDef.directionDef.direction.direction = dir;
+ }
+
+ void ParticleSystem::setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil)
+ {
+ mDef.emitterDef.positionDef.enableRandom = true;
+ mDef.emitterDef.positionDef.position.random.floor = floor;
+ mDef.emitterDef.positionDef.position.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitPosition(const Math::Vector2<float>& position)
+ {
+ mDef.emitterDef.positionDef.enableRandom = false;
+ mDef.emitterDef.positionDef.position.position = position;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle Emitter modification.
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ParticleSystem::setParticleLife(float floor, float ceil)
+ {
+ mDef.particleDef.lifeTimeDef.enableRandom = true;
+ mDef.particleDef.lifeTimeDef.life.random.floor = floor;
+ mDef.particleDef.lifeTimeDef.life.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setParticleLife(float time)
+ {
+ mDef.particleDef.lifeTimeDef.enableRandom = true;
+ mDef.particleDef.lifeTimeDef.life.life = time;
+ }
+
+ void ParticleSystem::setParticleLinearAccelaration(Math::Vector2<float> ac)
+ {
+ mDef.particleDef.linearAccelarationDef.linearAccelaration = ac;
+ }
+
+ void ParticleSystem::setParticleRadialAccelaration(float ra)
+ {
+ mDef.particleDef.radialAccelarationDef.radialAccelaration = ra;
+ }
+
+ void ParticleSystem::setParticleAngularSpeed(float floor, float ceil)
+ {
+ mDef.particleDef.angularSpeedDef.enableRandom = true;
+ mDef.particleDef.angularSpeedDef.angularSpeed.random.floor = floor;
+ mDef.particleDef.angularSpeedDef.angularSpeed.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setParticleAngularSpeed(float speed)
+ {
+ mDef.particleDef.angularSpeedDef.enableRandom = false;
+ mDef.particleDef.angularSpeedDef.angularSpeed.angularSpeed = speed;
+ }
+
+ void ParticleSystem::setParticleSpritesMode(SpriteMode mode)
+ {
+ mDef.particleDef.spritesDef.mode = mode;
+ }
+
+ void ParticleSystem::addParticleSprite(const Sprite* sprite)
+ {
+ mDef.particleDef.spritesDef.sprites.push_back(sprite);
+ }
+
+ void ParticleSystem::addParticleSprites(uint count, ...)
+ {
+ va_list args;
+ va_start(args, count);
+ while (count--)
+ {
+ Sprite* spr = va_arg(args, Sprite*);
+ addParticleSprite(spr);
+ }
+ va_end(args);
+ }
+
+ void ParticleSystem::addParticleSprites(const std::vector<const Sprite*>& sprs)
+ {
+ for (const Sprite* spr : sprs)
+ {
+ addParticleSprite(spr);
+ }
+ }
+
+ void ParticleSystem::removeParticleSprite(uint i)
+ {
+ mDef.particleDef.spritesDef.sprites.erase(mDef.particleDef.spritesDef.sprites.begin() + i);
+ }
+
+ void ParticleSystem::enableParticleBlendAdditive(bool enable)
+ {
+ mDef.particleDef.blendDef.additive = enable;
+ }
+
+ void ParticleSystem::setParticleScale(float scale)
+ {
+ mDef.particleDef.scaleDef.overTime.enable = false;
+ mDef.particleDef.scaleDef.scale = scale;
+ }
+
+ void ParticleSystem::addParticleScalePoint(float scale, float t)
+ {
+ mDef.particleDef.scaleDef.overTime.enable = true;
+ mDef.particleDef.scaleDef.overTime.value.addPoint(t, scale);
+ }
+
+ void ParticleSystem::removeParticleScalePoint(uint i)
+ {
+ mDef.particleDef.scaleDef.overTime.value.removePoint(i);
+ }
+
+ void ParticleSystem::setParticleColor(Color tint)
+ {
+ mDef.particleDef.colorDef.overTime.enable = false;
+ mDef.particleDef.colorDef.color = tint;
+ }
+
+ void ParticleSystem::addParticleColorPoint(Color tint, float t)
+ {
+ mDef.particleDef.colorDef.overTime.enable = true;
+ mDef.particleDef.colorDef.overTime.value.addColor(tint, t);
+ }
+
+ void ParticleSystem::removeParticleColorPoint(uint i)
+ {
+ mDef.particleDef.colorDef.overTime.value.removeColor(i);
+ }
+
+ void ParticleSystem::setParticleTransparency(float transparency)
+ {
+ mDef.particleDef.transparencyDef.overTime.enable = false;
+ mDef.particleDef.transparencyDef.transparency = transparency;
+ }
+
+ void ParticleSystem::addParticleTransparencyPoint(float transparency, float t)
+ {
+ mDef.particleDef.transparencyDef.overTime.enable = true;
+ mDef.particleDef.transparencyDef.overTime.value.addPoint(t, transparency);
+ }
+
+ void ParticleSystem::removeParticleTransparencyPoint(uint i)
+ {
+ mDef.particleDef.transparencyDef.overTime.value.removePoint(i);
+ }
+
+ }
+ }
+} \ No newline at end of file