Files
UnrealEngineUWP/Engine/Source/Developer/RigVMDeveloper/Private/RigVMModel/Nodes/RigVMUnitNode.cpp
Helge Mathee 9c189267d5 ControlRig: user defined events and event invocation
#rb sara.schvartzman
#jira UE-153498 UE-153499
#preflight https://horde.devtools.epicgames.com/job/62975ffb2c618ddc66bb49a4

[CL 20453170 by Helge Mathee in ue5-main branch]
2022-06-01 11:28:01 -04:00

404 lines
10 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "RigVMModel/Nodes/RigVMUnitNode.h"
#include "Animation/Rig.h"
#include "RigVMCore/RigVMStruct.h"
#include "RigVMModel/RigVMControllerActions.h"
#include "RigVMUserWorkflowRegistry.h"
void URigVMUnitNode::PostLoad()
{
Super::PostLoad();
// if we have a script struct but no notation let's figure out the template
if(GetScriptStruct() != nullptr && GetTemplate() == nullptr)
{
if(const FRigVMFunction* Function = FRigVMRegistry::Get().FindFunction(GetScriptStruct(), *GetMethodName().ToString()))
{
if(Function->TemplateIndex != INDEX_NONE)
{
const FRigVMTemplate& Template = FRigVMRegistry::Get().GetTemplates()[Function->TemplateIndex];
TemplateNotation = Template.GetNotation();
}
ResolvedFunctionName = Function->GetName();
}
}
}
FString URigVMUnitNode::GetNodeTitle() const
{
if (UScriptStruct* Struct = GetScriptStruct())
{
return Struct->GetDisplayNameText().ToString();
}
return Super::GetNodeTitle();
}
FText URigVMUnitNode::GetToolTipText() const
{
if (UScriptStruct* Struct = GetScriptStruct())
{
return Struct->GetToolTipText();
}
return URigVMNode::GetToolTipText();
}
bool URigVMUnitNode::IsDefinedAsConstant() const
{
if (UScriptStruct* Struct = GetScriptStruct())
{
return Struct->HasMetaData(FRigVMStruct::ConstantMetaName);
}
return false;
}
bool URigVMUnitNode::IsDefinedAsVarying() const
{
if (UScriptStruct* Struct = GetScriptStruct())
{
return Struct->HasMetaData(FRigVMStruct::VaryingMetaName);
}
return false;
}
FName URigVMUnitNode::GetEventName() const
{
TSharedPtr<FStructOnScope> StructOnScope = ConstructStructInstance(false);
if (StructOnScope.IsValid())
{
const FRigVMStruct* StructMemory = (FRigVMStruct*)StructOnScope->GetStructMemory();
return StructMemory->GetEventName();
}
return Super::GetEventName();
}
bool URigVMUnitNode::CanOnlyExistOnce() const
{
TSharedPtr<FStructOnScope> StructOnScope = ConstructStructInstance(false);
if (StructOnScope.IsValid())
{
const FRigVMStruct* StructMemory = (FRigVMStruct*)StructOnScope->GetStructMemory();
return StructMemory->CanOnlyExistOnce();
}
return Super::CanOnlyExistOnce();
}
FText URigVMUnitNode::GetToolTipTextForPin(const URigVMPin* InPin) const
{
if(UScriptStruct* Struct = GetScriptStruct())
{
TArray<FString> Parts;
URigVMPin::SplitPinPath(InPin->GetPinPath(), Parts);
for (int32 PartIndex = 1; PartIndex < Parts.Num(); PartIndex++)
{
FProperty* Property = Struct->FindPropertyByName(*Parts[PartIndex]);
if (!Property)
{
break;
}
if (FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property))
{
if (PartIndex < Parts.Num() - 1)
{
Property = ArrayProperty->Inner;
PartIndex++;
}
}
if (PartIndex == Parts.Num() - 1)
{
return Property->GetToolTipText();
}
if (FStructProperty* StructProperty = CastField<FStructProperty>(Property))
{
Struct = StructProperty->Struct;
}
}
}
return URigVMNode::GetToolTipTextForPin(InPin);
}
bool URigVMUnitNode::IsDeprecated() const
{
return !GetDeprecatedMetadata().IsEmpty();
}
FString URigVMUnitNode::GetDeprecatedMetadata() const
{
if (UScriptStruct* Struct = GetScriptStruct())
{
FString DeprecatedMetadata;
if(Struct->GetStringMetaDataHierarchical(FRigVMStruct::DeprecatedMetaName, &DeprecatedMetadata))
{
return DeprecatedMetadata;
}
}
return FString();
}
TArray<FRigVMUserWorkflow> URigVMUnitNode::GetSupportedWorkflows(ERigVMUserWorkflowType InType, const UObject* InSubject) const
{
TArray<FRigVMUserWorkflow> Workflows = Super::GetSupportedWorkflows(InType, InSubject);
if(InSubject == nullptr)
{
InSubject = this;
}
if(UScriptStruct* Struct = GetScriptStruct())
{
check(Struct->IsChildOf(FRigVMStruct::StaticStruct()));
const TSharedPtr<FStructOnScope> StructOnScope = ConstructStructInstance();
const FRigVMStruct* StructMemory = (const FRigVMStruct*)StructOnScope->GetStructMemory();
TArray<FRigVMUserWorkflow> StructWorkflows = StructMemory->GetWorkflows(InType, InSubject);
StructWorkflows.Append(URigVMUserWorkflowRegistry::Get()->GetWorkflows(InType, Struct, InSubject));
Swap(Workflows, StructWorkflows);
Workflows.Append(StructWorkflows);
}
return Workflows;
}
bool URigVMUnitNode::IsAggregate() const
{
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
const TArray<URigVMPin*> AggregateInputs = GetAggregateInputs();
const TArray<URigVMPin*> AggregateOutputs = GetAggregateOutputs();
if ((AggregateInputs.Num() == 2 && AggregateOutputs.Num() == 1) ||
(AggregateInputs.Num() == 1 && AggregateOutputs.Num() == 2))
{
TArray<URigVMPin*> AggregateAll = AggregateInputs;
AggregateAll.Append(AggregateOutputs);
for (int32 i = 1; i < 3; ++i)
{
if (AggregateAll[0]->GetCPPType() != AggregateAll[i]->GetCPPType() ||
AggregateAll[0]->GetCPPTypeObject() != AggregateAll[i]->GetCPPTypeObject())
{
return false;
}
}
return true;
}
#endif
return false;
}
URigVMPin* URigVMUnitNode::GetFirstAggregatePin() const
{
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
const TArray<URigVMPin*> Inputs = GetAggregateInputs();
const TArray<URigVMPin*> Outputs = GetAggregateOutputs();
if (Inputs.Num() == 2 && Outputs.Num() == 1)
{
return Inputs[0];
}
if (Inputs.Num() == 1 && Outputs.Num() == 2)
{
return Outputs[0];
}
#endif
return nullptr;
}
URigVMPin* URigVMUnitNode::GetSecondAggregatePin() const
{
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
const TArray<URigVMPin*> Inputs = GetAggregateInputs();
const TArray<URigVMPin*> Outputs = GetAggregateOutputs();
if (Inputs.Num() == 2 && Outputs.Num() == 1)
{
return Inputs[1];
}
if (Inputs.Num() == 1 && Outputs.Num() == 2)
{
return Outputs[1];
}
#endif
return nullptr;
}
URigVMPin* URigVMUnitNode::GetOppositeAggregatePin() const
{
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
const TArray<URigVMPin*> Inputs = GetAggregateInputs();
const TArray<URigVMPin*> Outputs = GetAggregateOutputs();
if (Inputs.Num() == 2 && Outputs.Num() == 1)
{
return Outputs[0];
}
if (Inputs.Num() == 1 && Outputs.Num() == 2)
{
return Inputs[0];
}
#endif
return nullptr;
}
bool URigVMUnitNode::IsInputAggregate() const
{
return GetAggregateInputs().Num() == 2;
}
TArray<URigVMPin*> URigVMUnitNode::GetAggregateInputs() const
{
TArray<URigVMPin*> AggregateInputs;
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
if (const UScriptStruct* Struct = GetScriptStruct())
{
for (URigVMPin* Pin : GetPins())
{
if (Pin->GetDirection() == ERigVMPinDirection::Input)
{
if (const FProperty* Property = Struct->FindPropertyByName(Pin->GetFName()))
{
if (Property->HasMetaData(FRigVMStruct::AggregateMetaName))
{
AggregateInputs.Add(Pin);
}
}
}
}
}
#endif
return AggregateInputs;
}
TArray<URigVMPin*> URigVMUnitNode::GetAggregateOutputs() const
{
TArray<URigVMPin*> AggregateOutputs;
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
if (const UScriptStruct* Struct = GetScriptStruct())
{
for (URigVMPin* Pin : GetPins())
{
if (Pin->GetDirection() == ERigVMPinDirection::Output)
{
if (const FProperty* Property = Struct->FindPropertyByName(Pin->GetFName()))
{
if (Property->HasMetaData(FRigVMStruct::AggregateMetaName))
{
AggregateOutputs.Add(Pin);
}
}
}
}
}
#endif
return AggregateOutputs;
}
FName URigVMUnitNode::GetNextAggregateName(const FName& InLastAggregatePinName) const
{
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
if(const UScriptStruct* Struct = GetScriptStruct())
{
check(Struct->IsChildOf(FRigVMStruct::StaticStruct()));
const TSharedPtr<FStructOnScope> StructOnScope = ConstructStructInstance();
const FRigVMStruct* StructMemory = (const FRigVMStruct*)StructOnScope->GetStructMemory();
return StructMemory->GetNextAggregateName(InLastAggregatePinName);
}
#endif
return FName();
}
UScriptStruct* URigVMUnitNode::GetScriptStruct() const
{
if(UScriptStruct* ResolvedStruct = Super::GetScriptStruct())
{
return ResolvedStruct;
}
return ScriptStruct_DEPRECATED;
}
bool URigVMUnitNode::IsLoopNode() const
{
const TSharedPtr<FStructOnScope> StructOnScope = ConstructStructInstance(true);
if (StructOnScope.IsValid())
{
const FRigVMStruct* StructMemory = (FRigVMStruct*)StructOnScope->GetStructMemory();
return StructMemory->IsForLoop();
}
return false;
}
FName URigVMUnitNode::GetMethodName() const
{
const FName ResolvedMethodName = Super::GetMethodName();
if(!ResolvedMethodName.IsNone())
{
return ResolvedMethodName;
}
return MethodName_DEPRECATED;
}
FString URigVMUnitNode::GetStructDefaultValue() const
{
TArray<FString> PinDefaultValues;
for (URigVMPin* Pin : GetPins())
{
if (Pin->GetDirection() == ERigVMPinDirection::Hidden)
{
continue;
}
FString PinDefaultValue = Pin->GetDefaultValue();
if (Pin->IsStringType())
{
PinDefaultValue = TEXT("\"") + PinDefaultValue + TEXT("\"");
}
else if (PinDefaultValue.IsEmpty() || PinDefaultValue == TEXT("()"))
{
continue;
}
PinDefaultValues.Add(FString::Printf(TEXT("%s=%s"), *Pin->GetName(), *PinDefaultValue));
}
if (PinDefaultValues.Num() == 0)
{
return TEXT("()");
}
return FString::Printf(TEXT("(%s)"), *FString::Join(PinDefaultValues, TEXT(",")));
}
TSharedPtr<FStructOnScope> URigVMUnitNode::ConstructStructInstance(bool bUseDefault) const
{
if (UScriptStruct* Struct = GetScriptStruct())
{
TSharedPtr<FStructOnScope> StructOnScope = MakeShareable(new FStructOnScope(Struct));
FRigVMStruct* StructMemory = (FRigVMStruct*)StructOnScope->GetStructMemory();
if (bUseDefault)
{
Struct->InitializeDefaultValue((uint8*)StructMemory);
}
else
{
FString StructDefaultValue = GetStructDefaultValue();
Struct->ImportText(*StructDefaultValue, StructMemory, nullptr, PPF_IncludeTransient, GLog, Struct->GetName());
}
return StructOnScope;
}
return nullptr;
}
FRigVMStructUpgradeInfo URigVMUnitNode::GetUpgradeInfo() const
{
if(UScriptStruct* Struct = GetScriptStruct())
{
check(Struct->IsChildOf(FRigVMStruct::StaticStruct()));
const TSharedPtr<FStructOnScope> StructOnScope = ConstructStructInstance();
const FRigVMStruct* StructMemory = (const FRigVMStruct*)StructOnScope->GetStructMemory();
return StructMemory->GetUpgradeInfo();
}
return FRigVMStructUpgradeInfo();
}