2019-12-27 09:26:59 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-01-08 11:38:48 -05:00
# include "ControlRigBlueprint.h"
2021-03-25 16:51:36 -04:00
2023-01-10 09:05:18 -05:00
# include "RigVMBlueprintGeneratedClass.h"
2019-01-08 11:38:48 -05:00
# include "EdGraph/EdGraph.h"
2019-05-31 18:25:32 -04:00
# include "EdGraphNode_Comment.h"
2019-01-08 11:38:48 -05:00
# include "Engine/SkeletalMesh.h"
# include "BlueprintActionDatabaseRegistrar.h"
2023-10-30 08:25:55 -04:00
# include "ControlRig.h"
2019-05-21 19:25:23 -04:00
# include "Graph/ControlRigGraph.h"
2020-12-14 08:58:12 -04:00
# include "Graph/ControlRigGraphSchema.h"
2021-03-25 16:51:36 -04:00
# include "UObject/ObjectSaveContext.h"
2019-09-17 19:12:19 -04:00
# include "UObject/UObjectGlobals.h"
2020-01-22 17:58:55 -05:00
# include "ControlRigObjectVersion.h"
# include "BlueprintCompilationManager.h"
2023-10-26 06:52:34 -04:00
# include "ModularRig.h"
2023-11-29 03:23:17 -05:00
# include "ModularRigController.h"
2020-01-22 17:58:55 -05:00
# include "RigVMCompiler/RigVMCompiler.h"
# include "RigVMCore/RigVMRegistry.h"
# include "Units/Execution/RigUnit_BeginExecution.h"
2020-09-24 00:43:27 -04:00
# include "Units/Hierarchy/RigUnit_SetBoneTransform.h"
2022-05-02 18:59:38 -04:00
# include "AssetRegistry/AssetRegistryModule.h"
2021-07-19 06:35:29 -04:00
# include "RigVMPythonUtils.h"
2021-11-18 08:00:07 -05:00
# include "RigVMTypeUtils.h"
2022-03-30 05:21:45 -04:00
# include "RigVMModel/Nodes/RigVMAggregateNode.h"
2022-04-05 10:42:37 -04:00
# include "Rigs/RigControlHierarchy.h"
2023-06-19 11:25:29 -04:00
# include "Settings/ControlRigSettings.h"
2023-09-28 05:01:38 -04:00
# include "Units/ControlRigNodeWorkflow.h"
2023-09-19 03:38:24 -04:00
# include "Units/Execution/RigUnit_PrepareForExecution.h"
# include "Units/Execution/RigUnit_DynamicHierarchy.h"
2019-01-08 11:38:48 -05:00
2022-09-28 01:06:15 -04:00
# include UE_INLINE_GENERATED_CPP_BY_NAME(ControlRigBlueprint)
2019-01-08 11:38:48 -05:00
# if WITH_EDITOR
# include "IControlRigEditorModule.h"
2021-10-25 20:05:28 -04:00
# include "Kismet2/WatchedPin.h"
2019-05-21 19:25:23 -04:00
# include "Kismet2/BlueprintEditorUtils.h"
2020-08-11 01:36:57 -04:00
# include "Editor/UnrealEdEngine.h"
2022-08-09 12:54:53 -04:00
# include "Editor/Transactor.h"
2020-08-11 01:36:57 -04:00
# include "CookOnTheSide/CookOnTheFlyServer.h"
2023-09-19 03:38:24 -04:00
# include "ScopedTransaction.h"
2024-02-06 07:45:44 -05:00
# include "Algo/Count.h"
2019-01-08 11:38:48 -05:00
# endif //WITH_EDITOR
# define LOCTEXT_NAMESPACE "ControlRigBlueprint"
2020-01-22 17:58:55 -05:00
TArray < UControlRigBlueprint * > UControlRigBlueprint : : sCurrentlyOpenedRigBlueprints ;
2023-08-01 11:54:10 -04:00
# if WITH_EDITOR
const FName UControlRigBlueprint : : ControlRigPanelNodeFactoryName ( TEXT ( " FControlRigGraphPanelPinFactory " ) ) ;
# endif
2020-01-22 17:58:55 -05:00
UControlRigBlueprint : : UControlRigBlueprint ( const FObjectInitializer & ObjectInitializer )
2023-06-15 11:30:29 -04:00
: URigVMBlueprint ( ObjectInitializer )
2019-01-08 11:38:48 -05:00
{
2019-09-17 19:12:19 -04:00
# if WITH_EDITORONLY_DATA
2021-10-20 11:56:18 -04:00
GizmoLibrary_DEPRECATED = nullptr ;
ShapeLibraries . Add ( UControlRigSettings : : Get ( ) - > DefaultShapeLibrary ) ;
2019-09-17 19:12:19 -04:00
# endif
2020-01-22 17:58:55 -05:00
2020-09-24 00:43:27 -04:00
Validator = ObjectInitializer . CreateDefaultSubobject < UControlRigValidator > ( this , TEXT ( " ControlRigValidator " ) ) ;
2021-05-19 09:16:54 -04:00
DebugBoneRadius = 1.f ;
2023-03-08 12:32:42 -05:00
2020-09-24 00:43:27 -04:00
bExposesAnimatableControls = false ;
2021-01-19 07:26:41 -04:00
2021-02-22 13:36:33 -04:00
Hierarchy = CreateDefaultSubobject < URigHierarchy > ( TEXT ( " Hierarchy " ) ) ;
2021-09-17 11:26:26 -04:00
URigHierarchyController * Controller = Hierarchy - > GetController ( true ) ;
2021-06-21 08:03:43 -04:00
// give BP a chance to propagate hierarchy changes to available control rig instances
2021-09-17 11:26:26 -04:00
Controller - > OnModified ( ) . AddUObject ( this , & UControlRigBlueprint : : HandleHierarchyModified ) ;
2023-06-15 11:30:29 -04:00
if ( GetClass ( ) = = UControlRigBlueprint : : StaticClass ( ) )
{
CommonInitialization ( ObjectInitializer ) ;
}
2023-10-26 06:52:34 -04:00
ModularRigModel . SetOuterClientHost ( this ) ;
UModularRigController * ModularController = ModularRigModel . GetController ( ) ;
ModularController - > OnModified ( ) . AddUObject ( this , & UControlRigBlueprint : : HandleRigModulesModified ) ;
2019-05-21 19:25:23 -04:00
}
2021-04-15 14:30:33 -04:00
UControlRigBlueprint : : UControlRigBlueprint ( )
{
2024-02-12 09:26:20 -05:00
ModulesRecompilationBracket = 0 ;
2021-04-15 14:30:33 -04:00
}
2021-04-01 14:29:05 -04:00
UClass * UControlRigBlueprint : : RegenerateClass ( UClass * ClassToRegenerate , UObject * PreviousCDO )
{
2023-06-15 11:30:29 -04:00
UClass * Result = Super : : RegenerateClass ( ClassToRegenerate , PreviousCDO ) ;
2022-02-18 10:27:44 -05:00
Hierarchy - > CleanupInvalidCaches ( ) ;
2021-04-01 14:29:05 -04:00
PropagateHierarchyFromBPToInstances ( ) ;
return Result ;
}
2023-03-07 07:37:27 -05:00
bool UControlRigBlueprint : : RequiresForceLoadMembers ( UObject * InObject ) const
{
2023-03-09 11:16:16 -05:00
// old assets don't support preload filtering
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : RemoveParameters )
{
return UBlueprint : : RequiresForceLoadMembers ( InObject ) ;
}
2023-06-15 11:30:29 -04:00
return Super : : RequiresForceLoadMembers ( InObject ) ;
2023-03-07 07:37:27 -05:00
}
2023-09-21 08:46:06 -04:00
void UControlRigBlueprint : : PostEditChangeProperty ( FPropertyChangedEvent & PropertyChangedEvent )
{
Super : : PostEditChangeProperty ( PropertyChangedEvent ) ;
// if this is any of our external variables we need to request construction so that the rig rebuilds itself
if ( NewVariables . ContainsByPredicate ( [ & PropertyChangedEvent ] ( const FBPVariableDescription & Variable )
{
return Variable . VarName = = PropertyChangedEvent . GetMemberPropertyName ( ) ;
} ) )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * DebuggedControlRig = Cast < UControlRig > ( GetObjectBeingDebugged ( ) ) )
2023-09-21 08:46:06 -04:00
{
if ( const FProperty * PropertyOnRig = DebuggedControlRig - > GetClass ( ) - > FindPropertyByName ( PropertyChangedEvent . MemberProperty - > GetFName ( ) ) )
{
if ( PropertyOnRig - > SameType ( PropertyChangedEvent . MemberProperty ) )
{
2023-10-30 07:01:53 -04:00
UControlRig * CDO = DebuggedControlRig - > GetClass ( ) - > GetDefaultObject < UControlRig > ( ) ;
2023-09-21 08:46:06 -04:00
const uint8 * SourceMemory = PropertyOnRig - > ContainerPtrToValuePtr < uint8 > ( CDO ) ;
uint8 * TargetMemory = PropertyOnRig - > ContainerPtrToValuePtr < uint8 > ( DebuggedControlRig ) ;
PropertyOnRig - > CopyCompleteValue ( TargetMemory , SourceMemory ) ;
}
}
DebuggedControlRig - > RequestConstruction ( ) ;
}
}
}
2021-02-22 13:36:33 -04:00
void UControlRigBlueprint : : PostEditChangeChainProperty ( FPropertyChangedChainEvent & PropertyChangedEvent )
{
Super : : PostEditChangeChainProperty ( PropertyChangedEvent ) ;
2023-04-28 16:03:46 -04:00
// Propagate shape libraries
if ( PropertyChangedEvent . Property & & PropertyChangedEvent . Property - > GetFName ( ) = = GET_MEMBER_NAME_CHECKED ( UControlRigBlueprint , ShapeLibraries ) )
{
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( false /* create if needed */ ) ) ;
2023-04-28 16:03:46 -04:00
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
ArchetypeInstances . Add ( CDO ) ;
// Propagate libraries to archetypes
for ( UObject * Instance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * InstanceRig = Cast < UControlRig > ( Instance ) )
2023-04-28 16:03:46 -04:00
{
InstanceRig - > ShapeLibraries = ShapeLibraries ;
}
}
}
2021-02-22 13:36:33 -04:00
}
2023-10-30 08:39:38 -04:00
UClass * UControlRigBlueprint : : GetControlRigClass ( ) const
2023-06-21 05:12:44 -04:00
{
return GetRigVMHostClass ( ) ;
}
2023-10-30 08:39:38 -04:00
bool UControlRigBlueprint : : IsModularRig ( ) const
{
if ( const UClass * Class = GetControlRigClass ( ) )
{
return Class - > IsChildOf ( UModularRig : : StaticClass ( ) ) ;
}
return false ;
}
2019-01-08 11:38:48 -05:00
USkeletalMesh * UControlRigBlueprint : : GetPreviewMesh ( ) const
{
2019-07-16 11:49:59 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2021-08-10 14:19:17 -04:00
# if WITH_EDITORONLY_DATA
2019-01-08 11:38:48 -05:00
if ( ! PreviewSkeletalMesh . IsValid ( ) )
{
2023-06-15 11:30:29 -04:00
( void ) PreviewSkeletalMesh . LoadSynchronous ( ) ;
2019-01-08 11:38:48 -05:00
}
return PreviewSkeletalMesh . Get ( ) ;
2021-08-10 14:19:17 -04:00
# else
return nullptr ;
# endif
2019-01-08 11:38:48 -05:00
}
2023-08-11 10:34:25 -04:00
bool UControlRigBlueprint : : IsControlRigModule ( ) const
{
2023-09-19 03:38:24 -04:00
return RigModuleSettings . Identifier . IsValid ( ) ;
}
# if WITH_EDITORONLY_DATA
bool UControlRigBlueprint : : CanTurnIntoControlRigModule ( bool InAutoConvertHierarchy , FString * OutErrorMessage ) const
{
if ( IsControlRigModule ( ) )
{
if ( OutErrorMessage )
{
static const FString Message = TEXT ( " This asset is already a Control Rig Module. " ) ;
* OutErrorMessage = Message ;
}
return false ;
}
2023-10-26 06:52:34 -04:00
if ( GetRigVMHostClass ( ) - > IsChildOf < UModularRig > ( ) )
{
if ( OutErrorMessage )
{
static const FString Message = TEXT ( " This asset is a Modular Rig. " ) ;
* OutErrorMessage = Message ;
}
return false ;
}
2023-09-19 03:38:24 -04:00
if ( Hierarchy = = nullptr )
{
if ( OutErrorMessage )
{
static const FString Message = TEXT ( " This asset contains no hierarchy. " ) ;
* OutErrorMessage = Message ;
}
return false ;
}
const TArray < FRigElementKey > Keys = Hierarchy - > GetAllKeys ( true ) ;
for ( const FRigElementKey & Key : Keys )
{
if ( ! InAutoConvertHierarchy )
{
if ( Key . Type ! = ERigElementType : : Bone & &
Key . Type ! = ERigElementType : : Curve & &
Key . Type ! = ERigElementType : : Connector )
{
if ( OutErrorMessage )
{
static constexpr TCHAR Format [ ] = TEXT ( " The hierarchy contains elements other than bones (for example '%s'). Modules only allow imported bones and user authored connectors. " ) ;
* OutErrorMessage = FString : : Printf ( Format , * Key . ToString ( ) ) ;
}
return false ;
}
if ( Key . Type = = ERigElementType : : Bone )
{
if ( Hierarchy - > FindChecked < FRigBoneElement > ( Key ) - > BoneType ! = ERigBoneType : : Imported )
{
if ( OutErrorMessage )
{
static constexpr TCHAR Format [ ] = TEXT ( " The hierarchy contains a user defined bone ('%s') - only imported bones are allowed. " ) ;
* OutErrorMessage = FString : : Printf ( Format , * Key . ToString ( ) ) ;
}
return false ;
}
}
}
}
return true ;
}
bool UControlRigBlueprint : : TurnIntoControlRigModule ( bool InAutoConvertHierarchy , FString * OutErrorMessage )
{
if ( ! CanTurnIntoControlRigModule ( InAutoConvertHierarchy , OutErrorMessage ) )
{
return false ;
}
FScopedTransaction Transaction ( LOCTEXT ( " TurnIntoControlRigModule " , " Turn Rig into Module " ) ) ;
Modify ( ) ;
RigModuleSettings . Identifier = FRigModuleIdentifier ( ) ;
RigModuleSettings . Identifier . Name = GetName ( ) ;
2023-08-11 10:34:25 -04:00
if ( Hierarchy )
{
2023-09-19 03:38:24 -04:00
URigHierarchyController * Controller = Hierarchy - > GetController ( true ) ;
// create a copy of this hierarchy
URigHierarchy * CopyOfHierarchy = NewObject < URigHierarchy > ( GetTransientPackage ( ) ) ;
CopyOfHierarchy - > CopyHierarchy ( Hierarchy ) ;
// also create a hierarchy based on the preview mesh
URigHierarchy * PreviewMeshHierarchy = NewObject < URigHierarchy > ( GetTransientPackage ( ) ) ;
if ( PreviewSkeletalMesh )
{
PreviewMeshHierarchy - > GetController ( true ) - > ImportBones ( PreviewSkeletalMesh - > GetSkeleton ( ) ) ;
}
// disable compilation
{
FRigVMBlueprintCompileScope CompileScope ( this ) ;
// remove everything from the hierarchy
Hierarchy - > Reset ( ) ;
const TArray < FRigElementKey > AllKeys = CopyOfHierarchy - > GetAllKeys ( true ) ;
TArray < FRigElementKey > KeysToSpawn ;
for ( const FRigElementKey & Key : AllKeys )
{
if ( Key . Type = = ERigElementType : : Curve )
{
continue ;
}
if ( Key . Type = = ERigElementType : : Bone )
{
if ( PreviewMeshHierarchy - > Contains ( Key ) )
{
continue ;
}
}
KeysToSpawn . Add ( Key ) ;
}
( void ) ConvertHierarchyElementsToSpawnerNodes ( CopyOfHierarchy , KeysToSpawn , false ) ;
if ( Hierarchy - > Num ( ERigElementType : : Connector ) = = 0 )
{
static const FName RootName = TEXT ( " Root " ) ;
2023-12-04 05:02:39 -05:00
static const FString RootDescription = TEXT ( " This is the default temporary socket used for the root connection. " ) ;
const FRigElementKey ConnectorKey = Controller - > AddConnector ( RootName ) ;
const FRigElementKey SocketKey = Controller - > AddSocket ( RootName , FRigElementKey ( ) , FTransform : : Identity , false , FRigSocketElement : : SocketDefaultColor , RootDescription , false ) ;
( void ) ResolveConnector ( ConnectorKey , SocketKey ) ;
2023-09-19 03:38:24 -04:00
}
}
2023-08-11 10:34:25 -04:00
}
2023-09-19 03:38:24 -04:00
OnRigTypeChangedDelegate . Broadcast ( this ) ;
return true ;
}
bool UControlRigBlueprint : : CanTurnIntoStandaloneRig ( FString * OutErrorMessage ) const
{
return IsControlRigModule ( ) ;
}
bool UControlRigBlueprint : : TurnIntoStandaloneRig ( FString * OutErrorMessage )
{
if ( ! CanTurnIntoStandaloneRig ( OutErrorMessage ) )
{
return false ;
}
FScopedTransaction Transaction ( LOCTEXT ( " TurnIntoControlRigModule " , " Turn Rig into Module " ) ) ;
Modify ( ) ;
RigModuleSettings = FRigModuleSettings ( ) ;
if ( Hierarchy )
{
Hierarchy - > Modify ( ) ;
Hierarchy - > Reset ( ) ;
if ( PreviewSkeletalMesh )
{
Hierarchy - > GetController ( true ) - > ImportBones ( PreviewSkeletalMesh - > GetSkeleton ( ) ) ;
}
}
OnRigTypeChangedDelegate . Broadcast ( this ) ;
return true ;
}
TArray < URigVMNode * > UControlRigBlueprint : : ConvertHierarchyElementsToSpawnerNodes ( URigHierarchy * InHierarchy , TArray < FRigElementKey > InKeys , bool bRemoveElements )
{
TArray < URigVMNode * > SpawnerNodes ;
// find the construction event
const URigVMNode * EventNode = nullptr ;
for ( const URigVMGraph * Graph : GetRigVMClient ( ) - > GetAllModels ( false , false ) )
{
for ( const URigVMNode * Node : Graph - > GetNodes ( ) )
{
if ( Node - > IsEvent ( ) & & Node - > GetEventName ( ) = = FRigUnit_PrepareForExecution : : EventName )
{
EventNode = Node ;
break ;
}
}
if ( EventNode )
{
break ;
}
}
FVector2D NodePosition = FVector2D : : ZeroVector ;
const FVector2D NodePositionIncrement = FVector2D ( 400 , 0 ) ;
// if we didn't find the construction event yet, create it
if ( EventNode = = nullptr )
{
const URigVMGraph * ConstructionGraph = GetRigVMClient ( ) - > AddModel ( TEXT ( " ConstructionGraph " ) , true ) ;
URigVMController * GraphController = GetRigVMClient ( ) - > GetOrCreateController ( ConstructionGraph ) ;
EventNode = GraphController - > AddUnitNode ( FRigUnit_PrepareForExecution : : StaticStruct ( ) , FRigUnit : : GetMethodName ( ) , NodePosition ) ;
NodePosition + = NodePositionIncrement ;
}
const URigVMPin * LastPin = EventNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_PrepareForExecution , ExecuteContext ) ) ;
if ( LastPin )
{
// follow the node's execution links to find the last one
bool bCarryOn = true ;
while ( bCarryOn )
{
static const TArray < FString > ExecutePinPaths = {
FRigVMStruct : : ControlFlowCompletedName . ToString ( ) ,
FRigVMStruct : : ExecuteContextName . ToString ( )
} ;
for ( const FString & ExecutePinPath : ExecutePinPaths )
{
if ( const URigVMPin * ExecutePin = LastPin - > GetNode ( ) - > FindPin ( ExecutePinPath ) )
{
const TArray < URigVMPin * > TargetPins = ExecutePin - > GetLinkedTargetPins ( ) ;
if ( TargetPins . IsEmpty ( ) )
{
bCarryOn = false ;
break ;
}
LastPin = TargetPins [ 0 ] ;
NodePosition = LastPin - > GetNode ( ) - > GetPosition ( ) + NodePositionIncrement ;
}
}
}
}
const URigVMGraph * ConstructionGraph = EventNode - > GetGraph ( ) ;
URigVMController * GraphController = GetRigVMClient ( ) - > GetOrCreateController ( ConstructionGraph ) ;
auto GetParentAndTransformDefaults = [ InHierarchy ] ( const FRigElementKey & InKey , FString & OutParentDefault , FString & OutTransformDefault )
{
const FRigElementKey Parent = InHierarchy - > GetFirstParent ( InKey ) ;
OutParentDefault . Reset ( ) ;
FRigElementKey : : StaticStruct ( ) - > ExportText ( OutParentDefault , & Parent , nullptr , nullptr , PPF_None , nullptr ) ;
const FTransform Transform = InHierarchy - > GetInitialLocalTransform ( InKey ) ;
OutTransformDefault . Reset ( ) ;
TBaseStructure < FTransform > : : Get ( ) - > ExportText ( OutTransformDefault , & Transform , nullptr , nullptr , PPF_None , nullptr ) ;
} ;
TMap < FRigElementKey , const URigVMPin * > ParentItemPinMap ;
auto AddParentItemLink = [ GraphController , InHierarchy , & SpawnerNodes , & ParentItemPinMap ]
( const FRigElementKey & Key , URigVMNode * Node )
{
SpawnerNodes . Add ( Node ) ;
ParentItemPinMap . Add ( Key , Node - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Item ) ) ) ;
if ( const URigVMPin * * SourcePin = ParentItemPinMap . Find ( InHierarchy - > GetFirstParent ( Key ) ) )
{
if ( const URigVMPin * TargetPin = Node - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Parent ) ) )
{
GraphController - > AddLink ( ( * SourcePin ) - > GetPinPath ( ) , TargetPin - > GetPinPath ( ) , true ) ;
}
}
} ;
for ( const FRigElementKey & Key : InKeys )
{
if ( Key . Type = = ERigElementType : : Bone )
{
FString ParentDefault , TransformDefault ;
GetParentAndTransformDefaults ( Key , ParentDefault , TransformDefault ) ;
URigVMNode * AddBoneNode = GraphController - > AddUnitNode ( FRigUnit_HierarchyAddBone : : StaticStruct ( ) , FRigUnit : : GetMethodName ( ) , NodePosition ) ;
NodePosition + = NodePositionIncrement ;
AddParentItemLink ( Key , AddBoneNode ) ;
if ( LastPin )
{
if ( const URigVMPin * NextPin = AddBoneNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddBone , ExecuteContext ) ) )
{
GraphController - > AddLink ( LastPin - > GetPinPath ( ) , NextPin - > GetPinPath ( ) , true ) ;
LastPin = NextPin ;
}
}
GraphController - > SetPinDefaultValue ( AddBoneNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Name ) ) - > GetPinPath ( ) , Key . Name . ToString ( ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddBoneNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Parent ) ) - > GetPinPath ( ) , ParentDefault , true , true ) ;
GraphController - > SetPinDefaultValue ( AddBoneNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddBone , Space ) ) - > GetPinPath ( ) , TEXT ( " LocalSpace " ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddBoneNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddBone , Transform ) ) - > GetPinPath ( ) , TransformDefault , true , true ) ;
}
else if ( Key . Type = = ERigElementType : : Null )
{
FString ParentDefault , TransformDefault ;
GetParentAndTransformDefaults ( Key , ParentDefault , TransformDefault ) ;
URigVMNode * AddNullNode = GraphController - > AddUnitNode ( FRigUnit_HierarchyAddNull : : StaticStruct ( ) , FRigUnit : : GetMethodName ( ) , NodePosition ) ;
NodePosition + = NodePositionIncrement ;
2023-10-16 13:09:22 -04:00
AddParentItemLink ( Key , AddNullNode ) ;
2023-09-19 03:38:24 -04:00
SpawnerNodes . Add ( AddNullNode ) ;
if ( LastPin )
{
if ( const URigVMPin * NextPin = AddNullNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddBone , ExecuteContext ) ) )
{
GraphController - > AddLink ( LastPin - > GetPinPath ( ) , NextPin - > GetPinPath ( ) , true ) ;
LastPin = NextPin ;
}
}
GraphController - > SetPinDefaultValue ( AddNullNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Name ) ) - > GetPinPath ( ) , Key . Name . ToString ( ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddNullNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Parent ) ) - > GetPinPath ( ) , ParentDefault , true , true ) ;
GraphController - > SetPinDefaultValue ( AddNullNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddNull , Space ) ) - > GetPinPath ( ) , TEXT ( " LocalSpace " ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddNullNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddNull , Transform ) ) - > GetPinPath ( ) , TransformDefault , true , true ) ;
}
else if ( Key . Type = = ERigElementType : : Control )
{
FRigControlElement * ControlElement = InHierarchy - > FindChecked < FRigControlElement > ( Key ) ;
FString ParentDefault , TransformDefault ;
GetParentAndTransformDefaults ( Key , ParentDefault , TransformDefault ) ;
const FTransform OffsetTransform = InHierarchy - > GetControlOffsetTransform ( ControlElement , ERigTransformType : : InitialLocal ) ;
FString OffsetDefault ;
TBaseStructure < FTransform > : : Get ( ) - > ExportText ( OffsetDefault , & OffsetTransform , nullptr , nullptr , PPF_None , nullptr ) ;
if ( ControlElement - > Settings . AnimationType = = ERigControlAnimationType : : AnimationChannel )
{
2023-10-17 08:08:05 -04:00
UScriptStruct * UnitNodeStruct = nullptr ;
TRigVMTypeIndex TypeIndex = INDEX_NONE ;
FString InitialValue , MinimumValue , MaximumValue , SettingsValue ;
switch ( ControlElement - > Settings . ControlType )
{
case ERigControlType : : Bool :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelBool : : StaticStruct ( ) ;
TypeIndex = RigVMTypeUtils : : TypeIndex : : Bool ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < float > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < float > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < float > ( ) ;
break ;
}
case ERigControlType : : Float :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelFloat : : StaticStruct ( ) ;
TypeIndex = RigVMTypeUtils : : TypeIndex : : Float ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < float > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < float > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < float > ( ) ;
if ( ControlElement - > Settings . LimitEnabled . Num ( ) = = 1 )
{
FRigUnit_HierarchyAddAnimationChannelSingleLimitSettings Settings ;
Settings . Enabled = ControlElement - > Settings . LimitEnabled [ 0 ] ;
FRigUnit_HierarchyAddAnimationChannelSingleLimitSettings : : StaticStruct ( ) - > ExportText ( SettingsValue , & Settings , & Settings , nullptr , PPF_None , nullptr ) ;
}
break ;
}
case ERigControlType : : ScaleFloat :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelScaleFloat : : StaticStruct ( ) ;
TypeIndex = RigVMTypeUtils : : TypeIndex : : Float ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < float > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < float > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < float > ( ) ;
if ( ControlElement - > Settings . LimitEnabled . Num ( ) = = 1 )
{
FRigUnit_HierarchyAddAnimationChannelSingleLimitSettings Settings ;
Settings . Enabled = ControlElement - > Settings . LimitEnabled [ 0 ] ;
FRigUnit_HierarchyAddAnimationChannelSingleLimitSettings : : StaticStruct ( ) - > ExportText ( SettingsValue , & Settings , & Settings , nullptr , PPF_None , nullptr ) ;
}
break ;
}
case ERigControlType : : Integer :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelInteger : : StaticStruct ( ) ;
TypeIndex = RigVMTypeUtils : : TypeIndex : : Int32 ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < int32 > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < int32 > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < int32 > ( ) ;
if ( ControlElement - > Settings . LimitEnabled . Num ( ) = = 1 )
{
FRigUnit_HierarchyAddAnimationChannelSingleLimitSettings Settings ;
Settings . Enabled = ControlElement - > Settings . LimitEnabled [ 0 ] ;
FRigUnit_HierarchyAddAnimationChannelSingleLimitSettings : : StaticStruct ( ) - > ExportText ( SettingsValue , & Settings , & Settings , nullptr , PPF_None , nullptr ) ;
}
break ;
}
case ERigControlType : : Vector2D :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelVector2D : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FVector2D > ( ) ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < FVector2D > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < FVector2D > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < FVector2D > ( ) ;
if ( ControlElement - > Settings . LimitEnabled . Num ( ) = = 2 )
{
FRigUnit_HierarchyAddAnimationChannel2DLimitSettings Settings ;
Settings . X = ControlElement - > Settings . LimitEnabled [ 0 ] ;
Settings . Y = ControlElement - > Settings . LimitEnabled [ 1 ] ;
FRigUnit_HierarchyAddAnimationChannel2DLimitSettings : : StaticStruct ( ) - > ExportText ( SettingsValue , & Settings , & Settings , nullptr , PPF_None , nullptr ) ;
}
break ;
}
case ERigControlType : : Position :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelVector : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FVector > ( ) ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < FVector > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < FVector > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < FVector > ( ) ;
if ( ControlElement - > Settings . LimitEnabled . Num ( ) = = 3 )
{
FRigUnit_HierarchyAddAnimationChannelVectorLimitSettings Settings ;
Settings . X = ControlElement - > Settings . LimitEnabled [ 0 ] ;
Settings . Y = ControlElement - > Settings . LimitEnabled [ 1 ] ;
Settings . Z = ControlElement - > Settings . LimitEnabled [ 2 ] ;
FRigUnit_HierarchyAddAnimationChannelVectorLimitSettings : : StaticStruct ( ) - > ExportText ( SettingsValue , & Settings , & Settings , nullptr , PPF_None , nullptr ) ;
}
break ;
}
case ERigControlType : : Scale :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelScaleVector : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FVector > ( ) ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < FVector > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < FVector > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < FVector > ( ) ;
if ( ControlElement - > Settings . LimitEnabled . Num ( ) = = 3 )
{
FRigUnit_HierarchyAddAnimationChannelVectorLimitSettings Settings ;
Settings . X = ControlElement - > Settings . LimitEnabled [ 0 ] ;
Settings . Y = ControlElement - > Settings . LimitEnabled [ 1 ] ;
Settings . Z = ControlElement - > Settings . LimitEnabled [ 2 ] ;
FRigUnit_HierarchyAddAnimationChannelVectorLimitSettings : : StaticStruct ( ) - > ExportText ( SettingsValue , & Settings , & Settings , nullptr , PPF_None , nullptr ) ;
}
break ;
}
case ERigControlType : : Rotator :
{
UnitNodeStruct = FRigUnit_HierarchyAddAnimationChannelRotator : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FRotator > ( ) ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < FRotator > ( ) ;
MinimumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Minimum ) . ToString < FRotator > ( ) ;
MaximumValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Maximum ) . ToString < FRotator > ( ) ;
if ( ControlElement - > Settings . LimitEnabled . Num ( ) = = 3 )
{
FRigUnit_HierarchyAddAnimationChannelRotatorLimitSettings Settings ;
Settings . Pitch = ControlElement - > Settings . LimitEnabled [ 0 ] ;
Settings . Yaw = ControlElement - > Settings . LimitEnabled [ 1 ] ;
Settings . Roll = ControlElement - > Settings . LimitEnabled [ 2 ] ;
FRigUnit_HierarchyAddAnimationChannelRotatorLimitSettings : : StaticStruct ( ) - > ExportText ( SettingsValue , & Settings , & Settings , nullptr , PPF_None , nullptr ) ;
}
break ;
}
default :
{
break ;
}
}
if ( UnitNodeStruct = = nullptr )
{
continue ;
}
URigVMNode * AddControlNode = GraphController - > AddUnitNode ( UnitNodeStruct , FRigUnit : : GetMethodName ( ) , NodePosition ) ;
NodePosition + = NodePositionIncrement ;
AddParentItemLink ( Key , AddControlNode ) ;
if ( LastPin )
{
if ( const URigVMPin * NextPin = AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddBone , ExecuteContext ) ) )
{
GraphController - > AddLink ( LastPin - > GetPinPath ( ) , NextPin - > GetPinPath ( ) , true ) ;
LastPin = NextPin ;
}
}
GraphController - > ResolveWildCardPin ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddAnimationChannelFloat , InitialValue ) ) - > GetPinPath ( ) , TypeIndex , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddAnimationChannelFloat , Name ) ) - > GetPinPath ( ) , Key . Name . ToString ( ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddAnimationChannelFloat , Parent ) ) - > GetPinPath ( ) , ParentDefault , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddAnimationChannelFloat , InitialValue ) ) - > GetPinPath ( ) , InitialValue , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddAnimationChannelFloat , MinimumValue ) ) - > GetPinPath ( ) , MinimumValue , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddAnimationChannelFloat , MaximumValue ) ) - > GetPinPath ( ) , MaximumValue , true , true ) ;
if ( ! SettingsValue . IsEmpty ( ) )
{
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddAnimationChannelFloat , LimitsEnabled ) ) - > GetPinPath ( ) , SettingsValue , true , true ) ;
}
2023-09-19 03:38:24 -04:00
}
else
{
UScriptStruct * UnitNodeStruct = nullptr ;
TRigVMTypeIndex TypeIndex = INDEX_NONE ;
FString InitialValue ;
switch ( ControlElement - > Settings . ControlType )
{
case ERigControlType : : Float :
case ERigControlType : : ScaleFloat :
{
UnitNodeStruct = FRigUnit_HierarchyAddControlFloat : : StaticStruct ( ) ;
TypeIndex = RigVMTypeUtils : : TypeIndex : : Float ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < float > ( ) ;
break ;
}
case ERigControlType : : Integer :
{
UnitNodeStruct = FRigUnit_HierarchyAddControlInteger : : StaticStruct ( ) ;
TypeIndex = RigVMTypeUtils : : TypeIndex : : Int32 ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < int32 > ( ) ;
break ;
}
case ERigControlType : : Vector2D :
{
UnitNodeStruct = FRigUnit_HierarchyAddControlVector2D : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FVector2D > ( ) ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < FVector2D > ( ) ;
break ;
}
case ERigControlType : : Position :
case ERigControlType : : Scale :
{
UnitNodeStruct = FRigUnit_HierarchyAddControlVector : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FVector > ( ) ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < FVector > ( ) ;
break ;
}
case ERigControlType : : Rotator :
{
UnitNodeStruct = FRigUnit_HierarchyAddControlRotator : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FRotator > ( ) ;
InitialValue = InHierarchy - > GetControlValue ( Key , ERigControlValueType : : Initial ) . ToString < FRotator > ( ) ;
break ;
}
case ERigControlType : : Transform :
case ERigControlType : : TransformNoScale :
case ERigControlType : : EulerTransform :
{
UnitNodeStruct = FRigUnit_HierarchyAddControlTransform : : StaticStruct ( ) ;
TypeIndex = FRigVMRegistry : : Get ( ) . GetTypeIndex < FTransform > ( ) ;
const FTransform InitialTransform = InHierarchy - > GetInitialLocalTransform ( Key ) ;
TBaseStructure < FTransform > : : Get ( ) - > ExportText ( InitialValue , & InitialTransform , nullptr , nullptr , PPF_None , nullptr ) ;
break ;
}
default :
{
break ;
}
}
if ( UnitNodeStruct = = nullptr )
{
continue ;
}
URigVMNode * AddControlNode = GraphController - > AddUnitNode ( UnitNodeStruct , FRigUnit : : GetMethodName ( ) , NodePosition ) ;
NodePosition + = NodePositionIncrement ;
AddParentItemLink ( Key , AddControlNode ) ;
if ( LastPin )
{
if ( const URigVMPin * NextPin = AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddBone , ExecuteContext ) ) )
{
GraphController - > AddLink ( LastPin - > GetPinPath ( ) , NextPin - > GetPinPath ( ) , true ) ;
LastPin = NextPin ;
}
}
GraphController - > ResolveWildCardPin ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddControlInteger , InitialValue ) ) - > GetPinPath ( ) , TypeIndex , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Name ) ) - > GetPinPath ( ) , Key . Name . ToString ( ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Parent ) ) - > GetPinPath ( ) , ParentDefault , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddControlElement , OffsetSpace ) ) - > GetPinPath ( ) , TEXT ( " LocalSpace " ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddControlElement , OffsetTransform ) ) - > GetPinPath ( ) , OffsetDefault , true , true ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddControlInteger , InitialValue ) ) - > GetPinPath ( ) , InitialValue , true , true ) ;
if ( const FStructProperty * SettingsProperty = CastField < FStructProperty > ( UnitNodeStruct - > FindPropertyByName ( TEXT ( " Settings " ) ) ) )
{
UScriptStruct * SettingsStruct = CastChecked < UScriptStruct > ( SettingsProperty - > Struct ) ;
FStructOnScope SettingsScope ( SettingsStruct ) ;
FRigUnit_HierarchyAddControl_Settings * Settings = ( FRigUnit_HierarchyAddControl_Settings * ) SettingsScope . GetStructMemory ( ) ;
Settings - > ConfigureFrom ( ControlElement , ControlElement - > Settings ) ;
FString SettingsDefault ;
SettingsStruct - > ExportText ( SettingsDefault , Settings , nullptr , nullptr , PPF_None , nullptr ) ;
GraphController - > SetPinDefaultValue ( AddControlNode - > FindPin ( SettingsProperty - > GetName ( ) ) - > GetPinPath ( ) , SettingsDefault , true , true ) ;
}
}
}
2023-10-16 13:09:22 -04:00
else if ( Key . Type = = ERigElementType : : Socket )
{
FString ParentDefault , TransformDefault ;
GetParentAndTransformDefaults ( Key , ParentDefault , TransformDefault ) ;
URigVMNode * AddSocketNode = GraphController - > AddUnitNode ( FRigUnit_HierarchyAddSocket : : StaticStruct ( ) , FRigUnit : : GetMethodName ( ) , NodePosition ) ;
NodePosition + = NodePositionIncrement ;
AddParentItemLink ( Key , AddSocketNode ) ;
SpawnerNodes . Add ( AddSocketNode ) ;
if ( LastPin )
{
if ( const URigVMPin * NextPin = AddSocketNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddBone , ExecuteContext ) ) )
{
GraphController - > AddLink ( LastPin - > GetPinPath ( ) , NextPin - > GetPinPath ( ) , true ) ;
LastPin = NextPin ;
}
}
GraphController - > SetPinDefaultValue ( AddSocketNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Name ) ) - > GetPinPath ( ) , Key . Name . ToString ( ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddSocketNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddElement , Parent ) ) - > GetPinPath ( ) , ParentDefault , true , true ) ;
GraphController - > SetPinDefaultValue ( AddSocketNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddNull , Space ) ) - > GetPinPath ( ) , TEXT ( " LocalSpace " ) , true , true ) ;
GraphController - > SetPinDefaultValue ( AddSocketNode - > FindPin ( GET_MEMBER_NAME_STRING_CHECKED ( FRigUnit_HierarchyAddNull , Transform ) ) - > GetPinPath ( ) , TransformDefault , true , true ) ;
}
2023-09-19 03:38:24 -04:00
}
if ( bRemoveElements & & InHierarchy )
{
InHierarchy - > Modify ( ) ;
for ( const FRigElementKey & Key : InKeys )
{
InHierarchy - > GetController ( true ) - > RemoveElement ( Key , true ) ;
}
}
return SpawnerNodes ;
}
# endif // WITH_EDITORONLY_DATA
UTexture2D * UControlRigBlueprint : : GetRigModuleIcon ( ) const
{
if ( IsControlRigModule ( ) )
{
if ( UTexture2D * Icon = Cast < UTexture2D > ( RigModuleSettings . Icon . TryLoad ( ) ) )
{
return Icon ;
}
}
return nullptr ;
2023-08-11 10:34:25 -04:00
}
2019-01-08 11:38:48 -05:00
void UControlRigBlueprint : : SetPreviewMesh ( USkeletalMesh * PreviewMesh , bool bMarkAsDirty /*=true*/ )
{
2021-08-10 14:19:17 -04:00
# if WITH_EDITORONLY_DATA
2019-01-08 11:38:48 -05:00
if ( bMarkAsDirty )
{
Modify ( ) ;
}
PreviewSkeletalMesh = PreviewMesh ;
2021-08-10 14:19:17 -04:00
# endif
2019-01-08 11:38:48 -05:00
}
2021-03-03 14:44:58 -04:00
void UControlRigBlueprint : : Serialize ( FArchive & Ar )
{
2023-11-13 10:28:11 -05:00
if ( IsValid ( this ) )
{
RigVMClient . SetOuterClientHost ( this , GET_MEMBER_NAME_CHECKED ( UControlRigBlueprint , RigVMClient ) ) ;
ModularRigModel . SetOuterClientHost ( this ) ;
}
2022-05-31 04:27:20 -04:00
2021-03-03 14:44:58 -04:00
Super : : Serialize ( Ar ) ;
if ( Ar . IsObjectReferenceCollector ( ) )
{
2023-03-07 07:37:27 -05:00
Ar . UsingCustomVersion ( FControlRigObjectVersion : : GUID ) ;
2021-03-03 14:44:58 -04:00
2023-03-07 07:37:27 -05:00
# if WITH_EDITORONLY_DATA
if ( Ar . IsCooking ( ) & & ReferencedObjectPathsStored )
2021-03-03 14:44:58 -04:00
{
2023-03-07 07:37:27 -05:00
for ( FSoftObjectPath ObjectPath : ReferencedObjectPaths )
2022-11-17 06:53:56 -05:00
{
2023-03-07 07:37:27 -05:00
ObjectPath . Serialize ( Ar ) ;
2022-11-17 06:53:56 -05:00
}
2021-03-03 14:44:58 -04:00
}
2023-03-07 07:37:27 -05:00
else
# endif
2022-01-27 03:46:30 -05:00
{
2023-03-07 07:37:27 -05:00
TArray < IRigVMGraphFunctionHost * > ReferencedFunctionHosts = GetReferencedFunctionHosts ( false ) ;
for ( IRigVMGraphFunctionHost * ReferencedFunctionHost : ReferencedFunctionHosts )
2022-01-27 03:46:30 -05:00
{
2023-03-07 07:37:27 -05:00
if ( URigVMBlueprintGeneratedClass * BPGeneratedClass = Cast < URigVMBlueprintGeneratedClass > ( ReferencedFunctionHost ) )
{
Ar < < BPGeneratedClass ;
}
}
for ( const TSoftObjectPtr < UControlRigShapeLibrary > & ShapeLibraryPtr : ShapeLibraries )
{
if ( ShapeLibraryPtr . IsValid ( ) )
{
UControlRigShapeLibrary * ShapeLibrary = ShapeLibraryPtr . Get ( ) ;
Ar < < ShapeLibrary ;
}
2022-01-27 03:46:30 -05:00
}
}
2021-03-03 14:44:58 -04:00
}
2022-05-31 04:27:20 -04:00
if ( Ar . IsLoading ( ) )
{
if ( Model_DEPRECATED | | FunctionLibrary_DEPRECATED )
{
TGuardValue < bool > DisableClientNotifs ( RigVMClient . bSuspendNotifications , true ) ;
RigVMClient . SetFromDeprecatedData ( Model_DEPRECATED , FunctionLibrary_DEPRECATED ) ;
}
2023-10-26 06:52:34 -04:00
ModularRigModel . UpdateCachedChildren ( ) ;
2024-02-12 07:07:41 -05:00
ModularRigModel . Connections . UpdateFromConnectionList ( ) ;
2022-05-31 04:27:20 -04:00
}
2021-03-03 14:44:58 -04:00
}
2021-03-25 16:51:36 -04:00
void UControlRigBlueprint : : PreSave ( FObjectPreSaveContext ObjectSaveContext )
{
Super : : PreSave ( ObjectSaveContext ) ;
2020-09-24 00:43:27 -04:00
2023-08-01 08:23:56 -04:00
// make sure to save the VM with high performance settings
// so that during cooking we reach small footprints.
// these settings may have changed during the user session.
VMCompileSettings . ASTSettings . bFoldAssignments = true ;
VMCompileSettings . ASTSettings . bFoldLiterals = true ;
2020-09-24 00:43:27 -04:00
bExposesAnimatableControls = false ;
2021-02-22 13:36:33 -04:00
Hierarchy - > ForEach < FRigControlElement > ( [ this ] ( FRigControlElement * ControlElement ) - > bool
{
2022-05-11 08:12:21 -04:00
if ( Hierarchy - > IsAnimatable ( ControlElement ) )
2020-09-24 00:43:27 -04:00
{
bExposesAnimatableControls = true ;
2021-02-22 13:36:33 -04:00
return false ;
2020-09-24 00:43:27 -04:00
}
2021-02-22 13:36:33 -04:00
return true ;
} ) ;
2023-08-11 10:34:25 -04:00
2023-12-05 06:19:11 -05:00
if ( IsControlRigModule ( ) )
{
URigHierarchy * DebuggedHierarchy = Hierarchy ;
if ( UControlRig * DebuggedRig = Cast < UControlRig > ( GetObjectBeingDebugged ( ) ) )
{
DebuggedHierarchy = DebuggedRig - > GetHierarchy ( ) ;
}
TGuardValue < bool > SuspendNotifGuard ( Hierarchy - > GetSuspendNotificationsFlag ( ) , true ) ;
TGuardValue < bool > SuspendNotifGuardOnDebuggedHierarchy ( DebuggedHierarchy - > GetSuspendNotificationsFlag ( ) , true ) ;
UpdateExposedModuleConnectors ( ) ;
}
2023-10-27 11:07:43 -04:00
if ( IsControlRigModule ( ) )
{
ControlRigType = EControlRigType : : RigModule ;
ItemTypeDisplayName = TEXT ( " Rig Module " ) ;
}
else if ( GetControlRigClass ( ) - > IsChildOf ( UModularRig : : StaticClass ( ) ) )
{
ControlRigType = EControlRigType : : ModularRig ;
ItemTypeDisplayName = TEXT ( " Modular Rig " ) ;
}
else
{
ControlRigType = EControlRigType : : IndependentRig ;
ItemTypeDisplayName = TEXT ( " Control Rig " ) ;
}
2023-08-11 10:34:25 -04:00
}
2023-09-19 03:38:24 -04:00
void UControlRigBlueprint : : UpdateExposedModuleConnectors ( ) const
2023-08-11 10:34:25 -04:00
{
2023-09-19 03:38:24 -04:00
UControlRigBlueprint * MutableThis = ( ( UControlRigBlueprint * ) this ) ;
MutableThis - > RigModuleSettings . ExposedConnectors . Reset ( ) ;
Hierarchy - > ForEach < FRigConnectorElement > ( [ MutableThis ] ( const FRigConnectorElement * ConnectorElement ) - > bool
2023-08-11 10:34:25 -04:00
{
FRigModuleConnector ExposedConnector ;
2023-08-18 04:03:07 -04:00
ExposedConnector . Name = ConnectorElement - > GetName ( ) ;
2023-08-11 10:34:25 -04:00
ExposedConnector . Settings = ConnectorElement - > Settings ;
2023-09-19 03:38:24 -04:00
MutableThis - > RigModuleSettings . ExposedConnectors . Add ( ExposedConnector ) ;
2023-08-11 10:34:25 -04:00
return true ;
} ) ;
2023-11-24 10:05:53 -05:00
PropagateHierarchyFromBPToInstances ( ) ;
2020-09-24 00:43:27 -04:00
}
2023-09-19 03:38:24 -04:00
bool UControlRigBlueprint : : ResolveConnector ( const FRigElementKey & DraggedKey , const FRigElementKey & TargetKey , bool bSetupUndoRedo )
{
FScopedTransaction Transaction ( LOCTEXT ( " ResolveConnector " , " Resolve connector " ) ) ;
if ( bSetupUndoRedo )
{
Modify ( ) ;
}
if ( TargetKey . IsValid ( ) )
{
FRigElementKey & ExistingTargetKey = ConnectionMap . FindOrAdd ( DraggedKey ) ;
if ( ExistingTargetKey = = TargetKey )
{
return false ;
}
ExistingTargetKey = TargetKey ;
2023-10-26 06:52:34 -04:00
2024-01-19 04:34:33 -05:00
if ( IsModularRig ( ) )
2023-10-26 06:52:34 -04:00
{
2024-01-19 04:34:33 -05:00
// Add connection to the model
if ( UModularRigController * Controller = GetModularRigController ( ) )
{
Controller - > ConnectConnectorToElement ( DraggedKey , TargetKey , bSetupUndoRedo , ModularRigSettings . bAutoResolve ) ;
}
}
else
{
ConnectionMap . FindOrAdd ( DraggedKey ) = TargetKey ;
2023-10-26 06:52:34 -04:00
}
2023-09-19 03:38:24 -04:00
}
else
{
2024-01-19 04:34:33 -05:00
if ( IsModularRig ( ) )
{
// Add connection to the model
if ( UModularRigController * Controller = GetModularRigController ( ) )
{
2024-02-12 04:56:13 -05:00
Controller - > DisconnectConnector ( DraggedKey , false , bSetupUndoRedo ) ;
2024-01-19 04:34:33 -05:00
}
}
else
{
ConnectionMap . Remove ( DraggedKey ) ;
}
2023-09-19 03:38:24 -04:00
}
2023-10-26 06:52:34 -04:00
RecompileModularRig ( ) ;
2023-09-19 03:38:24 -04:00
PropagateHierarchyFromBPToInstances ( ) ;
2023-09-28 09:19:30 -04:00
2023-10-30 07:01:53 -04:00
if ( UControlRig * ControlRig = Cast < UControlRig > ( GetObjectBeingDebugged ( ) ) )
2023-09-28 09:19:30 -04:00
{
for ( UEdGraph * Graph : UbergraphPages )
{
UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( Graph ) ;
if ( RigGraph = = nullptr )
{
continue ;
}
RigGraph - > CacheNameLists ( ControlRig - > GetHierarchy ( ) , & DrawContainer , ShapeLibraries ) ;
}
}
2023-09-19 03:38:24 -04:00
return true ;
}
2024-01-19 04:34:33 -05:00
void UControlRigBlueprint : : UpdateConnectionMapFromModel ( )
{
if ( IsModularRig ( ) )
{
ConnectionMap . Reset ( ) ;
2024-01-24 07:26:18 -05:00
for ( const FModularRigSingleConnection & Connection : ModularRigModel . Connections )
2024-01-19 04:34:33 -05:00
{
ConnectionMap . Add ( Connection . Connector , Connection . Target ) ;
}
}
}
2019-09-17 19:12:19 -04:00
void UControlRigBlueprint : : PostLoad ( )
{
Super : : PostLoad ( ) ;
2021-07-28 17:11:36 -04:00
{
2023-06-15 11:30:29 -04:00
# if WITH_EDITOR
2021-09-20 12:22:17 -04:00
2021-09-10 10:04:27 -04:00
// correct the offset transforms
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : ControlOffsetTransform )
{
HierarchyContainer_DEPRECATED . ControlHierarchy . PostLoad ( ) ;
if ( HierarchyContainer_DEPRECATED . ControlHierarchy . Num ( ) > 0 )
{
2023-06-15 11:30:29 -04:00
MarkDirtyDuringLoad ( ) ;
2021-09-10 10:04:27 -04:00
}
for ( FRigControl & Control : HierarchyContainer_DEPRECATED . ControlHierarchy )
{
const FTransform PreviousOffsetTransform = Control . GetTransformFromValue ( ERigControlValueType : : Initial ) ;
Control . OffsetTransform = PreviousOffsetTransform ;
Control . InitialValue = Control . Value ;
if ( Control . ControlType = = ERigControlType : : Transform )
{
Control . InitialValue = FRigControlValue : : Make < FTransform > ( FTransform : : Identity ) ;
}
else if ( Control . ControlType = = ERigControlType : : TransformNoScale )
{
Control . InitialValue = FRigControlValue : : Make < FTransformNoScale > ( FTransformNoScale : : Identity ) ;
}
else if ( Control . ControlType = = ERigControlType : : EulerTransform )
{
Control . InitialValue = FRigControlValue : : Make < FEulerTransform > ( FEulerTransform : : Identity ) ;
}
}
}
// convert the hierarchy from V1 to V2
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : RigHierarchyV2 )
{
Modify ( ) ;
TGuardValue < bool > SuspendNotifGuard ( Hierarchy - > GetSuspendNotificationsFlag ( ) , true ) ;
Hierarchy - > Reset ( ) ;
GetHierarchyController ( ) - > ImportFromHierarchyContainer ( HierarchyContainer_DEPRECATED , false ) ;
}
// perform backwards compat value upgrades
TArray < URigVMGraph * > GraphsToValidate = GetAllModels ( ) ;
for ( int32 GraphIndex = 0 ; GraphIndex < GraphsToValidate . Num ( ) ; GraphIndex + + )
{
URigVMGraph * GraphToValidate = GraphsToValidate [ GraphIndex ] ;
if ( GraphToValidate = = nullptr )
2021-01-14 15:00:40 -04:00
{
2021-09-10 10:04:27 -04:00
continue ;
2021-01-14 15:00:40 -04:00
}
2021-09-10 10:04:27 -04:00
for ( URigVMNode * Node : GraphToValidate - > GetNodes ( ) )
{
TArray < URigVMPin * > Pins = Node - > GetAllPinsRecursively ( ) ;
for ( URigVMPin * Pin : Pins )
2021-03-05 04:30:31 -04:00
{
2021-09-10 10:04:27 -04:00
if ( Pin - > GetCPPTypeObject ( ) = = StaticEnum < ERigElementType > ( ) )
2021-03-05 04:30:31 -04:00
{
2021-09-10 10:04:27 -04:00
if ( Pin - > GetDefaultValue ( ) = = TEXT ( " Space " ) )
2021-03-05 04:30:31 -04:00
{
2021-09-10 10:04:27 -04:00
if ( URigVMController * Controller = GetController ( GraphToValidate ) )
{
2022-11-29 06:36:47 -05:00
FRigVMControllerNotifGuard NotifGuard ( Controller , true ) ;
2021-09-10 10:04:27 -04:00
Controller - > SetPinDefaultValue ( Pin - > GetPinPath ( ) , TEXT ( " Null " ) , false , false , false ) ;
}
}
}
}
2021-03-05 04:30:31 -04:00
}
2022-11-23 04:49:43 -05:00
}
2021-04-15 14:30:33 -04:00
2021-09-10 10:04:27 -04:00
# endif
}
2021-03-05 04:30:31 -04:00
2021-10-20 11:56:18 -04:00
// upgrade the gizmo libraries to shape libraries
2022-02-24 19:26:12 -05:00
if ( ! GizmoLibrary_DEPRECATED . IsNull ( ) | | GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : RenameGizmoToShape )
2021-10-20 11:56:18 -04:00
{
// if it's an older file and it doesn't have the GizmoLibrary stored,
// refer to the previous default.
ShapeLibraries . Reset ( ) ;
2021-10-26 14:46:01 -04:00
2022-02-24 19:26:12 -05:00
if ( ! GizmoLibrary_DEPRECATED . IsNull ( ) )
2021-10-26 14:46:01 -04:00
{
2022-02-24 19:26:12 -05:00
ShapeLibrariesToLoadOnPackageLoaded . Add ( GizmoLibrary_DEPRECATED . ToString ( ) ) ;
2021-10-26 14:46:01 -04:00
}
else
{
2022-01-25 05:00:23 -05:00
static const FString DefaultGizmoLibraryPath = TEXT ( " /ControlRig/Controls/DefaultGizmoLibrary.DefaultGizmoLibrary " ) ;
ShapeLibrariesToLoadOnPackageLoaded . Add ( DefaultGizmoLibraryPath ) ;
2021-10-26 14:46:01 -04:00
}
2021-10-20 11:56:18 -04:00
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( false /* create if needed */ ) ) ;
2021-10-26 14:46:01 -04:00
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
2022-01-25 05:00:23 -05:00
ArchetypeInstances . Insert ( CDO , 0 ) ;
2021-10-26 14:46:01 -04:00
for ( UObject * Instance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * InstanceRig = Cast < UControlRig > ( Instance ) )
2021-10-26 14:46:01 -04:00
{
2022-01-25 05:00:23 -05:00
InstanceRig - > ShapeLibraries . Reset ( ) ;
2021-10-26 14:46:01 -04:00
InstanceRig - > GizmoLibrary_DEPRECATED . Reset ( ) ;
}
}
2021-10-20 11:56:18 -04:00
}
2023-11-29 03:23:17 -05:00
2024-02-06 07:45:44 -05:00
# if WITH_EDITOR
if ( IsControlRigModule ( ) & & Hierarchy )
{
// backwards compat - makes sure to only ever allow one primary connector
TArray < FRigConnectorElement * > Connectors = Hierarchy - > GetConnectors ( ) ;
const int32 NumPrimaryConnectors = Algo : : CountIf ( Connectors , [ ] ( const FRigConnectorElement * InConnector ) - > bool
{
return InConnector - > IsPrimary ( ) ;
} ) ;
if ( NumPrimaryConnectors > 1 )
{
bool bHasSeenPrimary = false ;
for ( FRigConnectorElement * Connector : Connectors )
{
if ( bHasSeenPrimary )
{
Connector - > Settings . Type = EConnectorType : : Secondary ;
}
else
{
bHasSeenPrimary = Connector - > IsPrimary ( ) ;
}
}
UpdateExposedModuleConnectors ( ) ;
}
}
# endif
2024-01-19 04:34:33 -05:00
ModularRigModel . PatchModelsOnLoad ( ) ;
2023-11-29 03:23:17 -05:00
UpdateModularDependencyDelegates ( ) ;
2020-01-22 17:58:55 -05:00
}
2021-09-20 12:22:17 -04:00
# if WITH_EDITOR
2022-05-19 08:04:52 -04:00
void UControlRigBlueprint : : HandlePackageDone ( )
{
2022-01-25 05:00:23 -05:00
if ( ShapeLibrariesToLoadOnPackageLoaded . Num ( ) > 0 )
{
for ( const FString & ShapeLibraryToLoadOnPackageLoaded : ShapeLibrariesToLoadOnPackageLoaded )
{
ShapeLibraries . Add ( LoadObject < UControlRigShapeLibrary > ( nullptr , * ShapeLibraryToLoadOnPackageLoaded ) ) ;
}
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( false /* create if needed */ ) ) ;
2022-01-25 05:00:23 -05:00
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
ArchetypeInstances . Insert ( CDO , 0 ) ;
for ( UObject * Instance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * InstanceRig = Cast < UControlRig > ( Instance ) )
2022-01-25 05:00:23 -05:00
{
InstanceRig - > ShapeLibraries = ShapeLibraries ;
}
}
ShapeLibrariesToLoadOnPackageLoaded . Reset ( ) ;
}
2022-02-10 07:13:27 -05:00
2021-10-06 12:58:15 -04:00
PropagateHierarchyFromBPToInstances ( ) ;
2023-06-15 11:30:29 -04:00
Super : : HandlePackageDone ( ) ;
2023-11-29 03:23:17 -05:00
if ( IsModularRig ( ) )
{
// force load all dependencies
ModularRigModel . ForEachModule ( [ ] ( const FRigModuleReference * Element ) - > bool
{
( void ) Element - > Class . LoadSynchronous ( ) ;
return true ;
} ) ;
2023-12-05 06:19:11 -05:00
2023-11-29 03:23:17 -05:00
RecompileModularRig ( ) ;
}
2022-02-10 07:13:27 -05:00
}
2023-09-28 05:01:38 -04:00
void UControlRigBlueprint : : HandleConfigureRigVMController ( const FRigVMClient * InClient , URigVMController * InControllerToConfigure )
{
Super : : HandleConfigureRigVMController ( InClient , InControllerToConfigure ) ;
TWeakObjectPtr < URigVMBlueprint > WeakThis ( this ) ;
InControllerToConfigure - > ConfigureWorkflowOptionsDelegate . BindLambda ( [ WeakThis ] ( URigVMUserWorkflowOptions * Options )
{
if ( UControlRigWorkflowOptions * ControlRigNodeWorkflowOptions = Cast < UControlRigWorkflowOptions > ( Options ) )
{
ControlRigNodeWorkflowOptions - > Hierarchy = nullptr ;
ControlRigNodeWorkflowOptions - > Selection . Reset ( ) ;
if ( const URigVMBlueprint * StrongThis = WeakThis . Get ( ) )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * ControlRig = Cast < UControlRig > ( StrongThis - > GetObjectBeingDebugged ( ) ) )
2023-09-28 05:01:38 -04:00
{
ControlRigNodeWorkflowOptions - > Hierarchy = ControlRig - > GetHierarchy ( ) ;
ControlRigNodeWorkflowOptions - > Selection = ControlRig - > GetHierarchy ( ) - > GetSelectedKeys ( ) ;
}
}
}
} ) ;
}
2021-04-21 11:25:07 -04:00
# endif
2023-06-15 11:30:29 -04:00
UClass * UControlRigBlueprint : : GetRigVMEdGraphNodeClass ( ) const
2020-01-22 17:58:55 -05:00
{
2023-06-15 11:30:29 -04:00
return UControlRigGraphNode : : StaticClass ( ) ;
2020-01-22 17:58:55 -05:00
}
2023-06-15 11:30:29 -04:00
UClass * UControlRigBlueprint : : GetRigVMEdGraphSchemaClass ( ) const
2020-12-07 07:55:48 -04:00
{
2023-06-15 11:30:29 -04:00
return UControlRigGraphSchema : : StaticClass ( ) ;
2020-12-07 07:55:48 -04:00
}
2023-06-15 11:30:29 -04:00
UClass * UControlRigBlueprint : : GetRigVMEdGraphClass ( ) const
2020-12-14 08:58:12 -04:00
{
2023-06-15 11:30:29 -04:00
return UControlRigGraph : : StaticClass ( ) ;
2020-12-07 07:55:48 -04:00
}
2023-06-19 11:25:29 -04:00
UClass * UControlRigBlueprint : : GetRigVMEditorSettingsClass ( ) const
{
return UControlRigEditorSettings : : StaticClass ( ) ;
}
2023-10-26 06:52:34 -04:00
void UControlRigBlueprint : : GetPreloadDependencies ( TArray < UObject * > & OutDeps )
{
Super : : GetPreloadDependencies ( OutDeps ) ;
for ( FRigModuleReference & Module : ModularRigModel . Modules )
{
OutDeps . Add ( Module . Class . Get ( ) ) ;
}
}
2023-06-29 05:33:20 -04:00
# if WITH_EDITOR
2023-08-01 11:54:10 -04:00
const FName & UControlRigBlueprint : : GetPanelPinFactoryName ( ) const
{
return ControlRigPanelNodeFactoryName ;
}
2023-06-29 05:33:20 -04:00
IRigVMEditorModule * UControlRigBlueprint : : GetEditorModule ( ) const
{
return & IControlRigEditorModule : : Get ( ) ;
}
# endif
2021-06-16 13:02:50 -04:00
TArray < FString > UControlRigBlueprint : : GeneratePythonCommands ( const FString InNewBlueprintName )
{
2022-04-07 13:03:59 -04:00
TArray < FString > InternalCommands ;
2023-06-15 11:30:29 -04:00
InternalCommands . Add ( TEXT ( " import unreal " ) ) ;
2022-04-07 13:03:59 -04:00
InternalCommands . Add ( TEXT ( " unreal.load_module('ControlRigDeveloper') " ) ) ;
InternalCommands . Add ( TEXT ( " factory = unreal.ControlRigBlueprintFactory " ) ) ;
InternalCommands . Add ( FString : : Printf ( TEXT ( " blueprint = factory.create_new_control_rig_asset(desired_package_path = '%s') " ) , * InNewBlueprintName ) ) ;
InternalCommands . Add ( TEXT ( " hierarchy = blueprint.hierarchy " ) ) ;
InternalCommands . Add ( TEXT ( " hierarchy_controller = hierarchy.get_controller() " ) ) ;
2021-06-16 13:02:50 -04:00
// Hierarchy
2022-04-07 13:03:59 -04:00
InternalCommands . Append ( Hierarchy - > GetController ( true ) - > GeneratePythonCommands ( ) ) ;
2021-06-16 13:02:50 -04:00
2021-08-10 14:19:17 -04:00
# if WITH_EDITORONLY_DATA
2023-06-15 11:30:29 -04:00
const FString PreviewMeshPath = GetPreviewMesh ( ) - > GetPathName ( ) ;
2022-04-07 13:03:59 -04:00
InternalCommands . Add ( FString : : Printf ( TEXT ( " blueprint.set_preview_mesh(unreal.load_object(name='%s', outer=None)) " ) ,
2021-06-16 13:02:50 -04:00
* PreviewMeshPath ) ) ;
2021-08-10 14:19:17 -04:00
# endif
2021-06-16 13:02:50 -04:00
2023-06-15 11:30:29 -04:00
InternalCommands . Append ( Super : : GeneratePythonCommands ( InNewBlueprintName ) ) ;
return InternalCommands ;
2021-04-15 14:30:33 -04:00
}
2019-01-08 11:38:48 -05:00
void UControlRigBlueprint : : GetTypeActions ( FBlueprintActionDatabaseRegistrar & ActionRegistrar ) const
{
2019-07-16 11:49:59 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2020-09-24 00:43:27 -04:00
IControlRigEditorModule : : Get ( ) . GetTypeActions ( ( UControlRigBlueprint * ) this , ActionRegistrar ) ;
}
void UControlRigBlueprint : : GetInstanceActions ( FBlueprintActionDatabaseRegistrar & ActionRegistrar ) const
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
IControlRigEditorModule : : Get ( ) . GetInstanceActions ( ( UControlRigBlueprint * ) this , ActionRegistrar ) ;
2019-01-08 11:38:48 -05:00
}
2019-09-17 19:12:19 -04:00
void UControlRigBlueprint : : PostTransacted ( const FTransactionObjectEvent & TransactionEvent )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
Super : : PostTransacted ( TransactionEvent ) ;
if ( TransactionEvent . GetEventType ( ) = = ETransactionObjectEventType : : UndoRedo )
{
2021-10-20 04:50:20 -04:00
TArray < FName > PropertiesChanged = TransactionEvent . GetChangedProperties ( ) ;
2024-03-06 13:20:40 -05:00
int32 TransactionIndex = GEditor - > Trans - > FindTransactionIndex ( TransactionEvent . GetTransactionId ( ) ) ;
const FTransaction * Transaction = GEditor - > Trans - > GetTransaction ( TransactionIndex ) ;
if ( Transaction & & Transaction - > ContainsObject ( Hierarchy ) )
2019-09-17 19:12:19 -04:00
{
2022-07-20 18:33:03 -04:00
if ( Transaction - > GetTitle ( ) . BuildSourceString ( ) = = TEXT ( " Transform Gizmo " ) )
2020-01-22 17:58:55 -05:00
{
PropagatePoseFromBPToInstances ( ) ;
return ;
}
2021-02-22 13:36:33 -04:00
PropagateHierarchyFromBPToInstances ( ) ;
2019-09-17 19:12:19 -04:00
// make sure the bone name list is up 2 date for the editor graph
2021-02-22 13:36:33 -04:00
for ( UEdGraph * Graph : UbergraphPages )
{
UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( Graph ) ;
2019-09-17 19:12:19 -04:00
if ( RigGraph = = nullptr )
{
continue ;
}
2022-06-21 04:15:34 -04:00
RigGraph - > CacheNameLists ( Hierarchy , & DrawContainer , ShapeLibraries ) ;
2019-09-17 19:12:19 -04:00
}
2020-01-22 17:58:55 -05:00
RequestAutoVMRecompilation ( ) ;
2023-06-15 11:30:29 -04:00
( void ) MarkPackageDirty ( ) ;
2020-01-22 17:58:55 -05:00
}
2023-11-03 07:05:55 -04:00
if ( PropertiesChanged . Contains ( GET_MEMBER_NAME_CHECKED ( UControlRigBlueprint , ModularRigModel ) ) )
{
if ( IsModularRig ( ) )
{
ModularRigModel . UpdateCachedChildren ( ) ;
2024-02-12 07:07:41 -05:00
ModularRigModel . Connections . UpdateFromConnectionList ( ) ;
2023-11-03 07:05:55 -04:00
RecompileModularRig ( ) ;
}
}
2022-05-31 04:27:20 -04:00
if ( PropertiesChanged . Contains ( GET_MEMBER_NAME_CHECKED ( UControlRigBlueprint , DrawContainer ) ) )
2020-01-22 17:58:55 -05:00
{
PropagateDrawInstructionsFromBPToInstances ( ) ;
2019-09-17 19:12:19 -04:00
}
2023-09-19 03:38:24 -04:00
if ( PropertiesChanged . Contains ( GET_MEMBER_NAME_CHECKED ( UControlRigBlueprint , ConnectionMap ) ) )
{
PropagateHierarchyFromBPToInstances ( ) ;
}
2019-09-17 19:12:19 -04:00
}
}
2021-09-13 14:45:23 -04:00
void UControlRigBlueprint : : PostDuplicate ( bool bDuplicateForPIE )
2021-09-13 13:52:43 -04:00
{
2023-06-15 11:30:29 -04:00
Super : : PostDuplicate ( bDuplicateForPIE ) ;
2021-09-13 14:45:23 -04:00
2021-09-17 11:26:26 -04:00
if ( URigHierarchyController * Controller = Hierarchy - > GetController ( true ) )
2021-09-13 13:52:43 -04:00
{
2021-09-17 11:26:26 -04:00
Controller - > OnModified ( ) . RemoveAll ( this ) ;
Controller - > OnModified ( ) . AddUObject ( this , & UControlRigBlueprint : : HandleHierarchyModified ) ;
2021-09-13 13:52:43 -04:00
}
2023-10-26 06:52:34 -04:00
if ( UModularRigController * ModularController = ModularRigModel . GetController ( ) )
{
ModularController - > OnModified ( ) . RemoveAll ( this ) ;
ModularController - > OnModified ( ) . AddUObject ( this , & UControlRigBlueprint : : HandleRigModulesModified ) ;
}
2023-12-07 05:19:14 -05:00
// update the rig module identifier after save-as or duplicate asset
if ( IsControlRigModule ( ) )
{
RigModuleSettings . Identifier . Name = URigHierarchy : : GetSanitizedName ( FRigName ( GetName ( ) ) ) . ToString ( ) ;
}
2023-10-26 06:52:34 -04:00
ModularRigModel . UpdateCachedChildren ( ) ;
2024-02-12 07:07:41 -05:00
ModularRigModel . Connections . UpdateFromConnectionList ( ) ;
2020-01-22 17:58:55 -05:00
}
2023-12-07 05:19:14 -05:00
void UControlRigBlueprint : : PostRename ( UObject * OldOuter , const FName OldName )
{
Super : : PostRename ( OldOuter , OldName ) ;
// update the rig module identifier after renaming the asset
if ( IsControlRigModule ( ) )
{
RigModuleSettings . Identifier . Name = URigHierarchy : : GetSanitizedName ( FRigName ( GetName ( ) ) ) . ToString ( ) ;
}
}
2020-01-22 17:58:55 -05:00
TArray < UControlRigBlueprint * > UControlRigBlueprint : : GetCurrentlyOpenRigBlueprints ( )
{
return sCurrentlyOpenedRigBlueprints ;
}
# if WITH_EDITOR
2021-10-20 11:56:18 -04:00
const FControlRigShapeDefinition * UControlRigBlueprint : : GetControlShapeByName ( const FName & InName ) const
{
2023-04-03 10:06:06 -04:00
TMap < FString , FString > LibraryNameMap ;
2023-10-30 07:01:53 -04:00
if ( UControlRig * ControlRig = Cast < UControlRig > ( GetObjectBeingDebugged ( ) ) )
2023-04-03 10:06:06 -04:00
{
LibraryNameMap = ControlRig - > ShapeLibraryNameMap ;
}
return UControlRigShapeLibrary : : GetShapeByName ( InName , ShapeLibraries , LibraryNameMap ) ;
2021-10-20 11:56:18 -04:00
}
2023-08-01 08:23:56 -04:00
FName UControlRigBlueprint : : AddTransientControl ( const URigVMUnitNode * InNode , const FRigDirectManipulationTarget & InTarget )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
TUniquePtr < FControlValueScope > ValueScope ;
2021-06-12 00:44:35 -04:00
if ( ! UControlRigEditorSettings : : Get ( ) - > bResetControlsOnPinValueInteraction ) // if we need to retain the controls
2020-09-24 00:43:27 -04:00
{
ValueScope = MakeUnique < FControlValueScope > ( this ) ;
}
2020-01-22 17:58:55 -05:00
// for now we only allow one pin control at the same time
ClearTransientControls ( ) ;
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( true /* create if needed */ ) ) ;
2020-01-22 17:58:55 -05:00
FName ReturnName = NAME_None ;
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
UControlRig * InstancedControlRig = Cast < UControlRig > ( ArchetypeInstance ) ;
2020-01-22 17:58:55 -05:00
if ( InstancedControlRig )
{
2023-08-01 08:23:56 -04:00
FName ControlName = InstancedControlRig - > AddTransientControl ( InNode , InTarget ) ;
2020-01-22 17:58:55 -05:00
if ( ReturnName = = NAME_None )
2020-09-24 00:43:27 -04:00
{
2020-01-22 17:58:55 -05:00
ReturnName = ControlName ;
}
}
}
return ReturnName ;
}
2023-08-01 08:23:56 -04:00
FName UControlRigBlueprint : : RemoveTransientControl ( const URigVMUnitNode * InNode , const FRigDirectManipulationTarget & InTarget )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
TUniquePtr < FControlValueScope > ValueScope ;
2021-06-12 00:44:35 -04:00
if ( ! UControlRigEditorSettings : : Get ( ) - > bResetControlsOnPinValueInteraction ) // if we need to retain the controls
2020-09-24 00:43:27 -04:00
{
ValueScope = MakeUnique < FControlValueScope > ( this ) ;
}
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( true /* create if needed */ ) ) ;
2020-01-22 17:58:55 -05:00
FName RemovedName = NAME_None ;
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
UControlRig * InstancedControlRig = Cast < UControlRig > ( ArchetypeInstance ) ;
2020-01-22 17:58:55 -05:00
if ( InstancedControlRig )
{
2023-08-01 08:23:56 -04:00
FName Name = InstancedControlRig - > RemoveTransientControl ( InNode , InTarget ) ;
2020-01-22 17:58:55 -05:00
if ( RemovedName = = NAME_None )
Reimplementing FProperty changes from //UE4/Main
+ Reimplemented FProperty related fixed from //UE4/Main:
CL#10791312, 10804850, 10851666, 10855122, 10855198, 10942138, 11030611, 11030639, 11032261, 11061515, 11136964,11138881, 11214238, 11214865
#rb none (previously reviewed in Dev-Core)
[FYI] Chris.Bunnner, Daniel.Lamb
#ROBOMERGE-OWNER: robert.manuszewski
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 11302985 via CL 11303011 via CL 11303019
#ROBOMERGE-BOT: (v0-11244347)
[CL 11303183 by robert manuszewski in Main branch]
2020-02-10 08:06:56 -05:00
{
2020-01-22 17:58:55 -05:00
RemovedName = Name ;
}
}
}
return RemovedName ;
}
FName UControlRigBlueprint : : AddTransientControl ( const FRigElementKey & InElement )
{
2020-09-24 00:43:27 -04:00
TUniquePtr < FControlValueScope > ValueScope ;
2021-06-12 00:44:35 -04:00
if ( ! UControlRigEditorSettings : : Get ( ) - > bResetControlsOnPinValueInteraction ) // if we need to retain the controls
2020-09-24 00:43:27 -04:00
{
ValueScope = MakeUnique < FControlValueScope > ( this ) ;
}
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( true /* create if needed */ ) ) ;
2020-01-22 17:58:55 -05:00
FName ReturnName = NAME_None ;
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
2021-04-08 10:49:40 -04:00
// hierarchy transforms will be reset when ClearTransientControls() is called,
// so to retain any bone transform modifications we have to save them
TMap < UObject * , FTransform > SavedElementLocalTransforms ;
2020-01-22 17:58:55 -05:00
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
UControlRig * InstancedControlRig = Cast < UControlRig > ( ArchetypeInstance ) ;
2020-01-22 17:58:55 -05:00
if ( InstancedControlRig )
2021-02-22 13:36:33 -04:00
{
2021-04-08 10:49:40 -04:00
if ( InstancedControlRig - > DynamicHierarchy )
{
SavedElementLocalTransforms . FindOrAdd ( InstancedControlRig ) = InstancedControlRig - > DynamicHierarchy - > GetLocalTransform ( InElement ) ;
}
}
}
// for now we only allow one pin control at the same time
ClearTransientControls ( ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
UControlRig * InstancedControlRig = Cast < UControlRig > ( ArchetypeInstance ) ;
2021-04-08 10:49:40 -04:00
if ( InstancedControlRig )
{
// restore the element transforms so that transient controls are created at the right place
if ( const FTransform * SavedTransform = SavedElementLocalTransforms . Find ( InstancedControlRig ) )
{
if ( InstancedControlRig - > DynamicHierarchy )
{
InstancedControlRig - > DynamicHierarchy - > SetLocalTransform ( InElement , * SavedTransform ) ;
}
}
2020-01-22 17:58:55 -05:00
FName ControlName = InstancedControlRig - > AddTransientControl ( InElement ) ;
if ( ReturnName = = NAME_None )
2021-02-22 13:36:33 -04:00
{
2021-03-01 18:14:52 -04:00
ReturnName = ControlName ;
2020-01-22 17:58:55 -05:00
}
}
}
return ReturnName ;
}
FName UControlRigBlueprint : : RemoveTransientControl ( const FRigElementKey & InElement )
{
2020-09-24 00:43:27 -04:00
TUniquePtr < FControlValueScope > ValueScope ;
2021-06-12 00:44:35 -04:00
if ( ! UControlRigEditorSettings : : Get ( ) - > bResetControlsOnPinValueInteraction ) // if we need to retain the controls
2020-09-24 00:43:27 -04:00
{
ValueScope = MakeUnique < FControlValueScope > ( this ) ;
}
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( true /* create if needed */ ) ) ;
2020-01-22 17:58:55 -05:00
FName RemovedName = NAME_None ;
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
UControlRig * InstancedControlRig = Cast < UControlRig > ( ArchetypeInstance ) ;
2020-01-22 17:58:55 -05:00
if ( InstancedControlRig )
{
FName Name = InstancedControlRig - > RemoveTransientControl ( InElement ) ;
if ( RemovedName = = NAME_None )
{
RemovedName = Name ;
}
}
}
return RemovedName ;
}
void UControlRigBlueprint : : ClearTransientControls ( )
{
2020-09-24 00:43:27 -04:00
TUniquePtr < FControlValueScope > ValueScope ;
2021-06-12 00:44:35 -04:00
if ( ! UControlRigEditorSettings : : Get ( ) - > bResetControlsOnPinValueInteraction ) // if we need to retain the controls
2020-09-24 00:43:27 -04:00
{
ValueScope = MakeUnique < FControlValueScope > ( this ) ;
}
2023-06-15 11:30:29 -04:00
if ( URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) )
2020-01-22 17:58:55 -05:00
{
2023-10-30 07:01:53 -04:00
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( true /* create if needed */ ) ) ;
2022-11-08 16:28:43 -05:00
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
2020-01-22 17:58:55 -05:00
{
2023-10-30 07:01:53 -04:00
UControlRig * InstancedControlRig = Cast < UControlRig > ( ArchetypeInstance ) ;
2022-11-08 16:28:43 -05:00
if ( InstancedControlRig )
{
InstancedControlRig - > ClearTransientControls ( ) ;
}
2020-01-22 17:58:55 -05:00
}
}
}
2023-10-26 06:52:34 -04:00
UModularRigController * UControlRigBlueprint : : GetModularRigController ( )
{
if ( ! GetControlRigClass ( ) - > IsChildOf ( UModularRig : : StaticClass ( ) ) )
{
return nullptr ;
}
return ModularRigModel . GetController ( ) ;
}
void UControlRigBlueprint : : RecompileModularRig ( )
{
2023-12-12 11:01:19 -05:00
RefreshModuleConnectors ( ) ;
2023-11-15 07:37:23 -05:00
OnModularRigPreCompiled ( ) . Broadcast ( this ) ;
2023-11-29 03:23:17 -05:00
if ( const UClass * MyControlRigClass = GeneratedClass )
2023-10-26 06:52:34 -04:00
{
if ( UModularRig * DefaultObject = Cast < UModularRig > ( MyControlRigClass - > GetDefaultObject ( false ) ) )
{
2023-11-23 09:55:54 -05:00
PropagateModuleHierarchyFromBPToInstances ( ) ;
2023-10-26 06:52:34 -04:00
}
}
2023-11-29 03:23:17 -05:00
UpdateModularDependencyDelegates ( ) ;
2023-11-09 05:26:12 -05:00
OnModularRigCompiled ( ) . Broadcast ( this ) ;
2023-10-26 06:52:34 -04:00
}
2020-01-22 17:58:55 -05:00
# endif
2023-06-15 11:30:29 -04:00
void UControlRigBlueprint : : SetupDefaultObjectDuringCompilation ( URigVMHost * InCDO )
2019-05-21 19:25:23 -04:00
{
2023-06-15 11:30:29 -04:00
Super : : SetupDefaultObjectDuringCompilation ( InCDO ) ;
2023-10-30 07:01:53 -04:00
CastChecked < UControlRig > ( InCDO ) - > GetHierarchy ( ) - > CopyHierarchy ( Hierarchy ) ;
2019-05-21 19:25:23 -04:00
}
2020-09-24 00:43:27 -04:00
void UControlRigBlueprint : : SetupPinRedirectorsForBackwardsCompatibility ( )
{
2022-05-31 04:27:20 -04:00
for ( URigVMGraph * Model : RigVMClient )
2020-09-24 00:43:27 -04:00
{
2022-05-31 04:27:20 -04:00
for ( URigVMNode * Node : Model - > GetNodes ( ) )
2020-09-24 00:43:27 -04:00
{
2022-05-31 04:27:20 -04:00
if ( URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( Node ) )
2020-09-24 00:43:27 -04:00
{
2022-05-31 04:27:20 -04:00
UScriptStruct * Struct = UnitNode - > GetScriptStruct ( ) ;
if ( Struct = = FRigUnit_SetBoneTransform : : StaticStruct ( ) )
{
URigVMPin * TransformPin = UnitNode - > FindPin ( TEXT ( " Transform " ) ) ;
URigVMPin * ResultPin = UnitNode - > FindPin ( TEXT ( " Result " ) ) ;
GetOrCreateController ( ) - > AddPinRedirector ( false , true , TransformPin - > GetPinPath ( ) , ResultPin - > GetPinPath ( ) ) ;
}
2020-09-24 00:43:27 -04:00
}
}
}
}
2023-06-15 11:30:29 -04:00
void UControlRigBlueprint : : PathDomainSpecificContentOnLoad ( )
2019-05-24 14:09:14 -04:00
{
2023-06-15 11:30:29 -04:00
PatchRigElementKeyCacheOnLoad ( ) ;
PatchPropagateToChildren ( ) ;
2020-09-24 00:43:27 -04:00
}
2021-11-24 05:32:05 -05:00
void UControlRigBlueprint : : PatchRigElementKeyCacheOnLoad ( )
{
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : RigElementKeyCache )
{
for ( URigVMGraph * Graph : GetAllModels ( ) )
{
URigVMController * Controller = GetOrCreateController ( Graph ) ;
TGuardValue < bool > DisablePinDefaultValueValidation ( Controller - > bValidatePinDefaults , false ) ;
2022-11-29 06:36:47 -05:00
FRigVMControllerNotifGuard NotifGuard ( Controller , true ) ;
2021-11-24 05:32:05 -05:00
for ( URigVMNode * Node : Graph - > GetNodes ( ) )
{
if ( URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( Node ) )
{
UScriptStruct * ScriptStruct = UnitNode - > GetScriptStruct ( ) ;
2022-03-01 04:23:55 -05:00
FString FunctionName = FString : : Printf ( TEXT ( " %s::%s " ) , * ScriptStruct - > GetStructCPPName ( ) , * UnitNode - > GetMethodName ( ) . ToString ( ) ) ;
const FRigVMFunction * Function = FRigVMRegistry : : Get ( ) . FindFunction ( * FunctionName ) ;
check ( Function ) ;
for ( TFieldIterator < FProperty > It ( Function - > Struct ) ; It ; + + It )
2021-11-24 05:32:05 -05:00
{
if ( It - > GetCPPType ( ) = = TEXT ( " FCachedRigElement " ) )
{
if ( URigVMPin * Pin = Node - > FindPin ( It - > GetName ( ) ) )
{
int32 BoneIndex = FCString : : Atoi ( * Pin - > GetDefaultValue ( ) ) ;
FRigElementKey Key = Hierarchy - > GetKey ( BoneIndex ) ;
FCachedRigElement DefaultValueElement ( Key , Hierarchy ) ;
FString Result ;
TBaseStructure < FCachedRigElement > : : Get ( ) - > ExportText ( Result , & DefaultValueElement , nullptr , nullptr , PPF_None , nullptr ) ;
Controller - > SetPinDefaultValue ( Pin - > GetPinPath ( ) , Result , true , false , false ) ;
2023-06-15 11:30:29 -04:00
MarkDirtyDuringLoad ( ) ;
2021-11-24 05:32:05 -05:00
}
}
}
}
}
}
}
}
2022-03-11 19:02:15 -05:00
// change the default value form False to True for transform nodes
void UControlRigBlueprint : : PatchPropagateToChildren ( )
{
// no need to update default value past this version
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) > = FControlRigObjectVersion : : RenameGizmoToShape )
{
return ;
}
auto IsNullOrControl = [ ] ( const URigVMPin * InPin )
{
const bool bHasItem = InPin - > GetCPPTypeObject ( ) = = FRigElementKey : : StaticStruct ( ) & & InPin - > GetName ( ) = = " Item " ;
if ( ! bHasItem )
{
return false ;
}
if ( const URigVMPin * TypePin = InPin - > FindSubPin ( TEXT ( " Type " ) ) )
{
const FString & TypeValue = TypePin - > GetDefaultValue ( ) ;
2022-06-15 16:00:03 -04:00
return TypeValue = = TEXT ( " Null " ) | | TypeValue = = TEXT ( " Space " ) | | TypeValue = = TEXT ( " Control " ) ;
2022-03-11 19:02:15 -05:00
}
return false ;
} ;
auto IsPropagateChildren = [ ] ( const URigVMPin * InPin )
{
return InPin - > GetCPPType ( ) = = TEXT ( " bool " ) & & InPin - > GetName ( ) = = TEXT ( " bPropagateToChildren " ) ;
} ;
auto FindPropagatePin = [ IsNullOrControl , IsPropagateChildren ] ( const URigVMNode * InNode ) - > URigVMPin *
{
URigVMPin * PropagatePin = nullptr ;
URigVMPin * ItemPin = nullptr ;
for ( URigVMPin * Pin : InNode - > GetPins ( ) )
{
// look for Item pin
if ( ! ItemPin & & IsNullOrControl ( Pin ) )
{
ItemPin = Pin ;
}
// look for bPropagateToChildren pin
if ( ! PropagatePin & & IsPropagateChildren ( Pin ) )
{
PropagatePin = Pin ;
}
// return propagation pin if both found
if ( ItemPin & & PropagatePin )
{
return PropagatePin ;
}
}
return nullptr ;
} ;
for ( URigVMGraph * Graph : GetAllModels ( ) )
{
TArray < const URigVMPin * > PinsToUpdate ;
for ( const URigVMNode * Node : Graph - > GetNodes ( ) )
{
if ( const URigVMPin * PropagatePin = FindPropagatePin ( Node ) )
{
PinsToUpdate . Add ( PropagatePin ) ;
}
}
if ( URigVMController * Controller = GetOrCreateController ( Graph ) )
{
2022-11-29 06:36:47 -05:00
FRigVMControllerNotifGuard NotifGuard ( Controller , true ) ;
2022-03-11 19:02:15 -05:00
for ( const URigVMPin * Pin : PinsToUpdate )
{
Controller - > SetPinDefaultValue ( Pin - > GetPinPath ( ) , TEXT ( " True " ) , false , false , false ) ;
}
}
}
}
2022-11-16 03:33:17 -05:00
void UControlRigBlueprint : : PatchFunctionsOnLoad ( )
{
2023-06-15 11:30:29 -04:00
URigVMBlueprintGeneratedClass * CRGeneratedClass = GetRigVMBlueprintGeneratedClass ( ) ;
2022-11-16 03:33:17 -05:00
FRigVMGraphFunctionStore & Store = CRGeneratedClass - > GraphFunctionStore ;
const URigVMFunctionLibrary * Library = GetLocalFunctionLibrary ( ) ;
2022-11-23 04:49:43 -05:00
TMap < URigVMLibraryNode * , FRigVMGraphFunctionHeader > OldHeaders ;
// Backwards compatibility. Store public access in the model
TArray < FName > BackwardsCompatiblePublicFunctions ;
2022-11-16 03:33:17 -05:00
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : StoreFunctionsInGeneratedClass )
{
2023-06-19 08:48:25 -04:00
for ( const FRigVMOldPublicFunctionData & OldPublicFunction : PublicFunctions_DEPRECATED )
2022-11-16 03:33:17 -05:00
{
2023-06-19 08:48:25 -04:00
BackwardsCompatiblePublicFunctions . Add ( OldPublicFunction . Name ) ;
2022-11-16 03:33:17 -05:00
}
}
2022-11-23 04:49:43 -05:00
else
2022-11-16 03:33:17 -05:00
{
2022-11-23 04:49:43 -05:00
if ( GetLinkerCustomVersion ( FUE5MainStreamObjectVersion : : GUID ) < FUE5MainStreamObjectVersion : : RigVMSaveFunctionAccessInModel )
2022-11-16 03:33:17 -05:00
{
2022-11-23 04:49:43 -05:00
for ( const FRigVMGraphFunctionData & FunctionData : Store . PublicFunctions )
2022-11-16 03:33:17 -05:00
{
2022-11-23 04:49:43 -05:00
BackwardsCompatiblePublicFunctions . Add ( FunctionData . Header . Name ) ;
URigVMLibraryNode * LibraryNode = Cast < URigVMLibraryNode > ( FunctionData . Header . LibraryPointer . LibraryNode . ResolveObject ( ) ) ;
OldHeaders . Add ( LibraryNode , FunctionData . Header ) ;
2022-11-16 03:33:17 -05:00
}
}
}
2023-02-01 11:14:45 -05:00
// Addressing issue where PublicGraphFunctions is populated, but the model PublicFunctionNames is not
URigVMFunctionLibrary * FunctionLibrary = GetLocalFunctionLibrary ( ) ;
if ( FunctionLibrary )
{
if ( PublicGraphFunctions . Num ( ) > FunctionLibrary - > PublicFunctionNames . Num ( ) )
{
for ( const FRigVMGraphFunctionHeader & PublicHeader : PublicGraphFunctions )
{
BackwardsCompatiblePublicFunctions . Add ( PublicHeader . Name ) ;
}
}
}
2022-11-16 03:33:17 -05:00
2022-11-23 04:49:43 -05:00
// Lets rebuild the FunctionStore from the model
2023-02-01 11:14:45 -05:00
if ( FunctionLibrary )
2022-11-16 03:33:17 -05:00
{
2022-11-23 04:49:43 -05:00
Store . PublicFunctions . Reset ( ) ;
Store . PrivateFunctions . Reset ( ) ;
for ( URigVMLibraryNode * LibraryNode : FunctionLibrary - > GetFunctions ( ) )
{
bool bIsPublic = FunctionLibrary - > IsFunctionPublic ( LibraryNode - > GetFName ( ) ) ;
if ( ! bIsPublic )
{
bIsPublic = BackwardsCompatiblePublicFunctions . Contains ( LibraryNode - > GetFName ( ) ) ;
if ( bIsPublic )
{
FunctionLibrary - > PublicFunctionNames . Add ( LibraryNode - > GetFName ( ) ) ;
}
}
FRigVMGraphFunctionHeader Header = LibraryNode - > GetFunctionHeader ( CRGeneratedClass ) ;
if ( FRigVMGraphFunctionHeader * OldHeader = OldHeaders . Find ( LibraryNode ) )
{
Header . ExternalVariables = OldHeader - > ExternalVariables ;
Header . Dependencies = OldHeader - > Dependencies ;
}
Store . AddFunction ( Header , bIsPublic ) ;
}
}
// Update dependencies and external variables if needed
for ( URigVMLibraryNode * LibraryNode : Library - > GetFunctions ( ) )
{
GetRigVMClient ( ) - > UpdateExternalVariablesForFunction ( LibraryNode ) ;
GetRigVMClient ( ) - > UpdateDependenciesForFunction ( LibraryNode ) ;
2022-11-16 03:33:17 -05:00
}
}
2023-07-25 08:51:17 -04:00
void UControlRigBlueprint : : CreateMemberVariablesOnLoad ( )
{
# if WITH_EDITOR
const int32 LinkerVersion = GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) ;
if ( LinkerVersion < FControlRigObjectVersion : : SwitchedToRigVM )
{
// ignore errors during the first potential compile of the VM
// since that this point variable nodes may still be ill-formed.
TGuardValue < FRigVMReportDelegate > SuspendReportDelegate ( VMCompileSettings . ASTSettings . ReportDelegate ,
FRigVMReportDelegate : : CreateLambda ( [ ] ( EMessageSeverity : : Type , UObject * , const FString & )
{
// do nothing
} )
) ;
InitializeModelIfRequired ( ) ;
}
AddedMemberVariableMap . Reset ( ) ;
for ( int32 VariableIndex = 0 ; VariableIndex < NewVariables . Num ( ) ; VariableIndex + + )
{
AddedMemberVariableMap . Add ( NewVariables [ VariableIndex ] . VarName , VariableIndex ) ;
}
if ( RigVMClient . Num ( ) = = 0 )
{
return ;
}
// setup variables on the blueprint based on the previous "parameters"
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : BlueprintVariableSupport )
{
TSharedPtr < FKismetNameValidator > NameValidator = MakeShareable ( new FKismetNameValidator ( this , NAME_None , nullptr ) ) ;
auto CreateVariable = [ this , NameValidator ] ( const URigVMVariableNode * InVariableNode )
{
if ( ! InVariableNode )
{
return ;
}
static const FString VariableString = TEXT ( " Variable " ) ;
if ( URigVMPin * VariablePin = InVariableNode - > FindPin ( VariableString ) )
{
if ( VariablePin - > GetDirection ( ) ! = ERigVMPinDirection : : Visible )
{
return ;
}
}
const FRigVMGraphVariableDescription Description = InVariableNode - > GetVariableDescription ( ) ;
if ( AddedMemberVariableMap . Contains ( Description . Name ) )
{
return ;
}
const FEdGraphPinType PinType = RigVMTypeUtils : : PinTypeFromExternalVariable ( Description . ToExternalVariable ( ) ) ;
if ( ! PinType . PinCategory . IsValid ( ) )
{
return ;
}
const FName VarName = FindHostMemberVariableUniqueName ( NameValidator , Description . Name . ToString ( ) ) ;
const int32 VariableIndex = AddHostMemberVariable ( this , VarName , PinType , false , false , FString ( ) ) ;
if ( VariableIndex ! = INDEX_NONE )
{
AddedMemberVariableMap . Add ( Description . Name , VariableIndex ) ;
MarkDirtyDuringLoad ( ) ;
}
} ;
auto CreateParameter = [ this , NameValidator ] ( const URigVMParameterNode * InParameterNode )
{
if ( ! InParameterNode )
{
return ;
}
static const FString ParameterString = TEXT ( " Parameter " ) ;
if ( const URigVMPin * ParameterPin = InParameterNode - > FindPin ( ParameterString ) )
{
if ( ParameterPin - > GetDirection ( ) ! = ERigVMPinDirection : : Visible )
{
return ;
}
}
const FRigVMGraphParameterDescription Description = InParameterNode - > GetParameterDescription ( ) ;
if ( AddedMemberVariableMap . Contains ( Description . Name ) )
{
return ;
}
const FEdGraphPinType PinType = RigVMTypeUtils : : PinTypeFromExternalVariable ( Description . ToExternalVariable ( ) ) ;
if ( ! PinType . PinCategory . IsValid ( ) )
{
return ;
}
const FName VarName = FindHostMemberVariableUniqueName ( NameValidator , Description . Name . ToString ( ) ) ;
const int32 VariableIndex = AddHostMemberVariable ( this , VarName , PinType , true , ! Description . bIsInput , FString ( ) ) ;
if ( VariableIndex ! = INDEX_NONE )
{
AddedMemberVariableMap . Add ( Description . Name , VariableIndex ) ;
MarkDirtyDuringLoad ( ) ;
}
} ;
for ( const URigVMGraph * Model : RigVMClient )
{
const TArray < URigVMNode * > & Nodes = Model - > GetNodes ( ) ;
for ( const URigVMNode * Node : Nodes )
{
if ( const URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( Node ) )
{
CreateVariable ( VariableNode ) ;
}
// Leaving this for backwards compatibility, even though we don't support parameters anymore
// When a parameter node is found, we will create a variable
else if ( const URigVMParameterNode * ParameterNode = Cast < URigVMParameterNode > ( Node ) )
{
CreateParameter ( ParameterNode ) ;
}
}
}
}
# endif
}
void UControlRigBlueprint : : PatchVariableNodesOnLoad ( )
{
# if WITH_EDITOR
// setup variables on the blueprint based on the previous "parameters"
if ( GetLinkerCustomVersion ( FControlRigObjectVersion : : GUID ) < FControlRigObjectVersion : : BlueprintVariableSupport )
{
TGuardValue < bool > GuardNotifsSelf ( bSuspendModelNotificationsForSelf , true ) ;
check ( GetDefaultModel ( ) ) ;
auto PatchVariableNode = [ this ] ( const URigVMVariableNode * InVariableNode )
{
if ( ! InVariableNode )
{
return ;
}
const FRigVMGraphVariableDescription Description = InVariableNode - > GetVariableDescription ( ) ;
if ( ! AddedMemberVariableMap . Contains ( Description . Name ) )
{
return ;
}
const int32 VariableIndex = AddedMemberVariableMap . FindChecked ( Description . Name ) ;
const FName VarName = NewVariables [ VariableIndex ] . VarName ;
GetOrCreateController ( ) - > RefreshVariableNode (
InVariableNode - > GetFName ( ) , VarName , Description . CPPType , Description . CPPTypeObject , false ) ;
MarkDirtyDuringLoad ( ) ;
} ;
auto PatchParameterNode = [ this ] ( const URigVMParameterNode * InParameterNode )
{
if ( ! InParameterNode )
{
return ;
}
const FRigVMGraphParameterDescription Description = InParameterNode - > GetParameterDescription ( ) ;
if ( ! AddedMemberVariableMap . Contains ( Description . Name ) )
{
return ;
}
const int32 VariableIndex = AddedMemberVariableMap . FindChecked ( Description . Name ) ;
const FName VarName = NewVariables [ VariableIndex ] . VarName ;
GetOrCreateController ( ) - > ReplaceParameterNodeWithVariable (
InParameterNode - > GetFName ( ) , VarName , Description . CPPType , Description . CPPTypeObject , false ) ;
MarkDirtyDuringLoad ( ) ;
} ;
for ( const URigVMGraph * Model : RigVMClient )
{
TArray < URigVMNode * > Nodes = Model - > GetNodes ( ) ;
for ( URigVMNode * Node : Nodes )
{
if ( const URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( Node ) )
{
PatchVariableNode ( VariableNode ) ;
}
else if ( const URigVMParameterNode * ParameterNode = Cast < URigVMParameterNode > ( Node ) )
{
PatchParameterNode ( ParameterNode ) ;
}
}
}
}
# endif
Super : : PatchVariableNodesOnLoad ( ) ;
}
2023-10-30 07:01:53 -04:00
void UControlRigBlueprint : : UpdateElementKeyRedirector ( UControlRig * InControlRig ) const
2023-09-19 03:38:24 -04:00
{
InControlRig - > HierarchySettings = HierarchySettings ;
InControlRig - > RigModuleSettings = RigModuleSettings ;
2023-10-26 06:52:34 -04:00
InControlRig - > ElementKeyRedirector = FRigElementKeyRedirector ( ConnectionMap , InControlRig - > GetHierarchy ( ) ) ;
2023-09-19 03:38:24 -04:00
}
2023-10-30 07:01:53 -04:00
void UControlRigBlueprint : : PropagatePoseFromInstanceToBP ( UControlRig * InControlRig ) const
2019-09-17 19:12:19 -04:00
{
2020-01-22 17:58:55 -05:00
check ( InControlRig ) ;
2021-11-08 09:59:36 -05:00
// current transforms in BP and CDO are meaningless, no need to copy them
// we use BP hierarchy to initialize CDO and instances' hierarchy,
// so it should always be in the initial state.
2022-02-18 10:27:44 -05:00
Hierarchy - > CopyPose ( InControlRig - > GetHierarchy ( ) , false , true , false , true ) ;
2019-09-17 19:12:19 -04:00
}
2023-06-15 11:30:29 -04:00
void UControlRigBlueprint : : PropagatePoseFromBPToInstances ( ) const
2019-09-17 19:12:19 -04:00
{
if ( UClass * MyControlRigClass = GeneratedClass )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * DefaultObject = Cast < UControlRig > ( MyControlRigClass - > GetDefaultObject ( false ) ) )
2019-09-17 19:12:19 -04:00
{
2021-09-21 05:06:09 -04:00
DefaultObject - > PostInitInstanceIfRequired ( ) ;
2022-02-18 10:27:44 -05:00
DefaultObject - > GetHierarchy ( ) - > CopyPose ( Hierarchy , true , true , true ) ;
2021-06-09 17:27:12 -04:00
2020-01-22 17:58:55 -05:00
TArray < UObject * > ArchetypeInstances ;
DefaultObject - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * InstanceRig = Cast < UControlRig > ( ArchetypeInstance ) )
2021-02-22 13:36:33 -04:00
{
2021-09-21 05:06:09 -04:00
InstanceRig - > PostInitInstanceIfRequired ( ) ;
2023-11-29 03:23:17 -05:00
if ( ! InstanceRig - > IsRigModuleInstance ( ) )
{
InstanceRig - > GetHierarchy ( ) - > CopyPose ( Hierarchy , true , true , true ) ;
}
2021-02-22 13:36:33 -04:00
}
}
2020-01-22 17:58:55 -05:00
}
}
}
2023-06-15 11:30:29 -04:00
void UControlRigBlueprint : : PropagateHierarchyFromBPToInstances ( ) const
2020-01-22 17:58:55 -05:00
{
if ( UClass * MyControlRigClass = GeneratedClass )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * DefaultObject = Cast < UControlRig > ( MyControlRigClass - > GetDefaultObject ( false ) ) )
2020-01-22 17:58:55 -05:00
{
2021-09-21 05:06:09 -04:00
DefaultObject - > PostInitInstanceIfRequired ( ) ;
2021-02-22 13:36:33 -04:00
DefaultObject - > GetHierarchy ( ) - > CopyHierarchy ( Hierarchy ) ;
2023-09-19 03:38:24 -04:00
UpdateElementKeyRedirector ( DefaultObject ) ;
2023-08-23 03:13:37 -04:00
if ( ! DefaultObject - > HasAnyFlags ( RF_NeedPostLoad ) ) // If CDO is loading, skip Init, it will be done later
{
DefaultObject - > Initialize ( true ) ;
}
2019-09-17 19:12:19 -04:00
2021-02-22 13:36:33 -04:00
TArray < UObject * > ArchetypeInstances ;
DefaultObject - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
2020-01-22 17:58:55 -05:00
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * InstanceRig = Cast < UControlRig > ( ArchetypeInstance ) )
2019-09-17 19:12:19 -04:00
{
2024-02-01 11:59:55 -05:00
if ( InstanceRig - > IsRigModuleInstance ( ) )
{
if ( UModularRig * ModularRig = Cast < UModularRig > ( InstanceRig - > GetOuter ( ) ) )
{
ModularRig - > RequestInit ( ) ;
}
}
else
{
InstanceRig - > PostInitInstanceIfRequired ( ) ;
InstanceRig - > GetHierarchy ( ) - > CopyHierarchy ( Hierarchy ) ;
InstanceRig - > HierarchySettings = HierarchySettings ;
UpdateElementKeyRedirector ( InstanceRig ) ;
InstanceRig - > Initialize ( true ) ;
}
2019-09-17 19:12:19 -04:00
}
}
}
}
}
2023-06-15 11:30:29 -04:00
void UControlRigBlueprint : : PropagateDrawInstructionsFromBPToInstances ( ) const
2020-01-22 17:58:55 -05:00
{
if ( UClass * MyControlRigClass = GeneratedClass )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * DefaultObject = Cast < UControlRig > ( MyControlRigClass - > GetDefaultObject ( false ) ) )
Reimplementing FProperty changes from //UE4/Main
+ Reimplemented FProperty related fixed from //UE4/Main:
CL#10791312, 10804850, 10851666, 10855122, 10855198, 10942138, 11030611, 11030639, 11032261, 11061515, 11136964,11138881, 11214238, 11214865
#rb none (previously reviewed in Dev-Core)
[FYI] Chris.Bunnner, Daniel.Lamb
#ROBOMERGE-OWNER: robert.manuszewski
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 11302985 via CL 11303011 via CL 11303019
#ROBOMERGE-BOT: (v0-11244347)
[CL 11303183 by robert manuszewski in Main branch]
2020-02-10 08:06:56 -05:00
{
2020-01-22 17:58:55 -05:00
DefaultObject - > DrawContainer = DrawContainer ;
TArray < UObject * > ArchetypeInstances ;
DefaultObject - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * InstanceRig = Cast < UControlRig > ( ArchetypeInstance ) )
Reimplementing FProperty changes from //UE4/Main
+ Reimplemented FProperty related fixed from //UE4/Main:
CL#10791312, 10804850, 10851666, 10855122, 10855198, 10942138, 11030611, 11030639, 11032261, 11061515, 11136964,11138881, 11214238, 11214865
#rb none (previously reviewed in Dev-Core)
[FYI] Chris.Bunnner, Daniel.Lamb
#ROBOMERGE-OWNER: robert.manuszewski
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 11302985 via CL 11303011 via CL 11303019
#ROBOMERGE-BOT: (v0-11244347)
[CL 11303183 by robert manuszewski in Main branch]
2020-02-10 08:06:56 -05:00
{
2020-01-22 17:58:55 -05:00
InstanceRig - > DrawContainer = DrawContainer ;
}
}
}
}
// make sure the bone name list is up 2 date for the editor graph
for ( UEdGraph * Graph : UbergraphPages )
{
UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( Graph ) ;
if ( RigGraph = = nullptr )
{
continue ;
}
2022-06-21 04:15:34 -04:00
RigGraph - > CacheNameLists ( Hierarchy , & DrawContainer , ShapeLibraries ) ;
2020-01-22 17:58:55 -05:00
}
}
2023-06-15 11:30:29 -04:00
void UControlRigBlueprint : : PropagatePropertyFromBPToInstances ( FRigElementKey InRigElement , const FProperty * InProperty ) const
2020-01-22 17:58:55 -05:00
{
2021-02-22 13:36:33 -04:00
int32 ElementIndex = Hierarchy - > GetIndex ( InRigElement ) ;
2020-01-22 17:58:55 -05:00
ensure ( ElementIndex ! = INDEX_NONE ) ;
check ( InProperty ) ;
if ( UClass * MyControlRigClass = GeneratedClass )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * DefaultObject = Cast < UControlRig > ( MyControlRigClass - > GetDefaultObject ( false ) ) )
2020-01-22 17:58:55 -05:00
{
TArray < UObject * > ArchetypeInstances ;
DefaultObject - > GetArchetypeInstances ( ArchetypeInstances ) ;
2021-02-22 13:36:33 -04:00
const int32 PropertyOffset = InProperty - > GetOffset_ReplaceWith_ContainerPtrToValuePtr ( ) ;
const int32 PropertySize = InProperty - > GetSize ( ) ;
2020-01-22 17:58:55 -05:00
2021-02-22 13:36:33 -04:00
uint8 * Source = ( ( uint8 * ) Hierarchy - > Get ( ElementIndex ) ) + PropertyOffset ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
2020-01-22 17:58:55 -05:00
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * InstanceRig = Cast < UControlRig > ( ArchetypeInstance ) )
2020-01-22 17:58:55 -05:00
{
2021-09-21 05:06:09 -04:00
InstanceRig - > PostInitInstanceIfRequired ( ) ;
2021-02-22 13:36:33 -04:00
uint8 * Dest = ( ( uint8 * ) InstanceRig - > GetHierarchy ( ) - > Get ( ElementIndex ) ) + PropertyOffset ;
FMemory : : Memcpy ( Dest , Source , PropertySize ) ;
2020-01-22 17:58:55 -05:00
}
}
}
2021-02-22 13:36:33 -04:00
}
2020-01-22 17:58:55 -05:00
}
2023-10-30 07:01:53 -04:00
void UControlRigBlueprint : : PropagatePropertyFromInstanceToBP ( FRigElementKey InRigElement , const FProperty * InProperty , UControlRig * InInstance ) const
2020-01-22 17:58:55 -05:00
{
2021-02-22 13:36:33 -04:00
const int32 ElementIndex = Hierarchy - > GetIndex ( InRigElement ) ;
2020-01-22 17:58:55 -05:00
ensure ( ElementIndex ! = INDEX_NONE ) ;
check ( InProperty ) ;
2021-02-22 13:36:33 -04:00
const int32 PropertyOffset = InProperty - > GetOffset_ReplaceWith_ContainerPtrToValuePtr ( ) ;
const int32 PropertySize = InProperty - > GetSize ( ) ;
uint8 * Source = ( ( uint8 * ) InInstance - > GetHierarchy ( ) - > Get ( ElementIndex ) ) + PropertyOffset ;
uint8 * Dest = ( ( uint8 * ) Hierarchy - > Get ( ElementIndex ) ) + PropertyOffset ;
FMemory : : Memcpy ( Dest , Source , PropertySize ) ;
}
2020-01-22 17:58:55 -05:00
2023-11-23 09:55:54 -05:00
void UControlRigBlueprint : : PropagateModuleHierarchyFromBPToInstances ( ) const
{
2023-11-29 03:23:17 -05:00
if ( const UClass * MyControlRigClass = GeneratedClass )
2023-11-23 09:55:54 -05:00
{
2024-02-20 20:21:15 -05:00
if ( UModularRig * DefaultObject = Cast < UModularRig > ( MyControlRigClass - > GetDefaultObject ( false ) ) )
2023-11-23 09:55:54 -05:00
{
2024-02-20 20:21:15 -05:00
// We need to first transfer the model from the blueprint to the CDO
// We then ask instances to initialize which will provoke a call UModularRig::UpdateModuleHierarchyFromCDO
DefaultObject - > ResetModules ( ) ;
// copy the model over to the CDO.
// non-CDO instances are going to instantiate the model into a
// UObject module instance tree. CDO's are data only to avoid bugs /
// behaviors in the blueprint re-instancer - which is disregarding any
// object under a CDO.
DefaultObject - > ModularRigModel = ModularRigModel ;
DefaultObject - > ModularRigModel . SetOuterClientHost ( DefaultObject ) ;
DefaultObject - > ModularRigSettings = ModularRigSettings ;
2023-11-23 09:55:54 -05:00
TArray < UObject * > ArchetypeInstances ;
DefaultObject - > GetArchetypeInstances ( ArchetypeInstances ) ;
for ( UObject * ArchetypeInstance : ArchetypeInstances )
{
if ( UControlRig * InstanceRig = Cast < UControlRig > ( ArchetypeInstance ) )
{
// this will provoke a call to InitializeFromCDO
InstanceRig - > Initialize ( true ) ;
}
}
}
}
}
2021-02-22 13:36:33 -04:00
2023-11-29 03:23:17 -05:00
void UControlRigBlueprint : : UpdateModularDependencyDelegates ( )
{
TArray < const UBlueprint * > VisitList ;
ModularRigModel . ForEachModule ( [ & VisitList , this ] ( const FRigModuleReference * Element ) - > bool
{
if ( const UClass * Class = Element - > Class . Get ( ) )
{
if ( UControlRigBlueprint * Blueprint = Cast < UControlRigBlueprint > ( Class - > ClassGeneratedBy ) )
{
if ( ! VisitList . Contains ( Blueprint ) )
{
Blueprint - > OnVMCompiled ( ) . RemoveAll ( this ) ;
Blueprint - > OnVMCompiled ( ) . AddUObject ( this , & UControlRigBlueprint : : OnModularDependencyVMCompiled ) ;
Blueprint - > OnModularRigCompiled ( ) . AddUObject ( this , & UControlRigBlueprint : : OnModularDependencyChanged ) ;
VisitList . Add ( Blueprint ) ;
}
}
}
return true ;
} ) ;
}
void UControlRigBlueprint : : OnModularDependencyVMCompiled ( UObject * InBlueprint , URigVM * InVM , FRigVMExtendedExecuteContext & InExecuteContext )
{
if ( URigVMBlueprint * RigVMBlueprint = Cast < URigVMBlueprint > ( InBlueprint ) )
{
OnModularDependencyChanged ( RigVMBlueprint ) ;
}
}
void UControlRigBlueprint : : OnModularDependencyChanged ( URigVMBlueprint * InBlueprint )
2024-02-09 08:55:19 -05:00
{
RequestConstructionOnAllModules ( ) ;
}
void UControlRigBlueprint : : RequestConstructionOnAllModules ( )
2023-11-29 03:23:17 -05:00
{
// the rig will perform initialize itself - but we should request construction
check ( IsModularRig ( ) ) ;
const URigVMBlueprintGeneratedClass * RigClass = GetRigVMBlueprintGeneratedClass ( ) ;
check ( RigClass ) ;
UControlRig * CDO = Cast < UControlRig > ( RigClass - > GetDefaultObject ( true /* create if needed */ ) ) ;
TArray < UObject * > ArchetypeInstances ;
CDO - > GetArchetypeInstances ( ArchetypeInstances ) ;
// visit all or our instances and request construction
for ( UObject * Instance : ArchetypeInstances )
{
if ( UModularRig * InstanceRig = Cast < UModularRig > ( Instance ) )
{
InstanceRig - > RequestConstruction ( ) ;
}
}
}
2023-12-05 06:19:11 -05:00
void UControlRigBlueprint : : RefreshModuleConnectors ( )
{
if ( ! IsModularRig ( ) )
{
return ;
}
ModularRigModel . ForEachModule ( [ this ] ( const FRigModuleReference * Element ) - > bool
{
RefreshModuleConnectors ( Element ) ;
return true ;
} ) ;
}
void UControlRigBlueprint : : RefreshModuleConnectors ( const FRigModuleReference * InModule )
{
if ( ! IsModularRig ( ) )
{
return ;
}
// avoid dead class pointers
if ( InModule - > Class . Get ( ) = = nullptr )
{
return ;
}
const bool bRemoveAllConnectors = ! ModularRigModel . FindModule ( InModule - > GetPath ( ) ) ;
if ( URigHierarchyController * Controller = GetHierarchyController ( ) )
{
if ( UControlRig * CDO = GetControlRigClass ( ) - > GetDefaultObject < UControlRig > ( ) )
{
Hierarchy - > Modify ( ) ;
const FString Namespace = InModule - > GetNamespace ( ) ;
const TArray < FRigElementKey > AllConnectors = Hierarchy - > GetKeysOfType < FRigConnectorElement > ( ) ;
const TArray < FRigElementKey > ExistingConnectors = AllConnectors . FilterByPredicate ( [ Namespace ] ( const FRigElementKey & ConnectorKey ) - > bool
{
const FString ConnectorName = ConnectorKey . Name . ToString ( ) ;
2024-01-23 06:29:09 -05:00
FString ConnectorNamespace ;
( void ) URigHierarchy : : SplitNameSpace ( ConnectorName , & ConnectorNamespace , nullptr ) ;
2023-12-05 06:19:11 -05:00
ConnectorNamespace . Append ( UModularRig : : NamespaceSeparator ) ;
return ConnectorNamespace . Equals ( Namespace , ESearchCase : : CaseSensitive ) ;
} ) ;
// setup the module information. this is needed so that newly added
// connectors result in the right namespace metadata etc
FRigVMExtendedExecuteContext & Context = CDO - > GetRigVMExtendedExecuteContext ( ) ;
FControlRigExecuteContext & PublicContext = Context . GetPublicDataSafe < FControlRigExecuteContext > ( ) ;
const UControlRig * ModuleCDO = InModule - > Class - > GetDefaultObject < UControlRig > ( ) ;
const TArray < FRigModuleConnector > & ExpectedConnectors = ModuleCDO - > GetRigModuleSettings ( ) . ExposedConnectors ;
// remove the obsolete connectors
for ( const FRigElementKey & Connector : ExistingConnectors )
{
const FString ConnectorNameString = Connector . Name . ToString ( ) ;
FString ConnectorNamespace , ShortName = ConnectorNameString ;
2024-01-23 06:29:09 -05:00
( void ) URigHierarchy : : SplitNameSpace ( ConnectorNameString , & ConnectorNamespace , & ShortName ) ;
2023-12-05 06:19:11 -05:00
const bool bConnectorExpected = ExpectedConnectors . ContainsByPredicate (
[ ShortName ] ( const FRigModuleConnector & ExpectedConnector ) - > bool
{
return ExpectedConnector . Name . Equals ( ShortName , ESearchCase : : CaseSensitive ) ;
}
) ;
if ( bRemoveAllConnectors | | ! bConnectorExpected )
{
( void ) Controller - > RemoveElement ( Connector ) ;
2023-12-12 11:01:19 -05:00
ConnectionMap . Remove ( Connector ) ;
2023-12-05 06:19:11 -05:00
}
}
// add the missing expected connectors
if ( ! bRemoveAllConnectors )
{
for ( const FRigModuleConnector & Connector : ExpectedConnectors )
{
const FName ConnectorName = * Connector . Name ;
2023-12-12 11:01:19 -05:00
const FName ConnectorNameWithNameSpace = * URigHierarchy : : JoinNameSpace ( InModule - > GetNamespace ( ) , Connector . Name ) ;
const FRigElementKey ConnectorKeyWithNameSpace ( ConnectorNameWithNameSpace , ERigElementType : : Connector ) ;
if ( ! Hierarchy - > Contains ( ConnectorKeyWithNameSpace ) )
2023-12-05 06:19:11 -05:00
{
2023-12-12 11:01:19 -05:00
FRigHierarchyExecuteContextBracket HierarchyContextGuard ( Hierarchy , & Context ) ;
FControlRigExecuteContextRigModuleGuard RigModuleGuard ( PublicContext , InModule - > GetNamespace ( ) ) ;
2023-12-05 06:19:11 -05:00
( void ) Controller - > AddConnector ( ConnectorName , Connector . Settings ) ;
}
2023-12-12 11:01:19 -05:00
else
{
// copy the connector settings
FRigConnectorElement * ExistingConnector = Hierarchy - > FindChecked < FRigConnectorElement > ( ConnectorKeyWithNameSpace ) ;
ExistingConnector - > Settings = Connector . Settings ;
}
2023-12-05 06:19:11 -05:00
}
}
PropagateHierarchyFromBPToInstances ( ) ;
}
}
}
2021-02-22 13:36:33 -04:00
void UControlRigBlueprint : : HandleHierarchyModified ( ERigHierarchyNotification InNotification , URigHierarchy * InHierarchy , const FRigBaseElement * InElement )
{
# if WITH_EDITOR
if ( bSuspendAllNotifications )
2020-01-22 17:58:55 -05:00
{
2021-02-22 13:36:33 -04:00
return ;
}
switch ( InNotification )
{
case ERigHierarchyNotification : : ElementRemoved :
2020-01-22 17:58:55 -05:00
{
2021-02-22 13:36:33 -04:00
Modify ( ) ;
Influences . OnKeyRemoved ( InElement - > GetKey ( ) ) ;
PropagateHierarchyFromBPToInstances ( ) ;
2020-01-22 17:58:55 -05:00
break ;
}
2021-02-22 13:36:33 -04:00
case ERigHierarchyNotification : : ElementRenamed :
{
Modify ( ) ;
2024-01-28 14:06:08 -05:00
const FRigElementKey OldKey ( InHierarchy - > GetPreviousName ( InElement - > GetKey ( ) ) , InElement - > GetType ( ) ) ;
Influences . OnKeyRenamed ( OldKey , InElement - > GetKey ( ) ) ;
if ( IsControlRigModule ( ) & & InElement - > IsTypeOf ( ERigElementType : : Connector ) )
{
if ( FRigElementKey * Target = ConnectionMap . Find ( OldKey ) )
{
ConnectionMap . FindOrAdd ( InElement - > GetKey ( ) , * Target ) ;
ConnectionMap . Remove ( OldKey ) ;
}
}
2021-02-22 13:36:33 -04:00
PropagateHierarchyFromBPToInstances ( ) ;
break ;
}
case ERigHierarchyNotification : : ElementAdded :
case ERigHierarchyNotification : : ParentChanged :
2022-10-14 07:53:25 -04:00
case ERigHierarchyNotification : : ElementReordered :
2021-02-22 13:36:33 -04:00
case ERigHierarchyNotification : : HierarchyReset :
{
Modify ( ) ;
PropagateHierarchyFromBPToInstances ( ) ;
break ;
}
case ERigHierarchyNotification : : ElementSelected :
{
bool bClearTransientControls = true ;
if ( const FRigControlElement * ControlElement = Cast < FRigControlElement > ( InElement ) )
Reimplementing FProperty changes from //UE4/Main
+ Reimplemented FProperty related fixed from //UE4/Main:
CL#10791312, 10804850, 10851666, 10855122, 10855198, 10942138, 11030611, 11030639, 11032261, 11061515, 11136964,11138881, 11214238, 11214865
#rb none (previously reviewed in Dev-Core)
[FYI] Chris.Bunnner, Daniel.Lamb
#ROBOMERGE-OWNER: robert.manuszewski
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 11302985 via CL 11303011 via CL 11303019
#ROBOMERGE-BOT: (v0-11244347)
[CL 11303183 by robert manuszewski in Main branch]
2020-02-10 08:06:56 -05:00
{
2021-02-22 13:36:33 -04:00
if ( ControlElement - > Settings . bIsTransientControl )
{
bClearTransientControls = false ;
}
}
2021-06-09 09:19:35 -04:00
if ( bClearTransientControls )
{
2023-10-30 07:01:53 -04:00
if ( UControlRig * RigBeingDebugged = Cast < UControlRig > ( GetObjectBeingDebugged ( ) ) )
2021-06-09 09:19:35 -04:00
{
2023-10-30 07:01:53 -04:00
const FName TransientControlName = UControlRig : : GetNameForTransientControl ( InElement - > GetKey ( ) ) ;
2021-06-09 09:19:35 -04:00
const FRigElementKey TransientControlKey ( TransientControlName , ERigElementType : : Control ) ;
if ( const FRigControlElement * ControlElement = RigBeingDebugged - > GetHierarchy ( ) - > Find < FRigControlElement > ( TransientControlKey ) )
{
if ( ControlElement - > Settings . bIsTransientControl )
{
bClearTransientControls = false ;
}
}
}
}
2021-02-22 13:36:33 -04:00
if ( bClearTransientControls )
{
ClearTransientControls ( ) ;
}
2020-01-22 17:58:55 -05:00
break ;
}
2023-08-01 08:23:56 -04:00
case ERigHierarchyNotification : : ElementDeselected :
{
if ( const FRigControlElement * ControlElement = Cast < FRigControlElement > ( InElement ) )
{
if ( ControlElement - > Settings . bIsTransientControl )
{
ClearTransientControls ( ) ;
}
}
break ;
}
2020-01-22 17:58:55 -05:00
default :
{
break ;
}
}
2021-06-21 08:03:43 -04:00
HierarchyModifiedEvent . Broadcast ( InNotification , InHierarchy , InElement ) ;
2021-02-22 13:36:33 -04:00
2019-09-17 19:12:19 -04:00
# endif
2021-02-22 13:36:33 -04:00
}
2019-09-17 19:12:19 -04:00
2023-10-26 06:52:34 -04:00
void UControlRigBlueprint : : HandleRigModulesModified ( EModularRigNotification InNotification , const FRigModuleReference * InModule )
{
2024-01-19 04:34:33 -05:00
bool bRecompile = true ;
2023-11-03 08:15:33 -04:00
switch ( InNotification )
{
2023-11-10 06:13:25 -05:00
case EModularRigNotification : : ModuleAdded :
{
if ( InModule )
{
2023-12-05 06:19:11 -05:00
RefreshModuleConnectors ( InModule ) ;
2023-11-29 03:23:17 -05:00
UpdateModularDependencyDelegates ( ) ;
2023-11-10 06:13:25 -05:00
}
break ;
}
case EModularRigNotification : : ModuleRenamed :
2023-11-13 12:30:59 -05:00
case EModularRigNotification : : ModuleReparented :
2023-11-10 06:13:25 -05:00
{
if ( InModule )
{
if ( URigHierarchyController * Controller = GetHierarchyController ( ) )
{
if ( UControlRig * CDO = GetControlRigClass ( ) - > GetDefaultObject < UControlRig > ( ) )
{
2023-11-13 12:30:59 -05:00
Hierarchy - > Modify ( ) ;
2023-11-10 06:13:25 -05:00
struct ConnectionInfo
{
FString NewPath ;
FRigElementKey TargetConnection ;
FRigConnectorSettings Settings ;
} ;
2023-11-16 08:46:07 -05:00
FString OldNamespace ;
2023-11-13 12:30:59 -05:00
if ( InNotification = = EModularRigNotification : : ModuleRenamed )
{
2023-12-07 09:11:55 -05:00
OldNamespace = ( InModule - > ParentPath . IsEmpty ( ) ) ? * InModule - > PreviousName . ToString ( ) : URigHierarchy : : JoinNameSpace ( InModule - > ParentPath , InModule - > PreviousName . ToString ( ) ) ;
2023-11-13 12:30:59 -05:00
}
else if ( InNotification = = EModularRigNotification : : ModuleReparented )
{
2024-02-14 16:09:39 -05:00
OldNamespace = ( InModule - > PreviousParentPath . IsEmpty ( ) ) ? * InModule - > PreviousName . ToString ( ) : URigHierarchy : : JoinNameSpace ( InModule - > PreviousParentPath , InModule - > PreviousName . ToString ( ) ) ;
2023-11-13 12:30:59 -05:00
}
2023-12-07 09:11:55 -05:00
FString NewNamespace = ( InModule - > ParentPath . IsEmpty ( ) ) ? * InModule - > Name . ToString ( ) : URigHierarchy : : JoinNameSpace ( InModule - > ParentPath , InModule - > Name . ToString ( ) ) ;
2023-11-16 08:46:07 -05:00
OldNamespace . Append ( UModularRig : : NamespaceSeparator ) ;
NewNamespace . Append ( UModularRig : : NamespaceSeparator ) ;
2023-11-10 06:13:25 -05:00
TArray < FRigElementKey > Connectors = Controller - > GetHierarchy ( ) - > GetKeysOfType < FRigConnectorElement > ( ) ;
TMap < FRigElementKey , ConnectionInfo > RenamedConnectors ; // old key -> new key
for ( const FRigElementKey & Connector : Connectors )
{
FString OldConnectorName = Connector . Name . ToString ( ) ;
2023-11-16 08:46:07 -05:00
FString OldConnectorNamespace , ShortName ;
2024-01-23 06:29:09 -05:00
( void ) URigHierarchy : : SplitNameSpace ( OldConnectorName , & OldConnectorNamespace , & ShortName ) ;
2023-11-16 08:46:07 -05:00
OldConnectorNamespace . Append ( UModularRig : : NamespaceSeparator ) ;
2023-11-24 10:45:27 -05:00
if ( OldConnectorNamespace . StartsWith ( OldNamespace ) )
2023-11-10 06:13:25 -05:00
{
ConnectionInfo & Info = RenamedConnectors . FindOrAdd ( Connector ) ;
2023-11-16 08:46:07 -05:00
Info . NewPath = OldConnectorName . Replace ( * OldNamespace , * NewNamespace ) ;
2023-11-10 06:13:25 -05:00
Info . Settings = CastChecked < FRigConnectorElement > ( Controller - > GetHierarchy ( ) - > FindChecked ( Connector ) ) - > Settings ;
if ( FRigElementKey * TargetKey = ConnectionMap . Find ( Connector ) )
{
Info . TargetConnection = * TargetKey ;
}
}
}
// Remove connectors
for ( TPair < FRigElementKey , ConnectionInfo > & Pair : RenamedConnectors )
{
Controller - > RemoveElement ( Pair . Key ) ;
}
// Add connectors
{
FRigVMExtendedExecuteContext & Context = CDO - > GetRigVMExtendedExecuteContext ( ) ;
FRigHierarchyExecuteContextBracket HierarchyContextGuard ( Controller - > GetHierarchy ( ) , & Context ) ;
FControlRigExecuteContext & PublicContext = Context . GetPublicDataSafe < FControlRigExecuteContext > ( ) ;
for ( TPair < FRigElementKey , ConnectionInfo > & Pair : RenamedConnectors )
{
FString Namespace , ConnectorName ;
2024-01-23 06:29:09 -05:00
( void ) URigHierarchy : : SplitNameSpace ( Pair . Value . NewPath , & Namespace , & ConnectorName ) ;
2023-11-16 08:46:07 -05:00
Namespace . Append ( UModularRig : : NamespaceSeparator ) ;
2023-11-10 06:13:25 -05:00
FControlRigExecuteContextRigModuleGuard RigModuleGuard ( PublicContext , Namespace ) ;
2024-01-24 07:26:18 -05:00
const TGuardValue < bool > DisableErrors ( Controller - > bReportWarningsAndErrors , false ) ;
2023-11-10 06:13:25 -05:00
Controller - > AddConnector ( * ConnectorName , Pair . Value . Settings ) ;
}
}
2024-01-19 04:34:33 -05:00
UpdateConnectionMapFromModel ( ) ;
2023-11-10 06:13:25 -05:00
PropagateHierarchyFromBPToInstances ( ) ;
}
}
}
break ;
}
2023-11-13 12:30:59 -05:00
case EModularRigNotification : : ModuleRemoved :
{
if ( InModule )
{
2023-12-05 06:19:11 -05:00
RefreshModuleConnectors ( InModule ) ;
2024-01-19 04:34:33 -05:00
UpdateConnectionMapFromModel ( ) ;
2023-11-29 03:23:17 -05:00
UpdateModularDependencyDelegates ( ) ;
2023-11-13 12:30:59 -05:00
}
break ;
}
2023-11-03 08:15:33 -04:00
case EModularRigNotification : : ConnectionChanged :
{
2023-11-13 12:30:59 -05:00
Hierarchy - > Modify ( ) ;
2024-01-19 04:34:33 -05:00
UpdateConnectionMapFromModel ( ) ;
2023-11-03 08:15:33 -04:00
HierarchyModifiedEvent . Broadcast ( ERigHierarchyNotification : : HierarchyReset , Hierarchy , nullptr ) ;
break ;
}
2024-01-19 04:34:33 -05:00
case EModularRigNotification : : ModuleShortNameChanged :
{
bRecompile = false ;
break ;
}
2024-02-09 08:55:19 -05:00
case EModularRigNotification : : ModuleConfigValueChanged :
{
bRecompile = false ;
PropagateModuleHierarchyFromBPToInstances ( ) ;
RequestConstructionOnAllModules ( ) ;
break ;
}
2024-02-12 09:26:20 -05:00
case EModularRigNotification : : InteractionBracketOpened :
{
ModulesRecompilationBracket + + ;
break ;
}
case EModularRigNotification : : InteractionBracketClosed :
case EModularRigNotification : : InteractionBracketCanceled :
{
ModulesRecompilationBracket - - ;
break ;
}
2024-02-09 08:55:19 -05:00
default :
{
break ;
}
2024-01-19 04:34:33 -05:00
}
2024-02-12 09:26:20 -05:00
if ( bRecompile & & ModulesRecompilationBracket = = 0 )
2024-01-19 04:34:33 -05:00
{
RecompileModularRig ( ) ;
2023-11-03 08:15:33 -04:00
}
2023-10-26 06:52:34 -04:00
}
2020-09-24 00:43:27 -04:00
UControlRigBlueprint : : FControlValueScope : : FControlValueScope ( UControlRigBlueprint * InBlueprint )
: Blueprint ( InBlueprint )
{
# if WITH_EDITOR
check ( Blueprint ) ;
2023-10-30 07:01:53 -04:00
if ( UControlRig * CR = Cast < UControlRig > ( Blueprint - > GetObjectBeingDebugged ( ) ) )
2020-09-24 00:43:27 -04:00
{
2021-02-22 13:36:33 -04:00
TArray < FRigControlElement * > Controls = CR - > AvailableControls ( ) ;
for ( FRigControlElement * ControlElement : Controls )
2020-09-24 00:43:27 -04:00
{
2023-08-18 04:03:07 -04:00
ControlValues . Add ( ControlElement - > GetFName ( ) , CR - > GetControlValue ( ControlElement - > GetFName ( ) ) ) ;
2020-09-24 00:43:27 -04:00
}
}
# endif
}
UControlRigBlueprint : : FControlValueScope : : ~ FControlValueScope ( )
{
# if WITH_EDITOR
check ( Blueprint ) ;
2023-10-30 07:01:53 -04:00
if ( UControlRig * CR = Cast < UControlRig > ( Blueprint - > GetObjectBeingDebugged ( ) ) )
2020-09-24 00:43:27 -04:00
{
for ( const TPair < FName , FRigControlValue > & Pair : ControlValues )
{
if ( CR - > FindControl ( Pair . Key ) )
{
CR - > SetControlValue ( Pair . Key , Pair . Value ) ;
}
}
}
# endif
}
2019-01-08 11:38:48 -05:00
# undef LOCTEXT_NAMESPACE
2022-09-28 01:06:15 -04:00