mirror of
https://github.com/FortniteModdingHub/FNGameProj.git
synced 2026-08-26 19:43:31 +00:00
123 lines
4.4 KiB
C++
123 lines
4.4 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#include "FortKismetLibrary.h"
|
|
#include "SkeletalMeshMerge.h"
|
|
#include "Engine/SkeletalMeshSocket.h"
|
|
#include "Engine/SkeletalMesh.h"
|
|
#include "Animation/Skeleton.h"
|
|
|
|
static void ToMergeParams(const TArray<FSkelMeshMergeSectionMapping_BP>& InSectionMappings, TArray<FSkelMeshMergeSectionMapping>& OutSectionMappings)
|
|
{
|
|
if (InSectionMappings.Num() > 0)
|
|
{
|
|
OutSectionMappings.AddUninitialized(InSectionMappings.Num());
|
|
for (int32 i = 0; i < InSectionMappings.Num(); ++i)
|
|
{
|
|
OutSectionMappings[i].SectionIDs = InSectionMappings[i].SectionIDs;
|
|
}
|
|
}
|
|
};
|
|
static void ToMergeParams(const TArray<FSkelMeshMergeUVTransformMapping>& InUVTransformsPerMesh, TArray<FSkelMeshMergeUVTransforms>& OutUVTransformsPerMesh)
|
|
{
|
|
if (InUVTransformsPerMesh.Num() > 0)
|
|
{
|
|
OutUVTransformsPerMesh.Empty();
|
|
OutUVTransformsPerMesh.AddUninitialized(InUVTransformsPerMesh.Num());
|
|
for (int32 i = 0; i < InUVTransformsPerMesh.Num(); ++i)
|
|
{
|
|
TArray<TArray<FTransform>>& OutUVTransforms = OutUVTransformsPerMesh[i].UVTransformsPerMesh;
|
|
const TArray<FSkelMeshMergeUVTransform>& InUVTransforms = InUVTransformsPerMesh[i].UVTransformsPerMesh;
|
|
if (InUVTransforms.Num() > 0)
|
|
{
|
|
OutUVTransforms.Empty();
|
|
OutUVTransforms.AddUninitialized(InUVTransforms.Num());
|
|
for (int32 j = 0; j < InUVTransforms.Num(); j++)
|
|
{
|
|
OutUVTransforms[i] = InUVTransforms[i].UVTransforms;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
USkeletalMesh* UMeshMergeFunctionLibrary::MergeMeshes(const FSkeletalMeshMergeParams& Params)
|
|
{
|
|
TArray<USkeletalMesh*> MeshesToMergeCopy = Params.MeshesToMerge;
|
|
MeshesToMergeCopy.RemoveAll([](USkeletalMesh* InMesh)
|
|
{
|
|
return InMesh == nullptr;
|
|
});
|
|
if (MeshesToMergeCopy.Num() <= 1)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("Must provide multiple valid Skeletal Meshes in order to perform a merge."));
|
|
return nullptr;
|
|
}
|
|
EMeshBufferAccess BufferAccess = Params.bNeedsCpuAccess ?
|
|
EMeshBufferAccess::ForceCPUAndGPU :
|
|
EMeshBufferAccess::Default;
|
|
TArray<FSkelMeshMergeSectionMapping> SectionMappings;
|
|
TArray<FSkelMeshMergeUVTransforms> UvTransforms;
|
|
ToMergeParams(Params.MeshSectionMappings, SectionMappings);
|
|
ToMergeParams(Params.UVTransformsPerMesh, UvTransforms);
|
|
bool bRunDuplicateCheck = false;
|
|
USkeletalMesh* BaseMesh = NewObject<USkeletalMesh>();
|
|
if (Params.Skeleton && Params.bSkeletonBefore)
|
|
{
|
|
BaseMesh->Skeleton = Params.Skeleton;
|
|
bRunDuplicateCheck = true;
|
|
for (USkeletalMeshSocket* Socket : BaseMesh->GetMeshOnlySocketList())
|
|
{
|
|
if (Socket)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("SkelMeshSocket: %s"), *(Socket->SocketName.ToString()));
|
|
}
|
|
}
|
|
for (USkeletalMeshSocket* Socket : BaseMesh->Skeleton->Sockets)
|
|
{
|
|
if (Socket)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("SkelSocket: %s"), *(Socket->SocketName.ToString()));
|
|
}
|
|
}
|
|
}
|
|
FSkeletalMeshMerge Merger(BaseMesh, MeshesToMergeCopy, SectionMappings, Params.StripTopLODS, BufferAccess, UvTransforms.GetData());
|
|
if (!Merger.DoMerge())
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("Merge failed!"));
|
|
return nullptr;
|
|
}
|
|
if (Params.Skeleton && !Params.bSkeletonBefore)
|
|
{
|
|
BaseMesh->Skeleton = Params.Skeleton;
|
|
}
|
|
if (bRunDuplicateCheck)
|
|
{
|
|
TArray<FName> SkelMeshSockets;
|
|
TArray<FName> SkelSockets;
|
|
for (USkeletalMeshSocket* Socket : BaseMesh->GetMeshOnlySocketList())
|
|
{
|
|
if (Socket)
|
|
{
|
|
SkelMeshSockets.Add(Socket->GetFName());
|
|
UE_LOG(LogTemp, Warning, TEXT("SkelMeshSocket: %s"), *(Socket->SocketName.ToString()));
|
|
}
|
|
}
|
|
for (USkeletalMeshSocket* Socket : BaseMesh->Skeleton->Sockets)
|
|
{
|
|
if (Socket)
|
|
{
|
|
SkelSockets.Add(Socket->GetFName());
|
|
UE_LOG(LogTemp, Warning, TEXT("SkelSocket: %s"), *(Socket->SocketName.ToString()));
|
|
}
|
|
}
|
|
TSet<FName> UniqueSkelMeshSockets;
|
|
TSet<FName> UniqueSkelSockets;
|
|
UniqueSkelMeshSockets.Append(SkelMeshSockets);
|
|
UniqueSkelSockets.Append(SkelSockets);
|
|
int32 Total = SkelSockets.Num() + SkelMeshSockets.Num();
|
|
int32 UniqueTotal = UniqueSkelMeshSockets.Num() + UniqueSkelSockets.Num();
|
|
UE_LOG(LogTemp, Warning, TEXT("SkelMeshSocketCount: %d | SkelSocketCount: %d | Combined: %d"), SkelMeshSockets.Num(), SkelSockets.Num(), Total);
|
|
UE_LOG(LogTemp, Warning, TEXT("SkelMeshSocketCount: %d | SkelSocketCount: %d | Combined: %d"), UniqueSkelMeshSockets.Num(), UniqueSkelSockets.Num(), UniqueTotal);
|
|
UE_LOG(LogTemp, Warning, TEXT("Found Duplicates: %s"), *((Total != UniqueTotal) ? FString("True") : FString("False")));
|
|
}
|
|
return BaseMesh;
|
|
} |