upgrade emitters garbage collection

This commit is contained in:
MihailRis 2024-12-23 17:26:22 +03:00
parent 78761a445a
commit 52494a680c
3 changed files with 21 additions and 12 deletions

View File

@ -19,7 +19,7 @@ Emitter::Emitter(
) )
: level(level), : level(level),
origin(std::move(origin)), origin(std::move(origin)),
prototype({this, 0, glm::vec3(), preset.velocity, preset.lifetime, region}), prototype({this, 0, {}, preset.velocity, preset.lifetime, region}),
texture(texture), texture(texture),
count(count), count(count),
preset(std::move(preset)) { preset(std::move(preset)) {
@ -113,6 +113,7 @@ void Emitter::update(
if (count > 0) { if (count > 0) {
count--; count--;
} }
refCount++;
} }
} }
@ -124,6 +125,10 @@ bool Emitter::isDead() const {
return count == 0; return count == 0;
} }
bool Emitter::isReferred() const {
return refCount > 0;
}
const EmitterOrigin& Emitter::getOrigin() const { const EmitterOrigin& Emitter::getOrigin() const {
return origin; return origin;
} }

View File

@ -54,6 +54,9 @@ class Emitter {
util::PseudoRandom random; util::PseudoRandom random;
public: public:
/// @brief Number of references (alive particles)
int refCount = 0;
/// @brief Particle settings
ParticlesPreset preset; ParticlesPreset preset;
Emitter( Emitter(
@ -86,6 +89,9 @@ public:
/// @return true if the emitter has spawned all particles /// @return true if the emitter has spawned all particles
bool isDead() const; bool isDead() const;
/// @return true if there is at least one alive referring particle left
bool isReferred() const;
const EmitterOrigin& getOrigin() const; const EmitterOrigin& getOrigin() const;
void setOrigin(const EmitterOrigin& origin); void setOrigin(const EmitterOrigin& origin);

View File

@ -63,7 +63,8 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
auto iter = vec.begin(); auto iter = vec.begin();
while (iter != vec.end()) { while (iter != vec.end()) {
auto& particle = *iter; auto& particle = *iter;
auto& preset = particle.emitter->preset; auto& emitter = *particle.emitter;
auto& preset = emitter.preset;
if (!preset.frames.empty()) { if (!preset.frames.empty()) {
float time = preset.lifetime - particle.lifetime; float time = preset.lifetime - particle.lifetime;
@ -137,6 +138,7 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
); );
if (particle.lifetime <= 0.0f) { if (particle.lifetime <= 0.0f) {
iter = vec.erase(iter); iter = vec.erase(iter);
emitter.refCount--;
} else { } else {
iter++; iter++;
} }
@ -159,19 +161,15 @@ void ParticlesRenderer::render(const Camera& camera, float delta) {
auto iter = emitters.begin(); auto iter = emitters.begin();
while (iter != emitters.end()) { while (iter != emitters.end()) {
auto& emitter = *iter->second; auto& emitter = *iter->second;
auto texture = emitter.getTexture(); if (emitter.isDead() && !emitter.isReferred()) {
const auto& found = particles.find(texture);
std::vector<Particle>* vec;
if (found == particles.end()) {
if (emitter.isDead()) {
// destruct Emitter only when there is no particles spawned by it // destruct Emitter only when there is no particles spawned by it
iter = emitters.erase(iter); iter = emitters.erase(iter);
continue; continue;
} }
auto texture = emitter.getTexture();
const auto& found = particles.find(texture);
std::vector<Particle>* vec;
vec = &particles[texture]; vec = &particles[texture];
} else {
vec = &found->second;
}
emitter.update(delta, camera.position, *vec); emitter.update(delta, camera.position, *vec);
iter++; iter++;
} }