void FNiagaraSimulation::Tick(float DeltaSeconds)
{
	SCOPE_CYCLE_COUNTER(STAT_NiagaraTick);
	SimpleTimer TickTime;

	UNiagaraEmitterProperties* PinnedProps = Props.Get();
	if (!PinnedProps || !bIsEnabled || TickState == NTS_Suspended || TickState == NTS_Dead)
	{
		return;
	}

	Age += DeltaSeconds;

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

	// Figure out how many we will spawn.
	int32 OrigNumParticles = Data.GetNumInstances();
	int32 NumToSpawn = CalcNumToSpawn(DeltaSeconds);
	int32 MaxNewParticles = OrigNumParticles + NumToSpawn;
	Data.Allocate(MaxNewParticles);

	ExternalConstants.SetOrAdd(BUILTIN_CONST_EMITTERAGE, FVector4(Age, Age, Age, Age));
	ExternalConstants.SetOrAdd(BUILTIN_CONST_DELTATIME, FVector4(DeltaSeconds, DeltaSeconds, DeltaSeconds, DeltaSeconds));

	// Simulate particles forward by DeltaSeconds.
	if (TickState==NTS_Running || TickState==NTS_Dieing)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSimulate);
		RunVMScript(PinnedProps->UpdateScriptProps, EUnusedAttributeBehaviour::PassThrough);
	}

	//Init new particles with the spawn script.
	if (TickState==NTS_Running)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSpawn);
		Data.SetNumInstances(MaxNewParticles);
		//For now, zero any unused attributes here. But as this is really uninitialized data we should maybe make this a more serious error.
		RunVMScript(PinnedProps->SpawnScriptProps, EUnusedAttributeBehaviour::Zero, OrigNumParticles, NumToSpawn);

		if (bGenerateSpawnEvents)
		{
			SpawnEventGenerator.OnSpawned(OrigNumParticles, NumToSpawn);
		}
	}


	CPUTimeMS = TickTime.GetElapsedMilliseconds();

	INC_DWORD_STAT_BY(STAT_NiagaraNumParticles, Data.GetNumInstances());
}
void FNiagaraSimulation::Tick(float DeltaSeconds)
{
	SCOPE_CYCLE_COUNTER(STAT_NiagaraTick);

	UNiagaraEmitterProperties* PinnedProps = Props.Get();
	if (!PinnedProps || !bIsEnabled || TickState==NTS_Suspended || TickState==NTS_Dead)
		return;

	SimpleTimer TickTime;

	check(Data.GetNumVariables() > 0);
	check(PinnedProps->SpawnScriptProps.Script);
	check(PinnedProps->UpdateScriptProps.Script);
	
	//Handle Event Actions.
	auto CallEventActions = [&](FNiagaraEventReceiverProperties& Receiver)
	{
		for (auto& Action : Receiver.EmitterActions)
		{
			if (Action)
				Action->PerformAction(*this, Receiver);
		}
	};
	for (auto& Receiver : Props->SpawnScriptProps.EventReceivers)	{ CallEventActions(Receiver); }
	for (auto& Receiver : Props->UpdateScriptProps.EventReceivers)	{ CallEventActions(Receiver); }

	int32 OrigNumParticles = Data.GetNumInstances();
	int32 NumToSpawn = 0;

	// Figure out how many we will spawn.
	NumToSpawn = CalcNumToSpawn(DeltaSeconds);
	int32 MaxNewParticles = OrigNumParticles + NumToSpawn;
	Data.Allocate(MaxNewParticles);

	Age += DeltaSeconds;
	Constants.SetOrAdd(TEXT("Emitter Age"), FVector4(Age, Age, Age, Age));
	Constants.SetOrAdd(TEXT("Delta Time"), FVector4(DeltaSeconds, DeltaSeconds, DeltaSeconds, DeltaSeconds));

	// Simulate particles forward by DeltaSeconds.
	if (TickState==NTS_Running || TickState==NTS_Dieing)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSimulate);
		RunVMScript(PinnedProps->UpdateScriptProps, EUnusedAttributeBehaviour::Copy);
	}

	DebuggerHook_PreSpawn(this, OrigNumParticles, NumToSpawn);

	//Init new particles with the spawn script.
	if (TickState==NTS_Running)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSpawn);
		Data.SetNumInstances(MaxNewParticles);
		//For now, zero any unused attributes here. But as this is really uninitialized data we should maybe make this a more serious error.
		RunVMScript(PinnedProps->SpawnScriptProps, EUnusedAttributeBehaviour::Zero, OrigNumParticles, NumToSpawn);
	}

	if (bGenerateSpawnEvents)
	{
		SpawnEventGenerator.OnSpawned(OrigNumParticles, NumToSpawn);
	}


	CPUTimeMS = TickTime.GetElapsedMilliseconds();

	INC_DWORD_STAT_BY(STAT_NiagaraNumParticles, Data.GetNumInstances());

}
Ejemplo n.º 3
0
void FNiagaraSimulation::Tick(float DeltaSeconds)
{
	SCOPE_CYCLE_COUNTER(STAT_NiagaraTick);

	if (!bIsEnabled || TickState==NTS_Suspended || TickState==NTS_Dead)
		return;

	SimpleTimer TickTime;

	check(Data.GetNumAttributes() > 0);
	check(Props->SpawnScript);
	check(Props->UpdateScript);

	// Cache the ComponentToWorld transform.
//	CachedComponentToWorld = Component.GetComponentToWorld();

	Data.SwapBuffers();
	Data.SetNumParticles(Data.GetPrevNumParticles());

	int32 OrigNumParticles = Data.GetNumParticles();
	int32 NumToSpawn = 0;

	// Figure out how many we will spawn.
	NumToSpawn = CalcNumToSpawn(DeltaSeconds);
	int32 MaxNewParticles = OrigNumParticles + NumToSpawn;
	Data.Allocate(MaxNewParticles);

	Age += DeltaSeconds;
	Constants.SetOrAdd(TEXT("Emitter Age"), FVector4(Age, Age, Age, Age));
	Constants.SetOrAdd(TEXT("Delta Time"), FVector4(DeltaSeconds, DeltaSeconds, DeltaSeconds, DeltaSeconds));

	// Simulate particles forward by DeltaSeconds.
	if (TickState==NTS_Running || TickState==NTS_Dieing)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSimulate);
		RunVMScript(Props->UpdateScript, EUnusedAttributeBehaviour::Copy);
	}
	
	//Init new particles with the spawn script.
	if (TickState==NTS_Running)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSpawn);
		Data.SetNumParticles(MaxNewParticles);
		//For now, zero any unused attributes here. But as this is really uninitialized data we should maybe make this a more serious error.
		RunVMScript(Props->SpawnScript, EUnusedAttributeBehaviour::Zero, OrigNumParticles, NumToSpawn);
	}

	// Iterate over looking for dead particles and move from the end of the list to the dead location, compacting in the process
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraKill);
		int32 CurNumParticles = OrigNumParticles = Data.GetNumParticles();
		int32 ParticleIndex = 0;
		const FVector4* ParticleRelativeTimes = Data.GetAttributeData(FNiagaraVariableInfo(FName(TEXT("Age")), ENiagaraDataType::Vector));
		if (ParticleRelativeTimes)
		{
			while (ParticleIndex < OrigNumParticles)
			{
				if (ParticleRelativeTimes[ParticleIndex].X > 1.0f)
				{
					// Particle is dead, move one from the end here. 
					MoveParticleToIndex(--CurNumParticles, ParticleIndex);
				}
				ParticleIndex++;
			}
		}
		Data.SetNumParticles(CurNumParticles);

		// check if the emitter has officially died
		if (GetTickState() == NTS_Dieing && CurNumParticles == 0)
		{
			SetTickState(NTS_Dead);
		}
	}



	CPUTimeMS = TickTime.GetElapsedMilliseconds();

	DECLARE_DWORD_COUNTER_STAT(TEXT("NumParticles"), STAT_NiagaraNumParticles, STATGROUP_Niagara);
	INC_DWORD_STAT_BY(STAT_NiagaraNumParticles, Data.GetNumParticles());

}