까먹지 않으려고 적어놓음..!
void UMeshProcessor::OffsetUVs(UStaticMesh* StaticMesh, int32 TargetMaterialID, float UVRangeOffset, int32 UVChannel)
{
if (!StaticMesh || !StaticMesh->GetRenderData())
{
UE_LOG(LogTemp, Warning, TEXT("Invalid Static Mesh or no Render Data available"));
return;
}
FStaticMeshRenderData* RenderData = StaticMesh->GetRenderData();
FStaticMeshLODResources& LODResources = RenderData->LODResources[0];
const FStaticMeshSectionArray& Sections = LODResources.Sections;
// Material ID 검증
if (TargetMaterialID <= 0 || TargetMaterialID > Sections.Num())
{
UE_LOG(LogTemp, Warning, TEXT("Invalid Material ID"));
UE_LOG(LogTemp, Warning, TEXT("MaterialID: %d"), TargetMaterialID);
UE_LOG(LogTemp, Warning, TEXT("Sections.Num(): %d"), Sections.Num());
return;
}
// Target Material ID에 해당하는 섹션 선택
const FStaticMeshSection& TargetSection = Sections[TargetMaterialID - 1];
FStaticMeshVertexBuffers& VertexBuffers = LODResources.VertexBuffers;
// UV Offset 계산
float MaterialOffsetX = (TargetMaterialID - 1) * UVRangeOffset;
UE_LOG(LogTemp, Log, TEXT("MaterialOffsetX for MaterialID %d: %f"), TargetMaterialID, MaterialOffsetX);
// 중복 정점 추적
TSet<uint32> ModifiedVertices;
// 특정 Material ID에 속하는 Vertex만 UV 이동
for (uint32 TriangleIndex = 0; TriangleIndex < TargetSection.NumTriangles; ++TriangleIndex)
{
uint32 BaseIndex = TargetSection.FirstIndex + TriangleIndex * 3;
uint32 Index0 = LODResources.IndexBuffer.GetIndex(BaseIndex);
uint32 Index1 = LODResources.IndexBuffer.GetIndex(BaseIndex + 1);
uint32 Index2 = LODResources.IndexBuffer.GetIndex(BaseIndex + 2);
// Index 0
if (!ModifiedVertices.Contains(Index0))
{
FVector2f UV0 = VertexBuffers.StaticMeshVertexBuffer.GetVertexUV(Index0, UVChannel);
UV0.X += MaterialOffsetX; // Apply offset
VertexBuffers.StaticMeshVertexBuffer.SetVertexUV(Index0, UVChannel, UV0);
ModifiedVertices.Add(Index0);
}
// Index 1
if (!ModifiedVertices.Contains(Index1))
{
FVector2f UV1 = VertexBuffers.StaticMeshVertexBuffer.GetVertexUV(Index1, UVChannel);
UV1.X += MaterialOffsetX; // Apply offset
VertexBuffers.StaticMeshVertexBuffer.SetVertexUV(Index1, UVChannel, UV1);
ModifiedVertices.Add(Index1);
}
// Index 2
if (!ModifiedVertices.Contains(Index2))
{
FVector2f UV2 = VertexBuffers.StaticMeshVertexBuffer.GetVertexUV(Index2, UVChannel);
UV2.X += MaterialOffsetX; // Apply offset
VertexBuffers.StaticMeshVertexBuffer.SetVertexUV(Index2, UVChannel, UV2);
ModifiedVertices.Add(Index2);
}
}
// Static Mesh 업데이트
StaticMesh->Modify();
StaticMesh->MarkPackageDirty();
UE_LOG(LogTemp, Log, TEXT("UVs have been adjusted for Material ID %d in UVChannel %d."), TargetMaterialID, UVChannel);
}
중복정점이 이동했는지 안했는 지 추적하지않으면 계속 누적해서 uvoffset이 이동된다.
같은 좌표에 여러개의 vertex가 있으면 uv offset이 한 정점에만 적용되는것이아니라 위치 기준으로 적용되서 포문을 돌때마다 위치가 같은 모든정점에 offset이 누적되게된다.