After some searching I have given up on trying to find a way to set the heightmap using c++. It just is not worth it. I instead focused on making a heightmap using c++. This has worked a litle bit. Combining the info from redblobgames (Making maps with noise functions) and Isara Tech (UE4 - Save a procedurally generated texture as a new asset - Isara Tech.) I was able to create a 2 dimensonal array containing perlin noise values. I then used these values to set the gray colors of a texture (make shure u are using PF_G8 as pixel format). This texture is then saved to the /Game/ProceduralTextures/ folder. After that u have to export the texture out of the map, open the file using paint and the save the file as a png. The result I got from the code where les than optimal but it something. If you find this I hope you have better luck automating this then I did.
//my input is a landscape object
void ACPP_TestLevel::VeranderLandschap(ALandscape* landscape)
{
// this is code from https://isaratech.com/save-a-procedurally-generated-texture-as-a-new-asset/
// it is about saving textures to a local folder.
// tested this code out to see if i actualy created the texture.
int TextureWidth = 256;
int TextureHeight = 256;
FString TextureName = "testtexture5";
FString PackageName = TEXT("/Game/ProceduralTextures/");
PackageName += TextureName;
UPackage* Package = CreatePackage(NULL, *PackageName);
Package->FullyLoad();
UTexture2D* NewTexture = NewObject<UTexture2D>(Package, *TextureName, RF_Public | RF_Standalone | RF_MarkAsRootSet);
NewTexture->AddToRoot(); // This line prevents garbage collection of the texture
NewTexture->PlatformData = new FTexturePlatformData(); // Then we initialize the PlatformData
NewTexture->PlatformData->SizeX = TextureWidth;
NewTexture->PlatformData->SizeY = TextureHeight;
//NewTexture->PlatformData->NumSlices = 1;
NewTexture->PlatformData->PixelFormat = EPixelFormat::PF_G8;
int height = TextureHeight;
int width = TextureWidth;
double value[256][256];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float nx = (x/(width-0.5));
float ny = (y/(height-0.5));
float e = 1*FMath::PerlinNoise2D(FVector2D((1*nx), (1*ny)));
e = (e+0.5*FMath::PerlinNoise2D(FVector2D((2*nx), (2*ny))));
e = (e+0.25 *FMath::PerlinNoise2D(FVector2D((4*nx),(4*ny))));
e = (e /(1 + 0.5 + 0.25));
value[y][x] = pow(e, 1.00);
}
}
uint8* Pixels = new uint8[TextureWidth * TextureHeight];
for (int32 y = 0; y < TextureHeight; y++)
{
for (int32 x = 0; x < TextureWidth; x++)
{
//int color = FMath::PerlinNoise1D(static_cast <float> (rand()) / static_cast <float> (RAND_MAX))*255;
int32 curPixelIndex = ((y * TextureWidth) + x);
Pixels[curPixelIndex] = (value[y][x])*255;
}
}
// Allocate first mipmap.
FTexture2DMipMap* Mip = new(NewTexture->PlatformData->Mips) FTexture2DMipMap();
Mip->SizeX = TextureWidth;
Mip->SizeY = TextureHeight;
// Lock the texture so it can be modified
Mip->BulkData.Lock(LOCK_READ_WRITE);
uint8* TextureData = (uint8*)Mip->BulkData.Realloc(TextureWidth * TextureHeight * 4);
FMemory::Memcpy(TextureData, Pixels, sizeof(uint8) * TextureHeight * TextureWidth * 4);
Mip->BulkData.Unlock();
NewTexture->Source.Init(TextureWidth, TextureHeight, 1, 1, ETextureSourceFormat::TSF_G8, Pixels);
NewTexture->UpdateResource();
Package->MarkPackageDirty();
FAssetRegistryModule::AssetCreated(NewTexture);
FString PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension());
bool bSaved = UPackage::SavePackage(Package, NewTexture, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *PackageFileName, GError, nullptr, true, true, SAVE_NoError);
delete[] Pixels; // Don't forget to free the memory here
int aantal = landscape->LandscapeComponents.Num();
for (int i = 0; i < aantal; ++i)
{
landscape->LandscapeComponents[i]->SetHeightmap(NewTexture);
landscape->LandscapeComponents[i]->RequestHeightmapUpdate();
landscape->LandscapeComponents[i]->PostLoad();
}
}