/*! * \brief Applies the controllers * * \param mapper Mapper containing layout information of each particle * \param particleCount Number of particles * \param elapsedTime Delta time between the previous frame */ void ParticleGroup::ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime) { m_processing = true; // To avoid a lock in case of exception CallOnExit onExit([this]() { m_processing = false; }); for (ParticleController* controller : m_controllers) controller->Apply(*this, mapper, 0, particleCount - 1, elapsedTime); onExit.CallAndReset(); // We only kill now the dead particles during the update if (m_dyingParticles.size() < m_particleCount) { // We kill them in reverse order, std::set sorting them via std::greater // The reason is simple, as the death of a particle means moving the last particle in the buffer, // without this solution, certain particles could avoid death for (unsigned int index : m_dyingParticles) KillParticle(index); } else KillParticles(); // Every particles are dead, this is way faster m_dyingParticles.clear(); }
void ParticleSystem::AddTime(double time) { if(liveParticles > 0) { for(int i = 0;i < liveParticles;i++) { if(cpuData[i].currentLifeTime + time >= cpuData[i].lifeTime) { KillParticle(i); if(i == liveParticles) break; } ParticleCPUData & cdata = cpuData[i]; ParticleGPUData & gdata = gpuData[i]; cdata.currentLifeTime += time; float lifeTimeFactor = ((cdata.lifeTime - cdata.currentLifeTime) / cdata.lifeTime); if(useSizeOverLife) gdata.size = lifeTimeFactor* cdata.size; else gdata.size = cdata.size; Vector3 currentVelocity; if(useVelocityOverLife) currentVelocity = cdata.velocity * lifeTimeFactor; else currentVelocity = cdata.velocity; gdata.worldPos = gdata.worldPos + currentVelocity; if(useOpacityOverLife) gdata.opacityFactor = lifeTimeFactor; else gdata.opacityFactor = 1.0f; } } if(addParticles) if(currentSpawnTime + time >= spawnTime && liveParticles < maxParticles) { unsigned int spownCount = minSpawnParitcles + rand() % (maxSpawnParticles - minSpawnParitcles); if(liveParticles + spownCount > maxParticles) spownCount = maxParticles - liveParticles; for(unsigned int i = 0;i < spownCount;i++) { AddParticle(); } currentSpawnTime = 0; } else currentSpawnTime += time; }