Getting the world position of skeletal mesh vertex

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);
}
3 Likes