Heres a function to obtain UV-coordinates from SkeletalMeshComponent without FaceIndex. However it still doesnt work since my USkeletalMeshComponents doesnt have UVInformation…
FVector2D FaceIndexSkeletalMesh(FHitResult& HitInfo) const
{
FVector2D UVCoordinates(-1, -1);
TArray<USkeletalMeshComponent*> SkelMeshComps;
HitInfo.GetActor()->GetComponents(SkelMeshComps, false);
if (SkelMeshComps.Num() == 0) return UVCoordinates*2;
UBodySetup* BodySetup = SkelMeshComps[0]->GetBodySetup();
//UPrimitiveComponent* PrimComp = HitInfo.GetComponent();
//UBodySetup* BodySetup = PrimComp->GetBodySetup();
if (!BodySetup) return UVCoordinates*3;
FBodySetupUVInfo UVInfo = BodySetup->UVInfo;
// Get the vertex positions
const TArray<FVector>& VertPositions = UVInfo.VertPositions;
// Get the index buffer
const TArray<int32> IndexBuffer = UVInfo.IndexBuffer;
// ImpactPoint in Local Perspective
const FVector LocalHitPos = SkelMeshComps[0]->GetComponentToWorld().InverseTransformPosition(HitInfo.ImpactPoint);
// Normal of Surface
const FVector SurfaceNormal = HitInfo.ImpactNormal;
// Iterate over the triangles of the mesh
int UVChannel = 0;
while ((UVCoordinates.X < 0.f || UVCoordinates.X > 1.f || UVCoordinates.Y < 0.f || UVCoordinates.Y > 1.f) && UVChannel < 4) {
if ( !UVInfo.VertUVs.IsValidIndex(UVChannel) ) return UVCoordinates*4;
// Get the vertex UV coordinates
const TArray<FVector2D> VertUVs = UVInfo.VertUVs[UVChannel];
if (VertUVs.Num() == 0) return UVCoordinates*5;
UVChannel++;
for (int32 i = 0; i < IndexBuffer.Num(); i += 3)
{
// Get the vertex indices of the current triangle
int32 VertexIndex0 = IndexBuffer[i];
int32 VertexIndex1 = IndexBuffer[i + 1];
int32 VertexIndex2 = IndexBuffer[i + 2];
// Get the vertex positions of the current triangle
const FVector& Position0 = VertPositions[VertexIndex0];
const FVector& Position1 = VertPositions[VertexIndex1];
const FVector& Position2 = VertPositions[VertexIndex2];
FVector Input1, Input2;
// Check if the impact point lies on this triangle
if (FMath::SegmentTriangleIntersection(LocalHitPos - SurfaceNormal * 0.1f, LocalHitPos + SurfaceNormal * 0.1f, Position0, Position1, Position2, Input1, Input2))
{
// Get the UV coordinates of the current triangle
const FVector2D UV0 = VertUVs[VertexIndex0];
const FVector2D UV1 = VertUVs[VertexIndex1];
const FVector2D UV2 = VertUVs[VertexIndex2];
// Barycentric interpolation to get the UV coordinates of the impact point
FVector BaryCoords = FMath::ComputeBaryCentric2D(LocalHitPos, Position0, Position1, Position2);
UVCoordinates = UV0 * BaryCoords.X + UV1 * BaryCoords.Y + UV2 * BaryCoords.Z;
break;
}
}
}
return UVCoordinates;
}
UE 4.26