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()); }
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()); }