Example #1
0
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);
		}
	    }
	}
    }
}
Example #2
0
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;
        }
    }
}
Example #3
0
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);
				}
			}
		}
	}