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

View File

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

View File

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