particles afectors upgrade and timer rework
This commit is contained in:
parent
a4eed64709
commit
eed6fab4b1
|
@ -1,16 +1,21 @@
|
||||||
ParticleSystem
|
ParticleSystem
|
||||||
AttractionAffector
|
AttractionAffector
|
||||||
|
delay: 0
|
||||||
|
duration: 12
|
||||||
destination: 200 200
|
destination: 200 200
|
||||||
acceleration: 64
|
acceleration: 64
|
||||||
velocity-reduction-percent: 0
|
velocity-reduction-percent: 0
|
||||||
|
|
||||||
Emitter
|
Emitter
|
||||||
position: 200 264
|
position: 200 264
|
||||||
duration: 12
|
duration: 2
|
||||||
burstRate: 2
|
burstRate: 0.2
|
||||||
burstCount: 1
|
burstCount: 1
|
||||||
delay: 0.5
|
delay: 0
|
||||||
particle-duration: 9999
|
|
||||||
|
particle-ignore-physics-after: 999
|
||||||
|
|
||||||
|
particle-duration: 12
|
||||||
particle-position-radius: 0
|
particle-position-radius: 0
|
||||||
particle-velocity: 32
|
particle-velocity: 32
|
||||||
particle-velocity-angle: 0
|
particle-velocity-angle: 0
|
||||||
|
@ -21,9 +26,12 @@ ParticleSystem
|
||||||
|
|
||||||
Emitter
|
Emitter
|
||||||
position: 200 200
|
position: 200 200
|
||||||
burstRate: 9999999999
|
burstRate: 13
|
||||||
burstCount: 1
|
burstCount: 1
|
||||||
particle-duration: 9999999
|
duration: 12
|
||||||
|
|
||||||
|
particle-duration: 12
|
||||||
|
|
||||||
particle-position-radius: 0
|
particle-position-radius: 0
|
||||||
particle-velocity: 0
|
particle-velocity: 0
|
||||||
particle-velocity-angle: 0
|
particle-velocity-angle: 0
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include <framework/core/clock.h>
|
#include <framework/core/clock.h>
|
||||||
|
|
||||||
Particle::Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, const Color& color, TexturePtr texture)
|
Particle::Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const Color& color, TexturePtr texture)
|
||||||
{
|
{
|
||||||
m_rect = Rect(pos, size);
|
m_rect = Rect(pos, size);
|
||||||
m_position = PointF(pos.x, pos.y);
|
m_position = PointF(pos.x, pos.y);
|
||||||
|
@ -34,8 +34,8 @@ Particle::Particle(const Point& pos, const Size& size, const PointF& velocity, c
|
||||||
m_color = color;
|
m_color = color;
|
||||||
m_texture = texture;
|
m_texture = texture;
|
||||||
m_duration = duration;
|
m_duration = duration;
|
||||||
m_startTime = g_clock.time();
|
m_ignorePhysicsAfter = ignorePhysicsAfter;
|
||||||
m_lastUpdateTime = g_clock.time();
|
m_elapsedTime = 0;
|
||||||
m_finished = false;
|
m_finished = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,24 +52,25 @@ void Particle::render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Particle::update()
|
void Particle::update(double elapsedTime)
|
||||||
{
|
{
|
||||||
float elapsedTime = g_clock.timeElapsed(m_lastUpdateTime);
|
|
||||||
m_lastUpdateTime = g_clock.time();
|
|
||||||
|
|
||||||
// check if finished
|
// check if finished
|
||||||
if(m_duration > 0 && g_clock.timeElapsed(m_startTime) >= m_duration) {
|
if(m_duration > 0 && m_elapsedTime >= m_duration) {
|
||||||
m_finished = true;
|
m_finished = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update position
|
m_elapsedTime += elapsedTime;
|
||||||
PointF delta = m_velocity * elapsedTime;
|
|
||||||
delta.y *= -1; // painter orientate Y axis in the inverse direction
|
|
||||||
m_position += delta;
|
|
||||||
|
|
||||||
// update acceleration
|
if(m_ignorePhysicsAfter < 0 || m_elapsedTime < m_ignorePhysicsAfter ) {
|
||||||
m_velocity += m_acceleration * elapsedTime;
|
// update position
|
||||||
|
PointF delta = m_velocity * elapsedTime;
|
||||||
|
delta.y *= -1; // painter orientate Y axis in the inverse direction
|
||||||
|
m_position += delta;
|
||||||
|
|
||||||
m_rect.moveTo((int)m_position.x - m_size.width() / 2, (int)m_position.y - m_size.height() / 2);
|
// update acceleration
|
||||||
|
m_velocity += m_acceleration * elapsedTime;
|
||||||
|
|
||||||
|
m_rect.moveTo((int)m_position.x - m_size.width() / 2, (int)m_position.y - m_size.height() / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
|
|
||||||
class Particle {
|
class Particle {
|
||||||
public:
|
public:
|
||||||
Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, const Color& color = Fw::white, TexturePtr texture = nullptr);
|
Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const Color& color = Fw::white, TexturePtr texture = nullptr);
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
void update();
|
void update(double elapsedTime);
|
||||||
|
|
||||||
bool hasFinished() { return m_finished; }
|
bool hasFinished() { return m_finished; }
|
||||||
|
|
||||||
|
@ -49,9 +49,8 @@ private:
|
||||||
PointF m_acceleration;
|
PointF m_acceleration;
|
||||||
Size m_size;
|
Size m_size;
|
||||||
Rect m_rect;
|
Rect m_rect;
|
||||||
float m_duration;
|
float m_duration, m_ignorePhysicsAfter;
|
||||||
double m_startTime;
|
double m_elapsedTime;
|
||||||
double m_lastUpdateTime;
|
|
||||||
bool m_finished;
|
bool m_finished;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,64 @@
|
||||||
|
|
||||||
#define DEG_TO_RAD (acos(-1)/180.0)
|
#define DEG_TO_RAD (acos(-1)/180.0)
|
||||||
|
|
||||||
|
ParticleAffector::ParticleAffector()
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
m_finished = false;
|
||||||
|
m_delay = 0;
|
||||||
|
m_duration = 0;
|
||||||
|
m_elapsedTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleAffector::update(double elapsedTime)
|
||||||
|
{
|
||||||
|
if(m_duration > 0 && m_elapsedTime >= m_duration + m_delay) {
|
||||||
|
m_finished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_active && m_elapsedTime > m_delay)
|
||||||
|
m_active = true;
|
||||||
|
|
||||||
|
m_elapsedTime += elapsedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParticleAffector::load(const OTMLNodePtr& node)
|
||||||
|
{
|
||||||
|
float minDelay = 0, maxDelay = 0;
|
||||||
|
float minDuration = -1, maxDuration = -1;
|
||||||
|
|
||||||
|
for(const OTMLNodePtr& childNode : node->children()) {
|
||||||
|
if(childNode->tag() == "delay") {
|
||||||
|
minDelay = childNode->value<float>();
|
||||||
|
maxDelay = childNode->value<float>();
|
||||||
|
}
|
||||||
|
else if(childNode->tag() == "min-delay")
|
||||||
|
minDelay = childNode->value<float>();
|
||||||
|
else if(childNode->tag() == "max-delay")
|
||||||
|
maxDelay = childNode->value<float>();
|
||||||
|
|
||||||
|
if(childNode->tag() == "duration") {
|
||||||
|
minDuration = childNode->value<float>();
|
||||||
|
maxDuration = childNode->value<float>();
|
||||||
|
}
|
||||||
|
else if(childNode->tag() == "min-duration")
|
||||||
|
minDuration = childNode->value<float>();
|
||||||
|
else if(childNode->tag() == "max-duration")
|
||||||
|
maxDuration = childNode->value<float>();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_delay = Fw::randomRange(minDelay, maxDelay);
|
||||||
|
m_duration = Fw::randomRange(minDuration, maxDuration);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool GravityAffector::load(const OTMLNodePtr& node)
|
bool GravityAffector::load(const OTMLNodePtr& node)
|
||||||
{
|
{
|
||||||
|
if(!ParticleAffector::load(node))
|
||||||
|
return false;
|
||||||
|
|
||||||
m_angle = 270 * DEG_TO_RAD;
|
m_angle = 270 * DEG_TO_RAD;
|
||||||
m_gravity = 9.8;
|
m_gravity = 9.8;
|
||||||
|
|
||||||
|
@ -40,8 +96,11 @@ bool GravityAffector::load(const OTMLNodePtr& node)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GravityAffector::update(const ParticlePtr& particle, double elapsedTime)
|
void GravityAffector::updateParticle(const ParticlePtr& particle, double elapsedTime)
|
||||||
{
|
{
|
||||||
|
if(!m_active)
|
||||||
|
return;
|
||||||
|
|
||||||
PointF velocity = particle->getVelocity();
|
PointF velocity = particle->getVelocity();
|
||||||
velocity += PointF(m_gravity * elapsedTime * cos(m_angle), m_gravity * elapsedTime * sin(m_angle));
|
velocity += PointF(m_gravity * elapsedTime * cos(m_angle), m_gravity * elapsedTime * sin(m_angle));
|
||||||
particle->setVelocity(velocity);
|
particle->setVelocity(velocity);
|
||||||
|
@ -49,6 +108,9 @@ void GravityAffector::update(const ParticlePtr& particle, double elapsedTime)
|
||||||
|
|
||||||
bool AttractionAffector::load(const OTMLNodePtr& node)
|
bool AttractionAffector::load(const OTMLNodePtr& node)
|
||||||
{
|
{
|
||||||
|
if(!ParticleAffector::load(node))
|
||||||
|
return false;
|
||||||
|
|
||||||
m_acceleration = 32;
|
m_acceleration = 32;
|
||||||
|
|
||||||
for(const OTMLNodePtr& childNode : node->children()) {
|
for(const OTMLNodePtr& childNode : node->children()) {
|
||||||
|
@ -62,17 +124,16 @@ bool AttractionAffector::load(const OTMLNodePtr& node)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttractionAffector::update(const ParticlePtr& particle, double elapsedTime)
|
void AttractionAffector::updateParticle(const ParticlePtr& particle, double elapsedTime)
|
||||||
{
|
{
|
||||||
// must change velocity angle, keeping modulus.
|
if(!m_active)
|
||||||
|
return;
|
||||||
|
|
||||||
PointF pPosition = particle->getPosition();
|
PointF pPosition = particle->getPosition();
|
||||||
|
|
||||||
PointF d = PointF(m_destination.x - pPosition.x, pPosition.y - m_destination.y);
|
PointF d = PointF(m_destination.x - pPosition.x, pPosition.y - m_destination.y);
|
||||||
if(d.length() == 0)
|
if(d.length() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PointF pVelocity = particle->getVelocity() + (d / d.length() * m_acceleration * elapsedTime);
|
PointF pVelocity = particle->getVelocity() + (d / d.length() * m_acceleration * elapsedTime);
|
||||||
|
|
||||||
particle->setVelocity(pVelocity - pVelocity * m_reduction/100.0 * elapsedTime);
|
particle->setVelocity(pVelocity - pVelocity * m_reduction/100.0 * elapsedTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,25 @@
|
||||||
|
|
||||||
class ParticleAffector {
|
class ParticleAffector {
|
||||||
public:
|
public:
|
||||||
virtual bool load(const OTMLNodePtr&) { return true; }
|
ParticleAffector();
|
||||||
virtual void update(const ParticlePtr&, double) {}
|
virtual ~ParticleAffector() { dump << "ParticleAffector deleted"; }
|
||||||
|
|
||||||
|
void update(double elapsedTime);
|
||||||
|
virtual bool load(const OTMLNodePtr& node);
|
||||||
|
virtual void updateParticle(const ParticlePtr&, double) {}
|
||||||
|
|
||||||
|
bool hasFinished() { return m_finished; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_finished, m_active;
|
||||||
|
float m_delay, m_duration;
|
||||||
|
double m_elapsedTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GravityAffector : public ParticleAffector {
|
class GravityAffector : public ParticleAffector {
|
||||||
public:
|
public:
|
||||||
bool load(const OTMLNodePtr& node);
|
bool load(const OTMLNodePtr& node);
|
||||||
void update(const ParticlePtr& particle, double elapsedTime);
|
void updateParticle(const ParticlePtr& particle, double elapsedTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float m_angle, m_gravity;
|
float m_angle, m_gravity;
|
||||||
|
@ -44,7 +55,7 @@ private:
|
||||||
class AttractionAffector : public ParticleAffector {
|
class AttractionAffector : public ParticleAffector {
|
||||||
public:
|
public:
|
||||||
bool load(const OTMLNodePtr& node);
|
bool load(const OTMLNodePtr& node);
|
||||||
void update(const ParticlePtr& particle, double elapsedTime);
|
void updateParticle(const ParticlePtr& particle, double elapsedTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Point m_destination;
|
Point m_destination;
|
||||||
|
|
|
@ -38,7 +38,7 @@ ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent)
|
||||||
m_delay = 0;
|
m_delay = 0;
|
||||||
m_burstRate = 1; m_burstCount = 32;
|
m_burstRate = 1; m_burstCount = 32;
|
||||||
m_currentBurst = 0;
|
m_currentBurst = 0;
|
||||||
m_startTime = g_clock.time();
|
m_elapsedTime = 0;
|
||||||
m_finished = false;
|
m_finished = false;
|
||||||
|
|
||||||
// particles default configuration. (make them reasonable for user detect missing properties on scripts)
|
// particles default configuration. (make them reasonable for user detect missing properties on scripts)
|
||||||
|
@ -50,6 +50,7 @@ ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent)
|
||||||
m_pMaxSize = Size(32, 32);
|
m_pMaxSize = Size(32, 32);
|
||||||
m_pMinDuration = 0;
|
m_pMinDuration = 0;
|
||||||
m_pMaxDuration = 10;
|
m_pMaxDuration = 10;
|
||||||
|
m_pIgnorePhysicsAfter = -1;
|
||||||
m_pMinVelocity = 32;
|
m_pMinVelocity = 32;
|
||||||
m_pMaxVelocity = 64;
|
m_pMaxVelocity = 64;
|
||||||
m_pMinVelocityAngle = 0;
|
m_pMinVelocityAngle = 0;
|
||||||
|
@ -139,6 +140,8 @@ bool ParticleEmitter::load(const OTMLNodePtr& node)
|
||||||
m_pMinDuration = childNode->value<float>();
|
m_pMinDuration = childNode->value<float>();
|
||||||
else if(childNode->tag() == "particle-max-duration")
|
else if(childNode->tag() == "particle-max-duration")
|
||||||
m_pMaxDuration = childNode->value<float>();
|
m_pMaxDuration = childNode->value<float>();
|
||||||
|
else if(childNode->tag() == "particle-ignore-physics-after")
|
||||||
|
m_pIgnorePhysicsAfter = childNode->value<float>();
|
||||||
|
|
||||||
// visual
|
// visual
|
||||||
else if(childNode->tag() == "particle-size") {
|
else if(childNode->tag() == "particle-size") {
|
||||||
|
@ -157,24 +160,20 @@ bool ParticleEmitter::load(const OTMLNodePtr& node)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleEmitter::update()
|
void ParticleEmitter::update(double elapsedTime)
|
||||||
{
|
{
|
||||||
float elapsedTime = g_clock.timeElapsed(m_startTime);
|
|
||||||
|
|
||||||
// only start updating after delay
|
|
||||||
if(elapsedTime < m_delay)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// setup a new start time
|
|
||||||
elapsedTime -= m_delay;
|
|
||||||
|
|
||||||
// check if finished
|
// check if finished
|
||||||
if(m_duration > 0 && elapsedTime > m_duration) {
|
if(m_duration > 0 && m_elapsedTime >= m_duration + m_delay) {
|
||||||
m_finished = true;
|
m_finished = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentBurst = (elapsedTime / m_burstRate) + 1;
|
m_elapsedTime += elapsedTime;
|
||||||
|
|
||||||
|
if(m_elapsedTime - elapsedTime < m_delay)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int currentBurst = std::floor((m_elapsedTime - m_delay) / m_burstRate) + 1;
|
||||||
for(int b = m_currentBurst; b < currentBurst; ++b) {
|
for(int b = m_currentBurst; b < currentBurst; ++b) {
|
||||||
|
|
||||||
// every burst created at same position.
|
// every burst created at same position.
|
||||||
|
@ -199,7 +198,7 @@ void ParticleEmitter::update()
|
||||||
PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle));
|
PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle));
|
||||||
|
|
||||||
ParticleSystemPtr particleSystem = m_parent.lock();
|
ParticleSystemPtr particleSystem = m_parent.lock();
|
||||||
particleSystem->addParticle(ParticlePtr(new Particle(pPosition, pSize, pVelocity, pAcceleration, pDuration, m_pColor, m_pTexture)));
|
particleSystem->addParticle(ParticlePtr(new Particle(pPosition, pSize, pVelocity, pAcceleration, pDuration, m_pIgnorePhysicsAfter, m_pColor, m_pTexture)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
|
|
||||||
bool load(const OTMLNodePtr& node);
|
bool load(const OTMLNodePtr& node);
|
||||||
|
|
||||||
void update();
|
void update(double elapsedTime);
|
||||||
|
|
||||||
bool hasFinished() { return m_finished; }
|
bool hasFinished() { return m_finished; }
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ private:
|
||||||
// self related
|
// self related
|
||||||
Point m_position;
|
Point m_position;
|
||||||
float m_duration, m_delay;
|
float m_duration, m_delay;
|
||||||
double m_startTime;
|
double m_elapsedTime;
|
||||||
bool m_finished;
|
bool m_finished;
|
||||||
float m_burstRate;
|
float m_burstRate;
|
||||||
int m_currentBurst, m_burstCount;
|
int m_currentBurst, m_burstCount;
|
||||||
|
@ -67,7 +67,7 @@ private:
|
||||||
float m_pMinAccelerationAngle, m_pMaxAccelerationAngle;
|
float m_pMinAccelerationAngle, m_pMaxAccelerationAngle;
|
||||||
|
|
||||||
// particles duration
|
// particles duration
|
||||||
float m_pMinDuration, m_pMaxDuration;
|
float m_pMinDuration, m_pMaxDuration, m_pIgnorePhysicsAfter;
|
||||||
|
|
||||||
// visual ralated
|
// visual ralated
|
||||||
Color m_pColor;
|
Color m_pColor;
|
||||||
|
|
|
@ -68,8 +68,7 @@ void ParticleSystem::render()
|
||||||
|
|
||||||
void ParticleSystem::update()
|
void ParticleSystem::update()
|
||||||
{
|
{
|
||||||
float elapsedTime = g_clock.timeElapsed(m_lastUpdateTime);
|
static const double delay = 0.0166; // 60 updates/s
|
||||||
m_lastUpdateTime = g_clock.time();
|
|
||||||
|
|
||||||
// check if finished
|
// check if finished
|
||||||
if(m_particles.empty() && m_emitters.empty()) {
|
if(m_particles.empty() && m_emitters.empty()) {
|
||||||
|
@ -77,30 +76,50 @@ void ParticleSystem::update()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update emitters
|
// check time
|
||||||
for(auto it = m_emitters.begin(), end = m_emitters.end(); it != end;) {
|
double elapsedTime = g_clock.timeElapsed(m_lastUpdateTime);
|
||||||
const ParticleEmitterPtr& emitter = *it;
|
if(elapsedTime < delay)
|
||||||
if(emitter->hasFinished()) {
|
return;
|
||||||
it = m_emitters.erase(it);
|
m_lastUpdateTime = g_clock.time() - std::fmod(elapsedTime, delay);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
emitter->update();
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update particles
|
for(int i = 0; i < elapsedTime / delay; ++i) {
|
||||||
for(auto it = m_particles.begin(), end = m_particles.end(); it != end;) {
|
|
||||||
const ParticlePtr& particle = *it;
|
// update emitters
|
||||||
if(particle->hasFinished()) {
|
for(auto it = m_emitters.begin(), end = m_emitters.end(); it != end;) {
|
||||||
it = m_particles.erase(it);
|
const ParticleEmitterPtr& emitter = *it;
|
||||||
continue;
|
if(emitter->hasFinished()) {
|
||||||
|
it = m_emitters.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
emitter->update(delay);
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass particles through affectors
|
// update affectors
|
||||||
for(const ParticleAffectorPtr& particleAffector : m_affectors)
|
for(auto it = m_affectors.begin(), end = m_affectors.end(); it != end;) {
|
||||||
particleAffector->update(particle, elapsedTime);
|
const ParticleAffectorPtr& affector = *it;
|
||||||
|
if(affector->hasFinished()) {
|
||||||
|
it = m_affectors.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
affector->update(delay);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
particle->update();
|
// update particles
|
||||||
++it;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass particles through affectors
|
||||||
|
for(const ParticleAffectorPtr& particleAffector : m_affectors)
|
||||||
|
particleAffector->updateParticle(particle, delay);
|
||||||
|
|
||||||
|
particle->update(delay);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue