Getting the world position of skeletal mesh vertex

So sorry to hear that. :smiling_face_with_tear:

WOW
This is awesome, thanks for sharing. It works in UE5, you just need to change a few variable types.

can you share Which varibale type to change
its related to cons but i cant get it to Work

1 Like

I am trying to do the same thing, did you solve it? :smiling_face_with_tear:

Can you share the UE5 version of this plugin please? That would be so nice of you. I straggled for quite some time but still failed…

bump! Has anyone figured out the change needed for UE5 by chance?

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