Files
UnrealEngine/Engine/Source/Developer/MeshUtilitiesEngine/Private/MeshUtilitiesEngine.cpp
2025-05-18 13:04:45 +08:00

77 lines
2.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "MeshUtilitiesEngine.h"
#include "Engine/SkeletalMesh.h"
#include "GPUSkinPublicDefs.h"
#include "MeshUtilitiesCommon.h"
#include "Rendering/SkeletalMeshLODModel.h"
#include "Rendering/SkeletalMeshModel.h"
// Find the most dominant bone for each vertex
int32 GetDominantBoneIndex(FSoftSkinVertex* SoftVert)
{
uint16 MaxWeightBone = 0;
uint16 MaxWeightWeight = 0;
for (int32 i = 0; i < MAX_TOTAL_INFLUENCES; i++)
{
if (SoftVert->InfluenceWeights[i] > MaxWeightWeight)
{
MaxWeightWeight = SoftVert->InfluenceWeights[i];
MaxWeightBone = SoftVert->InfluenceBones[i];
}
}
return MaxWeightBone;
}
void FMeshUtilitiesEngine::CalcBoneVertInfos(USkeletalMesh* SkeletalMesh, TArray<FBoneVertInfo>& Infos, bool bOnlyDominant)
{
FSkeletalMeshModel* ImportedResource = SkeletalMesh->GetImportedModel();
if (ImportedResource->LODModels.Num() == 0)
return;
SkeletalMesh->CalculateInvRefMatrices();
check(SkeletalMesh->GetRefSkeleton().GetRawBoneNum() == SkeletalMesh->GetRefBasesInvMatrix().Num());
Infos.Empty();
Infos.AddZeroed(SkeletalMesh->GetRefSkeleton().GetRawBoneNum());
FSkeletalMeshLODModel* LODModel = &ImportedResource->LODModels[0];
for (int32 SectionIndex = 0; SectionIndex < LODModel->Sections.Num(); SectionIndex++)
{
FSkelMeshSection& Section = LODModel->Sections[SectionIndex];
for (int32 i = 0; i < Section.SoftVertices.Num(); i++)
{
FSoftSkinVertex* SoftVert = &Section.SoftVertices[i];
if (bOnlyDominant)
{
int32 BoneIndex = Section.BoneMap[GetDominantBoneIndex(SoftVert)];
FVector3f LocalPos = SkeletalMesh->GetRefBasesInvMatrix()[BoneIndex].TransformPosition(SoftVert->Position);
Infos[BoneIndex].Positions.Add(LocalPos);
FVector3f LocalNormal = SkeletalMesh->GetRefBasesInvMatrix()[BoneIndex].TransformVector(SoftVert->TangentZ);
Infos[BoneIndex].Normals.Add(LocalNormal);
}
else
{
for (int32 j = 0; j < MAX_TOTAL_INFLUENCES; j++)
{
if (SoftVert->InfluenceWeights[j] > 0)
{
int32 BoneIndex = Section.BoneMap[SoftVert->InfluenceBones[j]];
FVector3f LocalPos = SkeletalMesh->GetRefBasesInvMatrix()[BoneIndex].TransformPosition(SoftVert->Position);
Infos[BoneIndex].Positions.Add(LocalPos);
FVector3f LocalNormal = SkeletalMesh->GetRefBasesInvMatrix()[BoneIndex].TransformVector(SoftVert->TangentZ);
Infos[BoneIndex].Normals.Add(LocalNormal);
}
}
}
}
}
}