#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ProceduralMeshComponent.h"
#include "TerrainCreateActor.generated.h"
UCLASS()
class UETERRAIN_API ATerrainCreateActor : public AActor
{
GENERATED_BODY()
public:
ATerrainCreateActor();
private:
UPROPERTY(VisibleAnywhere)
UProceduralMeshComponent * mesh;//自定义mesh
UPROPERTY(EditAnywhere)
UTexture2D * grayTexture;//传入灰度图
UPROPERTY(EditAnywhere)
float zScale;//z值系数
UPROPERTY(EditAnywhere)
UMaterial* meshMat;//材质
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
};
源文件
#include "TerrainCreateActor.h"
ATerrainCreateActor::ATerrainCreateActor()
{
PrimaryActorTick.bCanEverTick = true;
mesh = CreateDefaultSubobject(TEXT("terrainMesh"));
RootComponent = mesh;
mesh->bUseAsyncCooking = true;
}
void ATerrainCreateActor::BeginPlay()
{
Super::BeginPlay();
//读取灰度图像素信息
FTexture2DMipMap* MyMipMap = &grayTexture->PlatformData->Mips[0];
FByteBulkData* RawImageData = &MyMipMap->BulkData;
FColor* FormatedImageData = static_cast(RawImageData->Lock(LOCK_READ_ONLY));
uint32 TextureWidth = MyMipMap->SizeX, TextureHeight = MyMipMap->SizeY;
//mesh基础信息
TArray vertices;
TArray Triangles;
TArray normals;
TArray UV0;
TArray tangents;
TArray vertexColors;
for (size_t i = 0; i < TextureWidth; i++)
{
for (size_t j = 0; j < TextureHeight; j++)
{
//根据颜色设定顶点z值
FColor PixelColor = FormatedImageData[j * TextureWidth + i];
float tempZ = (PixelColor .B* 299 + PixelColor .G* 587 + PixelColor.R * 114 + 500) / 1000;//rgb转灰度
tempZ *= zScale;
vertices.Add(FVector(i*5, j*5, tempZ)); //顶点
normals.Add(FVector(0, 0, 1));//法线
UV0.Add(FVector2D((float)i/(float)TextureWidth, (float)j/(float)TextureHeight));//uv
//UV0.Add(FVector2D(i,j));//uv
tangents.Add(FProcMeshTangent(1, 0, 0));//切线
vertexColors.Add(FLinearColor(0.75, 0.75, 0.75, 1.0)); //顶点颜色
if (j < TextureHeight - 1 && i < TextureWidth - 1)
{
//三角索引 此处按照vertice的添加顺序确定索引
Triangles.Add(i*TextureHeight + j);
Triangles.Add(i*TextureHeight + j + 1);
Triangles.Add(i*TextureHeight + j + TextureHeight);
Triangles.Add(i*TextureHeight + j + TextureHeight);
Triangles.Add(i*TextureHeight + j + 1);
Triangles.Add(i*TextureHeight + j + TextureHeight + 1);
}
}
}
RawImageData->Unlock();
//创建mesh
mesh->CreateMeshSection_LinearColor(0, vertices, Triangles, normals, UV0, vertexColors, tangents, true);
mesh->ContainsPhysicsTriMeshData(true);
mesh->SetMaterial(0, meshMat);
}
void ATerrainCreateActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}