Retrieving UV Coordinates of a raycast in Unreal

Hello,

I’m a student in my final year and for one of my assignments I’m looking at how to retrieve UV Coordinates from a raycast.
But there really doesn’t seem alot of documentation about this. I know it’s possible to retrieve UV coordinates in Unity and draw on a texture but this doesn’t seem possible in Unreal.
So I pulled the sources of the Unreal engine (4.9.2) and added Rama’s edits as described here: https://forums.unrealengine.com/showthread.php?65827-New-Wiki-How-to-get-UV-hit-information-back-from-Line-Traces-in-UE4!&highlight=raycast+uv

But Rama only retrieves the barycentric coordinates from the PhysX engine. These coordinates needed to be converted to UV coordinates.

I then made these edits based on code I found elsewhere https://forums.unrealengine.com/showthread.php?62805-Question-about-traces-and-geometry&p=247562&viewfull=1 in the PhysXCollission.cpp in the RaycastSingle function:


				if (Params.bReturnUV)
				{
					UStaticMeshComponent* StaticMeshComponent = Cast<UStaticMeshComponent>(OutHit.GetComponent());
					if (StaticMeshComponent)
					{
						FStaticMeshRenderData* RenderData = StaticMeshComponent->StaticMesh->RenderData;
						// Get mesh data from the current LOD.
						const FStaticMeshLODResources& LODResourceData = RenderData->LODResources[StaticMeshComponent->PreviousLODLevel];

						FIndexArrayView IndexArray = LODResourceData.IndexBuffer.GetArrayView();
						uint32 HitVertIndex0 = (uint32)IndexArray[PHit.faceIndex * 3];
						uint32 HitVertIndex1 = (uint32)IndexArray[PHit.faceIndex * 3 + 1];
						uint32 HitVertIndex2 = (uint32)IndexArray[PHit.faceIndex * 3 + 2];

						FVector Vert0Pos = LODResourceData.PositionVertexBuffer.VertexPosition(HitVertIndex0);
						FVector Vert1Pos = LODResourceData.PositionVertexBuffer.VertexPosition(HitVertIndex1);
						FVector Vert2Pos = LODResourceData.PositionVertexBuffer.VertexPosition(HitVertIndex2);

						FVector2D Vert0UV = LODResourceData.VertexBuffer.GetVertexUV(HitVertIndex0, 0);
						FVector2D Vert1UV = LODResourceData.VertexBuffer.GetVertexUV(HitVertIndex1, 0);
						FVector2D Vert2UV = LODResourceData.VertexBuffer.GetVertexUV(HitVertIndex2, 0);

						FVector ComponentLocation = StaticMeshComponent->GetComponentLocation();
						FRotator ComponentRotation = StaticMeshComponent->GetComponentRotation();
						FVector ComponentScale = StaticMeshComponent->GetComponentScale();

						// Transform world impact point to local coordinates.
						FVector LocalImpactPoint = ComponentRotation.UnrotateVector(OutHit.ImpactPoint - ComponentLocation) / ComponentScale;

						// Determine the barycentric coordinates
						FVector u = Vert1Pos - Vert0Pos;
						FVector v = Vert2Pos - Vert0Pos;
						FVector w = LocalImpactPoint - Vert0Pos;

						FVector vCrossW = FVector::CrossProduct(v, w);
						FVector vCrossU = FVector::CrossProduct(v, u);

						if (FVector::DotProduct(vCrossW, vCrossU) < 0.0f)
						{
							return false;
						}

						FVector uCrossW = FVector::CrossProduct(u, w);
						FVector uCrossV = FVector::CrossProduct(u, v);

						if (FVector::DotProduct(uCrossW, uCrossV) < 0.0f)
						{
							return false;
						}

						float denom = uCrossV.Size();
						float b1 = vCrossW.Size() / denom;
						float b2 = uCrossW.Size() / denom;
						float b0 = 1.0f - b1 - b2;

						// Determine the hit UV.
						float hitU = b0 * Vert0UV.X + b1 * Vert1UV.X + b2 * Vert2UV.X;
						float hitV = b0 * Vert0UV.Y + b1 * Vert1UV.Y + b2 * Vert2UV.Y;

						OutHit.UV = FVector2D(hitU, hitV);

So basically I can retrieve the UV coordinates from the triangle of the point were the raycast hit and then with the barycentric coordinates we can calculate the UV’s.

But this still isn’t working for some reason. I have to use PHit.faceIndex (from the PhysX library) instead of OutHit.FaceIndex (this always returns -1)
and also the triangle described in the IndexArray doesn’t seem to be correct.

I’m really hoping there’s someone here who can help me or point me in the right direction as to what I can do.
Is there a reason for OutHit.FaceIndex always returning -1?

My long-term goal for this was to procedurally draw textures onto other textures and I need the UV coordinates of the raycast to do that.

Thanks in advance!

Awesome project! I’m not familiar with the raycast code but what the hoo ha, let me take a look, I might stumble onto something.

hey, did you ever solve this?

I’m having the same problem, FaceIndex is always -1
I tried searching the unreal code and I didn’t find any place where FaceIndex gets any value assinged other than INDEX_NONE. is it maybe an incomplete feature from the engine?