468 lines
17 KiB
C++
468 lines
17 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "ControlRigBlueprintGeneratedClass.h"
|
|
#include "UObject/ObjectMacros.h"
|
|
#include "Engine/Blueprint.h"
|
|
#include "Engine/Texture2D.h"
|
|
#include "ControlRigDefines.h"
|
|
#include "Rigs/RigHierarchyContainer.h"
|
|
#include "Rigs/RigHierarchy.h"
|
|
#include "Interfaces/Interface_PreviewMeshProvider.h"
|
|
#include "ControlRigGizmoLibrary.h"
|
|
#include "ControlRigSchema.h"
|
|
#include "RigVMCore/RigVMStatistics.h"
|
|
#include "RigVMModel/RigVMClient.h"
|
|
#include "ControlRigValidationPass.h"
|
|
#include "RigVMBlueprint.h"
|
|
#include "Rigs/RigModuleDefines.h"
|
|
#include "ModularRigModel.h"
|
|
|
|
#if WITH_EDITOR
|
|
#include "Kismet2/CompilerResultsLog.h"
|
|
#include "Overrides/SOverrideListWidget.h"
|
|
#endif
|
|
|
|
#include "ControlRigBlueprint.generated.h"
|
|
|
|
class URigVMBlueprintGeneratedClass;
|
|
class USkeletalMesh;
|
|
class UControlRigGraph;
|
|
struct FEndLoadPackageContext;
|
|
|
|
UENUM(BlueprintType)
|
|
enum class EControlRigType : uint8
|
|
{
|
|
IndependentRig = 0,
|
|
RigModule = 1,
|
|
ModularRig = 2,
|
|
MAX // Invalid
|
|
};
|
|
|
|
USTRUCT(BlueprintType)
|
|
struct CONTROLRIGDEVELOPER_API FModuleReferenceData
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
|
|
FModuleReferenceData(){}
|
|
|
|
FModuleReferenceData(const FRigModuleReference* InModule)
|
|
{
|
|
if (InModule)
|
|
{
|
|
ModulePath = InModule->GetModulePath();
|
|
if (InModule->Class.IsValid())
|
|
{
|
|
ReferencedModule = InModule->Class.Get();
|
|
}
|
|
}
|
|
}
|
|
|
|
UPROPERTY()
|
|
FString ModulePath;
|
|
|
|
UPROPERTY()
|
|
FSoftClassPath ReferencedModule;
|
|
};
|
|
|
|
UCLASS(BlueprintType, meta=(IgnoreClassThumbnail))
|
|
class CONTROLRIGDEVELOPER_API UControlRigBlueprint : public URigVMBlueprint, public IInterface_PreviewMeshProvider, public IRigHierarchyProvider
|
|
{
|
|
GENERATED_UCLASS_BODY()
|
|
|
|
public:
|
|
UControlRigBlueprint();
|
|
|
|
// --- IRigVMClientHost interface ---
|
|
virtual UClass* GetRigVMSchemaClass() const override { return UControlRigSchema::StaticClass(); }
|
|
virtual UScriptStruct* GetRigVMExecuteContextStruct() const override { return FControlRigExecuteContext::StaticStruct(); }
|
|
virtual UClass* GetRigVMEdGraphClass() const override;
|
|
virtual UClass* GetRigVMEdGraphNodeClass() const override;
|
|
virtual UClass* GetRigVMEdGraphSchemaClass() const override;
|
|
virtual UClass* GetRigVMEditorSettingsClass() const override;
|
|
|
|
// URigVMBlueprint interface
|
|
virtual UClass* GetRigVMBlueprintGeneratedClassPrototype() const override { return UControlRigBlueprintGeneratedClass::StaticClass(); }
|
|
virtual TArray<FString> GeneratePythonCommands(const FString InNewBlueprintName) override;
|
|
virtual void GetPreloadDependencies(TArray<UObject*>& OutDeps) override;
|
|
#if WITH_EDITOR
|
|
virtual const FLazyName& GetPanelPinFactoryName() const override;
|
|
static inline const FLazyName ControlRigPanelNodeFactoryName = FLazyName(TEXT("FControlRigGraphPanelPinFactory"));
|
|
virtual IRigVMEditorModule* GetEditorModule() const override;
|
|
#endif
|
|
|
|
virtual void Serialize(FArchive& Ar) override;
|
|
|
|
#if WITH_EDITOR
|
|
|
|
// UBlueprint interface
|
|
virtual UClass* RegenerateClass(UClass* ClassToRegenerate, UObject* PreviousCDO) override;
|
|
virtual bool SupportedByDefaultBlueprintFactory() const override { return false; }
|
|
virtual bool IsValidForBytecodeOnlyRecompile() const override { return false; }
|
|
virtual void GetTypeActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const override;
|
|
virtual void GetInstanceActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const override;
|
|
virtual void PreSave(FObjectPreSaveContext ObjectSaveContext) override;
|
|
virtual void PostLoad() override;
|
|
virtual void PostTransacted(const FTransactionObjectEvent& TransactionEvent) override;
|
|
virtual void PostDuplicate(bool bDuplicateForPIE) override;
|
|
virtual void PostRename(UObject* OldOuter, const FName OldName) override;
|
|
virtual bool RequiresForceLoadMembers(UObject* InObject) const override;
|
|
|
|
virtual bool SupportsGlobalVariables() const override { return true; }
|
|
virtual bool SupportsLocalVariables() const override { return !IsModularRig(); }
|
|
virtual bool SupportsFunctions() const override { return !IsModularRig(); }
|
|
virtual bool SupportsEventGraphs() const override { return !IsModularRig(); }
|
|
|
|
|
|
// UObject interface
|
|
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
|
virtual void PostEditChangeChainProperty(struct FPropertyChangedChainEvent& PropertyChangedEvent) override;
|
|
|
|
#endif // #if WITH_EDITOR
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "VM")
|
|
UClass* GetControlRigClass() const;
|
|
|
|
bool IsModularRig() const;
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Control Rig Blueprint")
|
|
UControlRig* CreateControlRig() { return Cast<UControlRig>(CreateRigVMHost()); }
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Control Rig Blueprint")
|
|
UControlRig* GetDebuggedControlRig() { return Cast<UControlRig>(GetDebuggedRigVMHost()); }
|
|
|
|
/** IInterface_PreviewMeshProvider interface */
|
|
UFUNCTION(BlueprintCallable, Category = "Control Rig Blueprint")
|
|
virtual void SetPreviewMesh(USkeletalMesh* PreviewMesh, bool bMarkAsDirty = true) override;
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Control Rig Blueprint")
|
|
virtual USkeletalMesh* GetPreviewMesh() const override;
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Control Rig Blueprint")
|
|
bool IsControlRigModule() const;
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
|
|
bool CanTurnIntoControlRigModule_Blueprint(bool InAutoConvertHierarchy = false) const { return CanTurnIntoControlRigModule(InAutoConvertHierarchy); }
|
|
|
|
bool CanTurnIntoControlRigModule(bool InAutoConvertHierarchy, FString* OutErrorMessage = nullptr) const;
|
|
|
|
UFUNCTION(BlueprintCallable, meta = (DisplayName = "TurnIntoControlRigModule", ScriptName = "TurnIntoControlRigModule"), Category = "Control Rig Blueprint")
|
|
bool TurnIntoControlRigModule_Blueprint() { return TurnIntoControlRigModule(); }
|
|
|
|
bool TurnIntoControlRigModule(bool InAutoConvertHierarchy = false, FString* OutErrorMessage = nullptr);
|
|
|
|
UFUNCTION(BlueprintPure, meta = (DisplayName = "CanTurnIntoStandaloneRig", ScriptName = "CanTurnIntoStandaloneRig"), Category = "Control Rig Blueprint")
|
|
bool CanTurnIntoStandaloneRig_Blueprint() const { return CanTurnIntoStandaloneRig(); }
|
|
|
|
bool CanTurnIntoStandaloneRig(FString* OutErrorMessage = nullptr) const;
|
|
|
|
UFUNCTION(BlueprintCallable, meta = (DisplayName = "TurnIntoStandaloneRig", ScriptName = "TurnIntoStandaloneRig"), Category = "Control Rig Blueprint")
|
|
bool TurnIntoStandaloneRig_Blueprint() { return TurnIntoStandaloneRig(); }
|
|
|
|
bool TurnIntoStandaloneRig(FString* OutErrorMessage = nullptr);
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Control Rig Blueprint")
|
|
TArray<URigVMNode*> ConvertHierarchyElementsToSpawnerNodes(URigHierarchy* InHierarchy, TArray<FRigElementKey> InKeys, bool bRemoveElements = true);
|
|
|
|
#endif // WITH_EDITORONLY_DATA
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Control Rig Blueprint")
|
|
UTexture2D* GetRigModuleIcon() const;
|
|
|
|
DECLARE_EVENT_OneParam(UControlRigBlueprint, FOnRigTypeChanged, UControlRigBlueprint*);
|
|
|
|
FOnRigTypeChanged& OnRigTypeChanged() { return OnRigTypeChangedDelegate; }
|
|
|
|
/// IRigHierarchyProvider interface
|
|
virtual URigHierarchy* GetHierarchy() const override
|
|
{
|
|
return Hierarchy;
|
|
}
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Modular Rig")
|
|
FModularRigSettings ModularRigSettings;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Hierarchy")
|
|
FRigHierarchySettings HierarchySettings;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Hierarchy", AssetRegistrySearchable)
|
|
FRigModuleSettings RigModuleSettings;
|
|
|
|
// This relates to FAssetThumbnailPool::CustomThumbnailTagName and allows
|
|
// the thumbnail pool to show the thumbnail of the icon rather than the
|
|
// rig itself to avoid deploying the 3D renderer.
|
|
UPROPERTY(EditAnywhere, Category = "Hierarchy", AssetRegistrySearchable)
|
|
FString CustomThumbnail;
|
|
|
|
/** Asset searchable information module references in this rig */
|
|
UPROPERTY(AssetRegistrySearchable)
|
|
TArray<FModuleReferenceData> ModuleReferenceData;
|
|
|
|
UPROPERTY()
|
|
TMap<FRigElementKey, FRigElementKey> ConnectionMap_DEPRECATED;
|
|
|
|
UPROPERTY()
|
|
TMap<FRigElementKey, FRigElementKeyCollection> ArrayConnectionMap;
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Control Rig Blueprint")
|
|
TArray<FModuleReferenceData> FindReferencesToModule() const;
|
|
|
|
static EControlRigType GetRigType(const FAssetData& InAsset);
|
|
static TArray<FSoftObjectPath> GetReferencesToRigModule(const FAssetData& InModuleAsset);
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Control Rig Blueprint")
|
|
void UpdateExposedModuleConnectors() const;
|
|
|
|
#if WITH_EDITOR
|
|
TArray<FOverrideStatusSubject> GetOverrideSubjects() const;
|
|
uint32 GetOverrideSubjectsHash() const;
|
|
#endif
|
|
|
|
protected:
|
|
|
|
TArray<FModuleReferenceData> GetModuleReferenceData() const;
|
|
|
|
FOnRigTypeChanged OnRigTypeChangedDelegate;
|
|
|
|
bool ResolveConnector(const FRigElementKey& DraggedKey, const FRigElementKey& TargetKey, bool bSetupUndoRedo = true);
|
|
bool ResolveConnectorToArray(const FRigElementKey& DraggedKey, const TArray<FRigElementKey>& TargetKeys, bool bSetupUndoRedo = true);
|
|
|
|
void UpdateConnectionMapFromModel();
|
|
|
|
/** Asset searchable information about exposed public functions on this rig */
|
|
UPROPERTY(AssetRegistrySearchable)
|
|
TArray<FRigVMOldPublicFunctionData> PublicFunctions_DEPRECATED;
|
|
|
|
virtual void SetupDefaultObjectDuringCompilation(URigVMHost* InCDO) override;
|
|
|
|
public:
|
|
|
|
virtual void SetupPinRedirectorsForBackwardsCompatibility() override;
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "VM")
|
|
static TArray<UControlRigBlueprint*> GetCurrentlyOpenRigBlueprints();
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
UPROPERTY()
|
|
TSoftObjectPtr<UControlRigShapeLibrary> GizmoLibrary_DEPRECATED;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
TArray<TSoftObjectPtr<UControlRigShapeLibrary>> ShapeLibraries;
|
|
|
|
const FControlRigShapeDefinition* GetControlShapeByName(const FName& InName) const;
|
|
|
|
UPROPERTY(transient, DuplicateTransient, meta = (DisplayName = "VM Statistics", DisplayAfter = "VMCompileSettings"))
|
|
FRigVMStatistics Statistics_DEPRECATED;
|
|
#endif
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Drawing")
|
|
FRigVMDrawContainer DrawContainer;
|
|
|
|
#if WITH_EDITOR
|
|
/** Remove a transient / temporary control used to interact with a pin */
|
|
FName AddTransientControl(const URigVMUnitNode* InNode, const FRigDirectManipulationTarget& InTarget);
|
|
|
|
/** Remove a transient / temporary control used to interact with a pin */
|
|
FName RemoveTransientControl(const URigVMUnitNode* InNode, const FRigDirectManipulationTarget& InTarget);
|
|
|
|
/** Remove a transient / temporary control used to interact with a bone */
|
|
FName AddTransientControl(const FRigElementKey& InElement);
|
|
|
|
/** Remove a transient / temporary control used to interact with a bone */
|
|
FName RemoveTransientControl(const FRigElementKey& InElement);
|
|
|
|
/** Removes all transient / temporary control used to interact with pins */
|
|
void ClearTransientControls();
|
|
|
|
#endif
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Influence Map")
|
|
FRigInfluenceMapPerEvent Influences;
|
|
|
|
public:
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
UPROPERTY()
|
|
FRigHierarchyContainer HierarchyContainer_DEPRECATED;
|
|
#endif
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "Hierarchy")
|
|
TObjectPtr<URigHierarchy> Hierarchy;
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Hierarchy")
|
|
URigHierarchyController* GetHierarchyController() { return Hierarchy->GetController(true); }
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "Modules")
|
|
FModularRigModel ModularRigModel;
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Modules")
|
|
UModularRigController* GetModularRigController();
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Control Rig Blueprint")
|
|
void RecompileModularRig();
|
|
|
|
UPROPERTY(AssetRegistrySearchable)
|
|
EControlRigType ControlRigType;
|
|
|
|
UPROPERTY(AssetRegistrySearchable)
|
|
FName ItemTypeDisplayName = TEXT("Control Rig");
|
|
|
|
private:
|
|
|
|
/** Whether or not this rig has an Inversion Event */
|
|
UPROPERTY(AssetRegistrySearchable)
|
|
bool bSupportsInversion;
|
|
|
|
/** Whether or not this rig has Controls on It */
|
|
UPROPERTY(AssetRegistrySearchable)
|
|
bool bSupportsControls;
|
|
|
|
/** The default skeletal mesh to use when previewing this asset */
|
|
#if WITH_EDITORONLY_DATA
|
|
UPROPERTY(AssetRegistrySearchable, EditAnywhere, Category="Control Rig Blueprint")
|
|
TSoftObjectPtr<USkeletalMesh> PreviewSkeletalMesh;
|
|
#endif
|
|
|
|
/** The skeleton from import into a hierarchy */
|
|
UPROPERTY(DuplicateTransient, AssetRegistrySearchable, EditAnywhere, Category="Control Rig Blueprint")
|
|
TSoftObjectPtr<UObject> SourceHierarchyImport;
|
|
|
|
/** The skeleton from import into a curve */
|
|
UPROPERTY(DuplicateTransient, AssetRegistrySearchable, EditAnywhere, Category="Control Rig Blueprint")
|
|
TSoftObjectPtr<UObject> SourceCurveImport;
|
|
|
|
/** If set to true, this control rig has animatable controls */
|
|
UPROPERTY(AssetRegistrySearchable)
|
|
bool bExposesAnimatableControls;
|
|
public:
|
|
|
|
/** If set to true, multiple control rig tracks can be created for the same rig in sequencer*/
|
|
UPROPERTY(EditAnywhere, Category="Sequencer", AssetRegistrySearchable)
|
|
bool bAllowMultipleInstances = false;
|
|
|
|
private:
|
|
|
|
static TArray<UControlRigBlueprint*> sCurrentlyOpenedRigBlueprints;
|
|
|
|
virtual void PathDomainSpecificContentOnLoad() override;
|
|
virtual void GetBackwardsCompatibilityPublicFunctions(TArray<FName>& BackwardsCompatiblePublicFunctions, TMap<URigVMLibraryNode*, FRigVMGraphFunctionHeader>& OldHeaders) override;
|
|
void PatchRigElementKeyCacheOnLoad();
|
|
void PatchPropagateToChildren();
|
|
|
|
protected:
|
|
virtual void CreateMemberVariablesOnLoad() override;
|
|
virtual void PatchVariableNodesOnLoad() override;
|
|
|
|
public:
|
|
void UpdateElementKeyRedirector(UControlRig* InControlRig) const;
|
|
void PropagatePoseFromInstanceToBP(UControlRig* InControlRig) const;
|
|
void PropagatePoseFromBPToInstances() const;
|
|
void PropagateHierarchyFromBPToInstances() const;
|
|
void PropagateDrawInstructionsFromBPToInstances() const;
|
|
void PropagatePropertyFromBPToInstances(FRigElementKey InRigElement, const FProperty* InProperty) const;
|
|
void PropagatePropertyFromInstanceToBP(FRigElementKey InRigElement, const FProperty* InProperty, UControlRig* InInstance) const;
|
|
void PropagateModuleHierarchyFromBPToInstances() const;
|
|
void UpdateModularDependencyDelegates();
|
|
void OnModularDependencyVMCompiled(UObject* InBlueprint, URigVM* InVM, FRigVMExtendedExecuteContext& InExecuteContext);
|
|
void OnModularDependencyChanged(URigVMBlueprint* InBlueprint);
|
|
void RequestConstructionOnAllModules();
|
|
void RefreshModuleVariables();
|
|
void RefreshModuleVariables(const FRigModuleReference* InModule);
|
|
void RefreshModuleConnectors();
|
|
void RefreshModuleConnectors(const FRigModuleReference* InModule, bool bPropagateHierarchy = true);
|
|
|
|
/**
|
|
* Returns the modified event, which can be used to
|
|
* subscribe to topological changes happening within the hierarchy. The event is broadcast only after all hierarchy instances are up to date
|
|
* @return The event used for subscription.
|
|
*/
|
|
FRigHierarchyModifiedEvent& OnHierarchyModified() { return HierarchyModifiedEvent; }
|
|
|
|
FOnRigVMRefreshEditorEvent& OnModularRigPreCompiled() { return ModularRigPreCompiled; }
|
|
FOnRigVMRefreshEditorEvent& OnModularRigCompiled() { return ModularRigCompiled; }
|
|
|
|
private:
|
|
|
|
UPROPERTY()
|
|
TObjectPtr<UControlRigValidator> Validator;
|
|
|
|
FRigHierarchyModifiedEvent HierarchyModifiedEvent;
|
|
FOnRigVMRefreshEditorEvent ModularRigPreCompiled;
|
|
FOnRigVMRefreshEditorEvent ModularRigCompiled;
|
|
|
|
UPROPERTY(transient, DuplicateTransient)
|
|
int32 ModulesRecompilationBracket = 0;
|
|
|
|
|
|
void HandleHierarchyModified(ERigHierarchyNotification InNotification, URigHierarchy* InHierarchy, const FRigNotificationSubject& InSubject);
|
|
void HandleHierarchyElementKeyChanged(const FRigElementKey& InOldKey, const FRigElementKey& InNewKey);
|
|
void HandleHierarchyComponentKeyChanged(const FRigComponentKey& InOldKey, const FRigComponentKey& InNewKey);
|
|
|
|
void HandleRigModulesModified(EModularRigNotification InNotification, const FRigModuleReference* InModule);
|
|
|
|
#if WITH_EDITOR
|
|
virtual void HandlePackageDone() override;
|
|
virtual void HandleConfigureRigVMController(const FRigVMClient* InClient, URigVMController* InControllerToConfigure) override;
|
|
#endif
|
|
|
|
void UpdateConnectionMapAfterRename(const FString& InOldModuleName);
|
|
|
|
// Class used to temporarily cache all
|
|
// current control values and reapply them
|
|
// on destruction
|
|
class CONTROLRIGDEVELOPER_API FControlValueScope
|
|
{
|
|
public:
|
|
FControlValueScope(UControlRigBlueprint* InBlueprint);
|
|
~FControlValueScope();
|
|
|
|
private:
|
|
|
|
UControlRigBlueprint* Blueprint;
|
|
TMap<FName, FRigControlValue> ControlValues;
|
|
};
|
|
|
|
UPROPERTY()
|
|
float DebugBoneRadius;
|
|
|
|
#if WITH_EDITOR
|
|
|
|
public:
|
|
|
|
/** Shape libraries to load during package load completed */
|
|
TArray<FString> ShapeLibrariesToLoadOnPackageLoaded;
|
|
|
|
#endif
|
|
|
|
private:
|
|
|
|
friend class FControlRigBlueprintCompilerContext;
|
|
friend class SRigHierarchy;
|
|
friend class SRigCurveContainer;
|
|
friend class FControlRigBaseEditor;
|
|
#if WITH_RIGVMLEGACYEDITOR
|
|
friend class FControlRigLegacyEditor;
|
|
#endif
|
|
friend class FControlRigEditor;
|
|
friend class UEngineTestControlRig;
|
|
friend class FControlRigEditMode;
|
|
friend class FControlRigBlueprintActions;
|
|
friend class FControlRigDrawContainerDetails;
|
|
friend class UDefaultControlRigManipulationLayer;
|
|
friend struct FRigValidationTabSummoner;
|
|
friend class UAnimGraphNode_ControlRig;
|
|
friend class UControlRigThumbnailRenderer;
|
|
friend class FControlRigGraphDetails;
|
|
friend class FControlRigEditorModule;
|
|
friend class UControlRigComponent;
|
|
friend struct FControlRigGraphSchemaAction_PromoteToVariable;
|
|
friend class UControlRigGraphSchema;
|
|
friend class FControlRigBlueprintDetails;
|
|
friend class FRigConnectorElementDetails;
|
|
};
|