151 lines
4.6 KiB
C++
151 lines
4.6 KiB
C++
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
|
|
|
|
#include "Nodes/AnimGraphNode_OLSMask.h"
|
|
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "OLSNodes"
|
|
|
|
UAnimGraphNode_OLSMask::UAnimGraphNode_OLSMask(const FObjectInitializer& objectInitializer) : Super(objectInitializer)
|
|
{
|
|
Node.BlendMasks.Reserve(1);
|
|
Node.MaskBlendWeights.Reserve(1);
|
|
Node.AllBoneBlendWeights.Reserve(1);
|
|
}
|
|
|
|
FLinearColor UAnimGraphNode_OLSMask::GetNodeTitleColor() const
|
|
{
|
|
return FLinearColor(0.0f, 204.0f, 204.0f);
|
|
}
|
|
|
|
FText UAnimGraphNode_OLSMask::GetTooltipText() const
|
|
{
|
|
return LOCTEXT("AnimGraphNode_OLSMask_Tooltip", "OLS Mask Node");
|
|
}
|
|
|
|
FText UAnimGraphNode_OLSMask::GetNodeTitle(ENodeTitleType::Type TitleType) const
|
|
{
|
|
return LOCTEXT("AnimGraphNode_OLSMaskBlend_Title", "Per Body Part Mask");
|
|
}
|
|
|
|
void UAnimGraphNode_OLSMask::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
{
|
|
const FName PropertyName = (PropertyChangedEvent.Property ? PropertyChangedEvent.Property->GetFName() : NAME_None);
|
|
|
|
|
|
if (PropertyName == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_OLSMask, BlendMasks))
|
|
{
|
|
FScopedTransaction Transaction(LOCTEXT("AddedBlendMask", "Add Blend Mask"));
|
|
Modify();
|
|
|
|
const int32 NumMasks = Node.BlendMasks.Num();
|
|
Node.MaskBlendWeights.SetNum(NumMasks);
|
|
Node.AllBoneBlendWeights.SetNum(NumMasks);
|
|
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(GetBlueprint());
|
|
ReconstructNode();
|
|
}
|
|
|
|
Super::PostEditChangeProperty(PropertyChangedEvent);
|
|
}
|
|
|
|
FString UAnimGraphNode_OLSMask::GetNodeCategory() const
|
|
{
|
|
return TEXT("Blends|OLS Nodes");
|
|
}
|
|
|
|
void UAnimGraphNode_OLSMask::PreloadRequiredAssets()
|
|
{
|
|
const TObjectPtr<UAnimBlueprint> animBlueprint = GetAnimBlueprint();
|
|
if (animBlueprint && !GIsCookerLoadingPackage && animBlueprint->TargetSkeleton)
|
|
{
|
|
const int32 numBlendMasks = Node.BlendMasks.Num();
|
|
if (numBlendMasks > 0)
|
|
{
|
|
for (int32 maskIndex = 0; maskIndex < numBlendMasks; ++maskIndex)
|
|
{
|
|
const FName blendProfileName = Node.BlendMasks[maskIndex].BlendProfileName;
|
|
if (const TObjectPtr<UBlendProfile> blendProfile = animBlueprint->TargetSkeleton->GetBlendProfile(
|
|
blendProfileName))
|
|
{
|
|
Node.BlendMasks[maskIndex].BlendProfile = blendProfile;
|
|
}
|
|
|
|
const TObjectPtr<UBlendProfile> blendMask = Node.BlendMasks[maskIndex].BlendProfile;
|
|
PreloadObject(blendMask);
|
|
}
|
|
}
|
|
}
|
|
|
|
Super::PreloadRequiredAssets();
|
|
}
|
|
|
|
void UAnimGraphNode_OLSMask::BakeDataDuringCompilation(FCompilerResultsLog& MessageLog)
|
|
{
|
|
const TObjectPtr<UAnimBlueprint> animBlueprint = GetAnimBlueprint();
|
|
if (!GIsCookerLoadingPackage && animBlueprint->TargetSkeleton)
|
|
{
|
|
const int32 numBlendMasks = Node.BlendMasks.Num();
|
|
for (int32 maskIndex = 0; maskIndex < numBlendMasks; ++maskIndex)
|
|
{
|
|
const FOLSMaskSettings& currentMask = Node.BlendMasks[maskIndex];
|
|
const FName& blendProfileName = Node.BlendMasks[maskIndex].BlendProfileName;
|
|
if (const TObjectPtr<UBlendProfile> bendProfile = animBlueprint->TargetSkeleton->GetBlendProfile(
|
|
blendProfileName))
|
|
{
|
|
Node.BlendMasks[maskIndex].BlendProfile = bendProfile;
|
|
}
|
|
|
|
if (currentMask.bShouldAddSlot)
|
|
{
|
|
animBlueprint->TargetSkeleton->RegisterSlotNode(currentMask.SlotName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UAnimGraphNode_OLSMask::ValidateAnimNodeDuringCompilation(USkeleton* skeleton, FCompilerResultsLog& MessageLog)
|
|
{
|
|
if (skeleton)
|
|
{
|
|
// ensure to cache the per-bone blend weights
|
|
if (!Node.ArePerBoneBlendWeightsValid(skeleton))
|
|
{
|
|
Node.RebuildPerBoneBlendWeights(skeleton);
|
|
}
|
|
|
|
if (Node.BlendMasks.Num() > 0)
|
|
{
|
|
const int32 numBlendMasks = Node.BlendMasks.Num();
|
|
for (int32 maskIndex = 0; maskIndex < numBlendMasks; ++maskIndex)
|
|
{
|
|
const FName& blendProfileName = Node.BlendMasks[maskIndex].BlendProfileName;
|
|
const TObjectPtr<UBlendProfile> blendProfile = skeleton->GetBlendProfile(blendProfileName);
|
|
if (blendProfile)
|
|
{
|
|
Node.BlendMasks[maskIndex].BlendProfile = blendProfile;
|
|
}
|
|
|
|
if (!blendProfile)
|
|
{
|
|
MessageLog.Error(
|
|
*FText::Format(
|
|
LOCTEXT("BlendProfileIsNull", "@@ has null BlendMask In Index {0}. "),
|
|
FText::AsNumber(maskIndex)).ToString(), this, blendProfile);
|
|
continue;
|
|
}
|
|
if (!blendProfile->IsBlendMask())
|
|
{
|
|
MessageLog.Error(
|
|
*FText::Format(LOCTEXT("BlendProfileModeError",
|
|
"@@ is using a BlendProfile(@@) without a BlendMask mode In Index {0}. "), FText::AsNumber(
|
|
maskIndex)).ToString(), this, blendProfile);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Super::ValidateAnimNodeDuringCompilation(skeleton, MessageLog);
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|