From 3a40506ddbc56ea53767f24648b22df233219c48 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sat, 1 Feb 2025 07:32:54 +0100 Subject: [PATCH] cleanup the partcile system a bit, and use new randomness --- Aquaria/Avatar.cpp | 7 +- BBGE/Base.h | 5 + BBGE/CMakeLists.txt | 1 - BBGE/Emitter.cpp | 185 ++++++++++++++++++++----------------- BBGE/ParticleManager.cpp | 61 +++--------- BBGE/Particles.h | 36 ++------ BBGE/SpawnParticleData.cpp | 72 --------------- 7 files changed, 126 insertions(+), 241 deletions(-) delete mode 100644 BBGE/SpawnParticleData.cpp diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 4f574f3..e5807a5 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -209,10 +209,9 @@ void Avatar::onAnimationKeyPassed(int key) Entity::onAnimationKeyPassed(key); } -Vector randCirclePos(Vector position, int radius) +static Vector randCirclePos(const Vector& position, float radius) { - float a = ((rand()%360)*(2*PI))/360.0f; - return position + Vector(sinf(a), cosf(a))*radius; + return position + randVector(radius); } SongIconParticle::SongIconParticle(Vector color, Vector pos, size_t note) @@ -224,7 +223,7 @@ SongIconParticle::SongIconParticle(Vector color, Vector pos, size_t note) setWidthHeight(32); - float life = 1.0; + const float life = 1; toIcon = 0; this->color = color; diff --git a/BBGE/Base.h b/BBGE/Base.h index ac0684d..6c2276d 100644 --- a/BBGE/Base.h +++ b/BBGE/Base.h @@ -192,6 +192,11 @@ enum LerpType #define DOUBLE_CLICK_DELAY 0.5f +inline float lerp(float v1, float v2, float t) +{ + return (v2-v1)*t+v1; +} + float lerp(float v1, float v2, float dt, int lerpType); diff --git a/BBGE/CMakeLists.txt b/BBGE/CMakeLists.txt index c1c0c0b..47e3a08 100644 --- a/BBGE/CMakeLists.txt +++ b/BBGE/CMakeLists.txt @@ -96,7 +96,6 @@ set(BBGE_SRCS Slider.h SoundManager.cpp SoundManager.h - SpawnParticleData.cpp SplineGrid.cpp SplineGrid.h StateMachine.cpp diff --git a/BBGE/Emitter.cpp b/BBGE/Emitter.cpp index 1a3a3fe..8b16e79 100644 --- a/BBGE/Emitter.cpp +++ b/BBGE/Emitter.cpp @@ -21,6 +21,46 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Particles.h" #include "RenderBase.h" + +SpawnParticleData::SpawnParticleData() +{ + suckIndex = -1; + suckStr = 0; + + randomScale1 = 1; + randomScale2 = 1; + randomAlphaMod1 = 1; + randomAlphaMod2 = 1; + influenced = 0; + spawnLocal = false; + life = 1; + blendType = BLEND_DEFAULT; + scale = Vector(1,1,1); + width = 64; + height = 64; + color = Vector(1,1,1); + alpha = 1; + randomSpawnRadius = 0; + lastDTDifference = 0; + + randomRotationRange = 0; + number = 1; + + randomSpawnRadiusRange = 0; + randomSpawnMod = Vector(1,1); + + randomVelocityMagnitude = 0; + + copyParentRotation = 0; + justOne = didOne = false; + flipH = flipV = 0; + spawnTimeOffset = 0; + pauseLevel = 0; + copyParentFlip = 0; + inheritColor = false; + inheritAlpha = false; +} + Emitter::Emitter(ParticleEffect *pe) : Quad(), pe(pe) { //HACK: @@ -63,52 +103,32 @@ void Emitter::spawnParticle(float perc) p->pos = lastSpawn + ((currentSpawn - lastSpawn) * perc); - int finalRadius = data.randomSpawnRadius; - if (data.randomSpawnRadiusRange > 0) - finalRadius += rand()%data.randomSpawnRadiusRange; + float finalRadius = data.randomSpawnRadius + rng.f01() * data.randomSpawnRadiusRange; - switch (data.spawnArea) { - case SpawnParticleData::SPAWN_CIRCLE: - { - float a = rand()%360; + float a = randAngle(); p->pos += Vector(sinf(a)*finalRadius * data.randomSpawnMod.x, cosf(a)*finalRadius * data.randomSpawnMod.y); } - break; - case SpawnParticleData::SPAWN_LINE: - { - if (rand()%2 == 0) - p->pos.x += finalRadius; - else - p->pos.x -= finalRadius; - } - break; - } - if (data.randomScale1 == 1 && data.randomScale1 == data.randomScale2) + if (!(data.randomScale1 == 1 && data.randomScale1 == data.randomScale2)) { - - } - else - { - int r = rand()%(int(data.randomScale2*100) - int(data.randomScale1*100)); - float sz = data.randomScale1 + float(r)/100.0f; + // Legacy codepath -- breaks animated scaling + float sz = lerp(data.randomScale1, data.randomScale2, rng.f01()); p->scale = Vector(sz,sz); } if (data.randomRotationRange > 0) { - p->rot.z = rand()%int(data.randomRotationRange); - p->rot.ensureData(); - p->rot.data->target.z += p->rot.z; + p->rot.z = rng.f01() * data.randomRotationRange; + p->rot.ensureData()->target.z += p->rot.z; } if (data.randomVelocityMagnitude > 0) { - float a = rand()%data.randomVelocityRange; + float a = randAngle(); Vector v = Vector(sinf(a)*data.randomVelocityMagnitude, cosf(a)*data.randomVelocityMagnitude); p->vel += v; } @@ -119,6 +139,11 @@ void Emitter::spawnParticle(float perc) } } +float Emitter::randAngle() +{ + return 2 * PI * rng.f01(); +} + Vector Emitter::getSpawnPosition() { if (!data.spawnLocal) @@ -130,70 +155,56 @@ void Emitter::onUpdate(float dt) { Quad::onUpdate(dt); + if(!(pe->isRunning() && core->particlesPaused <= data.pauseLevel)) + return; - if (pe->isRunning() && core->particlesPaused <= data.pauseLevel) + if (data.spawnTimeOffset > 0) { + data.spawnTimeOffset -= dt; if (data.spawnTimeOffset > 0) - { - data.spawnTimeOffset -= dt; - if (data.spawnTimeOffset > 0) - return; - } - - int spawnCount; - float spawnPerc; - if (data.justOne) - { - if (data.didOne) - spawnCount = 0; - else - spawnCount = data.justOne; - spawnPerc = 1; - data.didOne = 1; - } - else if (data.useSpawnRate) - { - spawnCount = 0; - spawnPerc = 1; - data.counter += dt; - while (data.counter > data.spawnRate.x) // Faster than division - { - data.counter -= data.spawnRate.x; - spawnCount++; - } - } - else - { - float num = data.number.x * dt; - num += data.lastDTDifference; - spawnCount = int(num); - data.lastDTDifference = num - float(spawnCount); - if (spawnCount > 0) - spawnPerc = 1.0f / float(spawnCount); - } - - if (spawnCount > 0) - { - // Avoid calling this until we know we actually need it for - // generating a particle (it has to apply the matrix chain, - // which is slow). - currentSpawn = getSpawnPosition(); - if (lastSpawn.isZero()) - lastSpawn = currentSpawn; - - for (; spawnCount > 0; spawnCount--) - { - spawnParticle(spawnPerc); - } - - lastSpawn = currentSpawn; - } - - data.number.update(dt); - data.velocityMagnitude.update(dt); - data.spawnOffset.update(dt); + return; } + + int spawnCount; + float spawnPerc; + if (data.justOne) + { + if (data.didOne) + spawnCount = 0; + else + spawnCount = data.justOne; + spawnPerc = 1; + data.didOne = 1; + } + else + { + float num = data.number.x * dt; + num += data.lastDTDifference; + spawnCount = int(num); + data.lastDTDifference = num - float(spawnCount); + if (spawnCount > 0) + spawnPerc = 1.0f / float(spawnCount); + } + + if (spawnCount > 0) + { + // Avoid calling this until we know we actually need it for + // generating a particle (it has to apply the matrix chain, + // which is slow). + currentSpawn = getSpawnPosition(); + if (lastSpawn.isZero()) + lastSpawn = currentSpawn; + + for (; spawnCount > 0; spawnCount--) + { + spawnParticle(spawnPerc); + } + + lastSpawn = currentSpawn; + } + + data.number.update(dt); } void Emitter::start() diff --git a/BBGE/ParticleManager.cpp b/BBGE/ParticleManager.cpp index b959b98..15db284 100644 --- a/BBGE/ParticleManager.cpp +++ b/BBGE/ParticleManager.cpp @@ -27,17 +27,19 @@ ParticleBank particleBank; std::string ParticleManager::particleBankPath = ""; +static int dummy_collideParticle(Vector pos) +{ + return 0; +} + ParticleManager::ParticleManager(int size) { particleManager = this; particles.resize(size); used = 0; free = 0; - oldFree = 0; - - collideFunction = 0; - specialFunction = 0; + collideFunction = dummy_collideParticle; numActive = 0; @@ -61,9 +63,8 @@ void ParticleManager::setSize(size_t size) particles.resize(size); this->size = size; - this->halfSize = size*0.5f; - free = oldFree = 0; + free = 0; } void ParticleManager::setNumSuckPositions(size_t num) @@ -104,31 +105,14 @@ void ParticleManager::updateParticle(Particle *p, float dt) { ParticleInfluence *pinf=0; - if (collideFunction) + if (collideFunction(p->pos)) { - if (collideFunction(p->pos)) - { - const bool bounce = false; - if (bounce) - { - p->pos = p->lpos; - p->vel = -p->vel; - } - else - { - // fade out - p->vel = 0; - endParticle(p); - return; - } - } + // fade out + p->vel = 0; + endParticle(p); + return; } - if (specialFunction) - { - specialFunction(p); - } - p->lpos = p->pos; Influences::iterator i = influences.begin(); for (; i != influences.end(); i++) { @@ -166,9 +150,6 @@ void ParticleManager::updateParticle(Particle *p, float dt) p->emitter->hasRot = true; } - p->lpos = p->pos; - - if (p->life <= 0) { endParticle(p); @@ -205,14 +186,6 @@ void ParticleManager::nextFree(size_t jump) free -= size; } -void ParticleManager::setFree(size_t free) -{ - if (free != -1) - { - this->free = free; - } -} - static const size_t spread = 8; static const size_t spreadCheck = 128; @@ -220,9 +193,7 @@ static const size_t spreadCheck = 128; Particle *ParticleManager::stomp() { int c = 0, idx = -1; - //int bFree = free; Particle *p = 0; - bool exceed = false; nextFree(); @@ -230,7 +201,6 @@ Particle *ParticleManager::stomp() { if (c >= spreadCheck) { - exceed = true; break; } @@ -241,13 +211,6 @@ Particle *ParticleManager::stomp() } while (p->active); - - - if (exceed) - { - - } - endParticle(p); p->index = idx; return p; diff --git a/BBGE/Particles.h b/BBGE/Particles.h index 952debe..99f185f 100644 --- a/BBGE/Particles.h +++ b/BBGE/Particles.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Core.h" #include "Quad.h" +#include "Randomness.h" class Emitter; class ParticleEffect; @@ -32,24 +33,14 @@ struct SpawnParticleData SpawnParticleData(); float randomScale1, randomScale2; - float randomAlphaMod1, randomAlphaMod2; - enum { NO_SPAWN = 999 }; - - enum SpawnArea { SPAWN_CIRCLE=0, SPAWN_LINE }; + float randomAlphaMod1, randomAlphaMod2; // both unused int pauseLevel; int flipH, flipV; - SpawnArea spawnArea; - - float updateMultiplier; - - InterpolatedVector velocityMagnitude; - int randomParticleAngleRange; - int randomVelocityRange; float randomVelocityMagnitude; int randomRotationRange; - InterpolatedVector initialVelocity, number, gravity; + Vector initialVelocity, gravity; float randomSpawnRadius; Vector randomSpawnMod; int randomSpawnRadiusRange; @@ -57,16 +48,11 @@ struct SpawnParticleData int justOne; int copyParentRotation, copyParentFlip; - bool useSpawnRate; - bool calculateVelocityToCenter; - bool fadeAlphaWithLife, addAsChild; int width, height; - InterpolatedVector scale, rotation, color, alpha, spawnOffset; + InterpolatedVector number, scale, rotation, color, alpha; float life; - InterpolatedVector spawnRate; std::string texture; BlendType blendType; - float counter; float spawnTimeOffset; bool spawnLocal; bool inheritColor; @@ -97,7 +83,6 @@ struct Particle pos = Vector(0,0); vel = Vector(0,0); gvy = Vector(0,0); - lpos = Vector(0,0); color = Vector(1,1,1); alpha = 1; scale = Vector(1,1); @@ -107,7 +92,7 @@ struct Particle } float life; bool active; - Vector pos, vel, gvy, lpos; + Vector pos, vel, gvy; InterpolatedVector color, alpha, scale, rot; Emitter *emitter; int index; @@ -139,11 +124,13 @@ protected: void onRender(const RenderState& rs) const OVERRIDE; void spawnParticle(float perc=1); void onUpdate(float dt) OVERRIDE; + float randAngle(); ParticleEffect *pe; typedef std::list Particles; Particles particles; + FastRand rng; }; class ParticleEffect : public RenderObject @@ -206,12 +193,9 @@ public: void clearInfluences(); void addInfluence(ParticleInfluence inf); int (*collideFunction)(Vector pos); - void (*specialFunction)(Particle *me); void endParticle(Particle *p); - void setFree(size_t free); - size_t getFree() { return free; } size_t getNumActive() { return numActive; } @@ -224,20 +208,16 @@ public: protected: - - std::vector suckPositions; size_t numActive; Particle* stomp(); void nextFree(size_t f=1); - size_t oldFree; - typedef std::vector Influences; Influences influences; - size_t size, used, free, halfSize; + size_t size, used, free; Particles particles; diff --git a/BBGE/SpawnParticleData.cpp b/BBGE/SpawnParticleData.cpp deleted file mode 100644 index c02a216..0000000 --- a/BBGE/SpawnParticleData.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright (C) 2007, 2010 - Bit-Blot - -This file is part of Aquaria. - -Aquaria is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "Particles.h" - -SpawnParticleData::SpawnParticleData() -{ - suckIndex = -1; - suckStr = 0; - - randomScale1 = 1; - randomScale2 = 1; - randomAlphaMod1 = 1; - randomAlphaMod2 = 1; - influenced = 0; - spawnLocal = false; - useSpawnRate = false; - counter = 0; - life = 1; - blendType = BLEND_DEFAULT; - spawnRate = 1; - scale = Vector(1,1,1); - width = 64; - height = 64; - fadeAlphaWithLife = false; - color = Vector(1,1,1); - alpha = 1; - randomSpawnRadius = 0; - lastDTDifference = 0; - addAsChild = false; - - randomRotationRange = 0; - number = 1; - - randomParticleAngleRange = 0; - velocityMagnitude = 1; - - calculateVelocityToCenter = false; - - randomSpawnRadiusRange = 0; - randomSpawnMod = Vector(1,1); - - spawnArea = SPAWN_CIRCLE; - randomVelocityMagnitude = 0; - randomVelocityRange = 360; - - copyParentRotation = 0; - justOne = didOne = false; - flipH = flipV = 0; - spawnTimeOffset = 0; - pauseLevel = 0; - copyParentFlip = 0; - inheritColor = false; - inheritAlpha = false; -}