Advertisement
Guest User

FindCollision UV

a guest
Jul 31st, 2019
2,042
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.61 KB | None | 0 0
  1. struct FVertexUVPair
  2. {
  3.     FVector2D UVs;
  4.     FVector Position;
  5. };
  6.  
  7. struct FSortVertexByDistance
  8. {
  9.     FSortVertexByDistance(const FVector& InSourceLocation)
  10.         : SourceLocation(InSourceLocation)
  11.     {
  12.  
  13.     }
  14.  
  15.     FVector SourceLocation;
  16.  
  17.     bool operator()(const FVertexUVPair A, const FVertexUVPair B) const
  18.     {
  19.         float DistanceA = FVector::DistSquared(SourceLocation, A.Position);
  20.         float DistanceB = FVector::DistSquared(SourceLocation, B.Position);
  21.  
  22.         return DistanceA < DistanceB;
  23.     }
  24. };
  25.  
  26.  
  27. bool USG_GameplayStatics::FindCollisionUVFromHit(const struct FHitResult& Hit, FVector2D& UV)
  28. {
  29.     if (UPrimitiveComponent* HitPrimComp = Hit.Component.Get())
  30.     {
  31.         TArray<FVertexUVPair> AllVertices;
  32.         const FVector LocalHitPos = HitPrimComp->GetComponentToWorld().InverseTransformPosition(Hit.Location);
  33.  
  34.         if (USkeletalMeshComponent* SkelComp = Cast<USkeletalMeshComponent>(HitPrimComp))
  35.         {
  36.             if (FSkeletalMeshRenderData* RenderData = SkelComp->GetSkeletalMeshRenderData())
  37.             {
  38.                 if (RenderData->LODRenderData.Num() > 0)
  39.                 {
  40.                     for (uint32 i = 0; i < RenderData->LODRenderData[0].StaticVertexBuffers.StaticMeshVertexBuffer.GetNumVertices() ; ++i)
  41.                     {
  42.                         FVertexUVPair NewPair;
  43.                         NewPair.Position = RenderData->LODRenderData[0].StaticVertexBuffers.PositionVertexBuffer.VertexPosition(i);
  44.                         NewPair.UVs = RenderData->LODRenderData[0].StaticVertexBuffers.StaticMeshVertexBuffer.GetVertexUV(i, 0);
  45.                         AllVertices.Emplace(NewPair);
  46.                     }
  47.                 }
  48.             }
  49.         }
  50.         else if(UBodySetup* BodySetup = HitPrimComp->GetBodySetup())
  51.         {
  52.             const int32 VertexCount = BodySetup->UVInfo.VertPositions.Num();
  53.             for (int32 Index = 0; Index < VertexCount; Index++)
  54.             {
  55.                 FVertexUVPair NewPair;
  56.                 NewPair.Position = BodySetup->UVInfo.VertPositions[Index];
  57.                 NewPair.UVs = BodySetup->UVInfo.VertUVs[0][Index];
  58.                 AllVertices.Emplace(NewPair);
  59.             }
  60.         }
  61.  
  62.         // Sort Shortest Vertex from LocalHitPos
  63.         AllVertices.Sort(FSortVertexByDistance(LocalHitPos));
  64.  
  65.         if (AllVertices.Num() < 7)
  66.         {
  67.             return false;
  68.         }
  69.  
  70.         // Get three vertex for computing barycentric coords
  71.         FVector Pos0 = AllVertices[0].Position;
  72.         FVector Pos1 = AllVertices[3].Position;
  73.         FVector Pos2 = AllVertices[6].Position;
  74.  
  75.         FVector2D UV0 = AllVertices[0].UVs;
  76.         FVector2D UV1 = AllVertices[3].UVs;
  77.         FVector2D UV2 = AllVertices[6].UVs;
  78.  
  79.         // Transform hit location from world to local space.
  80.         // Find barycentric coords
  81.         FVector BaryCoords = FMath::ComputeBaryCentric2D(LocalHitPos, Pos0, Pos1, Pos2);
  82.         // Use to blend UVs
  83.         UV = (BaryCoords.X * UV0) + (BaryCoords.Y * UV1) + (BaryCoords.Z * UV2);
  84.  
  85.         return true;
  86.     }
  87.  
  88.     return false;
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement