TNiagaraExprPtr FNiagaraCompiler::Expression_Collection(TArray<TNiagaraExprPtr>& SourceExpressions) { //Todo - Collection expressions are just to collect parts of a matrix currently. Its a crappy way to do things that should be replaced. //Definitely don't start using it for collections of other things. int32 Index = Expressions.Add(MakeShareable(new FNiagaraExpression_Collection(this, FNiagaraVariableInfo(NAME_None, ENiagaraDataType::Vector), SourceExpressions))); return Expressions[Index]; }
FNiagaraExpression_AcquireSharedDataIndex(class FNiagaraCompiler* InCompiler, FNiagaraDataSetID InDataSet, bool bInWrap, TNiagaraExprPtr& ValidExpr) : FNiagaraExpression(InCompiler, FNiagaraVariableInfo(TEXT("AcquireIndex"), ENiagaraDataType::Vector)) , DataSet(InDataSet) , bWrap(bInWrap) { ResultLocation = ENiagaraExpressionResultLocation::Temporaries; SourceExpressions.Add(ValidExpr); }
FNiagaraExpression_GetConstant(class FNiagaraCompiler* InCompiler, const FNiagaraVariableInfo& InConstant, bool bIsInternal) : FNiagaraExpression(InCompiler, InConstant) , bInternal(bIsInternal) { ResultLocation = ENiagaraExpressionResultLocation::Constants; //For matrix constants we must add 4 input expressions that will be filled in as the constant is processed. //They must at least exist now so that other expressions can reference them. if (Result.Type == ENiagaraDataType::Matrix) { static const FName ResultName(TEXT("MatrixComponent")); SourceExpressions.Add(MakeShareable(new FNiagaraExpression(InCompiler, FNiagaraVariableInfo(ResultName, ENiagaraDataType::Vector)))); SourceExpressions.Add(MakeShareable(new FNiagaraExpression(InCompiler, FNiagaraVariableInfo(ResultName, ENiagaraDataType::Vector)))); SourceExpressions.Add(MakeShareable(new FNiagaraExpression(InCompiler, FNiagaraVariableInfo(ResultName, ENiagaraDataType::Vector)))); SourceExpressions.Add(MakeShareable(new FNiagaraExpression(InCompiler, FNiagaraVariableInfo(ResultName, ENiagaraDataType::Vector)))); } // else if (Result.Type == ENiagaraDataType::Curve) // { // static const FName ResultName(TEXT("Curve")); // SourceExpressions.Add(MakeShareable(new FNiagaraExpression(InCompiler, FNiagaraVariableInfo(ResultName, ENiagaraDataType::Curve)))); // } }
void FNiagaraEmitterPropertiesDetails::OnGenerateScalarConstantEntry(TSharedRef<IPropertyHandle> ElementProperty, int32 ElementIndex, IDetailChildrenBuilder& ChildrenBuilder) { TSharedPtr<IPropertyHandle> ValueProperty = ElementProperty->GetChildHandle(GET_MEMBER_NAME_CHECKED(FNiagaraConstants_Float, Value)); TSharedPtr<IPropertyHandle> NameProperty = ElementProperty->GetChildHandle(GET_MEMBER_NAME_CHECKED(FNiagaraConstants_Float, Name)); FName DisplayName; NameProperty->GetValue(DisplayName); //Don't display system constants if (UNiagaraComponent::GetSystemConstants().Find(FNiagaraVariableInfo(DisplayName, ENiagaraDataType::Scalar)) == INDEX_NONE) { ChildrenBuilder.AddChildProperty(ValueProperty.ToSharedRef()).DisplayName(FText::FromName(DisplayName)); } }
/** Look for dead particles and move from the end of the list to the dead location, compacting in the process */ void FNiagaraSimulation::KillParticles() { SCOPE_CYCLE_COUNTER(STAT_NiagaraKill); int32 OrigNumParticles = Data.GetNumInstances(); int32 CurNumParticles = OrigNumParticles; int32 ParticleIndex = OrigNumParticles - 1; if (bGenerateDeathEvents) { DeathEventGenerator.BeginTrackingDeaths(); } const FVector4* ParticleRelativeTimes = Data.GetVariableData(FNiagaraVariableInfo(BUILTIN_VAR_PARTICLEAGE, ENiagaraDataType::Vector)); if (ParticleRelativeTimes) { while (ParticleIndex >= 0) { if (ParticleRelativeTimes[ParticleIndex].X > 1.0f) { if (bGenerateDeathEvents) { DeathEventGenerator.OnDeath(ParticleIndex); } check(CurNumParticles > ParticleIndex); // Particle is dead, move one from the end here. MoveParticleToIndex(--CurNumParticles, ParticleIndex); } --ParticleIndex; } } Data.SetNumInstances(CurNumParticles); if (bGenerateDeathEvents) { DeathEventGenerator.EndTrackingDeaths(); } // check if the emitter has officially died if (GetTickState() == NTS_Dieing && CurNumParticles == 0) { SetTickState(NTS_Dead); } }
TNiagaraExprPtr FNiagaraCompiler_VectorVM::Expression_VMNative(VectorVM::EOp Op, TArray<TNiagaraExprPtr>& InputExpressions) { static const FName OpName(TEXT("VMOp")); int32 Index = Expressions.Add(MakeShareable(new FNiagaraExpression_VMOperation(this, FNiagaraVariableInfo(OpName, ENiagaraDataType::Vector), InputExpressions, Op))); return Expressions[Index]; }
void FNiagaraSimulation::PreTick() { UNiagaraEmitterProperties* PinnedProps = Props.Get(); if (!PinnedProps || !bIsEnabled || TickState == NTS_Suspended || TickState == NTS_Dead) return; check(Data.GetNumVariables() > 0); check(PinnedProps->SpawnScriptProps.Script); check(PinnedProps->UpdateScriptProps.Script); // 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 OrigNumParticles = Data.GetNumInstances(); int32 CurNumParticles = OrigNumParticles; int32 ParticleIndex = OrigNumParticles-1; if (bGenerateDeathEvents) { DeathEventGenerator.BeginTrackingDeaths(); } const FVector4* ParticleRelativeTimes = Data.GetVariableData(FNiagaraVariableInfo(FName(TEXT("Age")), ENiagaraDataType::Vector)); if (ParticleRelativeTimes) { while (ParticleIndex >= 0) { if (ParticleRelativeTimes[ParticleIndex].X > 1.0f) { if (bGenerateDeathEvents) { DeathEventGenerator.OnDeath(ParticleIndex); } check(CurNumParticles > ParticleIndex); // Particle is dead, move one from the end here. MoveParticleToIndex(--CurNumParticles, ParticleIndex); DebuggerHook_OnDeath(this, ParticleIndex, CurNumParticles); } --ParticleIndex; } } Data.SetNumInstances(CurNumParticles); if (bGenerateDeathEvents) { DeathEventGenerator.EndTrackingDeaths(); } // check if the emitter has officially died if (GetTickState() == NTS_Dieing && CurNumParticles == 0) { SetTickState(NTS_Dead); } } //Swap all data set buffers before doing the main tick on any simulation. for (TPair<FNiagaraDataSetID, FNiagaraDataSet*> SetPair : DataSetMap) { SetPair.Value->Tick(); } }
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()); }