Files
UnrealEngineUWP/Engine/Source/Editor/AnimGraph/Private/AnimGraphNode_RotationOffsetBlendSpace.cpp
Michael Schoell 75200e5a0d Cached node titles can now be forced to refresh without iteration over every node.
This will occur with every structural modification to any BP, node titles refresh only when visible.

[CL 2499923 by Michael Schoell in Main branch]
2015-04-02 11:16:23 -04:00

156 lines
5.9 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "AnimGraphPrivatePCH.h"
#include "AnimGraphNode_RotationOffsetBlendSpace.h"
#include "GraphEditorActions.h"
#include "CompilerResultsLog.h"
#include "BlueprintNodeSpawner.h"
#include "BlueprintActionDatabaseRegistrar.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_RotationOffsetBlendSpace
#define LOCTEXT_NAMESPACE "A3Nodes"
UAnimGraphNode_RotationOffsetBlendSpace::UAnimGraphNode_RotationOffsetBlendSpace(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
FText UAnimGraphNode_RotationOffsetBlendSpace::GetTooltipText() const
{
// FText::Format() is slow, so we utilize the cached list title
return GetNodeTitle(ENodeTitleType::ListView);
}
FText UAnimGraphNode_RotationOffsetBlendSpace::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
if (Node.BlendSpace == nullptr)
{
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
return LOCTEXT("RotationOffsetBlend_NONE_ListTitle", "AimOffset '(None)'");
}
else
{
return LOCTEXT("RotationOffsetBlend_NONE_Title", "(None)\nAimOffset");
}
}
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
{
const FText BlendSpaceName = FText::FromString(Node.BlendSpace->GetName());
FFormatNamedArguments Args;
Args.Add(TEXT("BlendSpaceName"), BlendSpaceName);
// FText::Format() is slow, so we cache this to save on performance
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AimOffsetListTitle", "AimOffset '{BlendSpaceName}'"), Args), this);
}
else
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AimOffsetFullTitle", "{BlendSpaceName}\nAimOffset"), Args), this);
}
}
return CachedNodeTitles[TitleType];
}
void UAnimGraphNode_RotationOffsetBlendSpace::GetMenuEntries(FGraphContextMenuBuilder& ContextMenuBuilder) const
{
const bool bWantAimOffsets = true;
GetBlendSpaceEntries(bWantAimOffsets, ContextMenuBuilder);
}
void UAnimGraphNode_RotationOffsetBlendSpace::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
{
auto PostSpawnSetupLambda = [](UEdGraphNode* NewNode, bool /*bIsTemplateNode*/, TWeakObjectPtr<UBlendSpaceBase> BlendSpace)
{
UAnimGraphNode_RotationOffsetBlendSpace* BlendSpaceNode = CastChecked<UAnimGraphNode_RotationOffsetBlendSpace>(NewNode);
BlendSpaceNode->Node.BlendSpace = BlendSpace.Get();
};
for (TObjectIterator<UBlendSpaceBase> BlendSpaceIt; BlendSpaceIt; ++BlendSpaceIt)
{
UBlendSpaceBase* BlendSpace = *BlendSpaceIt;
// to keep from needlessly instantiating a UBlueprintNodeSpawner, first
// check to make sure that the registrar is looking for actions of this type
// (could be regenerating actions for a specific asset, and therefore the
// registrar would only accept actions corresponding to that asset)
if (!ActionRegistrar.IsOpenForRegistration(BlendSpace))
{
continue;
}
bool const bIsAimOffset = BlendSpace->IsA(UAimOffsetBlendSpace::StaticClass()) ||
BlendSpace->IsA(UAimOffsetBlendSpace1D::StaticClass());
if (bIsAimOffset)
{
UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
check(NodeSpawner != nullptr);
ActionRegistrar.AddBlueprintAction(BlendSpace, NodeSpawner);
TWeakObjectPtr<UBlendSpaceBase> BlendSpacePtr = BlendSpace;
NodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(PostSpawnSetupLambda, BlendSpacePtr);
}
}
}
FBlueprintNodeSignature UAnimGraphNode_RotationOffsetBlendSpace::GetSignature() const
{
FBlueprintNodeSignature NodeSignature = Super::GetSignature();
NodeSignature.AddSubObject(Node.BlendSpace);
return NodeSignature;
}
void UAnimGraphNode_RotationOffsetBlendSpace::ValidateAnimNodeDuringCompilation(class USkeleton* ForSkeleton, class FCompilerResultsLog& MessageLog)
{
if (Node.BlendSpace == NULL)
{
MessageLog.Error(TEXT("@@ references an unknown blend space"), this);
}
else if (Cast<UAimOffsetBlendSpace>(Node.BlendSpace) == NULL &&
Cast<UAimOffsetBlendSpace1D>(Node.BlendSpace) == NULL)
{
MessageLog.Error(TEXT("@@ references an invalid blend space (one that is not an aim offset)"), this);
}
else
{
USkeleton* BlendSpaceSkeleton = Node.BlendSpace->GetSkeleton();
if (BlendSpaceSkeleton && // if blend space doesn't have skeleton, it might be due to blend space not loaded yet, @todo: wait with anim blueprint compilation until all assets are loaded?
!BlendSpaceSkeleton->IsCompatible(ForSkeleton))
{
MessageLog.Error(TEXT("@@ references blendspace that uses different skeleton @@"), this, BlendSpaceSkeleton);
}
}
}
void UAnimGraphNode_RotationOffsetBlendSpace::GetContextMenuActions(const FGraphNodeContextMenuBuilder& Context) const
{
if (!Context.bIsDebugging)
{
// add an option to convert to single frame
Context.MenuBuilder->BeginSection("AnimGraphNodeBlendSpacePlayer", NSLOCTEXT("A3Nodes", "BlendSpaceHeading", "Blend Space"));
{
Context.MenuBuilder->AddMenuEntry(FGraphEditorCommands::Get().OpenRelatedAsset);
}
Context.MenuBuilder->EndSection();
}
}
void UAnimGraphNode_RotationOffsetBlendSpace::GetAllAnimationSequencesReferred(TArray<UAnimationAsset*>& ComplexAnims, TArray<UAnimSequence*>& AnimationSequences) const
{
if(Node.BlendSpace)
{
HandleAnimReferenceCollection(Node.BlendSpace, ComplexAnims, AnimationSequences);
}
}
void UAnimGraphNode_RotationOffsetBlendSpace::ReplaceReferredAnimations(const TMap<UAnimationAsset*, UAnimationAsset*>& ComplexAnimsMap, const TMap<UAnimSequence*, UAnimSequence*>& AnimSequenceMap)
{
HandleAnimReferenceReplacement(Node.BlendSpace, ComplexAnimsMap, AnimSequenceMap);
}
#undef LOCTEXT_NAMESPACE