From 2643de367a4ab4c64b87d76f0dbe3e19731d23e1 Mon Sep 17 00:00:00 2001 From: Henrique Santiago Date: Thu, 15 Dec 2011 18:54:42 -0200 Subject: [PATCH] remove particles from emitter --- src/framework/CMakeLists.txt | 1 + src/framework/graphics/particleemitter.cpp | 85 ++++------------------ src/framework/graphics/particleemitter.h | 25 ------- src/framework/graphics/particlesystem.cpp | 20 ++++- src/framework/graphics/particlesystem.h | 3 + 5 files changed, 36 insertions(+), 98 deletions(-) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 6ab577ee..3ee09aec 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -146,6 +146,7 @@ SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/graphics/particlemanager.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particlesystem.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particleemitter.cpp + ${CMAKE_CURRENT_LIST_DIR}/graphics/particle.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/shader.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp diff --git a/src/framework/graphics/particleemitter.cpp b/src/framework/graphics/particleemitter.cpp index d35d5f06..b3089f77 100644 --- a/src/framework/graphics/particleemitter.cpp +++ b/src/framework/graphics/particleemitter.cpp @@ -20,64 +20,15 @@ * THE SOFTWARE. */ +#include "particle.h" #include "particleemitter.h" -#include "graphics.h" +#include "particlesystem.h" #include #include #include #define DEG_TO_RAD (acos(-1)/180.0) -Particle::Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, const Color& color, TexturePtr texture) -{ - m_rect = Rect(pos, size); - m_pos = PointF(pos.x, pos.y); - m_size = size; - m_velocity = velocity; - m_acceleration = acceleration; - m_color = color; - m_texture = texture; - m_duration = duration; - m_startTime = g_clock.time(); - m_lastUpdateTime = g_clock.time(); - m_finished = false; -} - -void Particle::render() -{ - g_painter.setColor(m_color); - - if(!m_texture) - g_painter.drawFilledRect(m_rect); - else { - //g_painter.setCompositionMode(Painter::CompositionMode_AdditiveSource); - g_painter.drawTexturedRect(m_rect, m_texture); - //g_painter.setCompositionMode(Painter::CompositionMode_SourceOver); - } -} - -void Particle::update() -{ - float elapsedTime = g_clock.timeElapsed(m_lastUpdateTime); - m_lastUpdateTime = g_clock.time(); - - // check if finished - if(m_duration > 0 && g_clock.timeElapsed(m_startTime) >= m_duration) { - m_finished = true; - return; - } - - // update position - PointF delta = m_velocity * elapsedTime; - delta.y *= -1; // painter orientate Y axis in the inverse direction - m_pos += delta; - - // update acceleration - m_velocity += m_acceleration * elapsedTime; - - m_rect.moveTo((int)m_pos.x, (int)m_pos.y); -} - ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent) { m_parent = parent; @@ -121,6 +72,7 @@ bool ParticleEmitter::load(const OTMLNodePtr& node) m_burstRate = childNode->value(); else if(childNode->tag() == "burstCount") m_burstCount = childNode->value(); + // particles generation related else if(childNode->tag() == "particle-position-radius") { m_pMinPositionRadius = childNode->value(); @@ -139,6 +91,7 @@ bool ParticleEmitter::load(const OTMLNodePtr& node) else if(childNode->tag() == "particle-max-position-angle") m_pMaxPositionAngle = childNode->value() * DEG_TO_RAD; + // velocity else if(childNode->tag() == "particle-velocity") { m_pMinVelocity = childNode->value(); m_pMaxVelocity = childNode->value(); @@ -159,6 +112,8 @@ bool ParticleEmitter::load(const OTMLNodePtr& node) m_pMinAcceleration = childNode->value(); m_pMaxAcceleration = childNode->value(); } + + // acceleration else if(childNode->tag() == "particle-min-acceleration") m_pMinAcceleration = childNode->value(); else if(childNode->tag() == "particle-max-acceleration") @@ -171,6 +126,8 @@ bool ParticleEmitter::load(const OTMLNodePtr& node) m_pMinAccelerationAngle = childNode->value() * DEG_TO_RAD; else if(childNode->tag() == "particle-max-acceleration-angle") m_pMaxAccelerationAngle = childNode->value() * DEG_TO_RAD; + + // duration else if(childNode->tag() == "particle-duration") { m_pMinDuration = childNode->value(); m_pMaxDuration = childNode->value(); @@ -179,6 +136,8 @@ bool ParticleEmitter::load(const OTMLNodePtr& node) m_pMinDuration = childNode->value(); else if(childNode->tag() == "particle-max-duration") m_pMaxDuration = childNode->value(); + + // visual else if(childNode->tag() == "particle-size") { m_pMinSize = childNode->value(); m_pMaxSize = childNode->value(); @@ -195,32 +154,13 @@ bool ParticleEmitter::load(const OTMLNodePtr& node) return true; } -void ParticleEmitter::render() -{ - for(auto it = m_particles.begin(), end = m_particles.end(); it != end; ++it) - (*it)->render(); -} - void ParticleEmitter::update() { float elapsedTime = g_clock.timeElapsed(m_startTime); - // update particles - for(auto it = m_particles.begin(), end = m_particles.end(); it != end;) { - const ParticlePtr& particle = *it; - if(particle->hasFinished()) { - it = m_particles.erase(it); - continue; - } - particle->update(); - ++it; - } - // check if finished if(m_duration > 0 && elapsedTime > m_duration) { - // stop emitting but only self remove when there are no particles left - if(m_particles.size() == 0) - m_finished = true; + m_finished = true; return; } @@ -248,7 +188,8 @@ void ParticleEmitter::update() float pAccelerationAngle = Fw::randomRange(m_pMinAccelerationAngle, m_pMaxAccelerationAngle); PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle)); - m_particles.push_back(ParticlePtr(new Particle(pPosition, pSize, pVelocity, pAcceleration, pDuration, m_pColor, m_pTexture))); + ParticleSystemPtr particleSystem = m_parent.lock(); + particleSystem->addParticle(ParticlePtr(new Particle(pPosition, pSize, pVelocity, pAcceleration, pDuration, m_pColor, m_pTexture))); } } diff --git a/src/framework/graphics/particleemitter.h b/src/framework/graphics/particleemitter.h index 822eb298..fefed036 100644 --- a/src/framework/graphics/particleemitter.h +++ b/src/framework/graphics/particleemitter.h @@ -28,29 +28,6 @@ #include #include -class Particle { -public: - Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, const Color& color = Fw::white, TexturePtr texture = nullptr); - - void render(); - void update(); - - bool hasFinished() { return m_finished; } - -private: - Color m_color; - TexturePtr m_texture; - PointF m_pos; - PointF m_velocity; - PointF m_acceleration; - Size m_size; - Rect m_rect; - float m_duration; - double m_startTime; - double m_lastUpdateTime; - bool m_finished; -}; - class ParticleEmitter { public: @@ -58,7 +35,6 @@ public: bool load(const OTMLNodePtr& node); - void render(); void update(); bool hasFinished() { return m_finished; } @@ -73,7 +49,6 @@ private: bool m_finished; float m_burstRate; int m_currentBurst, m_burstCount; - std::list m_particles; // particles size Size m_pMinSize, m_pMaxSize; diff --git a/src/framework/graphics/particlesystem.cpp b/src/framework/graphics/particlesystem.cpp index fc4a83f5..01d77c20 100644 --- a/src/framework/graphics/particlesystem.cpp +++ b/src/framework/graphics/particlesystem.cpp @@ -20,6 +20,7 @@ * THE SOFTWARE. */ +#include "particle.h" #include "particlesystem.h" #include #include @@ -36,14 +37,20 @@ bool ParticleSystem::load(const OTMLNodePtr& node) return true; } +void ParticleSystem::addParticle(const ParticlePtr& particle) +{ + m_particles.push_back(particle); +} + void ParticleSystem::render() { - for(auto it = m_emitters.begin(), end = m_emitters.end(); it != end; ++it) + for(auto it = m_particles.begin(), end = m_particles.end(); it != end; ++it) (*it)->render(); } void ParticleSystem::update() { + // update emitters for(auto it = m_emitters.begin(), end = m_emitters.end(); it != end;) { const ParticleEmitterPtr& emitter = *it; if(emitter->hasFinished()) { @@ -53,4 +60,15 @@ void ParticleSystem::update() emitter->update(); ++it; } + + // update particles + for(auto it = m_particles.begin(), end = m_particles.end(); it != end;) { + const ParticlePtr& particle = *it; + if(particle->hasFinished()) { + it = m_particles.erase(it); + continue; + } + particle->update(); + ++it; + } } diff --git a/src/framework/graphics/particlesystem.h b/src/framework/graphics/particlesystem.h index a0000211..934a14cc 100644 --- a/src/framework/graphics/particlesystem.h +++ b/src/framework/graphics/particlesystem.h @@ -42,10 +42,13 @@ class ParticleSystem : public std::enable_shared_from_this { public: bool load(const OTMLNodePtr& node); + void addParticle(const ParticlePtr& particle); + void render(); void update(); private: + std::list m_particles; std::list m_emitters; std::list m_affectors; };