void ParticleSystem::increaseEmittedEmitterPool(size_t size) { // Don't proceed if the pool doesn't contain any keys of emitted emitters if (mEmittedEmitterPool.empty()) { return; } EmittedEmitterPool::iterator emittedEmitterPoolIterator; ParticleEmitterList::iterator emitterIterator; ParticleEmitter* emitter = 0; ParticleEmitter* clonedEmitter = 0; String name = BLANK; EmittedEmitterList* e = 0; size_t maxNumberOfEmitters = size / mEmittedEmitterPool.size(); // equally distribute the number for each emitted emitter list size_t oldSize = 0; // Run through mEmittedEmitterPool and search for every key (=name) its corresponding emitter in mEmitters for (emittedEmitterPoolIterator = mEmittedEmitterPool.begin(); emittedEmitterPoolIterator != mEmittedEmitterPool.end(); ++emittedEmitterPoolIterator) { name = emittedEmitterPoolIterator->first; e = &emittedEmitterPoolIterator->second; // Search the correct emitter in the mEmitters vector emitter = 0; for (emitterIterator = mEmitters.begin(); emitterIterator != mEmitters.end(); ++emitterIterator) { emitter = *emitterIterator; if (emitter && name != "" && name == emitter->getName()) { // Found the right emitter, clone each emitter a number of times oldSize = e->size(); for (size_t t = oldSize; t < maxNumberOfEmitters; ++t) { clonedEmitter = ParticleSystemManager::getSingleton()._createEmitter(emitter->getType(), this); emitter->copyParametersTo(clonedEmitter); clonedEmitter->setEmitted(emitter->isEmitted()); // is always 'true' by the way, but just in case // Initially deactivate the emitted emitter if duration/repeat_delay are set if (clonedEmitter->getDuration() > 0.0f && (clonedEmitter->getRepeatDelay() > 0.0f || clonedEmitter->getMinRepeatDelay() > 0.0f || clonedEmitter->getMinRepeatDelay() > 0.0f)) { clonedEmitter->setEnabled(false); } // Add cloned emitters to the pool e->push_back(clonedEmitter); } } } } }
void ParticleSystem::_expire(Real timeElapsed) { ActiveParticleList::iterator i, itEnd; Particle* pParticle; ParticleEmitter* pParticleEmitter; itEnd = mActiveParticles.end(); for (i = mActiveParticles.begin(); i != itEnd;) { pParticle = static_cast<Particle*>(*i); if (pParticle->timeToLive < timeElapsed) { // Notify renderer mRenderer->_notifyParticleExpired(pParticle); // Identify the particle type if (pParticle->particleType == Particle::Visual) { // Destroy this one mFreeParticles.splice(mFreeParticles.end(), mActiveParticles, i++); } else { // For now, it can only be an emitted emitter pParticleEmitter = static_cast<ParticleEmitter*>(*i); std::list<ParticleEmitter*>* fee = findFreeEmittedEmitter(pParticleEmitter->getName()); fee->push_back(pParticleEmitter); // Also erase from mActiveEmittedEmitters removeFromActiveEmittedEmitters (pParticleEmitter); // And erase from mActiveParticles i = mActiveParticles.erase( i ); } } else { // Decrement TTL pParticle->timeToLive -= timeElapsed; ++i; } } }
void ParticleSystem::initialiseEmittedEmitterPool(void) { if (mEmittedEmitterPoolInitialised) { return; } // Run through mEmitters and add keys to the pool ParticleEmitterList::iterator emitterIterator; ParticleEmitterList::iterator emitterIteratorInner; ParticleEmitter* emitter = 0; ParticleEmitter* emitterInner = 0; for (emitterIterator = mEmitters.begin(); emitterIterator != mEmitters.end(); ++emitterIterator) { // Determine the names of all emitters that are emitted emitter = *emitterIterator ; if (emitter && emitter->getEmittedEmitter() != BLANK) { // This one will be emitted, register its name and leave the vector empty! EmittedEmitterList empty; mEmittedEmitterPool.insert(make_pair(emitter->getEmittedEmitter(), empty)); } // Determine whether the emitter itself will be emitted and set the 'mEmitted' attribute for (emitterIteratorInner = mEmitters.begin(); emitterIteratorInner != mEmitters.end(); ++emitterIteratorInner) { emitterInner = *emitterIteratorInner; if (emitter && emitterInner && emitter->getName() != BLANK && emitter->getName() == emitterInner->getEmittedEmitter()) { emitter->setEmitted(true); break; } else { // Set explicitly to 'false' although the default value is already 'false' emitter->setEmitted(false); } } } mEmittedEmitterPoolInitialised = true; }
//----------------------------------------------------------------------- void ParticlePool::_increaseParticleEmitterPool(size_t size, Particle::ParticleBehaviourList& behaviours, ParticleTechnique* technique) { size_t oldSize = mEmitters.size(); if (size < oldSize) return; // Create new emitters, based on the already created emitters in the technique and which are marked for emission. size_t numberOfEmittedEmitters = technique->getNumEmittedEmitters(); if (numberOfEmittedEmitters == 0) return; ParticleEmitter* existingEmitter = 0; ParticleEmitter* clonedEmitter = 0; size_t numEmitters = technique->getNumEmitters(); // Distribute size equally size_t increment = (size-oldSize) / numberOfEmittedEmitters; // Run through emitters of the technique for (size_t emitterCount = 0; emitterCount < numEmitters; emitterCount++) { existingEmitter = technique->getEmitter(emitterCount); if (existingEmitter->_isMarkedForEmission()) { // Clone the emitter 'increment' times and add to the pool for (size_t i = 0; i < increment; i++) { clonedEmitter = ParticleSystemManager::getSingletonPtr()->cloneEmitter(existingEmitter); clonedEmitter->_setMarkedForEmission(true); clonedEmitter->copyBehaviours(behaviours); mParticleEmitterPool.addElement(clonedEmitter->getName(), clonedEmitter); mEmitters.push_back(clonedEmitter); /** Pooled emitters should be prepared here, because it cannot be done anywhere else because of the limitation of iterating through the pool. Besides, this is faster. */ clonedEmitter->_prepare(technique); } } } }