我想使用线迹来获取静态网格物体的材质,因为静态网格物体包含多种材质。我通过chaanel设置了复杂的线条跟踪,但是FHitResult没有返回渲染matrial,所以我想使用FHitResult.FaceIndx来获取三角形的材质。有什么建议吗?
答案 0 :(得分:1)
首先做一个样本光线投射,它击中一个正确的物体,做一个复杂的光线投射并获得目标网格,在复杂的光线投射FHitResult中,我们得到FaceIndex,它意味着我们击中了哪个三角形。 然后我们可以使用FaceIndex查询网格,并获得Section ID(在UE4中,Section是网格单元,一个Scetion使用一种材质,一个Scetion可以使多个三角形存在)。 最后,按部分ID获取材料ID。
FHitResult simpleResult = GetRaycastHitResultSimple(pc, startPos, endPos);
if (simpleResult.bBlockingHit)
{
UStaticMeshComponent* staticMeshComponent = Cast<UStaticMeshComponent>(simpleResult.GetComponent());
if (staticMeshComponent)
{
UStaticMesh* mesh = staticMeshComponent->StaticMesh;
if (mesh)
{
FHitResult complexResult = GetRaycastHitResultComplex(pc, startPos, endPos);
return GetMaterialByFaceIndex(mesh, complexResult.FaceIndex);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Get mesh from static mesh component faild"));
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Cast FHitResul.GetComponent to static mesh component faild"));
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Simple raycast faild"));
}
int32 UChangeMaterials::GetMaterialByFaceIndex(const UStaticMesh* mesh, const int32& faceIndex)
{
const FStaticMeshLODResources& lodRes = mesh->GetLODForExport(0);
int32 totalSection = lodRes.Sections.Num();
int32 totalFace = lodRes.GetNumTriangles();
if (faceIndex > totalFace)
{
///Wrong faceIndex.
UE_LOG(LogTemp, Warning, TEXT("GetMaterialbyFaceIndex Faild, Wrong faceIndex!"));
return -1;
}
int32 totalTriangleIndex = 0;
for (int32 sectionIndex = 0; sectionIndex < totalSection; ++sectionIndex)
{
FStaticMeshSection currentSection = lodRes.Sections[sectionIndex];
/*Check for each triangle, so we can know which section our faceIndex in. For Low Performance, do not use it.
for (int32 triangleIndex = totalTriangleIndex; triangleIndex < (int32)currentSection.NumTriangles + totalTriangleIndex; ++triangleIndex)
{
if (faceIndex == triangleIndex)
{
//return sectionIndex;
return currentSection.MaterialIndex;
}
}
totalTriangleIndex += lodRes.Sections[sectionIndex].NumTriangles;
*/
///the triangle index is sorted by section, the larger sectionIndex contains larger triangle index, so we can easily calculate which section the faceIndex in.Performance Well.
int32 triangleIndex = totalTriangleIndex;
if (faceIndex >= triangleIndex && faceIndex < triangleIndex + (int32)lodRes.Sections[sectionIndex].NumTriangles)
{
//return sectionIndex;
return currentSection.MaterialIndex;
}
totalTriangleIndex += lodRes.Sections[sectionIndex].NumTriangles;
}
/// did not find the face in the mesh.
UE_LOG(LogTemp, Warning, TEXT("GetMaterialByFaceIndex, did not find it!"));
return -2;
}