Пример #1
0
// |----------------------------------------------------------------------------|
// |							     Logic()									|
// |----------------------------------------------------------------------------|
bool ParticleSystem::Logic() {
    DebugLog ("ParticleSystem: Logic() called.", DB_LOGIC, 10);

    // Increment the frame time.
    float time = TimerManager::GetRef()->GetTime() / 1000;
    m_accumulatedTime += time;

    // Set emit particle to false for now.
    bool emitParticle = false;

    // Check if it is time to emit a new particle or not.
    if(m_accumulatedTime > (m_particleSpawnFrequency))
    {
        m_accumulatedTime = 0.0f;
        emitParticle = true;
    }

    if(m_spawnParticles && (emitParticle == true) && (m_particles.size() < (m_maxParticles - 1)))
    {
        // Emit new particles.
        EmitParticle();
    }

    // Update the position of the particles.
    UpdateParticles();

    // Release old particles.
    KillParticles();

    return true;
}
Пример #2
0
	/*!
	* \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();
	}
Пример #3
0
void Particle::Frame(float frameTime)
{
	// Release old particles.
	KillParticles();

	// Emit new particles.
	EmitParticles(frameTime);

	// Update the position of the particles.
	UpdateParticles(frameTime);

}
Пример #4
0
bool ParticleSystemClass::Frame(float frameTime, ID3D11DeviceContext* deviceContext, D3DXVECTOR3 emitterPosition, D3DXVECTOR3 camPos)
{
	bool result;

	KillParticles();

	EmitParticles(frameTime, emitterPosition);

	UpdateParticles(frameTime, camPos);

	result = UpdateBuffers(deviceContext); //updating dynamic vertex buffer with new position of each particle
	if(!result)
	{
		return false;
	}

	return true;
}
Пример #5
0
bool ParticleSystemClass::Frame(float frameTime, ID3D11DeviceContext* deviceContext)
{
	bool result;
	
	// Release old particles.
	KillParticles();

	// Emit new particles.
	EmitParticles(frameTime);
	
	// Update the position of the particles.
	UpdateParticles(frameTime);

	// Update the dynamic vertex buffer with the new position of each particle.
	result = UpdateBuffers(deviceContext);
	if(!result)
	{
		return false;
	}

	return true;
}
//Frame Particle System
bool CParticleSystem::Frame(ID3D11DeviceContext* deviceContext, float frameTime, CCamera* mainCamera)
{
	bool result;

	//Release previous Particles
	KillParticles();

	//Emit new Particles
	EmitParticles(frameTime);

	//Update positions of Particles
	UpdateParticles(frameTime);

	//Update Buffers (Dynamic)
	result = UpdateBuffers(deviceContext, mainCamera);

	if (!result)
	{
		return false;
	}

	return true;
}
/** 
  * PreTick - handles killing dead particles, emitter death, and buffer swaps
  */
void FNiagaraSimulation::PreTick()
{
	UNiagaraEmitterProperties* PinnedProps = Props.Get();

	if (!PinnedProps || !bIsEnabled
		|| TickState == NTS_Suspended || TickState == NTS_Dead
		|| Data.GetNumInstances() == 0)
	{
		return;
	}

	check(Data.GetNumVariables() > 0);
	check(PinnedProps->SpawnScriptProps.Script);
	check(PinnedProps->UpdateScriptProps.Script);

	KillParticles();

	//Swap all data set buffers before doing the main tick on any simulation.
	for (TPair<FNiagaraDataSetID, FNiagaraDataSet*> SetPair : DataSetMap)
	{
		SetPair.Value->Tick();
	}
}
/**
 *	Tick the instance.
 *
 *	@param	DeltaTime			The time slice to use
 *	@param	bSuppressSpawning	If true, do not spawn during Tick
 */
void FParticleBeam2EmitterInstance::Tick(float DeltaTime, bool bSuppressSpawning)
{
	SCOPE_CYCLE_COUNTER(STAT_BeamTickTime);
	if (Component)
	{
		UParticleLODLevel* LODLevel = SpriteTemplate->GetCurrentLODLevel(this);
		check(LODLevel);	// TTP #33141

		// Handle EmitterTime setup, looping, etc.
		float EmitterDelay = Tick_EmitterTimeSetup(DeltaTime, LODLevel);

		// Kill before the spawn... Otherwise, we can get 'flashing'
		KillParticles();

		// If not suppressing spawning...
		if (!bHaltSpawning && !bSuppressSpawning && (EmitterTime >= 0.0f))
		{
			if ((LODLevel->RequiredModule->EmitterLoops == 0) || 
				(LoopCount < LODLevel->RequiredModule->EmitterLoops) ||
				(SecondsSinceCreation < (EmitterDuration * LODLevel->RequiredModule->EmitterLoops)))
			{
				// For beams, we probably want to ignore the SpawnRate distribution,
				// and focus strictly on the BurstList...
				float SpawnRate = 0.0f;
				// Figure out spawn rate for this tick.
				SpawnRate = LODLevel->SpawnModule->Rate.GetValue(EmitterTime, Component);
				// Take Bursts into account as well...
				int32		Burst		= 0;
				float	BurstTime	= GetCurrentBurstRateOffset(DeltaTime, Burst);
				SpawnRate += BurstTime;

				// Spawn new particles...

				//@todo. Fix the issue of 'blanking' beams when the count drops...
				// This is a temporary hack!
				const float InvDeltaTime = (DeltaTime > 0.0f) ? 1.0f / DeltaTime : 0.0f;
				if ((ActiveParticles < BeamCount) && (SpawnRate <= 0.0f))
				{
					// Force the spawn of a single beam...
					SpawnRate = 1.0f * InvDeltaTime;
				}

				// Force beams if the emitter is marked "AlwaysOn"
				if ((ActiveParticles < BeamCount) && BeamTypeData->bAlwaysOn)
				{
					Burst		= BeamCount;
					if (DeltaTime > KINDA_SMALL_NUMBER)
					{
						BurstTime	 = Burst * InvDeltaTime;
						SpawnRate	+= BurstTime;
					}
				}

				if (SpawnRate > 0.f)
				{
					SpawnFraction = SpawnBeamParticles(SpawnFraction, SpawnRate, DeltaTime, Burst, BurstTime);
				}
			}
		}

		// Reset particle data
		ResetParticleParameters(DeltaTime);

		// Not really necessary as beams do not LOD at the moment, but for consistency...
		CurrentMaterial = LODLevel->RequiredModule->Material;

		Tick_ModuleUpdate(DeltaTime, LODLevel);
		Tick_ModulePostUpdate(DeltaTime, LODLevel);

		// Calculate bounding box and simulate velocity.
		UpdateBoundingBox(DeltaTime);

		if (!bSuppressSpawning)
		{
			// Ensure that we flip the 'FirstEmission' flag
			FirstEmission = false;
		}

		// Invalidate the contents of the vertex/index buffer.
		IsRenderDataDirty = 1;

		// Bump the tick count
		TickCount++;

		// 'Reset' the emitter time so that the delay functions correctly
		EmitterTime += CurrentDelay;
		
		// Reset particles position offset
		PositionOffsetThisTick = FVector::ZeroVector;
	}
	INC_DWORD_STAT(STAT_BeamParticlesUpdateCalls);
}