Names addapted to naming convention
This commit is contained in:
parent
737c9991fc
commit
63147bb780
|
@ -15,49 +15,46 @@
|
||||||
#include "LandscapeProxy.h"
|
#include "LandscapeProxy.h"
|
||||||
#include "Runtime/Engine/Classes/Engine/ObjectLibrary.h"
|
#include "Runtime/Engine/Classes/Engine/ObjectLibrary.h"
|
||||||
|
|
||||||
#define DEBUG_MSG(x, ...) if(GEngine){GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, FString::Printf(TEXT(x), __VA_ARGS__));}
|
|
||||||
#define DEBUG_MSG_RED(x, ...) if(GEngine){GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT(x), __VA_ARGS__));}
|
|
||||||
|
|
||||||
|
FString UMapGeneratorWidget::GenerateMapFiles(const FMapGeneratorMetaInfo& MetaInfo)
|
||||||
|
|
||||||
FString UMapGeneratorWidget::GenerateMapFiles(const FMapGeneratorMetaInfo& metaInfo)
|
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Generating new map...");
|
|
||||||
|
|
||||||
FString errorMsg = "";
|
FString ErrorMsg = "";
|
||||||
|
|
||||||
// 1. Creating Levels
|
// 1. Creating Levels
|
||||||
CreateMainLargeMap(metaInfo);
|
CreateMainLargeMap(MetaInfo);
|
||||||
CreateTilesMaps(metaInfo);
|
CreateTilesMaps(MetaInfo);
|
||||||
// bool bLoaded = LoadWorld(worldAssetData);
|
// bool bLoaded = LoadWorld(WorldAssetData);
|
||||||
// GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, bLoaded ? "Loaded CORRECT" : "NOT loaded");
|
// GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow,
|
||||||
|
// bLoaded ? "Loaded CORRECT" : "NOT loaded");
|
||||||
|
|
||||||
// 2. Applying heightmap
|
// 2. Applying heightmap
|
||||||
// UWorld* world = CastChecked<UWorld>(worldAssetData.GetAsset());
|
// UWorld* World = CastChecked<UWorld>(WorldAssetData.GetAsset());
|
||||||
// ALandscape* landscape = (ALandscape*) UGameplayStatics::GetActorOfClass(world, ALandscape::StaticClass());
|
// ALandscape* landscape =
|
||||||
// GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, landscape!=nullptr ? "L TRUE" : "L FALSE");
|
// (ALandscape*) UGameplayStatics::GetActorOfClass(World, ALandscape::StaticClass());
|
||||||
|
// GEngine->AddOnScreenDebugMessage(
|
||||||
|
// -1, 15.0f, FColor::Green, landscape!=nullptr ? "L TRUE" : "L FALSE");
|
||||||
// AssignLandscapeHeightMap(landscape);
|
// AssignLandscapeHeightMap(landscape);
|
||||||
|
|
||||||
// 3. Saving world
|
// 3. Saving World
|
||||||
// bool bSaved = SaveWorld(worldAssetData, metaInfo.destinationPath, metaInfo.mapName);
|
// bool bSaved = SaveWorld(WorldAssetData, MetaInfo.DestinationPath, MetaInfo.MapName);
|
||||||
// GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, bSaved ? "Saved CORRECT" : "NOT saved");
|
|
||||||
|
|
||||||
return errorMsg;
|
return ErrorMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UMapGeneratorWidget::LoadBaseTileWorld(FAssetData& WorldAssetData)
|
bool UMapGeneratorWidget::LoadBaseTileWorld(FAssetData& WorldAssetData)
|
||||||
{
|
{
|
||||||
const FString baseMapPath= TEXT("/CarlaTools/MapGenerator/BaseMap/Tiles");
|
const FString BaseMapPath= TEXT("/CarlaTools/MapGenerator/BaseMap/Tiles");
|
||||||
return LoadWorld(WorldAssetData, baseMapPath);
|
return LoadWorld(WorldAssetData, BaseMapPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UMapGeneratorWidget::LoadBaseLargeMapWorld(FAssetData& WorldAssetData)
|
bool UMapGeneratorWidget::LoadBaseLargeMapWorld(FAssetData& WorldAssetData)
|
||||||
{
|
{
|
||||||
const FString baseMapPath= TEXT("/CarlaTools/MapGenerator/BaseMap/MainLargeMap");
|
const FString BaseMapPath= TEXT("/CarlaTools/MapGenerator/BaseMap/MainLargeMap");
|
||||||
return LoadWorld(WorldAssetData, baseMapPath);
|
return LoadWorld(WorldAssetData, BaseMapPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UMapGeneratorWidget::LoadWorld(FAssetData& WorldAssetData, const FString& baseMapPath)
|
bool UMapGeneratorWidget::LoadWorld(FAssetData& WorldAssetData, const FString& BaseMapPath)
|
||||||
{
|
{
|
||||||
TArray<FAssetData> AssetDatas;
|
TArray<FAssetData> AssetDatas;
|
||||||
UObjectLibrary *MapObjectLibrary;
|
UObjectLibrary *MapObjectLibrary;
|
||||||
|
@ -65,7 +62,7 @@ bool UMapGeneratorWidget::LoadWorld(FAssetData& WorldAssetData, const FString& b
|
||||||
// Loading Map from folder using object library
|
// Loading Map from folder using object library
|
||||||
MapObjectLibrary = UObjectLibrary::CreateLibrary(UWorld::StaticClass(), false, GIsEditor);
|
MapObjectLibrary = UObjectLibrary::CreateLibrary(UWorld::StaticClass(), false, GIsEditor);
|
||||||
MapObjectLibrary->AddToRoot();
|
MapObjectLibrary->AddToRoot();
|
||||||
MapObjectLibrary->LoadAssetDataFromPath(*baseMapPath);
|
MapObjectLibrary->LoadAssetDataFromPath(*BaseMapPath);
|
||||||
MapObjectLibrary->LoadAssetsFromAssetData();
|
MapObjectLibrary->LoadAssetsFromAssetData();
|
||||||
MapObjectLibrary->GetAssetDataList(AssetDatas);
|
MapObjectLibrary->GetAssetDataList(AssetDatas);
|
||||||
if (AssetDatas.Num() > 0)
|
if (AssetDatas.Num() > 0)
|
||||||
|
@ -78,90 +75,104 @@ bool UMapGeneratorWidget::LoadWorld(FAssetData& WorldAssetData, const FString& b
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UMapGeneratorWidget::SaveWorld(FAssetData& WorldToBeSaved, const FString& DestinationPath, const FString& WorldName)
|
bool UMapGeneratorWidget::SaveWorld(
|
||||||
|
FAssetData& WorldToBeSaved,
|
||||||
|
const FString& DestinationPath,
|
||||||
|
const FString& WorldName
|
||||||
|
)
|
||||||
{
|
{
|
||||||
UWorld* world;
|
UWorld* World;
|
||||||
UObjectRedirector *BaseMapRedirector = Cast<UObjectRedirector>(WorldToBeSaved.GetAsset());
|
UObjectRedirector *BaseMapRedirector =
|
||||||
|
Cast<UObjectRedirector>(WorldToBeSaved.GetAsset());
|
||||||
if(BaseMapRedirector != nullptr)
|
if(BaseMapRedirector != nullptr)
|
||||||
world = CastChecked<UWorld>(BaseMapRedirector->DestinationObject);
|
World = CastChecked<UWorld>(BaseMapRedirector->DestinationObject);
|
||||||
else
|
else
|
||||||
world = CastChecked<UWorld>(WorldToBeSaved.GetAsset());
|
World = CastChecked<UWorld>(WorldToBeSaved.GetAsset());
|
||||||
|
|
||||||
// Create package
|
// Create Package
|
||||||
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Preparing package");
|
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Preparing Package");
|
||||||
UPackage *package = WorldToBeSaved.GetPackage();
|
UPackage *Package = WorldToBeSaved.GetPackage();
|
||||||
package->SetFolderName("MapGeneratorPackage");
|
Package->SetFolderName("MapGeneratorPackage");
|
||||||
package->FullyLoad();
|
Package->FullyLoad();
|
||||||
package->MarkPackageDirty();
|
Package->MarkPackageDirty();
|
||||||
FAssetRegistryModule::AssetCreated(world);
|
FAssetRegistryModule::AssetCreated(World);
|
||||||
|
|
||||||
// Rename new World
|
// Rename new World
|
||||||
world->Rename(*WorldName, world->GetOuter());
|
World->Rename(*WorldName, World->GetOuter());
|
||||||
const FString PackagePath = DestinationPath + "/" + WorldName;
|
const FString PackagePath = DestinationPath + "/" + WorldName;
|
||||||
FAssetRegistryModule::AssetRenamed(world, *PackagePath);
|
FAssetRegistryModule::AssetRenamed(World, *PackagePath);
|
||||||
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, world->GetMapName());
|
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, World->GetMapName());
|
||||||
world->MarkPackageDirty();
|
World->MarkPackageDirty();
|
||||||
world->GetOuter()->MarkPackageDirty();
|
World->GetOuter()->MarkPackageDirty();
|
||||||
|
|
||||||
// Saving package
|
// Saving Package
|
||||||
const FString PackageFileName = FPackageName::LongPackageNameToFilename(PackagePath, FPackageName::GetMapPackageExtension());
|
const FString PackageFileName = FPackageName::LongPackageNameToFilename(
|
||||||
|
PackagePath,
|
||||||
|
FPackageName::GetMapPackageExtension()
|
||||||
|
);
|
||||||
if(FPaths::FileExists(*PackageFileName))
|
if(FPaths::FileExists(*PackageFileName))
|
||||||
{
|
{
|
||||||
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Package already Exists");
|
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Package already Exists");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return UPackage::SavePackage(package, world, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone,
|
return UPackage::SavePackage(
|
||||||
*PackageFileName, GError, nullptr, true, true, SAVE_NoError);
|
Package, World, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone,
|
||||||
|
*PackageFileName, GError, nullptr, true, true, SAVE_NoError
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UMapGeneratorWidget::CreateMainLargeMap(const FMapGeneratorMetaInfo& metaInfo)
|
bool UMapGeneratorWidget::CreateMainLargeMap(const FMapGeneratorMetaInfo& MetaInfo)
|
||||||
{
|
{
|
||||||
FAssetData worldAssetData;
|
FAssetData WorldAssetData;
|
||||||
bool bLoaded = LoadBaseLargeMapWorld(worldAssetData);
|
bool bLoaded = LoadBaseLargeMapWorld(WorldAssetData);
|
||||||
bool bSaved = SaveWorld(worldAssetData, metaInfo.destinationPath, metaInfo.mapName);
|
bool bSaved = SaveWorld(WorldAssetData, MetaInfo.DestinationPath, MetaInfo.MapName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UMapGeneratorWidget::CreateTilesMaps(const FMapGeneratorMetaInfo& metaInfo)
|
bool UMapGeneratorWidget::CreateTilesMaps(const FMapGeneratorMetaInfo& MetaInfo)
|
||||||
{
|
{
|
||||||
FAssetData worldAssetData;
|
FAssetData WorldAssetData;
|
||||||
|
|
||||||
int numberOfTiles = metaInfo.sizeX * metaInfo.sizeY;
|
|
||||||
|
|
||||||
for(int i = 0; i < metaInfo.sizeX; i++)
|
for(int i = 0; i < MetaInfo.SizeX; i++)
|
||||||
{
|
{
|
||||||
for(int j = 0; j < metaInfo.sizeY; j++)
|
for(int j = 0; j < MetaInfo.SizeY; j++)
|
||||||
{
|
{
|
||||||
bool bLoaded = LoadBaseTileWorld(worldAssetData);
|
bool bLoaded = LoadBaseTileWorld(WorldAssetData);
|
||||||
|
|
||||||
FMapGeneratorTileMetaInfo metaTileInfo;
|
FMapGeneratorTileMetaInfo MetaTileInfo;
|
||||||
metaTileInfo.indexX = i;
|
MetaTileInfo.IndexX = i;
|
||||||
metaTileInfo.indexY = j;
|
MetaTileInfo.IndexY = j;
|
||||||
ApplyHeightMapToLandscape(worldAssetData,metaTileInfo);
|
ApplyHeightMapToLandscape(WorldAssetData,MetaTileInfo);
|
||||||
|
|
||||||
const FString mapName = metaInfo.mapName + "_Tile_" + FString::FromInt(i) + "_" + FString::FromInt(j);
|
const FString MapName =
|
||||||
bool bSaved = SaveWorld(worldAssetData, metaInfo.destinationPath, mapName);
|
MetaInfo.MapName + "_Tile_" + FString::FromInt(i) + "_" + FString::FromInt(j);
|
||||||
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, bSaved ? "Saved CORRECT" : "NOT saved");
|
bool bSaved = SaveWorld(WorldAssetData, MetaInfo.DestinationPath, MapName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UMapGeneratorWidget::ApplyHeightMapToLandscape(FAssetData& worldAssetData, FMapGeneratorTileMetaInfo tileMetaInfo)
|
bool UMapGeneratorWidget::ApplyHeightMapToLandscape(
|
||||||
|
FAssetData& WorldAssetData,
|
||||||
|
FMapGeneratorTileMetaInfo tileMetaInfo
|
||||||
|
)
|
||||||
{
|
{
|
||||||
UWorld* world;
|
UWorld* World;
|
||||||
UObjectRedirector* BaseMapRedirector = Cast<UObjectRedirector>(worldAssetData.GetAsset());
|
UObjectRedirector* BaseMapRedirector =
|
||||||
|
Cast<UObjectRedirector>(WorldAssetData.GetAsset());
|
||||||
if(BaseMapRedirector != nullptr)
|
if(BaseMapRedirector != nullptr)
|
||||||
{
|
{
|
||||||
world = CastChecked<UWorld>(BaseMapRedirector->DestinationObject);
|
World = CastChecked<UWorld>(BaseMapRedirector->DestinationObject);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
world = CastChecked<UWorld>(worldAssetData.GetAsset());
|
World = CastChecked<UWorld>(WorldAssetData.GetAsset());
|
||||||
}
|
}
|
||||||
ALandscape* landscape = (ALandscape*) UGameplayStatics::GetActorOfClass(world, ALandscape::StaticClass());
|
ALandscape* landscape = (ALandscape*) UGameplayStatics::GetActorOfClass(
|
||||||
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, landscape!=nullptr ? "L TRUE" : "L FALSE");
|
World,
|
||||||
|
ALandscape::StaticClass()
|
||||||
|
);
|
||||||
AssignLandscapeHeightMap(landscape, tileMetaInfo);
|
AssignLandscapeHeightMap(landscape, tileMetaInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de Barcelona (UAB). This work is licensed under the terms of the MIT license. For a copy, see <https://opensource.org/licenses/MIT>.
|
// Copyright (c) 2022 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||||
|
// de Barcelona (UAB).
|
||||||
|
//
|
||||||
|
// This work is licensed under the terms of the MIT license.
|
||||||
|
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
#include "ProceduralWaterManager.h"
|
#include "ProceduralWaterManager.h"
|
||||||
|
|
||||||
|
@ -10,7 +13,7 @@
|
||||||
#include "Runtime/Engine/Public/DrawDebugHelpers.h"
|
#include "Runtime/Engine/Public/DrawDebugHelpers.h"
|
||||||
#include "UnrealString.h"
|
#include "UnrealString.h"
|
||||||
|
|
||||||
#include "Actor.h"
|
#include "GameFramework/Actor.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
#include "UObject/ConstructorHelpers.h"
|
#include "UObject/ConstructorHelpers.h"
|
||||||
|
|
||||||
|
@ -20,190 +23,196 @@ UProceduralWaterManager::UProceduralWaterManager()
|
||||||
// Pass
|
// Pass
|
||||||
}
|
}
|
||||||
|
|
||||||
FString UProceduralWaterManager::StartWaterGeneration(const FProceduralRiversMetaInfo metaInfo)
|
FString UProceduralWaterManager::StartWaterGeneration(const FProceduralRiversMetaInfo MetaInfo)
|
||||||
{
|
{
|
||||||
FString errorMsg="";
|
FString ErrorMsg="";
|
||||||
|
|
||||||
|
if(MetaInfo.WaterGenerationType == EWaterGenerationType::RIVERS)
|
||||||
|
|
||||||
if(metaInfo.WaterGenerationType == EWaterGenerationType::RIVERS)
|
|
||||||
{
|
{
|
||||||
if(RiverBlueprintClass)
|
if(RiverBlueprintClass)
|
||||||
errorMsg = RiverGeneration(metaInfo);
|
ErrorMsg = RiverGeneration(MetaInfo);
|
||||||
else
|
else
|
||||||
errorMsg = "ERROR: River class not assigned";
|
ErrorMsg = "ERROR: River class not assigned";
|
||||||
}
|
}
|
||||||
else if(metaInfo.WaterGenerationType == EWaterGenerationType::LAKE)
|
else if(MetaInfo.WaterGenerationType == EWaterGenerationType::LAKE)
|
||||||
{
|
{
|
||||||
errorMsg = LakeGeneration(metaInfo);
|
ErrorMsg = LakeGeneration(MetaInfo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
errorMsg = "Error in Water Generation Type";
|
ErrorMsg = "Error in Water Generation Type";
|
||||||
|
|
||||||
return errorMsg;
|
return ErrorMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
FString UProceduralWaterManager::RiverGeneration(const FProceduralRiversMetaInfo metaInfo)
|
FString UProceduralWaterManager::RiverGeneration(const FProceduralRiversMetaInfo MetaInfo)
|
||||||
{
|
{
|
||||||
FString errorMsg;
|
FString ErrorMsg;
|
||||||
|
|
||||||
const FString WaterInfoPath = metaInfo.WaterInfoPath;
|
const FString WaterInfoPath = MetaInfo.WaterInfoPath;
|
||||||
if(!FPlatformFileManager::Get().GetPlatformFile().FileExists(*WaterInfoPath))
|
if(!FPlatformFileManager::Get().GetPlatformFile().FileExists(*WaterInfoPath))
|
||||||
{
|
{
|
||||||
errorMsg = "File Not Found!! :(";
|
ErrorMsg = "File Not Found!! :(";
|
||||||
DEBUG_MSG("File Not Found!! :(");
|
return ErrorMsg;
|
||||||
return errorMsg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<FString> file;
|
TArray<FString> File;
|
||||||
FFileHelper::LoadFileToStringArray(file, *WaterInfoPath);
|
FFileHelper::LoadFileToStringArray(File, *WaterInfoPath);
|
||||||
|
|
||||||
TArray<FSplinePoint> riverPoints;
|
float InputKeyCount = 0.0f;
|
||||||
|
int IterationNumber = 0;
|
||||||
|
|
||||||
float inputKeyCount = 0.0f;
|
AActor* RiverActor = nullptr;
|
||||||
int iterationNumber = 0;
|
|
||||||
|
|
||||||
AActor* riverActor = nullptr;
|
FString StrX, StrY;
|
||||||
|
FVector PreviusPosition(NAN, NAN, NAN);
|
||||||
|
|
||||||
FString x_str, y_str;
|
float ScaleFactor = MetaInfo.CustomScaleFactor;
|
||||||
FVector previusPosition(NAN, NAN, NAN);
|
|
||||||
|
|
||||||
float scaleFactor = metaInfo.CustomScaleFactor;
|
if(File.Num() == 0)
|
||||||
FVector locationOffset(0,0,0);
|
|
||||||
|
|
||||||
if(file.Num() == 0)
|
|
||||||
return "Error processing file. Check file path and it content.";
|
return "Error processing file. Check file path and it content.";
|
||||||
|
|
||||||
for(FString line : file)
|
for(FString Line : File)
|
||||||
{
|
{
|
||||||
if(line == "# _")
|
if(Line == "# _")
|
||||||
{
|
{
|
||||||
// Important IF to add last point for every spline
|
// Important IF to add last point for every spline
|
||||||
// Uses data from previus iteration
|
// Uses data from previus iteration
|
||||||
if(iterationNumber != 0 && iterationNumber != -1)
|
if(IterationNumber != 0 && IterationNumber != -1)
|
||||||
{
|
{
|
||||||
// Add Last point to river spline
|
// Add Last point to river spline
|
||||||
FSplinePoint location(inputKeyCount, previusPosition);
|
FSplinePoint Location(InputKeyCount, PreviusPosition);
|
||||||
if(riverActor != nullptr)
|
if(RiverActor != nullptr)
|
||||||
AddRiverPointFromCode(riverActor, location); // Last Point
|
AddRiverPointFromCode(RiverActor, Location); // Last Point
|
||||||
CheckAndReverseWaterFlow(riverActor);
|
CheckAndReverseWaterFlow(RiverActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
riverActor = SpawnRiverBlueprintActor();
|
RiverActor = SpawnRiverBlueprintActor();
|
||||||
inputKeyCount = 0.0f;
|
InputKeyCount = 0.0f;
|
||||||
iterationNumber = -1; // Wildcard value used for headers
|
IterationNumber = -1; // Wildcard value used for headers
|
||||||
}
|
}
|
||||||
else if (line == "# _L")
|
else if (Line == "# _L")
|
||||||
{
|
{
|
||||||
return "This is a LAKE file. Check the water type and the file content.";
|
return "This is a LAKE file. Check the water type and the file content.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!line.Split(TEXT(" "), &y_str, &x_str))
|
if(!Line.Split(TEXT(" "), &StrY, &StrX))
|
||||||
{
|
{
|
||||||
return "ERROR: Coordinated cannot be proccess... Check file format";
|
return "ERROR: Coordinated cannot be proccess... Check file format";
|
||||||
}
|
}
|
||||||
|
|
||||||
float positionX = scaleFactor*FCString::Atof(*x_str);
|
float PositionX = ScaleFactor*FCString::Atof(*StrX);
|
||||||
float positionY = scaleFactor*FCString::Atof(*y_str);
|
float PositionY = ScaleFactor*FCString::Atof(*StrY);
|
||||||
float positionZ;
|
float PositionZ;
|
||||||
|
|
||||||
if(metaInfo.CustomHeight > -100000000.0f)
|
if(MetaInfo.CustomHeight > -100000000.0f)
|
||||||
positionZ = metaInfo.CustomHeight;
|
PositionZ = MetaInfo.CustomHeight;
|
||||||
else
|
else
|
||||||
positionZ = GetLandscapeSurfaceHeight(positionX, positionY, false);
|
PositionZ = GetLandscapeSurfaceHeight(PositionX, PositionY, false);
|
||||||
|
|
||||||
FVector position(positionX, positionY, positionZ);
|
FVector Position(PositionX, PositionY, PositionZ);
|
||||||
|
|
||||||
|
|
||||||
position += metaInfo.CustomLocationOffset;
|
Position += MetaInfo.CustomLocationOffset;
|
||||||
|
|
||||||
if((iterationNumber % metaInfo.CustomSampling) == 0){
|
if((IterationNumber % MetaInfo.CustomSampling) == 0){
|
||||||
FSplinePoint newPoint(inputKeyCount, position);
|
FSplinePoint NewPoint(InputKeyCount, Position);
|
||||||
float width = (metaInfo.CustomRiverWidth > 0.0f) ? metaInfo.CustomRiverWidth : 2.5f;
|
float Width = (MetaInfo.CustomRiverWidth > 0.0f) ?
|
||||||
newPoint.Scale = FVector(1.0f, width, 1.0f);
|
MetaInfo.CustomRiverWidth : 2.5f;
|
||||||
if(riverActor != nullptr)
|
NewPoint.Scale = FVector(1.0f, Width, 1.0f);
|
||||||
AddRiverPointFromCode(riverActor, newPoint);
|
if(RiverActor != nullptr)
|
||||||
inputKeyCount += 1.0f;
|
AddRiverPointFromCode(RiverActor, NewPoint);
|
||||||
|
InputKeyCount += 1.0f;
|
||||||
}
|
}
|
||||||
previusPosition = position;
|
PreviusPosition = Position;
|
||||||
}
|
}
|
||||||
iterationNumber++;
|
IterationNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last river created must be destroyed as it is a wildcard
|
// Last river created must be destroyed as it is a wildcard
|
||||||
if(riverActor != nullptr)
|
if(RiverActor != nullptr)
|
||||||
riverActor->Destroy();
|
RiverActor->Destroy();
|
||||||
|
|
||||||
return "Successfully processed";
|
return "Successfully processed";
|
||||||
}
|
}
|
||||||
|
|
||||||
FString UProceduralWaterManager::LakeGeneration(const FProceduralRiversMetaInfo metaInfo)
|
FString UProceduralWaterManager::LakeGeneration(const FProceduralRiversMetaInfo MetaInfo)
|
||||||
{
|
{
|
||||||
const FString WaterInfoPath = metaInfo.WaterInfoPath;
|
const FString WaterInfoPath = MetaInfo.WaterInfoPath;
|
||||||
if(!FPlatformFileManager::Get().GetPlatformFile().FileExists(*WaterInfoPath))
|
if(!FPlatformFileManager::Get().GetPlatformFile().FileExists(*WaterInfoPath))
|
||||||
{
|
{
|
||||||
|
|
||||||
DEBUG_MSG("File Not Found!! :(");
|
|
||||||
return "File Not Found!! :(";
|
return "File Not Found!! :(";
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<FString> file;
|
TArray<FString> File;
|
||||||
FFileHelper::LoadFileToStringArray(file, *WaterInfoPath);
|
FFileHelper::LoadFileToStringArray(File, *WaterInfoPath);
|
||||||
|
|
||||||
if(file.Num() == 0)
|
if(File.Num() == 0)
|
||||||
return "Error processing file. Check file path and it content.";
|
return "Error processing file. Check file path and it content.";
|
||||||
|
|
||||||
FString centerX_str, centerY_str, sizeX_str, sizeY_str, angle_str;
|
AActor* LakeActor = nullptr;
|
||||||
|
|
||||||
AActor* lakeActor = nullptr;
|
for(FString Line : File)
|
||||||
|
|
||||||
for(FString line : file)
|
|
||||||
{
|
{
|
||||||
if(line == "# _L")
|
if(Line == "# _L")
|
||||||
{
|
{
|
||||||
lakeActor = SpawnLakeBlueprintActor();
|
LakeActor = SpawnLakeBlueprintActor();
|
||||||
}
|
}
|
||||||
else if(line == "# _")
|
else if(Line == "# _")
|
||||||
{
|
{
|
||||||
return "This is a RIVER file. Check the water type and the file content.";
|
return "This is a RIVER file. Check the water type and the file content.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TArray<FString> lineArray;
|
TArray<FString> LineArray;
|
||||||
|
|
||||||
line.ParseIntoArray(lineArray, TEXT(" "));
|
Line.ParseIntoArray(LineArray, TEXT(" "));
|
||||||
|
|
||||||
float centerX = FCString::Atof(*lineArray[0]);
|
float CenterX = FCString::Atof(*LineArray[0]);
|
||||||
float centerY = FCString::Atof(*lineArray[1]);
|
float CenterY = FCString::Atof(*LineArray[1]);
|
||||||
float sizeX = FCString::Atof(*lineArray[2]);
|
float SizeX = FCString::Atof(*LineArray[2]);
|
||||||
float sizeY = FCString::Atof(*lineArray[3]);
|
float SizeY = FCString::Atof(*LineArray[3]);
|
||||||
float angle = FCString::Atof(*lineArray[4]);
|
float Angle = FCString::Atof(*LineArray[4]);
|
||||||
|
|
||||||
float centerZ;
|
float CenterZ;
|
||||||
|
|
||||||
if(metaInfo.CustomHeight > -100000000.0f)
|
if(MetaInfo.CustomHeight > -100000000.0f)
|
||||||
centerZ = metaInfo.CustomHeight;
|
CenterZ = MetaInfo.CustomHeight;
|
||||||
else
|
else
|
||||||
centerZ = GetLandscapeSurfaceHeight(centerX, centerY, false);
|
CenterZ = GetLandscapeSurfaceHeight(CenterX, CenterY, false);
|
||||||
|
|
||||||
FVector location(metaInfo.CustomScaleFactor*centerX, metaInfo.CustomScaleFactor*centerY, centerZ);
|
FVector Location(
|
||||||
location += metaInfo.CustomLocationOffset;
|
MetaInfo.CustomScaleFactor*CenterX,
|
||||||
|
MetaInfo.CustomScaleFactor*CenterY,
|
||||||
|
CenterZ
|
||||||
|
);
|
||||||
|
|
||||||
FRotator rotation(0.0f, angle,0.0f);
|
Location += MetaInfo.CustomLocationOffset;
|
||||||
|
|
||||||
FVector scale(metaInfo.CustomRiverWidth*sizeX, metaInfo.CustomRiverWidth*sizeY, 1.0f);
|
FRotator Rotation(0.0f, Angle, 0.0f);
|
||||||
|
|
||||||
lakeActor->SetActorScale3D(scale);
|
FVector Scale(
|
||||||
lakeActor->SetActorLocationAndRotation(location, rotation, false, 0, ETeleportType::None);
|
MetaInfo.CustomRiverWidth * SizeX,
|
||||||
|
MetaInfo.CustomRiverWidth * SizeY,
|
||||||
|
1.0f
|
||||||
|
);
|
||||||
|
|
||||||
|
LakeActor->SetActorScale3D(Scale);
|
||||||
|
LakeActor->SetActorLocationAndRotation(
|
||||||
|
Location,
|
||||||
|
Rotation,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
ETeleportType::None
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last river created must be destroyed as it is a wildcard
|
// Last river created must be destroyed as it is a wildcard
|
||||||
if(lakeActor != nullptr)
|
if(LakeActor != nullptr)
|
||||||
lakeActor->Destroy();
|
LakeActor->Destroy();
|
||||||
|
|
||||||
return "Successfully processed";
|
return "Successfully processed";
|
||||||
}
|
}
|
||||||
|
@ -211,41 +220,51 @@ FString UProceduralWaterManager::LakeGeneration(const FProceduralRiversMetaInfo
|
||||||
AActor* UProceduralWaterManager::SpawnRiverBlueprintActor()
|
AActor* UProceduralWaterManager::SpawnRiverBlueprintActor()
|
||||||
{
|
{
|
||||||
|
|
||||||
FVector location(0, 0, 0);
|
FVector Location(0, 0, 0);
|
||||||
FRotator rotation(0,0,0);
|
FRotator Rotation(0,0,0);
|
||||||
FActorSpawnParameters spawnInfo;
|
FActorSpawnParameters SpawnInfo;
|
||||||
|
|
||||||
UWorld* World = GetWorld();
|
UWorld* World = GetWorld();
|
||||||
AActor* riverActor = World->SpawnActor<AActor>(RiverBlueprintClass, location, rotation, spawnInfo);
|
AActor* RiverActor = World->SpawnActor<AActor>(
|
||||||
|
RiverBlueprintClass,
|
||||||
|
Location,
|
||||||
|
Rotation,
|
||||||
|
SpawnInfo
|
||||||
|
);
|
||||||
|
|
||||||
return riverActor;
|
return RiverActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
AActor* UProceduralWaterManager::SpawnLakeBlueprintActor()
|
AActor* UProceduralWaterManager::SpawnLakeBlueprintActor()
|
||||||
{
|
{
|
||||||
|
|
||||||
FVector location(0, 0, 0);
|
FVector Location(0, 0, 0);
|
||||||
FRotator rotation(0,0,0);
|
FRotator Rotation(0,0,0);
|
||||||
FActorSpawnParameters spawnInfo;
|
FActorSpawnParameters SpawnInfo;
|
||||||
|
|
||||||
UWorld* World = GetWorld();
|
UWorld* World = GetWorld();
|
||||||
AActor* riverActor = World->SpawnActor<AActor>(LakeBlueprintClass, location, rotation, spawnInfo);
|
AActor* LakeActor = World->SpawnActor<AActor>(
|
||||||
|
LakeBlueprintClass,
|
||||||
|
Location,
|
||||||
|
Rotation,
|
||||||
|
SpawnInfo
|
||||||
|
);
|
||||||
|
|
||||||
return riverActor;
|
return LakeActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
float UProceduralWaterManager::GetLandscapeSurfaceHeight(float x, float y, bool bDrawDebugLines)
|
float UProceduralWaterManager::GetLandscapeSurfaceHeight(float x, float y, bool bDrawDebugLines)
|
||||||
{
|
{
|
||||||
UWorld* world = GetWorld();
|
UWorld* World = GetWorld();
|
||||||
|
|
||||||
if(world)
|
if(World)
|
||||||
{
|
{
|
||||||
FVector RayStartingPoint(x, y, 999999);
|
FVector RayStartingPoint(x, y, 999999);
|
||||||
FVector RayEndPoint(x, y, 0);
|
FVector RayEndPoint(x, y, 0);
|
||||||
|
|
||||||
// Raytrace
|
// Raytrace
|
||||||
FHitResult HitResult;
|
FHitResult HitResult;
|
||||||
world->LineTraceSingleByObjectType(
|
World->LineTraceSingleByObjectType(
|
||||||
OUT HitResult,
|
OUT HitResult,
|
||||||
RayStartingPoint,
|
RayStartingPoint,
|
||||||
RayEndPoint,
|
RayEndPoint,
|
||||||
|
@ -262,7 +281,7 @@ float UProceduralWaterManager::GetLandscapeSurfaceHeight(float x, float y, bool
|
||||||
else LineColor = FColor::Green;
|
else LineColor = FColor::Green;
|
||||||
|
|
||||||
DrawDebugLine(
|
DrawDebugLine(
|
||||||
world,
|
World,
|
||||||
RayStartingPoint,
|
RayStartingPoint,
|
||||||
RayEndPoint,
|
RayEndPoint,
|
||||||
LineColor,
|
LineColor,
|
||||||
|
@ -273,7 +292,7 @@ float UProceduralWaterManager::GetLandscapeSurfaceHeight(float x, float y, bool
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return Z location.
|
// Return Z Location.
|
||||||
if (HitResult.GetActor()) return HitResult.ImpactPoint.Z;
|
if (HitResult.GetActor()) return HitResult.ImpactPoint.Z;
|
||||||
}
|
}
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
|
@ -4,9 +4,6 @@
|
||||||
// This work is licensed under the terms of the MIT license.
|
// This work is licensed under the terms of the MIT license.
|
||||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
|
|
||||||
// #if WITH_EDITOR
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
@ -23,16 +20,16 @@ struct CARLATOOLS_API FMapGeneratorMetaInfo
|
||||||
GENERATED_USTRUCT_BODY();
|
GENERATED_USTRUCT_BODY();
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
FString destinationPath;
|
FString DestinationPath;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
FString mapName;
|
FString MapName;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
int sizeX;
|
int SizeX;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
int sizeY;
|
int SizeY;
|
||||||
};
|
};
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
|
@ -44,10 +41,10 @@ struct CARLATOOLS_API FMapGeneratorTileMetaInfo
|
||||||
bool bIsTiled = true;
|
bool bIsTiled = true;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
int indexX;
|
int IndexX;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
int indexY;
|
int IndexY;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Class UMapGeneratorWidget extends the functionality of UEditorUtilityWidget
|
/// Class UMapGeneratorWidget extends the functionality of UEditorUtilityWidget
|
||||||
|
@ -65,18 +62,18 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// This function invokes a blueprint event defined in widget blueprint
|
/// This function invokes a blueprint event defined in widget blueprint
|
||||||
/// event graph, which sets a heightmap to the @a landscape using
|
/// event graph, which sets a heightmap to the @a Landscape using
|
||||||
/// ALandscapeProxy::LandscapeImportHeightMapFromRenderTarget(...)
|
/// ALandscapeProxy::LandscapeImportHeightMapFromRenderTarget(...)
|
||||||
/// function, which is not exposed to be used in C++ code, only blueprints
|
/// function, which is not exposed to be used in C++ code, only blueprints
|
||||||
/// @a metaTileInfo contains some useful info to execute this function
|
/// @a metaTileInfo contains some useful info to execute this function
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
UFUNCTION(BlueprintImplementableEvent)
|
||||||
void AssignLandscapeHeightMap(ALandscape* landscape, FMapGeneratorTileMetaInfo tileMetaInfo);
|
void AssignLandscapeHeightMap(ALandscape* Landscape, FMapGeneratorTileMetaInfo TileMetaInfo);
|
||||||
|
|
||||||
/// Function called by Widget Blueprint which generates all tiles of map
|
/// Function called by Widget Blueprint which generates all tiles of map
|
||||||
/// @a mapName, and saves them in @a destinationPath
|
/// @a mapName, and saves them in @a destinationPath
|
||||||
/// Returns a void string is success and an error message if the process failed
|
/// Returns a void string is success and an error message if the process failed
|
||||||
UFUNCTION(Category="Map Generator",BlueprintCallable)
|
UFUNCTION(Category="Map Generator",BlueprintCallable)
|
||||||
FString GenerateMapFiles(const FMapGeneratorMetaInfo& metaInfo);
|
FString GenerateMapFiles(const FMapGeneratorMetaInfo& MetaInfo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Loads the base tile map and stores it in @a WorldAssetData
|
/// Loads the base tile map and stores it in @a WorldAssetData
|
||||||
|
@ -89,33 +86,33 @@ private:
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
bool LoadBaseLargeMapWorld(FAssetData& WorldAssetData);
|
bool LoadBaseLargeMapWorld(FAssetData& WorldAssetData);
|
||||||
|
|
||||||
/// Loads the base template UWorld object from @a baseMapPath and returns
|
/// Loads the base template UWorld object from @a BaseMapPath and returns
|
||||||
/// it in @a WorldAssetData
|
/// it in @a WorldAssetData
|
||||||
/// The funtions return true is success, otherwise false
|
/// The funtions return true is success, otherwise false
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
bool LoadWorld(FAssetData& WorldAssetData, const FString& baseMapPath);
|
bool LoadWorld(FAssetData& WorldAssetData, const FString& BaseMapPath);
|
||||||
|
|
||||||
/// Saves a world contained in @a WorldToBeSaved, in the path defined in @a DestinationPath
|
/// Saves a world contained in @a WorldToBeSaved, in the path defined in @a DestinationPath
|
||||||
/// named as @a WorldName, as a package .umap
|
/// named as @a WorldName, as a package .umap
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
bool SaveWorld(FAssetData& WorldToBeSaved, const FString& DestinationPath, const FString& WorldName);
|
bool SaveWorld(FAssetData& WorldToBeSaved, const FString& DestinationPath, const FString& WorldName);
|
||||||
|
|
||||||
/// Takes the name of the map from @a metaInfo and created the main map
|
/// Takes the name of the map from @a MetaInfo and created the main map
|
||||||
/// including all the actors needed by large map system
|
/// including all the actors needed by large map system
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
bool CreateMainLargeMap(const FMapGeneratorMetaInfo& metaInfo);
|
bool CreateMainLargeMap(const FMapGeneratorMetaInfo& MetaInfo);
|
||||||
|
|
||||||
/// Takes @a metaInfo as input and generates all tiles based on the
|
/// Takes @a MetaInfo as input and generates all tiles based on the
|
||||||
/// dimensions specified for the map
|
/// dimensions specified for the map
|
||||||
/// The funtions return true is success, otherwise false
|
/// The funtions return true is success, otherwise false
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
bool CreateTilesMaps(const FMapGeneratorMetaInfo& metaInfo);
|
bool CreateTilesMaps(const FMapGeneratorMetaInfo& MetaInfo);
|
||||||
|
|
||||||
/// Gets the landscape from the input world @a worldAssetData and
|
/// Gets the Landscape from the input world @a WorldAssetData and
|
||||||
/// applies the heightmap to it. The tile index is indexX and indexY in
|
/// applies the heightmap to it. The tile index is indexX and indexY in
|
||||||
/// @a tileMetaInfo argument
|
/// @a TileMetaInfo argument
|
||||||
/// The funtions return true is success, otherwise false
|
/// The funtions return true is success, otherwise false
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
bool ApplyHeightMapToLandscape(FAssetData& worldAssetData, FMapGeneratorTileMetaInfo tileMetaInfo);
|
bool ApplyHeightMapToLandscape(FAssetData& WorldAssetData, FMapGeneratorTileMetaInfo TileMetaInfo);
|
||||||
};
|
};
|
||||||
// #endif
|
// #endif
|
|
@ -1,4 +1,8 @@
|
||||||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de Barcelona (UAB). This work is licensed under the terms of the MIT license. For a copy, see <https://opensource.org/licenses/MIT>.
|
// Copyright (c) 2022 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||||
|
// de Barcelona (UAB).
|
||||||
|
//
|
||||||
|
// This work is licensed under the terms of the MIT license.
|
||||||
|
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -69,32 +73,32 @@ public:
|
||||||
TSubclassOf<class AActor> LakeBlueprintClass;
|
TSubclassOf<class AActor> LakeBlueprintClass;
|
||||||
|
|
||||||
/// Main function to be called from the widget to start all the generation process
|
/// Main function to be called from the widget to start all the generation process
|
||||||
/// @a metaInfo is the input data for this process
|
/// @a MetaInfo is the input data for this process
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
FString StartWaterGeneration(const FProceduralRiversMetaInfo metaInfo);
|
FString StartWaterGeneration(const FProceduralRiversMetaInfo MetaInfo);
|
||||||
|
|
||||||
/// Add river @a riverActor spline point @a splinePoint to SplinePoint
|
/// Add river @a riverActor spline point @a splinePoint to SplinePoint
|
||||||
/// collection to be added in later processes to the spline component.
|
/// collection to be added in later processes to the spline component.
|
||||||
/// This is implemented in blueprint code.
|
/// This is implemented in blueprint code.
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
UFUNCTION(BlueprintImplementableEvent)
|
||||||
void AddRiverPointFromCode(AActor* riverActor, FSplinePoint splinePoint);
|
void AddRiverPointFromCode(AActor* RiverActor, FSplinePoint SplinePoint);
|
||||||
|
|
||||||
/// It checks which is the direction the flow of the river depending on the
|
/// It checks which is the direction the flow of the river depending on the
|
||||||
/// altitude of the start and the end of the river @a riverActor
|
/// altitude of the start and the end of the river @a riverActor
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
UFUNCTION(BlueprintImplementableEvent)
|
||||||
void CheckAndReverseWaterFlow(AActor* riverActor);
|
void CheckAndReverseWaterFlow(AActor* RiverActor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// It is responsible of the rivers generation, parsing the file,
|
/// It is responsible of the rivers generation, parsing the file,
|
||||||
/// intantiating the actors and setting its splline points
|
/// intantiating the actors and setting its splline points
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
FString RiverGeneration(const FProceduralRiversMetaInfo metaInfo);
|
FString RiverGeneration(const FProceduralRiversMetaInfo MetaInfo);
|
||||||
|
|
||||||
/// It is responsible of the lakes generation, pasing the file,
|
/// It is responsible of the lakes generation, pasing the file,
|
||||||
/// instantiating the actors and setting its properties
|
/// instantiating the actors and setting its properties
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
FString LakeGeneration(const FProceduralRiversMetaInfo metaInfo);
|
FString LakeGeneration(const FProceduralRiversMetaInfo MetaInfo);
|
||||||
|
|
||||||
/// Instantiate a new actor of type RiverBlueprintClass
|
/// Instantiate a new actor of type RiverBlueprintClass
|
||||||
/// Returns the the actor created
|
/// Returns the the actor created
|
||||||
|
|
Loading…
Reference in New Issue