// Copyright Epic Games, Inc. All Rights Reserved. #include "PoseSearch/MotionMatchingAnimNodeLibrary.h" #include "AlphaBlend.h" #include "PoseSearch/AnimNode_MotionMatching.h" #include "PoseSearch/PoseSearchDatabase.h" #include "UObject/FortniteMainBranchObjectVersion.h" #include UE_INLINE_GENERATED_CPP_BY_NAME(MotionMatchingAnimNodeLibrary) FMotionMatchingBlueprintBlendSettings::FMotionMatchingBlueprintBlendSettings() : BlendTime(0.2f) , BlendProfile(nullptr) , BlendOption(UE::Anim::DefaultBlendOption) , bUseInertialBlend(false) { } bool FMotionMatchingBlueprintBlendSettings::Serialize(FArchive& Ar) { Ar.UsingCustomVersion(FFortniteMainBranchObjectVersion::GUID); if (Ar.IsLoading() && Ar.IsSerializingDefaults()) { const int32 CustomVersion = Ar.CustomVer(FFortniteMainBranchObjectVersion::GUID); if (CustomVersion < FFortniteMainBranchObjectVersion::ChangeDefaultAlphaBlendType) { // Switch the default back to Linear so old data remains the same BlendOption = EAlphaBlendOption::Linear; } } return false; } bool FMotionMatchingBlueprintBlendSettings::Serialize(FStructuredArchive::FSlot Slot) { FArchive& Ar = Slot.GetUnderlyingArchive(); Ar.UsingCustomVersion(FFortniteMainBranchObjectVersion::GUID); if (Ar.IsLoading() && Ar.IsSerializingDefaults()) { const int32 CustomVersion = Ar.CustomVer(FFortniteMainBranchObjectVersion::GUID); if (CustomVersion < FFortniteMainBranchObjectVersion::ChangeDefaultAlphaBlendType) { // Switch the default back to Linear so old data remains the same BlendOption = EAlphaBlendOption::Linear; } } return false; } FMotionMatchingAnimNodeReference UMotionMatchingAnimNodeLibrary::ConvertToMotionMatchingNode(const FAnimNodeReference& Node, EAnimNodeReferenceConversionResult& Result) { return FAnimNodeReference::ConvertToType(Node, Result); } void UMotionMatchingAnimNodeLibrary::GetMotionMatchingSearchResult(const FMotionMatchingAnimNodeReference& MotionMatchingNode, FPoseSearchBlueprintResult& Result, bool& bIsResultValid) { using namespace UE::PoseSearch; if (FAnimNode_MotionMatching* MotionMatchingNodePtr = MotionMatchingNode.GetAnimNodePtr()) { const FMotionMatchingState& MotionMatchingState = MotionMatchingNodePtr->GetMotionMatchingState(); Result = MotionMatchingState.SearchResult; bIsResultValid = MotionMatchingState.SearchResult.SelectedAnim != nullptr; } else { Result = FPoseSearchBlueprintResult(); bIsResultValid = false; UE_LOG(LogPoseSearch, Warning, TEXT("UMotionMatchingAnimNodeLibrary::GetMotionMatchingSearchResult called on an invalid context or with an invalid type")); } } void UMotionMatchingAnimNodeLibrary::GetMotionMatchingBlendSettings(const FMotionMatchingAnimNodeReference& MotionMatchingNode, FMotionMatchingBlueprintBlendSettings& BlendSettings, bool& bIsResultValid) { if (FAnimNode_MotionMatching* MotionMatchingNodePtr = MotionMatchingNode.GetAnimNodePtr()) { BlendSettings.BlendOption = MotionMatchingNodePtr->BlendOption; BlendSettings.BlendProfile = MotionMatchingNodePtr->BlendProfile; BlendSettings.BlendTime = MotionMatchingNodePtr->BlendTime; BlendSettings.bUseInertialBlend = MotionMatchingNodePtr->bUseInertialBlend; } else { BlendSettings = FMotionMatchingBlueprintBlendSettings(); UE_LOG(LogPoseSearch, Warning, TEXT("UMotionMatchingAnimNodeLibrary::GetMotionMatchingBlendSettings called on an invalid context or with an invalid type")); } } void UMotionMatchingAnimNodeLibrary::OverrideMotionMatchingBlendSettings(const FMotionMatchingAnimNodeReference& MotionMatchingNode, const FMotionMatchingBlueprintBlendSettings& BlendSettings, bool& bIsResultValid) { if (FAnimNode_MotionMatching* MotionMatchingNodePtr = MotionMatchingNode.GetAnimNodePtr()) { MotionMatchingNodePtr->BlendOption = BlendSettings.BlendOption; MotionMatchingNodePtr->BlendProfile = BlendSettings.BlendProfile; MotionMatchingNodePtr->BlendTime = BlendSettings.BlendTime; MotionMatchingNodePtr->bUseInertialBlend = BlendSettings.bUseInertialBlend; } else { UE_LOG(LogPoseSearch, Warning, TEXT("UMotionMatchingAnimNodeLibrary::OverrideMotionMatchingBlendSettings called on an invalid context or with an invalid type")); } } void UMotionMatchingAnimNodeLibrary::SetDatabaseToSearch(const FMotionMatchingAnimNodeReference& MotionMatchingNode, UPoseSearchDatabase* Database, EPoseSearchInterruptMode InterruptMode) { if (FAnimNode_MotionMatching* MotionMatchingNodePtr = MotionMatchingNode.GetAnimNodePtr()) { MotionMatchingNodePtr->SetDatabaseToSearch(Database, InterruptMode); } else { UE_LOG(LogPoseSearch, Warning, TEXT("UMotionMatchingAnimNodeLibrary::SetDatabaseToSearch called on an invalid context or with an invalid type")); } } void UMotionMatchingAnimNodeLibrary::SetDatabasesToSearch(const FMotionMatchingAnimNodeReference& MotionMatchingNode, const TArray& Databases, EPoseSearchInterruptMode InterruptMode) { if (FAnimNode_MotionMatching* MotionMatchingNodePtr = MotionMatchingNode.GetAnimNodePtr()) { MotionMatchingNodePtr->SetDatabasesToSearch(Databases, InterruptMode); } else { UE_LOG(LogPoseSearch, Warning, TEXT("UMotionMatchingAnimNodeLibrary::SetDatabasesToSearch called on an invalid context or with an invalid type")); } } void UMotionMatchingAnimNodeLibrary::ResetDatabasesToSearch(const FMotionMatchingAnimNodeReference& MotionMatchingNode, EPoseSearchInterruptMode InterruptMode) { if (FAnimNode_MotionMatching* MotionMatchingNodePtr = MotionMatchingNode.GetAnimNodePtr()) { MotionMatchingNodePtr->ResetDatabasesToSearch(InterruptMode); } else { UE_LOG(LogPoseSearch, Warning, TEXT("UMotionMatchingAnimNodeLibrary::ResetDatabasesToSearch called on an invalid context or with an invalid type")); } } void UMotionMatchingAnimNodeLibrary::SetInterruptMode(const FMotionMatchingAnimNodeReference& MotionMatchingNode, EPoseSearchInterruptMode InterruptMode) { if (FAnimNode_MotionMatching* MotionMatchingNodePtr = MotionMatchingNode.GetAnimNodePtr()) { MotionMatchingNodePtr->SetInterruptMode(InterruptMode); } else { UE_LOG(LogPoseSearch, Warning, TEXT("UMotionMatchingAnimNodeLibrary::SetInterruptMode called on an invalid context or with an invalid type")); } }