void UNiagaraNodeOutput::Compile(class INiagaraCompiler* Compiler, TArray<FNiagaraNodeResult>& OutputExpressions) { TArray<TNiagaraExprPtr> InputExpressions; for (int32 i = 0; i < Outputs.Num(); ++i) { const FNiagaraVariableInfo& Out = Outputs[i]; UEdGraphPin* Pin = Pins[i]; check(Pin->Direction == EGPD_Input); TNiagaraExprPtr Result = Compiler->CompilePin(Pin); if (!Result.IsValid()) { //The pin was not connected so pass through the initial value of the attribute. Result = Compiler->GetAttribute(Out); } InputExpressions.Add(Result); } check(Outputs.Num() == InputExpressions.Num()); for (int32 i = 0; i < Outputs.Num(); ++i) { OutputExpressions.Add(FNiagaraNodeResult(Compiler->Output(Outputs[i], InputExpressions[i]), Pins[i])); } }
void UNiagaraNodeWriteDataSet::Compile(class INiagaraCompiler* Compiler, TArray<FNiagaraNodeResult>& Outputs) { bool bError = false; if (DataSet.Type == ENiagaraDataSetType::Event) { //Compile the Emit pin. TNiagaraExprPtr EmitExpression = Compiler->CompilePin(Pins[0]); if (EmitExpression.IsValid()) { //Test the Valid pin result against 0. Maybe just require a direct connection of 0 or 0xFFFFFFFF? FNiagaraVariableInfo Zero(TEXT("0.0, 0.0, 0.0, 0.0"), ENiagaraDataType::Vector); TNiagaraExprPtr ZeroContantExpression = Compiler->GetInternalConstant(Zero, FVector4(0.0f, 0.0f, 0.0f, 0.0f)); TArray<TNiagaraExprPtr> ConditonInputs; ConditonInputs.Add(EmitExpression); ConditonInputs.Add(ZeroContantExpression); check(ZeroContantExpression.IsValid()); TArray<TNiagaraExprPtr> ConditionOpOutputs; INiagaraCompiler::GreaterThan(Compiler, ConditonInputs, ConditionOpOutputs); TNiagaraExprPtr ValidExpr = ConditionOpOutputs[0]; TArray<TNiagaraExprPtr> InputExpressions; for (int32 i = 0; i < Variables.Num(); ++i) { const FNiagaraVariableInfo& Var = Variables[i]; UEdGraphPin* Pin = Pins[i + 1];//Pin[0] is emit check(Pin->Direction == EGPD_Input); TNiagaraExprPtr Result = Compiler->CompilePin(Pin); if (!Result.IsValid()) { bError = true; Compiler->Error(FText::Format(LOCTEXT("DataSetWriteErrorFormat", "Error writing variable {0} to dataset {1}"), FText::FromName(DataSet.Name), Pin->PinFriendlyName), this, Pin); } InputExpressions.Add(Result); } //Gets the index to write to. TNiagaraExprPtr IndexExpression = Compiler->AcquireSharedDataIndex(DataSet, true, ValidExpr); if (!bError) { check(Variables.Num() == InputExpressions.Num()); for (int32 i = 0; i < Variables.Num(); ++i) { Outputs.Add(FNiagaraNodeResult(Compiler->SharedDataWrite(DataSet, Variables[i], IndexExpression, InputExpressions[i]), Pins[i + 1]));//Pin[0] is Emit } } } } else { check(false);//IMPLEMENT OTHER DATA SETS. } }
void UNiagaraNodeReadDataSet::Compile(class INiagaraCompiler* Compiler, TArray<FNiagaraNodeResult>& Outputs) { if(DataSet.Type == ENiagaraDataSetType::Event) { TNiagaraExprPtr IndexExpr = Compiler->ConsumeSharedDataIndex(DataSet, true);//Where do we decide wrapping? check(Variables.Num() == Pins.Num() - 1);//We should have a pin for each variable + 1 for the Valid pin. Outputs.Add(FNiagaraNodeResult(Compiler->SharedDataIndexIsValid(DataSet, IndexExpr), Pins[0])); for (int32 i = 0; i < Variables.Num(); ++i) { check(Variables[i].Type == ENiagaraDataType::Vector);//Only support vectors currently. Outputs.Add(FNiagaraNodeResult(Compiler->SharedDataRead(DataSet, Variables[i], IndexExpr), Pins[i+1])); } } else { Compiler->Error(LOCTEXT("UnImplDataSetTypeError", "This data set type hasn't been implemented."), this, nullptr); } }
void UNiagaraNodeOp::Compile(class INiagaraCompiler* Compiler, TArray<FNiagaraNodeResult>& Outputs) { const FNiagaraOpInfo* OpInfo = FNiagaraOpInfo::GetOpInfo(OpName); check(OpInfo); int32 NumInputs = OpInfo->Inputs.Num(); int32 NumOutputs = OpInfo->Outputs.Num(); TArray<TNiagaraExprPtr> Inputs; bool bError = false; for (int32 i = 0; i < NumInputs; ++i) { UEdGraphPin *Pin = Pins[i]; check(Pin->Direction == EGPD_Input); TNiagaraExprPtr InputExpr = Compiler->CompilePin(Pin); if (!InputExpr.IsValid()) { bError = true; FFormatNamedArguments Args; Args.Add(TEXT("OpName"), GetNodeTitle(ENodeTitleType::FullTitle)); FText Format = LOCTEXT("InputErrorFormat", "Error compiling input on {OpName} node."); Compiler->Error(FText::Format(Format, Args), this, Pin); } Inputs.Add(InputExpr); } TArray<TNiagaraExprPtr> OutputExpressions; if ( !bError && OpInfo->OpDelegate.Execute(Compiler, Inputs, OutputExpressions)) { check(OutputExpressions.Num() == OpInfo->Outputs.Num()); for (int32 i = 0; i < NumOutputs; ++i) { UEdGraphPin *Pin = Pins[NumInputs + i]; check(Pin->Direction == EGPD_Output); Outputs.Add(FNiagaraNodeResult(OutputExpressions[i], Pin)); } } else { FFormatNamedArguments Args; Args.Add(TEXT("OpName"), GetNodeTitle(ENodeTitleType::FullTitle)); FText Format = LOCTEXT("NodeErrorFormat", "Error compiling {OpName} node."); Compiler->Error(FText::Format(Format, Args), this, nullptr); } }
void UNiagaraNodeInput::Compile(class INiagaraCompiler* Compiler, TArray<FNiagaraNodeResult>& Outputs) { //Input nodes in scripts being used as functions by other scripts will actually never get this far. //The compiler will find them and replace them with direct links between the pins going in and the nodes connected to the corresponding input. const UEdGraphSchema_Niagara* Schema = CastChecked<UEdGraphSchema_Niagara>(GetSchema()); if (IsConstant()) { if (IsExposedConstant() || Schema->IsSystemConstant(Input)) { //treat this input as an external constant. switch (Input.Type) { case ENiagaraDataType::Scalar: Outputs.Add(FNiagaraNodeResult(Compiler->GetExternalConstant(Input, FloatDefault), Pins[0])); break; case ENiagaraDataType::Vector: Outputs.Add(FNiagaraNodeResult(Compiler->GetExternalConstant(Input, VectorDefault), Pins[0])); break; case ENiagaraDataType::Matrix: Outputs.Add(FNiagaraNodeResult(Compiler->GetExternalConstant(Input, MatrixDefault), Pins[0])); break; case ENiagaraDataType::Curve: Outputs.Add(FNiagaraNodeResult(Compiler->GetExternalConstant(Input, DataObjectDefault), Pins[0])); break; } } else { //treat this input as an internal constant. switch (Input.Type) { case ENiagaraDataType::Scalar: Outputs.Add(FNiagaraNodeResult(Compiler->GetInternalConstant(Input, FloatDefault), Pins[0])); break; case ENiagaraDataType::Vector: Outputs.Add(FNiagaraNodeResult(Compiler->GetInternalConstant(Input, VectorDefault), Pins[0])); break; case ENiagaraDataType::Matrix: Outputs.Add(FNiagaraNodeResult(Compiler->GetInternalConstant(Input, MatrixDefault), Pins[0])); break; case ENiagaraDataType::Curve: Outputs.Add(FNiagaraNodeResult(Compiler->GetInternalConstant(Input, DataObjectDefault), Pins[0])); break;//Internal curve Constant? } } } else { //This input is an attribute. Outputs.Add(FNiagaraNodeResult(Compiler->GetAttribute(Input), Pins[0])); } }