1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-15 09:05:52 +00:00

cleanup the partcile system a bit, and use new randomness

This commit is contained in:
fgenesis 2025-02-01 07:32:54 +01:00
parent 26e1da131d
commit 3a40506ddb
7 changed files with 126 additions and 241 deletions

View file

@ -209,10 +209,9 @@ void Avatar::onAnimationKeyPassed(int key)
Entity::onAnimationKeyPassed(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 + randVector(radius);
return position + Vector(sinf(a), cosf(a))*radius;
} }
SongIconParticle::SongIconParticle(Vector color, Vector pos, size_t note) SongIconParticle::SongIconParticle(Vector color, Vector pos, size_t note)
@ -224,7 +223,7 @@ SongIconParticle::SongIconParticle(Vector color, Vector pos, size_t note)
setWidthHeight(32); setWidthHeight(32);
float life = 1.0; const float life = 1;
toIcon = 0; toIcon = 0;
this->color = color; this->color = color;

View file

@ -192,6 +192,11 @@ enum LerpType
#define DOUBLE_CLICK_DELAY 0.5f #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); float lerp(float v1, float v2, float dt, int lerpType);

View file

@ -96,7 +96,6 @@ set(BBGE_SRCS
Slider.h Slider.h
SoundManager.cpp SoundManager.cpp
SoundManager.h SoundManager.h
SpawnParticleData.cpp
SplineGrid.cpp SplineGrid.cpp
SplineGrid.h SplineGrid.h
StateMachine.cpp StateMachine.cpp

View file

@ -21,6 +21,46 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Particles.h" #include "Particles.h"
#include "RenderBase.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) Emitter::Emitter(ParticleEffect *pe) : Quad(), pe(pe)
{ {
//HACK: //HACK:
@ -63,52 +103,32 @@ void Emitter::spawnParticle(float perc)
p->pos = lastSpawn + ((currentSpawn - lastSpawn) * perc); p->pos = lastSpawn + ((currentSpawn - lastSpawn) * perc);
int finalRadius = data.randomSpawnRadius; float finalRadius = data.randomSpawnRadius + rng.f01() * data.randomSpawnRadiusRange;
if (data.randomSpawnRadiusRange > 0)
finalRadius += rand()%data.randomSpawnRadiusRange;
switch (data.spawnArea)
{ {
case SpawnParticleData::SPAWN_CIRCLE: float a = randAngle();
{
float a = rand()%360;
p->pos += Vector(sinf(a)*finalRadius * data.randomSpawnMod.x, cosf(a)*finalRadius * data.randomSpawnMod.y); 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))
{ {
// Legacy codepath -- breaks animated scaling
} float sz = lerp(data.randomScale1, data.randomScale2, rng.f01());
else
{
int r = rand()%(int(data.randomScale2*100) - int(data.randomScale1*100));
float sz = data.randomScale1 + float(r)/100.0f;
p->scale = Vector(sz,sz); p->scale = Vector(sz,sz);
} }
if (data.randomRotationRange > 0) if (data.randomRotationRange > 0)
{ {
p->rot.z = rand()%int(data.randomRotationRange); p->rot.z = rng.f01() * data.randomRotationRange;
p->rot.ensureData(); p->rot.ensureData()->target.z += p->rot.z;
p->rot.data->target.z += p->rot.z;
} }
if (data.randomVelocityMagnitude > 0) if (data.randomVelocityMagnitude > 0)
{ {
float a = rand()%data.randomVelocityRange; float a = randAngle();
Vector v = Vector(sinf(a)*data.randomVelocityMagnitude, cosf(a)*data.randomVelocityMagnitude); Vector v = Vector(sinf(a)*data.randomVelocityMagnitude, cosf(a)*data.randomVelocityMagnitude);
p->vel += v; p->vel += v;
} }
@ -119,6 +139,11 @@ void Emitter::spawnParticle(float perc)
} }
} }
float Emitter::randAngle()
{
return 2 * PI * rng.f01();
}
Vector Emitter::getSpawnPosition() Vector Emitter::getSpawnPosition()
{ {
if (!data.spawnLocal) if (!data.spawnLocal)
@ -130,70 +155,56 @@ void Emitter::onUpdate(float dt)
{ {
Quad::onUpdate(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) if (data.spawnTimeOffset > 0)
{ return;
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);
} }
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() void Emitter::start()

View file

@ -27,17 +27,19 @@ ParticleBank particleBank;
std::string ParticleManager::particleBankPath = ""; std::string ParticleManager::particleBankPath = "";
static int dummy_collideParticle(Vector pos)
{
return 0;
}
ParticleManager::ParticleManager(int size) ParticleManager::ParticleManager(int size)
{ {
particleManager = this; particleManager = this;
particles.resize(size); particles.resize(size);
used = 0; used = 0;
free = 0; free = 0;
oldFree = 0;
collideFunction = dummy_collideParticle;
collideFunction = 0;
specialFunction = 0;
numActive = 0; numActive = 0;
@ -61,9 +63,8 @@ void ParticleManager::setSize(size_t size)
particles.resize(size); particles.resize(size);
this->size = size; this->size = size;
this->halfSize = size*0.5f;
free = oldFree = 0; free = 0;
} }
void ParticleManager::setNumSuckPositions(size_t num) void ParticleManager::setNumSuckPositions(size_t num)
@ -104,31 +105,14 @@ void ParticleManager::updateParticle(Particle *p, float dt)
{ {
ParticleInfluence *pinf=0; ParticleInfluence *pinf=0;
if (collideFunction) if (collideFunction(p->pos))
{ {
if (collideFunction(p->pos)) // fade out
{ p->vel = 0;
const bool bounce = false; endParticle(p);
if (bounce) return;
{
p->pos = p->lpos;
p->vel = -p->vel;
}
else
{
// fade out
p->vel = 0;
endParticle(p);
return;
}
}
} }
if (specialFunction)
{
specialFunction(p);
}
p->lpos = p->pos;
Influences::iterator i = influences.begin(); Influences::iterator i = influences.begin();
for (; i != influences.end(); i++) for (; i != influences.end(); i++)
{ {
@ -166,9 +150,6 @@ void ParticleManager::updateParticle(Particle *p, float dt)
p->emitter->hasRot = true; p->emitter->hasRot = true;
} }
p->lpos = p->pos;
if (p->life <= 0) if (p->life <= 0)
{ {
endParticle(p); endParticle(p);
@ -205,14 +186,6 @@ void ParticleManager::nextFree(size_t jump)
free -= size; free -= size;
} }
void ParticleManager::setFree(size_t free)
{
if (free != -1)
{
this->free = free;
}
}
static const size_t spread = 8; static const size_t spread = 8;
static const size_t spreadCheck = 128; static const size_t spreadCheck = 128;
@ -220,9 +193,7 @@ static const size_t spreadCheck = 128;
Particle *ParticleManager::stomp() Particle *ParticleManager::stomp()
{ {
int c = 0, idx = -1; int c = 0, idx = -1;
//int bFree = free;
Particle *p = 0; Particle *p = 0;
bool exceed = false;
nextFree(); nextFree();
@ -230,7 +201,6 @@ Particle *ParticleManager::stomp()
{ {
if (c >= spreadCheck) if (c >= spreadCheck)
{ {
exceed = true;
break; break;
} }
@ -241,13 +211,6 @@ Particle *ParticleManager::stomp()
} }
while (p->active); while (p->active);
if (exceed)
{
}
endParticle(p); endParticle(p);
p->index = idx; p->index = idx;
return p; return p;

View file

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Core.h" #include "Core.h"
#include "Quad.h" #include "Quad.h"
#include "Randomness.h"
class Emitter; class Emitter;
class ParticleEffect; class ParticleEffect;
@ -32,24 +33,14 @@ struct SpawnParticleData
SpawnParticleData(); SpawnParticleData();
float randomScale1, randomScale2; float randomScale1, randomScale2;
float randomAlphaMod1, randomAlphaMod2; float randomAlphaMod1, randomAlphaMod2; // both unused
enum { NO_SPAWN = 999 };
enum SpawnArea { SPAWN_CIRCLE=0, SPAWN_LINE };
int pauseLevel; int pauseLevel;
int flipH, flipV; int flipH, flipV;
SpawnArea spawnArea;
float updateMultiplier;
InterpolatedVector velocityMagnitude;
int randomParticleAngleRange;
int randomVelocityRange;
float randomVelocityMagnitude; float randomVelocityMagnitude;
int randomRotationRange; int randomRotationRange;
InterpolatedVector initialVelocity, number, gravity; Vector initialVelocity, gravity;
float randomSpawnRadius; float randomSpawnRadius;
Vector randomSpawnMod; Vector randomSpawnMod;
int randomSpawnRadiusRange; int randomSpawnRadiusRange;
@ -57,16 +48,11 @@ struct SpawnParticleData
int justOne; int justOne;
int copyParentRotation, copyParentFlip; int copyParentRotation, copyParentFlip;
bool useSpawnRate;
bool calculateVelocityToCenter;
bool fadeAlphaWithLife, addAsChild;
int width, height; int width, height;
InterpolatedVector scale, rotation, color, alpha, spawnOffset; InterpolatedVector number, scale, rotation, color, alpha;
float life; float life;
InterpolatedVector spawnRate;
std::string texture; std::string texture;
BlendType blendType; BlendType blendType;
float counter;
float spawnTimeOffset; float spawnTimeOffset;
bool spawnLocal; bool spawnLocal;
bool inheritColor; bool inheritColor;
@ -97,7 +83,6 @@ struct Particle
pos = Vector(0,0); pos = Vector(0,0);
vel = Vector(0,0); vel = Vector(0,0);
gvy = Vector(0,0); gvy = Vector(0,0);
lpos = Vector(0,0);
color = Vector(1,1,1); color = Vector(1,1,1);
alpha = 1; alpha = 1;
scale = Vector(1,1); scale = Vector(1,1);
@ -107,7 +92,7 @@ struct Particle
} }
float life; float life;
bool active; bool active;
Vector pos, vel, gvy, lpos; Vector pos, vel, gvy;
InterpolatedVector color, alpha, scale, rot; InterpolatedVector color, alpha, scale, rot;
Emitter *emitter; Emitter *emitter;
int index; int index;
@ -139,11 +124,13 @@ protected:
void onRender(const RenderState& rs) const OVERRIDE; void onRender(const RenderState& rs) const OVERRIDE;
void spawnParticle(float perc=1); void spawnParticle(float perc=1);
void onUpdate(float dt) OVERRIDE; void onUpdate(float dt) OVERRIDE;
float randAngle();
ParticleEffect *pe; ParticleEffect *pe;
typedef std::list<Particle*> Particles; typedef std::list<Particle*> Particles;
Particles particles; Particles particles;
FastRand rng;
}; };
class ParticleEffect : public RenderObject class ParticleEffect : public RenderObject
@ -206,12 +193,9 @@ public:
void clearInfluences(); void clearInfluences();
void addInfluence(ParticleInfluence inf); void addInfluence(ParticleInfluence inf);
int (*collideFunction)(Vector pos); int (*collideFunction)(Vector pos);
void (*specialFunction)(Particle *me);
void endParticle(Particle *p); void endParticle(Particle *p);
void setFree(size_t free);
size_t getFree() { return free; } size_t getFree() { return free; }
size_t getNumActive() { return numActive; } size_t getNumActive() { return numActive; }
@ -224,20 +208,16 @@ public:
protected: protected:
std::vector<Vector> suckPositions; std::vector<Vector> suckPositions;
size_t numActive; size_t numActive;
Particle* stomp(); Particle* stomp();
void nextFree(size_t f=1); void nextFree(size_t f=1);
size_t oldFree;
typedef std::vector<ParticleInfluence> Influences; typedef std::vector<ParticleInfluence> Influences;
Influences influences; Influences influences;
size_t size, used, free, halfSize; size_t size, used, free;
Particles particles; Particles particles;

View file

@ -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;
}