263 lines
7.3 KiB
C++
263 lines
7.3 KiB
C++
// Copyright 2020 Phyronnaz
|
|
|
|
#include "VoxelNodes/VoxelExecNodes.h"
|
|
|
|
#include "VoxelNodes/VoxelNodeColors.h"
|
|
#include "VoxelGraphConstants.h"
|
|
#include "VoxelGraphGenerator.h"
|
|
#include "VoxelGraphErrorReporter.h"
|
|
|
|
int32 UVoxelNode_MaterialSetter::GetOutputIndex() const
|
|
{
|
|
return FVoxelGraphOutputsIndices::MaterialIndex;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UVoxelNode_SetColor::UVoxelNode_SetColor()
|
|
{
|
|
SetInputs(
|
|
EC::Exec,
|
|
{ "Color", EC::Color, "Color" });
|
|
SetOutputs(EC::Exec);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UVoxelNode_SetSingleIndex::UVoxelNode_SetSingleIndex()
|
|
{
|
|
SetInputs(
|
|
EC::Exec,
|
|
{ "Index", EC::Int, "Index between 0 and 255", "", {0, 255} });
|
|
SetOutputs(EC::Exec);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UVoxelNode_SetMultiIndexWetness::UVoxelNode_SetMultiIndexWetness()
|
|
{
|
|
SetInputs(
|
|
EC::Exec,
|
|
{ "Wetness", EC::Float, "Wetness between 0 and 1", "", {0, 1 } });
|
|
SetOutputs(EC::Exec);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UVoxelNode_AddMultiIndex::UVoxelNode_AddMultiIndex()
|
|
{
|
|
SetInputs(
|
|
EC::Exec,
|
|
{ "Index", EC::Int, "Material index between 0 and 255", "", {0, 255 } },
|
|
{ "Strength", EC::Float, "Strength, usually between 0 and 1", "1" },
|
|
{ "Lock Strength", EC::Boolean, "If true, the strength won't be normalized. For example, if you want small rocks with the same density everywhere." });
|
|
SetOutputs(EC::Exec);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UVoxelNode_SetUVs::UVoxelNode_SetUVs()
|
|
{
|
|
SetInputs(
|
|
EC::Exec,
|
|
{ "Channel", EC::Int, "Channel, should be 0 or 1", "", {0, 255 } },
|
|
{ "U", EC::Float, "U coordinate between 0 and 1", "", {0, 1} },
|
|
{ "V", EC::Float, "V coordinate between 0 and 1", "", {0, 1} });
|
|
SetOutputs(EC::Exec);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UVoxelNode_SetNode::UVoxelNode_SetNode()
|
|
{
|
|
SetInputs(EC::Exec, EC::Exec);
|
|
SetOutputs(EC::Exec);
|
|
}
|
|
|
|
|
|
FText UVoxelNode_SetNode::GetTitle() const
|
|
{
|
|
return FText::FromString("Set " + CachedOutput.Name.ToString());
|
|
}
|
|
|
|
EVoxelPinCategory UVoxelNode_SetNode::GetInputPinCategory(int32 PinIndex) const
|
|
{
|
|
return PinIndex == 0
|
|
? EVoxelPinCategory::Exec
|
|
: FVoxelPinCategory::DataPinToPin(CachedOutput.Category);
|
|
}
|
|
|
|
FName UVoxelNode_SetNode::GetInputPinName(int32 PinIndex) const
|
|
{
|
|
return PinIndex == 0 ? FName() : CachedOutput.Name;
|
|
}
|
|
|
|
void UVoxelNode_SetNode::LogErrors(FVoxelGraphErrorReporter& ErrorReporter)
|
|
{
|
|
Super::LogErrors(ErrorReporter);
|
|
|
|
#if WITH_EDITOR
|
|
if (!UpdateSetterNode())
|
|
{
|
|
ErrorReporter.AddMessageToNode(this, "invalid output", EVoxelGraphNodeMessageType::Error);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
int32 UVoxelNode_SetNode::GetOutputIndex() const
|
|
{
|
|
return Index;
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
bool UVoxelNode_SetNode::UpdateSetterNode()
|
|
{
|
|
if (Graph)
|
|
{
|
|
auto Outputs = Graph->GetOutputs();
|
|
FVoxelGraphOutput NewOutput;
|
|
if (Outputs.Contains(Index) && !FVoxelGraphOutputsUtils::IsVoxelGraphOutputHidden(Index))
|
|
{
|
|
NewOutput = Outputs[Index];
|
|
}
|
|
if (CachedOutput.GUID.IsValid() && NewOutput.GUID != CachedOutput.GUID)
|
|
{
|
|
// Try to find it by GUID and name
|
|
TArray<FVoxelGraphOutput> OutputsArray;
|
|
Outputs.GenerateValueArray(OutputsArray);
|
|
auto* NewOutputPtr = OutputsArray.FindByPredicate([&](auto& Output) {return Output.GUID == CachedOutput.GUID; });
|
|
if (!NewOutputPtr)
|
|
{
|
|
NewOutputPtr = OutputsArray.FindByPredicate([&](auto& Output) {return Output.Name == CachedOutput.Name; });
|
|
}
|
|
if (NewOutputPtr)
|
|
{
|
|
NewOutput = *NewOutputPtr;
|
|
Index = NewOutputPtr->Index;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
const bool bDiffCategory = CachedOutput.Category != NewOutput.Category;
|
|
const bool bDiffName = CachedOutput.Name != NewOutput.Name;
|
|
if (GraphNode && (bDiffCategory || bDiffName))
|
|
{
|
|
CachedOutput = NewOutput;
|
|
GraphNode->ReconstructNode();
|
|
if (bDiffCategory)
|
|
{
|
|
Graph->CompileVoxelNodesFromGraphNodes();
|
|
}
|
|
}
|
|
}
|
|
return CachedOutput.GUID.IsValid();
|
|
}
|
|
|
|
void UVoxelNode_SetNode::SetIndex(uint32 NewIndex)
|
|
{
|
|
Index = NewIndex;
|
|
UpdateSetterNode();
|
|
}
|
|
|
|
void UVoxelNode_SetNode::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
{
|
|
Super::PostEditChangeProperty(PropertyChangedEvent);
|
|
|
|
if (PropertyChangedEvent.Property && PropertyChangedEvent.ChangeType != EPropertyChangeType::Interactive)
|
|
{
|
|
UpdateSetterNode();
|
|
}
|
|
}
|
|
|
|
void UVoxelNode_SetNode::PostLoad()
|
|
{
|
|
Super::PostLoad();
|
|
UpdateSetterNode();
|
|
}
|
|
#endif
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UVoxelNode_FunctionSeparator::UVoxelNode_FunctionSeparator()
|
|
{
|
|
SetColor(FVoxelNodeColors::ExecNode);
|
|
AddInput("", "", EC::Exec);
|
|
AddOutput("", "", EC::Exec);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
FLinearColor UVoxelNode_FlowMerge::GetColor() const
|
|
{
|
|
return FColor::White;
|
|
}
|
|
|
|
EVoxelPinCategory UVoxelNode_FlowMerge::GetInputPinCategory(int32 PinIndex) const
|
|
{
|
|
PinIndex = PinIndex % (Types.Num() + 1);
|
|
return PinIndex == 0 ? EVoxelPinCategory::Exec : FVoxelPinCategory::DataPinToPin(Types[PinIndex - 1].Type);
|
|
}
|
|
|
|
EVoxelPinCategory UVoxelNode_FlowMerge::GetOutputPinCategory(int32 PinIndex) const
|
|
{
|
|
return PinIndex == 0 ? EVoxelPinCategory::Exec : FVoxelPinCategory::DataPinToPin(Types[PinIndex - 1].Type);
|
|
}
|
|
|
|
FName UVoxelNode_FlowMerge::GetInputPinName(int32 PinIndex) const
|
|
{
|
|
const bool bIsA = PinIndex <= Types.Num();
|
|
PinIndex = PinIndex % (Types.Num() + 1);
|
|
if (PinIndex == 0)
|
|
{
|
|
return bIsA ? FName("Exec A") : FName("Exec B");
|
|
}
|
|
else
|
|
{
|
|
return FName(*(Types[PinIndex - 1].Name + (bIsA ? " A" : " B")));
|
|
}
|
|
}
|
|
|
|
FName UVoxelNode_FlowMerge::GetOutputPinName(int32 PinIndex) const
|
|
{
|
|
return PinIndex == 0 ? FName("Exec") : FName(*Types[PinIndex - 1].Name);
|
|
}
|
|
|
|
int32 UVoxelNode_FlowMerge::GetMinInputPins() const
|
|
{
|
|
return 2 + 2 * Types.Num();
|
|
}
|
|
|
|
int32 UVoxelNode_FlowMerge::GetMaxInputPins() const
|
|
{
|
|
return GetMinInputPins();
|
|
}
|
|
|
|
int32 UVoxelNode_FlowMerge::GetOutputPinsCount() const
|
|
{
|
|
return 1 + Types.Num();
|
|
}
|
|
|