Got it working in 5.4
#include "Rendering/SkeletalMeshRenderData.h"
#include "Engine/SkeletalMesh.h"
#include "SkeletalRenderPublic.h"
bool UCustomBP_Library::BP_GetSkeletalMeshVertexLocations(USkeletalMeshComponent* Mesh, TArray<FVector>& Locations, int32 LODIndex)
{
if (!Mesh || !Mesh->GetSkeletalMeshAsset())
{
return false;
}
const FSkeletalMeshRenderData* RenderData = Mesh->GetSkeletalMeshRenderData();
if (!RenderData)
{
return false;
}
const FSkeletalMeshLODRenderData& LOD = RenderData->LODRenderData[LODIndex];
const FSkinWeightVertexBuffer& Buffer = LOD.SkinWeightVertexBuffer;
TArray<FMatrix44f> CacheToLocals;
Mesh->GetCurrentRefToLocalMatrices(CacheToLocals, LODIndex);
if (Mesh->GetCPUSkinningEnabled())
{
// CPU skinning
TArray<FFinalSkinVertex> SkinnedVertices;
Mesh->GetCPUSkinnedVertices(SkinnedVertices, LODIndex);
Locations.Empty();
Locations.AddUninitialized(SkinnedVertices.Num());
for (int32 i = 0; i < SkinnedVertices.Num(); ++i)
{
Locations[i] = FVector(SkinnedVertices[i].Position);
}
}
else
{
// GPU skinning
TArray<UE::Math::TVector<float>> SkinnedPositions;
Mesh->ComputeSkinnedPositions(Mesh, SkinnedPositions, CacheToLocals, LOD, Buffer);
Locations.Empty();
Locations.AddUninitialized(SkinnedPositions.Num());
for (int32 i = 0; i < SkinnedPositions.Num(); ++i)
{
Locations[i] = FVector(SkinnedPositions[i]);
}
}
// Transform local positions to world positions
const FTransform ToWorld = Mesh->GetComponentTransform();
for (FVector& EachVertex : Locations)
{
EachVertex = ToWorld.TransformPosition(EachVertex);
}
return true;
}
void UCustomBP_Library::BP_SetCPUSkinningEnabled(USkinnedMeshComponent* Mesh, bool bEnable, bool bRecreateRenderStateImmediately)
{
Mesh->SetCPUSkinningEnabled(bEnable, bRecreateRenderStateImmediately);
}