Aollero/terrain rois (#5834)
* Terrain rois defined within the user widget * Improvementes in ROIs blending with original heightmap * Rois Tiling fixed * Support for multiple ROIs (overlapping bug) * Minor improvementes in river placement * Support for Spreaded and specific actors ROIs * Soil type Rois supported in widget * Soil type assignment to main map container actor * Soil type queried from soil type actor soil list and tag * Cleaning code * Basic Spreaded Actors feature * Single selection for specific actors placement * Misc Persistent state for specific location actors implemented * Spreaded Actors feature completed * Spreaded Actors Tagged, offset and delete option code * Specific Location Actor basic implementation * Specific actor placement feauture completed * Terrain Editor Bugs Fixed * Missing icon * Smoothing terrain boundaries * Sewing between terrain tiles * Terrain overlapping ROIs not allowed * Overlapping message bug fixed * Preset c++ funtions * Improvements in the terrain generation * Presets creation * Terrain preset feature finished * Missing references fixed * Format errors fixed * Last format fixes * Error in static member * Changing tabs for spaces * Identation to spaces * Duplicated include deleted Co-authored-by: bernat <bernatx@gmail.com>
This commit is contained in:
parent
5e4e82ab2e
commit
6117e548ae
|
@ -239,6 +239,11 @@ float ALargeMapManager::GetTileSize()
|
|||
return TileSide;
|
||||
}
|
||||
|
||||
FVector ALargeMapManager::GetTile0Offset()
|
||||
{
|
||||
return Tile0Offset;
|
||||
}
|
||||
|
||||
void ALargeMapManager::SetLayerStreamingDistance(float Distance)
|
||||
{
|
||||
LayerStreamingDistance = Distance;
|
||||
|
|
|
@ -156,6 +156,8 @@ public:
|
|||
|
||||
float GetTileSize();
|
||||
|
||||
FVector GetTile0Offset();
|
||||
|
||||
void SetLayerStreamingDistance(float Distance);
|
||||
|
||||
void SetActorStreamingDistance(float Distance);
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
// 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>.
|
||||
|
||||
#include "MapGen/SoilTypeManager.h"
|
||||
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
// Sets default values
|
||||
ASoilTypeManager::ASoilTypeManager()
|
||||
{
|
||||
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
}
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
void ASoilTypeManager::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
}
|
||||
|
||||
void ASoilTypeManager::Tick(float DeltaTime)
|
||||
{
|
||||
#if WITH_EDITOR // Only for debugging purposes. Requires to activate tick in contructor
|
||||
if((int)DeltaTime % 2000 == 0)
|
||||
{
|
||||
ALargeMapManager* LargeMapManager = (ALargeMapManager*) UGameplayStatics::GetActorOfClass(GetWorld(), ALargeMapManager::StaticClass());
|
||||
AActor* Car = UGameplayStatics::GetActorOfClass(GetWorld(), CarClass);
|
||||
|
||||
if(Car != nullptr)
|
||||
{
|
||||
FVector CarPos = Car->GetActorLocation();
|
||||
|
||||
FVector GlobalCarPos = LargeMapManager->LocalToGlobalLocation(CarPos);
|
||||
FIntVector TileVector = LargeMapManager->GetTileVectorID(GlobalCarPos);
|
||||
uint64 TileIndex = LargeMapManager->GetTileID(GlobalCarPos);
|
||||
|
||||
FString TypeStr = GetTerrainPropertiesAtGlobalLocation(GlobalCarPos).ToString();
|
||||
|
||||
UE_LOG(LogCarla, Log, TEXT("Current Tile Index %d ----> (%d, %d, %d) with position L[%f, %f, %f] G[%f, %f, %f] Terrain Type: %s"),
|
||||
TileIndex, TileVector.X, TileVector.Y, TileVector.Z, CarPos.X, CarPos.Y, CarPos.Z, GlobalCarPos.X, GlobalCarPos.Y, GlobalCarPos.Z,
|
||||
*TypeStr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
FSoilTerramechanicsProperties ASoilTypeManager::GetGeneralTerrainProperties()
|
||||
{
|
||||
return GeneralTerrainProperties;
|
||||
}
|
||||
|
||||
FSoilTerramechanicsProperties ASoilTypeManager::GetTerrainPropertiesAtGlobalLocation(FVector VehicleLocation)
|
||||
{
|
||||
// Get Indexes from location
|
||||
FIntVector TileVectorID = LargeMapManager->GetTileVectorID(VehicleLocation);
|
||||
|
||||
// Query the map, if not in map, return general
|
||||
if(TilesTerrainProperties.Contains(TileVectorID))
|
||||
return TilesTerrainProperties[TileVectorID]; // Tile properties
|
||||
else
|
||||
return GeneralTerrainProperties; // General properties
|
||||
}
|
||||
|
||||
FSoilTerramechanicsProperties ASoilTypeManager::GetTerrainPropertiesAtLocalLocation(FVector VehicleLocation)
|
||||
{
|
||||
FVector GlobalVehiclePosition = LargeMapManager->LocalToGlobalLocation(VehicleLocation);
|
||||
return GetTerrainPropertiesAtGlobalLocation(GlobalVehiclePosition);
|
||||
}
|
||||
|
||||
void ASoilTypeManager::SetGeneralTerrainProperties(FSoilTerramechanicsProperties TerrainProperties)
|
||||
{
|
||||
const FString TerrainPropertiesStr = TerrainProperties.ToString();
|
||||
UE_LOG(LogCarla, Log, TEXT("Setting General Terrain Settings %s"), *TerrainPropertiesStr);
|
||||
GeneralTerrainProperties = TerrainProperties;
|
||||
}
|
||||
|
||||
void ASoilTypeManager::AddTerrainPropertiesToTile(int TileX, int TileY, FSoilTerramechanicsProperties TerrainProperties)
|
||||
{
|
||||
// Compute ID from X,Y coords
|
||||
check(LargeMapManager != nullptr)
|
||||
|
||||
FIntVector TileVectorID(TileX, TileY, 0);
|
||||
|
||||
// Add to map
|
||||
if(TerrainProperties.TerrainType == ESoilTerramechanicsType::NONE_SOIL)
|
||||
TilesTerrainProperties.Add(TileVectorID, GeneralTerrainProperties);
|
||||
else
|
||||
TilesTerrainProperties.Add(TileVectorID, TerrainProperties);
|
||||
}
|
||||
|
||||
void ASoilTypeManager::ClearTerrainPropertiesMap()
|
||||
{
|
||||
TilesTerrainProperties.Empty(TilesTerrainProperties.Num());
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
// 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>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "Carla/MapGen/LargeMapManager.h"
|
||||
#include "SoilTypeManager.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum ESoilTerramechanicsType
|
||||
{
|
||||
NONE_SOIL = 0,
|
||||
DESERT = 1,
|
||||
FOREST = 2
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLA_API FSoilTerramechanicsProperties
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TEnumAsByte<ESoilTerramechanicsType> TerrainType;
|
||||
|
||||
const FString ToString() const
|
||||
{
|
||||
switch(TerrainType)
|
||||
{
|
||||
case ESoilTerramechanicsType::NONE_SOIL:
|
||||
return "None";
|
||||
case ESoilTerramechanicsType::DESERT:
|
||||
return "Desert";
|
||||
case ESoilTerramechanicsType::FOREST:
|
||||
return "Forest";
|
||||
}
|
||||
return "";
|
||||
};
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class CARLA_API ASoilTypeManager : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
private:
|
||||
UPROPERTY(EditAnywhere)
|
||||
FSoilTerramechanicsProperties GeneralTerrainProperties;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TMap<FIntVector, FSoilTerramechanicsProperties> TilesTerrainProperties;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
ALargeMapManager* LargeMapManager;
|
||||
|
||||
public:
|
||||
// Sets default values for this actor's properties
|
||||
ASoilTypeManager();
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TSubclassOf<AActor> CarClass;
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
UFUNCTION(Category="MapGen|Soil Manager")
|
||||
FSoilTerramechanicsProperties GetGeneralTerrainProperties();
|
||||
|
||||
UFUNCTION(Category="MapGen|Soil Manager")
|
||||
FSoilTerramechanicsProperties GetTerrainPropertiesAtGlobalLocation(FVector VehicleLocation);
|
||||
|
||||
UFUNCTION(Category="MapGen|Soil Manager")
|
||||
FSoilTerramechanicsProperties GetTerrainPropertiesAtLocalLocation(FVector VehicleLocation);
|
||||
|
||||
UFUNCTION(Category="MapGen|Soil Manager")
|
||||
void SetGeneralTerrainProperties(FSoilTerramechanicsProperties TerrainProperties);
|
||||
|
||||
UFUNCTION(Category="MapGen|Soil Manager")
|
||||
void AddTerrainPropertiesToTile(int TileX, int TileY, FSoilTerramechanicsProperties TerrainProperties);
|
||||
|
||||
UFUNCTION(Category="MapGen|Soil Manager")
|
||||
void ClearTerrainPropertiesMap();
|
||||
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
|
||||
};
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"isPersistentState": false,
|
||||
"inTileCoordinates":
|
||||
{
|
||||
"x": -1,
|
||||
"y": -1
|
||||
}
|
||||
}
|
|
@ -4,23 +4,23 @@
|
|||
"workingPath": "/Game/MyMaps",
|
||||
"activeTabName": "",
|
||||
"terrainGeneralSize": 4,
|
||||
"terrainGeneralSlope": 0.5,
|
||||
"terrainGeneralHeight": 3,
|
||||
"terrainGeneralSlope": 1.3600000143051147,
|
||||
"terrainGeneralHeight": 0.80000001192092896,
|
||||
"terrainGeneralMinHeight": 0,
|
||||
"terrainGeneralMaxHeight": 1,
|
||||
"terrainGeneralInvert": 0,
|
||||
"terrainOverallSeed": 700,
|
||||
"terrainOverallScale": 26,
|
||||
"terrainOverallSlope": 2.5,
|
||||
"terrainOverallHeight": 1,
|
||||
"terrainGeneralMaxHeight": 0.57999998331069946,
|
||||
"terrainGeneralInvert": 0.44999998807907104,
|
||||
"terrainOverallSeed": 8917.5087890625,
|
||||
"terrainOverallScale": 58,
|
||||
"terrainOverallSlope": 7.9000000953674316,
|
||||
"terrainOverallHeight": 2.7000000476837158,
|
||||
"terrainOverallMinHeight": 0,
|
||||
"terrainOverallMaxHeight": 1,
|
||||
"terrainOverallInvert": 0,
|
||||
"terrainDetailedSeed": 4300,
|
||||
"terrainDetailedScale": 10,
|
||||
"terrainDetailedSlope": 1,
|
||||
"terrainDetailedHeight": 2,
|
||||
"terrainOverallInvert": 0.20000000298023224,
|
||||
"terrainDetailedSeed": 1948.3016357421875,
|
||||
"terrainDetailedScale": 21,
|
||||
"terrainDetailedSlope": 0.30000001192092896,
|
||||
"terrainDetailedHeight": 2.5,
|
||||
"terrainDetailedMinHeight": 0,
|
||||
"terrainDetailedMaxHeight": 1,
|
||||
"terrainDetailedInvert": 0
|
||||
}
|
||||
"terrainDetailedInvert": 0.25
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"presetName": "Canyons",
|
||||
"widgetState":
|
||||
{
|
||||
"isPersistentState": false,
|
||||
"mapName": "",
|
||||
"workingPath": "",
|
||||
"activeTabName": "",
|
||||
"terrainGeneralSize": 0,
|
||||
"terrainGeneralSlope": 1.3600000143051147,
|
||||
"terrainGeneralHeight": 0.80000001192092896,
|
||||
"terrainGeneralMinHeight": 0,
|
||||
"terrainGeneralMaxHeight": 0.57999998331069946,
|
||||
"terrainGeneralInvert": 0.44999998807907104,
|
||||
"terrainOverallSeed": 2000,
|
||||
"terrainOverallScale": 58,
|
||||
"terrainOverallSlope": 7.9000000953674316,
|
||||
"terrainOverallHeight": 2.7000000476837158,
|
||||
"terrainOverallMinHeight": 0,
|
||||
"terrainOverallMaxHeight": 1,
|
||||
"terrainOverallInvert": 0.20000000298023224,
|
||||
"terrainDetailedSeed": 6000,
|
||||
"terrainDetailedScale": 21,
|
||||
"terrainDetailedSlope": 0.30000001192092896,
|
||||
"terrainDetailedHeight": 2.5,
|
||||
"terrainDetailedMinHeight": 0,
|
||||
"terrainDetailedMaxHeight": 1,
|
||||
"terrainDetailedInvert": 0.25
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"presetName": "Dunes",
|
||||
"widgetState":
|
||||
{
|
||||
"isPersistentState": false,
|
||||
"mapName": "",
|
||||
"workingPath": "",
|
||||
"activeTabName": "",
|
||||
"terrainGeneralSize": 0,
|
||||
"terrainGeneralSlope": 0.34000000357627869,
|
||||
"terrainGeneralHeight": 2.0999999046325684,
|
||||
"terrainGeneralMinHeight": 0,
|
||||
"terrainGeneralMaxHeight": 1,
|
||||
"terrainGeneralInvert": 0.40000000596046448,
|
||||
"terrainOverallSeed": 2000,
|
||||
"terrainOverallScale": 38,
|
||||
"terrainOverallSlope": 10,
|
||||
"terrainOverallHeight": 2.5,
|
||||
"terrainOverallMinHeight": 0.75,
|
||||
"terrainOverallMaxHeight": 1,
|
||||
"terrainOverallInvert": 0.070000000298023224,
|
||||
"terrainDetailedSeed": 6000,
|
||||
"terrainDetailedScale": 89,
|
||||
"terrainDetailedSlope": 1.7000000476837158,
|
||||
"terrainDetailedHeight": 0.40000000596046448,
|
||||
"terrainDetailedMinHeight": 0.014999999664723873,
|
||||
"terrainDetailedMaxHeight": 1,
|
||||
"terrainDetailedInvert": 0
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"presetName": "Flatlands",
|
||||
"widgetState":
|
||||
{
|
||||
"isPersistentState": false,
|
||||
"mapName": "",
|
||||
"workingPath": "",
|
||||
"activeTabName": "",
|
||||
"terrainGeneralSize": 0,
|
||||
"terrainGeneralSlope": 0.54000002145767212,
|
||||
"terrainGeneralHeight": 0.05000000074505806,
|
||||
"terrainGeneralMinHeight": 0.20000000298023224,
|
||||
"terrainGeneralMaxHeight": 1,
|
||||
"terrainGeneralInvert": 0.55000001192092896,
|
||||
"terrainOverallSeed": 2000,
|
||||
"terrainOverallScale": 22,
|
||||
"terrainOverallSlope": 10,
|
||||
"terrainOverallHeight": 6.6999998092651367,
|
||||
"terrainOverallMinHeight": 0.75,
|
||||
"terrainOverallMaxHeight": 1,
|
||||
"terrainOverallInvert": 0.6600000262260437,
|
||||
"terrainDetailedSeed": 6000,
|
||||
"terrainDetailedScale": 21,
|
||||
"terrainDetailedSlope": 10,
|
||||
"terrainDetailedHeight": 2.5999999046325684,
|
||||
"terrainDetailedMinHeight": 0.014999999664723873,
|
||||
"terrainDetailedMaxHeight": 1,
|
||||
"terrainDetailedInvert": 0
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"presetName": "Valley",
|
||||
"widgetState":
|
||||
{
|
||||
"isPersistentState": false,
|
||||
"mapName": "",
|
||||
"workingPath": "",
|
||||
"activeTabName": "",
|
||||
"terrainGeneralSize": 0,
|
||||
"terrainGeneralSlope": 0.54000002145767212,
|
||||
"terrainGeneralHeight": 0.10000000149011612,
|
||||
"terrainGeneralMinHeight": 0.20000000298023224,
|
||||
"terrainGeneralMaxHeight": 1,
|
||||
"terrainGeneralInvert": 0.55000001192092896,
|
||||
"terrainOverallSeed": 900.00018310546875,
|
||||
"terrainOverallScale": 22,
|
||||
"terrainOverallSlope": 10,
|
||||
"terrainOverallHeight": 6.6999998092651367,
|
||||
"terrainOverallMinHeight": 1,
|
||||
"terrainOverallMaxHeight": 1,
|
||||
"terrainOverallInvert": 0.64999997615814209,
|
||||
"terrainDetailedSeed": 89,
|
||||
"terrainDetailedScale": 21,
|
||||
"terrainDetailedSlope": 5.4000000953674316,
|
||||
"terrainDetailedHeight": 2.5999999046325684,
|
||||
"terrainDetailedMinHeight": 0.014999999664723873,
|
||||
"terrainDetailedMaxHeight": 1,
|
||||
"terrainDetailedInvert": 0.25
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -9,6 +9,7 @@
|
|||
#include "ActorFactories/ActorFactory.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "Carla/MapGen/LargeMapManager.h"
|
||||
#include "Carla/MapGen/SoilTypeManager.h"
|
||||
#include "Carla/Weather/Weather.h"
|
||||
#include "Components/SplineComponent.h"
|
||||
#include "Editor/FoliageEdit/Public/FoliageEdMode.h"
|
||||
|
@ -43,6 +44,11 @@
|
|||
#define CUR_LINE (FString::FromInt(__LINE__))
|
||||
#define CUR_CLASS_FUNC_LINE (CUR_CLASS_FUNC + "::" + CUR_LINE)
|
||||
|
||||
#define TAG_SPREADED FName("Spreaded Actor")
|
||||
#define TAG_SPECIFIC_LOCATION FName("Specific Location Actor")
|
||||
|
||||
#define TILESIZE 1009
|
||||
|
||||
#undef CreateDirectory
|
||||
#undef CopyFile
|
||||
|
||||
|
@ -90,6 +96,119 @@ void UMapGeneratorWidget::CookVegetation(const FMapGeneratorMetaInfo& MetaInfo)
|
|||
}
|
||||
}
|
||||
|
||||
void UMapGeneratorWidget::CookSoilTypeToMaps(const FMapGeneratorMetaInfo& MetaInfo)
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("%s: Starting Cooking Soil Type to Tiles in %s %s"),
|
||||
*CUR_CLASS_FUNC_LINE, *MetaInfo.DestinationPath, *MetaInfo.MapName);
|
||||
|
||||
// Check if map is valid
|
||||
const FString MapCompletePath = MetaInfo.DestinationPath + "/" + MetaInfo.MapName;
|
||||
const FString MapPackageFileName = FPackageName::LongPackageNameToFilename(
|
||||
MapCompletePath,
|
||||
FPackageName::GetMapPackageExtension());
|
||||
|
||||
if(!FPaths::FileExists(*MapPackageFileName))
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("%s: Soil Terramechanics cannot be applied to a non existing map"),
|
||||
*CUR_CLASS_FUNC_LINE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Instantiate Weather Actor in main map
|
||||
const FString WorldToLoadPath = MapCompletePath + "." + MetaInfo.MapName;
|
||||
UWorld* World = LoadObject<UWorld>(nullptr, *WorldToLoadPath);
|
||||
|
||||
ASoilTypeManager* SoilTypeManagerActor = (ASoilTypeManager*) UGameplayStatics::GetActorOfClass(World, ASoilTypeManager::StaticClass());
|
||||
|
||||
SoilTypeManagerActor->ClearTerrainPropertiesMap();
|
||||
|
||||
// Set General Settings
|
||||
SoilTypeManagerActor->SetGeneralTerrainProperties(MetaInfo.GeneralSoilType);
|
||||
|
||||
for(TPair<FRoiTile, FSoilTypeROI> SoilROIPair : MetaInfo.SoilTypeRoisMap)
|
||||
{
|
||||
FRoiTile SoilROITile = SoilROIPair.Key;
|
||||
FSoilTypeROI SoilROI = SoilROIPair.Value;
|
||||
SoilTypeManagerActor->AddTerrainPropertiesToTile(SoilROITile.X, SoilROITile.Y, SoilROI.SoilProperties);
|
||||
}
|
||||
}
|
||||
|
||||
void UMapGeneratorWidget::CookMiscSpreadedInformationToTiles(const FMapGeneratorMetaInfo& MetaInfo)
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("%s: Starting Cooking Miscellaneous Info to Tiles in %s %s"),
|
||||
*CUR_CLASS_FUNC_LINE, *MetaInfo.DestinationPath, *MetaInfo.MapName);
|
||||
|
||||
// Spreaded actors (ROIs)
|
||||
bool bSpreadedSuccess = CookMiscSpreadedActors(MetaInfo);
|
||||
if(!bSpreadedSuccess)
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("%s: Miscellaneous Spreaded Actor cooking was not successful..."),
|
||||
*CUR_CLASS_FUNC_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
void UMapGeneratorWidget::CookMiscSpecificLocationInformationToTiles(const FMapGeneratorMetaInfo& MetaInfo)
|
||||
{
|
||||
UWorld* World = GEditor->GetEditorWorldContext().World();
|
||||
|
||||
// Only one ROI at a time supported
|
||||
TArray<FMiscSpecificLocationActorsROI> ActorROIArray;
|
||||
MetaInfo.MiscSpecificLocationActorsRoisMap.GenerateValueArray(ActorROIArray);
|
||||
|
||||
if(ActorROIArray.Num() > 0)
|
||||
{
|
||||
FMiscSpecificLocationActorsROI ActorROI = ActorROIArray[0];
|
||||
|
||||
FRotator Rotation(0, FMath::RandRange(ActorROI.MinRotationRange, ActorROI.MaxRotationRange), 0);
|
||||
FActorSpawnParameters SpawnInfo;
|
||||
|
||||
AActor* SpawnedActor = World->SpawnActor<AActor>(
|
||||
ActorROI.ActorClass,
|
||||
ActorROI.ActorLocation,
|
||||
Rotation,
|
||||
SpawnInfo);
|
||||
SpawnedActor->Tags.Add(TAG_SPECIFIC_LOCATION);
|
||||
|
||||
SaveWorld(World);
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("%s: Miscellaneous Specific Location Actor cooking was not successful..."),
|
||||
*CUR_CLASS_FUNC_LINE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UMapGeneratorWidget::DeleteAllSpreadedActors(const FMapGeneratorMetaInfo& MetaInfo)
|
||||
{
|
||||
TArray<FAssetData> AssetsData;
|
||||
const FString TilesPath = MetaInfo.DestinationPath;
|
||||
bool success = LoadWorlds(AssetsData, TilesPath);
|
||||
|
||||
for(FAssetData AssetData : AssetsData)
|
||||
{
|
||||
UWorld* World = GetWorldFromAssetData(AssetData);
|
||||
|
||||
// Check if it is not a tile
|
||||
if(!World->GetMapName().Contains("_Tile_"))
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("%s: %s Skipped as it is not a tile"),
|
||||
*CUR_CLASS_FUNC_LINE, *World->GetMapName());
|
||||
continue;
|
||||
}
|
||||
|
||||
TArray<AActor*> TaggedActors;
|
||||
UGameplayStatics::GetAllActorsWithTag(World, TAG_SPREADED, TaggedActors);
|
||||
|
||||
for(AActor* Actor : TaggedActors)
|
||||
{
|
||||
Actor->Destroy();
|
||||
}
|
||||
|
||||
SaveWorld(World);
|
||||
}
|
||||
}
|
||||
|
||||
void UMapGeneratorWidget::CookVegetationToCurrentTile(const TArray<UProceduralFoliageSpawner*> FoliageSpawners)
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Log,
|
||||
|
@ -283,7 +402,7 @@ bool UMapGeneratorWidget::GenerateWaterFromWorld(UWorld* RiversWorld, TSubclassO
|
|||
SplinePosition.Z = GetLandscapeSurfaceHeight(RiversWorld, SplinePosition.X, SplinePosition.Y, false) + RiverSurfaceDisplacement;
|
||||
RiverSpline->SetWorldLocationAtSplinePoint(i, SplinePosition);
|
||||
}
|
||||
|
||||
UpdateRiverActorSplinesEvent(RiverActor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -377,7 +496,53 @@ TMap<FRoiTile, FTerrainROI> UMapGeneratorWidget::CreateTerrainRoisMap(TArray<FTe
|
|||
{
|
||||
for(FRoiTile TerrainRoiTile : TerrainRoi.TilesList)
|
||||
{
|
||||
ResultMap.Add(TerrainRoiTile, TerrainRoi);
|
||||
if(ResultMap.Contains(TerrainRoiTile))
|
||||
{
|
||||
ResultMap[TerrainRoiTile] = TerrainRoi;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResultMap.Add(TerrainRoiTile, TerrainRoi);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ResultMap;
|
||||
}
|
||||
|
||||
TMap<FRoiTile, FMiscSpreadedActorsROI> UMapGeneratorWidget::CreateMiscSpreadedActorsRoisMap(TArray<FMiscSpreadedActorsROI> SpreadedActorsRoisArray)
|
||||
{
|
||||
TMap<FRoiTile, FMiscSpreadedActorsROI> ResultMap;
|
||||
for(FMiscSpreadedActorsROI SpreadedRoi : SpreadedActorsRoisArray)
|
||||
{
|
||||
for(FRoiTile SpreadedRoiTile : SpreadedRoi.TilesList)
|
||||
{
|
||||
ResultMap.Add(SpreadedRoiTile, SpreadedRoi);
|
||||
}
|
||||
}
|
||||
return ResultMap;
|
||||
}
|
||||
|
||||
TMap<FRoiTile, FMiscSpecificLocationActorsROI> UMapGeneratorWidget::CreateMiscSpecificLocationActorsRoisMap(TArray<FMiscSpecificLocationActorsROI> SpecificLocationActorsRoisArray)
|
||||
{
|
||||
TMap<FRoiTile, FMiscSpecificLocationActorsROI> ResultMap;
|
||||
for(FMiscSpecificLocationActorsROI SpecificLocationRoi : SpecificLocationActorsRoisArray)
|
||||
{
|
||||
for(FRoiTile SpecificLocationRoiTile : SpecificLocationRoi.TilesList)
|
||||
{
|
||||
ResultMap.Add(SpecificLocationRoiTile, SpecificLocationRoi);
|
||||
}
|
||||
}
|
||||
return ResultMap;
|
||||
}
|
||||
|
||||
TMap<FRoiTile, FSoilTypeROI> UMapGeneratorWidget::CreateSoilTypeRoisMap(TArray<FSoilTypeROI> SoilTypeRoisArray)
|
||||
{
|
||||
TMap<FRoiTile, FSoilTypeROI> ResultMap;
|
||||
for(FSoilTypeROI SoilTypeRoi : SoilTypeRoisArray)
|
||||
{
|
||||
for(FRoiTile SoilTypeRoiTile : SoilTypeRoi.TilesList)
|
||||
{
|
||||
ResultMap.Add(SoilTypeRoiTile, SoilTypeRoi);
|
||||
}
|
||||
}
|
||||
return ResultMap;
|
||||
|
@ -449,6 +614,76 @@ FMapGeneratorWidgetState UMapGeneratorWidget::LoadWidgetStateStructFromFile(cons
|
|||
return WidgetState;
|
||||
}
|
||||
|
||||
bool UMapGeneratorWidget::GenerateMiscStateFileFromStruct(FMiscWidgetState MiscState, const FString JsonPath)
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("%s: Creating Miscellaneous State JSON"),
|
||||
*CUR_CLASS_FUNC_LINE);
|
||||
|
||||
TSharedRef<FJsonObject> OutJsonObject = MakeShareable(new FJsonObject());
|
||||
FJsonObjectConverter::UStructToJsonObject(FMiscWidgetState::StaticStruct(), &MiscState, OutJsonObject, 0, 0);
|
||||
|
||||
FString OutputJsonString;
|
||||
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&OutputJsonString);
|
||||
FJsonSerializer::Serialize(OutJsonObject, JsonWriter);
|
||||
|
||||
FFileHelper::SaveStringToFile(OutputJsonString, *JsonPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FMiscWidgetState UMapGeneratorWidget::LoadMiscStateStructFromFile(const FString JsonPath)
|
||||
{
|
||||
FMiscWidgetState MiscState;
|
||||
FString File;
|
||||
FFileHelper::LoadFileToString(File, *JsonPath);
|
||||
|
||||
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(*File);
|
||||
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
|
||||
bool bDeserializeSuccess = FJsonSerializer::Deserialize(JsonReader, JsonObject, FJsonSerializer::EFlags::None);
|
||||
|
||||
if(bDeserializeSuccess && JsonObject.IsValid())
|
||||
{
|
||||
FJsonObjectConverter::JsonObjectToUStruct(JsonObject.ToSharedRef(), FMiscWidgetState::StaticStruct(), &MiscState, 1, 0);
|
||||
}
|
||||
|
||||
return MiscState;
|
||||
}
|
||||
|
||||
bool UMapGeneratorWidget::GenerateTerrainPresetFileFromStruct(FMapGeneratorPreset Preset, const FString JsonPath)
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("%s: Creating Terrain Preset State JSON"),
|
||||
*CUR_CLASS_FUNC_LINE);
|
||||
|
||||
TSharedRef<FJsonObject> OutJsonObject = MakeShareable(new FJsonObject());
|
||||
FJsonObjectConverter::UStructToJsonObject(FMapGeneratorPreset::StaticStruct(), &Preset, OutJsonObject, 0, 0);
|
||||
|
||||
FString OutputJsonString;
|
||||
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&OutputJsonString);
|
||||
FJsonSerializer::Serialize(OutJsonObject, JsonWriter);
|
||||
|
||||
FFileHelper::SaveStringToFile(OutputJsonString, *JsonPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FMapGeneratorPreset UMapGeneratorWidget::LoadTerrainPresetStructFromFile(const FString JsonPath)
|
||||
{
|
||||
FMapGeneratorPreset Preset;
|
||||
FString File;
|
||||
FFileHelper::LoadFileToString(File, *JsonPath);
|
||||
|
||||
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(*File);
|
||||
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
|
||||
bool bDeserializeSuccess = FJsonSerializer::Deserialize(JsonReader, JsonObject, FJsonSerializer::EFlags::None);
|
||||
|
||||
if(bDeserializeSuccess && JsonObject.IsValid())
|
||||
{
|
||||
FJsonObjectConverter::JsonObjectToUStruct(JsonObject.ToSharedRef(), FMapGeneratorPreset::StaticStruct(), &Preset, 1, 0);
|
||||
}
|
||||
|
||||
return Preset;
|
||||
}
|
||||
|
||||
bool UMapGeneratorWidget::LoadWorlds(TArray<FAssetData>& WorldAssetsData, const FString& BaseMapPath, bool bRecursive)
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("%s: Loading Worlds from %s"),
|
||||
|
@ -542,9 +777,16 @@ bool UMapGeneratorWidget::CreateMainLargeMap(const FMapGeneratorMetaInfo& MetaIn
|
|||
|
||||
LargeMapManager->LargeMapTilePath = MetaInfo.DestinationPath;
|
||||
LargeMapManager->LargeMapName = MetaInfo.MapName;
|
||||
|
||||
|
||||
// Set Tile0Offset to 0 to cook tiles info
|
||||
FVector OriginalTile0Offset = LargeMapManager->GetTile0Offset();
|
||||
LargeMapManager->SetTile0Offset(FVector(0.0f, 0.0f, 0.0f));
|
||||
|
||||
LargeMapManager->GenerateMap_Editor();
|
||||
|
||||
// Reset Tile0Offset to original mid-tile position for runtime operations
|
||||
LargeMapManager->SetTile0Offset(OriginalTile0Offset);
|
||||
|
||||
UPackage::SavePackage(BaseMapPackage, World, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone,
|
||||
*PackageFileName, GError, nullptr, true, true, SAVE_NoError);
|
||||
|
||||
|
@ -674,36 +916,47 @@ bool UMapGeneratorWidget::CreateTilesMaps(const FMapGeneratorMetaInfo& MetaInfo)
|
|||
}
|
||||
|
||||
|
||||
int FlateningMargin = 30; // Not flatened
|
||||
//int FlateningMargin = 30; // Not flatened
|
||||
int FlateningMargin = 0; // Not flatened
|
||||
int FlateningFalloff = 100; // Transition from actual and flat value
|
||||
int TileSize = 1009; // Should be calculated by sqrt(HeightData.Num())
|
||||
int TileSize = TILESIZE; // Should be calculated by sqrt(HeightData.Num())
|
||||
|
||||
for(int X = FlateningMargin; X < (TileSize - FlateningMargin); X++)
|
||||
bool IsThereTileUp, IsThereTileDown, IsThereTileLeft, IsThereTileRight;
|
||||
|
||||
/* Blending the height data of the ROI with the height data of the tile. */
|
||||
if(FTerrainROI::IsTileInRoiBoundary(ThisTileIndex, MetaInfo.TerrainRoisMap, IsThereTileUp, IsThereTileRight, IsThereTileDown, IsThereTileLeft))
|
||||
{
|
||||
for(int Y = FlateningMargin; Y < (TileSize - FlateningMargin); Y++)
|
||||
/* Blending the height data of the ROI with the height data of the tile. */
|
||||
for(int X = FlateningMargin; X < (TileSize); X++)
|
||||
{
|
||||
float TransitionFactor = 1.0f;
|
||||
for(int Y = FlateningMargin; Y < (TileSize); Y++)
|
||||
{
|
||||
float TransitionFactor = 1.0f;
|
||||
|
||||
if(X < (FlateningMargin + FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= (X - FlateningMargin) / (float) FlateningFalloff;
|
||||
if(!IsThereTileLeft && X < (FlateningMargin + FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= (X - FlateningMargin) / (float) FlateningFalloff;
|
||||
}
|
||||
if(!IsThereTileUp && Y < (FlateningMargin + FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= (Y - FlateningMargin) / (float) FlateningFalloff;
|
||||
}
|
||||
if(!IsThereTileRight && X > (TileSize - FlateningMargin - FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= 1 - ((X - (TileSize - FlateningMargin - FlateningFalloff)) / (float) FlateningFalloff);
|
||||
}
|
||||
if(!IsThereTileDown && Y > (TileSize - FlateningMargin - FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= 1 - ((Y - (TileSize - FlateningMargin - FlateningFalloff)) / (float) FlateningFalloff);
|
||||
}
|
||||
HeightData[(X * TileSize) + Y] = (RoiHeightData[(X * TileSize) + Y]) * TransitionFactor + HeightData[(X * TileSize) + Y] * (1-TransitionFactor);
|
||||
}
|
||||
if(Y < (FlateningMargin + FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= (Y - FlateningMargin) / (float) FlateningFalloff;
|
||||
}
|
||||
if(X > (TileSize - FlateningMargin - FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= 1 - ((X - (TileSize - FlateningMargin - FlateningFalloff)) / (float) FlateningFalloff);
|
||||
}
|
||||
if(Y > (TileSize - FlateningMargin - FlateningFalloff))
|
||||
{
|
||||
TransitionFactor *= 1 - ((Y - (TileSize - FlateningMargin - FlateningFalloff)) / (float) FlateningFalloff);
|
||||
}
|
||||
HeightData[(X * TileSize) + Y] = (RoiHeightData[(X * TileSize) + Y]) * TransitionFactor + HeightData[(X * TileSize) + Y] * (1-TransitionFactor);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
HeightData = RoiHeightData;
|
||||
}
|
||||
}
|
||||
|
||||
// Flatening if contains river
|
||||
|
@ -711,9 +964,9 @@ bool UMapGeneratorWidget::CreateTilesMaps(const FMapGeneratorMetaInfo& MetaInfo)
|
|||
// TODO: Check and fix flatening algorithm
|
||||
if(TileMetaInfo.ContainsRiver)
|
||||
{
|
||||
int TileSize = TILESIZE; // Should be calculated by sqrt(HeightData.Num())
|
||||
int FlateningMargin = 30; // Not flatened
|
||||
int FlateningFalloff = 100; // Transition from actual and flat value
|
||||
int TileSize = 1009; // Should be calculated by sqrt(HeightData.Num())
|
||||
|
||||
for(int X = FlateningMargin; X < (TileSize - FlateningMargin); X++)
|
||||
{
|
||||
|
@ -750,6 +1003,32 @@ bool UMapGeneratorWidget::CreateTilesMaps(const FMapGeneratorMetaInfo& MetaInfo)
|
|||
SmoothHeightmap(HeightData, SmoothedData);
|
||||
HeightData = SmoothedData;
|
||||
|
||||
// Sew Upper and Left boundaries
|
||||
if(BoundariesInfo.Num() != 0) // To avoid crashing on the first Tile
|
||||
{
|
||||
TArray<uint16> SewedData;
|
||||
SewUpperAndLeftTiles(HeightData, SewedData, ThisTileIndex.X, ThisTileIndex.Y);
|
||||
HeightData = SewedData;
|
||||
}
|
||||
|
||||
// Store Boundaries Info
|
||||
FTileBoundariesInfo ThisTileBoundariesInfo;
|
||||
TArray<uint16> RightHeightData;
|
||||
TArray<uint16> BottomHeightData;
|
||||
|
||||
for(int DataIndex = 0; DataIndex < TILESIZE - 1; DataIndex++)
|
||||
{
|
||||
// Right
|
||||
RightHeightData.Add(HeightData[ Convert2DTo1DCoord(0, DataIndex, TILESIZE) ]);
|
||||
// Bottom
|
||||
BottomHeightData.Add(HeightData[ Convert2DTo1DCoord(DataIndex, TILESIZE - 1, TILESIZE) ]);
|
||||
}
|
||||
|
||||
ThisTileBoundariesInfo.RightHeightData = RightHeightData;
|
||||
ThisTileBoundariesInfo.BottomHeightData = BottomHeightData;
|
||||
BoundariesInfo.Add(ThisTileIndex, ThisTileBoundariesInfo);
|
||||
|
||||
|
||||
FVector LandscapeScaleVector(100.0f, 100.0f, 100.0f);
|
||||
Landscape->CreateLandscapeInfo();
|
||||
Landscape->SetActorTransform(FTransform(FQuat::Identity, FVector(), LandscapeScaleVector));
|
||||
|
@ -764,7 +1043,8 @@ bool UMapGeneratorWidget::CreateTilesMaps(const FMapGeneratorMetaInfo& MetaInfo)
|
|||
|
||||
Landscape->ReregisterAllComponents();
|
||||
Landscape->CreateLandscapeInfo();
|
||||
Landscape->SetActorLabel("Landscape");
|
||||
Landscape->SetActorLabel(TEXT("Landscape_"+FString::FromInt(i) + "_" + FString::FromInt(j)));
|
||||
// Landscape->SetActorLabel("Landscape");
|
||||
|
||||
// Apply material
|
||||
AssignLandscapeMaterial(Landscape);
|
||||
|
@ -785,11 +1065,12 @@ bool UMapGeneratorWidget::CreateTilesMaps(const FMapGeneratorMetaInfo& MetaInfo)
|
|||
*CUR_CLASS_FUNC_LINE, *ErrorUnloadingStr.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Instantiate water if needed
|
||||
}
|
||||
}
|
||||
|
||||
// Clear Boundaries Data Array
|
||||
BoundariesInfo.Empty();
|
||||
|
||||
CookTilesCollisions(MetaInfo);
|
||||
|
||||
return true;
|
||||
|
@ -923,6 +1204,88 @@ bool UMapGeneratorWidget::CookVegetationToWorld(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool UMapGeneratorWidget::CookMiscSpreadedActors(const FMapGeneratorMetaInfo& MetaInfo)
|
||||
{
|
||||
bool bSuccess = true;
|
||||
|
||||
TArray<FRoiTile> ListOfTiles;
|
||||
MetaInfo.MiscSpreadedActorsRoisMap.GetKeys(ListOfTiles);
|
||||
|
||||
for(FRoiTile ThisTile : ListOfTiles)
|
||||
{
|
||||
// Check if map is valid
|
||||
const FString MapCompletePath = MetaInfo.DestinationPath + "/" + MetaInfo.MapName +
|
||||
"_Tile_" + FString::FromInt(ThisTile.X) + "_" + FString::FromInt(ThisTile.Y);
|
||||
|
||||
// Instantiate Weather Actor in main map
|
||||
const FString WorldToLoadPath = MapCompletePath + "." + MetaInfo.MapName +
|
||||
"_Tile_" + FString::FromInt(ThisTile.X) + "_" + FString::FromInt(ThisTile.Y);
|
||||
// UWorld* World = LoadObject<UWorld>(nullptr, *WorldToLoadPath);
|
||||
bool bLoadedSuccess = FEditorFileUtils::LoadMap(*WorldToLoadPath, false, true);
|
||||
if(!bLoadedSuccess){
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("%s: Error Loading %s"),
|
||||
*CUR_CLASS_FUNC_LINE, *WorldToLoadPath);
|
||||
return false;
|
||||
}
|
||||
UWorld* World = GEditor->GetEditorWorldContext().World();
|
||||
|
||||
if(!IsValid(World))
|
||||
{
|
||||
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("%s: Error loading world %s"),
|
||||
*CUR_CLASS_FUNC_LINE, *WorldToLoadPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
FMiscSpreadedActorsROI ActorROI = MetaInfo.MiscSpreadedActorsRoisMap[ThisTile];
|
||||
|
||||
int NumOfTilesForSpreadedActorsGrid;
|
||||
switch(ActorROI.ActorsDensity)
|
||||
{
|
||||
case ESpreadedActorsDensity::LOW:
|
||||
NumOfTilesForSpreadedActorsGrid = 50;
|
||||
break;
|
||||
case ESpreadedActorsDensity::MEDIUM:
|
||||
NumOfTilesForSpreadedActorsGrid = 100;
|
||||
break;
|
||||
case ESpreadedActorsDensity::HIGH:
|
||||
NumOfTilesForSpreadedActorsGrid = 200;
|
||||
break;
|
||||
}
|
||||
|
||||
float TotalMapTileSize = 100800.0f; // In cm
|
||||
float MaxTileDisplacement = 0.5f * TotalMapTileSize / NumOfTilesForSpreadedActorsGrid;
|
||||
for(int i = 1; i < NumOfTilesForSpreadedActorsGrid - 1; i++)
|
||||
{
|
||||
for(int j = 1; j < NumOfTilesForSpreadedActorsGrid - 1; j++)
|
||||
{
|
||||
bool bIsGridTileEligible = FMath::RandRange(0.0f,100.0f) <= ActorROI.Probability;
|
||||
float ActorXCoord = (i * TotalMapTileSize / NumOfTilesForSpreadedActorsGrid) + FMath::RandRange(-MaxTileDisplacement,MaxTileDisplacement);
|
||||
float ActorYCoord = (j * TotalMapTileSize / NumOfTilesForSpreadedActorsGrid) + FMath::RandRange(-MaxTileDisplacement,MaxTileDisplacement);
|
||||
if(bIsGridTileEligible)
|
||||
{
|
||||
float ActorZCoord = GetLandscapeSurfaceHeight(World, ActorXCoord, ActorYCoord, false);
|
||||
FVector Location(ActorXCoord, ActorYCoord, ActorZCoord);
|
||||
// TODO: Add rotation randomly?
|
||||
FRotator Rotation(0, 0, 0);
|
||||
FActorSpawnParameters SpawnInfo;
|
||||
|
||||
AActor* SpreadedActor = World->SpawnActor<AActor>(
|
||||
ActorROI.ActorClass,
|
||||
Location,
|
||||
Rotation,
|
||||
SpawnInfo);
|
||||
SpreadedActor->Tags.Add(TAG_SPREADED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save map
|
||||
SaveWorld(World);
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
UWorld* UMapGeneratorWidget::GetWorldFromAssetData(FAssetData& WorldAssetData)
|
||||
{
|
||||
UWorld* World;
|
||||
|
@ -947,7 +1310,50 @@ float UMapGeneratorWidget::GetLandscapeSurfaceHeight(UWorld* World, float x, flo
|
|||
FVector Location(x, y, 0);
|
||||
TOptional<float> Height = Landscape->GetHeightAtLocation(Location);
|
||||
// TODO: Change function return type to TOptional<float>
|
||||
return Height.IsSet() ? Height.GetValue() : 0.0f;
|
||||
return Height.IsSet() ? Height.GetValue() : GetLandscapeSurfaceHeightFromRayCast(World, x, y, bDrawDebugLines);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float UMapGeneratorWidget::GetLandscapeSurfaceHeightFromRayCast(UWorld* World, float x, float y, bool bDrawDebugLines)
|
||||
{
|
||||
if(World)
|
||||
{
|
||||
FVector RayStartingPoint(x, y, 9999999);
|
||||
FVector RayEndPoint(x, y, -9999999);
|
||||
|
||||
// Raytrace
|
||||
FHitResult HitResult;
|
||||
World->LineTraceSingleByObjectType(
|
||||
OUT HitResult,
|
||||
RayStartingPoint,
|
||||
RayEndPoint,
|
||||
FCollisionObjectQueryParams(ECollisionChannel::ECC_WorldStatic),
|
||||
FCollisionQueryParams());
|
||||
|
||||
// Draw debug line.
|
||||
if (bDrawDebugLines)
|
||||
{
|
||||
FColor LineColor;
|
||||
|
||||
if (HitResult.GetActor()) LineColor = FColor::Red;
|
||||
else LineColor = FColor::Green;
|
||||
|
||||
DrawDebugLine(
|
||||
World,
|
||||
RayStartingPoint,
|
||||
RayEndPoint,
|
||||
LineColor,
|
||||
true,
|
||||
5.f,
|
||||
0.f,
|
||||
10.f);
|
||||
}
|
||||
|
||||
// Return Z Location.
|
||||
if (HitResult.GetActor())
|
||||
return HitResult.ImpactPoint.Z;
|
||||
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
@ -985,11 +1391,11 @@ void UMapGeneratorWidget::SmoothHeightmap(TArray<uint16> HeightData, TArray<uint
|
|||
|
||||
// Apply kernel to height data
|
||||
int TileMargin = 2;
|
||||
int TileSize = 1009; // Should be calculated by sqrt(HeightData.Num())
|
||||
|
||||
for(int X = TileMargin; X < (TileSize - TileMargin); X++)
|
||||
/* Applying a smoothing kernel to the height data */
|
||||
for(int X = 0; X < (TILESIZE); X++)
|
||||
{
|
||||
for(int Y = TileMargin; Y < (TileSize - TileMargin); Y++)
|
||||
for(int Y = 0; Y < (TILESIZE); Y++)
|
||||
{
|
||||
int Value = 0;
|
||||
|
||||
|
@ -998,15 +1404,56 @@ void UMapGeneratorWidget::SmoothHeightmap(TArray<uint16> HeightData, TArray<uint
|
|||
for(int j = -2; j <=2; j++)
|
||||
{
|
||||
float KernelValue = SmoothKernel[(i+2)*2 + (j+2)];
|
||||
int HeightValue = HeightData[ (X+i) * TileSize + (Y+j) ];
|
||||
|
||||
int IndexX = X+i;
|
||||
int IndexY = Y+j;
|
||||
|
||||
/* Checking if the index is out of bounds. If it is, it sets the index to the current X or Y. */
|
||||
if(IndexX < 0 || IndexX >= TILESIZE)
|
||||
IndexX = X;
|
||||
if(IndexY < 0 || IndexY >= TILESIZE)
|
||||
IndexY = Y;
|
||||
|
||||
int HeightValue = HeightData[ Convert2DTo1DCoord(IndexX, IndexY, TILESIZE) ];
|
||||
|
||||
Value += (int) ( KernelValue * HeightValue );
|
||||
}
|
||||
}
|
||||
|
||||
SmoothedData[(X * TileSize) + Y] = Value;
|
||||
SmoothedData[ Convert2DTo1DCoord(X, Y, TILESIZE) ] = Value;
|
||||
}
|
||||
}
|
||||
|
||||
OutHeightData = SmoothedData;
|
||||
}
|
||||
|
||||
void UMapGeneratorWidget::SewUpperAndLeftTiles(TArray<uint16> HeightData, TArray<uint16>& OutHeightData, int IndexX, int IndexY)
|
||||
{
|
||||
TArray<uint16> SewedData(HeightData);
|
||||
|
||||
FRoiTile ThisTile(IndexX, IndexY);
|
||||
FRoiTile UpTile = ThisTile.Up();
|
||||
FRoiTile LeftTile = ThisTile.Right(); // Right because of the coord system used
|
||||
|
||||
// Up
|
||||
if(BoundariesInfo.Contains(UpTile))
|
||||
{
|
||||
for(int DataIndex = 0; DataIndex < TILESIZE - 1; DataIndex++)
|
||||
{
|
||||
TArray<uint16> BottomInfo = BoundariesInfo[UpTile].BottomHeightData;
|
||||
SewedData[ Convert2DTo1DCoord(DataIndex, 0, TILESIZE) ] = BottomInfo[DataIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Left
|
||||
if(BoundariesInfo.Contains(LeftTile))
|
||||
{
|
||||
for(int DataIndex = 0; DataIndex < TILESIZE - 1; DataIndex++)
|
||||
{
|
||||
TArray<uint16> RightInfo = BoundariesInfo[LeftTile].RightHeightData;
|
||||
SewedData[ Convert2DTo1DCoord(TILESIZE - 1, DataIndex, TILESIZE) ] = RightInfo[DataIndex];
|
||||
}
|
||||
}
|
||||
|
||||
OutHeightData = SewedData;
|
||||
}
|
||||
|
|
|
@ -290,3 +290,10 @@ float UProceduralWaterManager::GetLandscapeSurfaceHeight(float x, float y, bool
|
|||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
||||
bool UProceduralWaterManager::CreateRiverPresetFiles(TSubclassOf<AActor> RiverParentClass)
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogCarlaToolsMapGenerator, Log, All);
|
||||
|
||||
struct FSoilTerramechanicsProperties;
|
||||
|
||||
/// Struct used as container of basic map information
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FMapGeneratorMetaInfo
|
||||
|
@ -40,10 +42,10 @@ struct CARLATOOLS_API FMapGeneratorMetaInfo
|
|||
TArray<UProceduralFoliageSpawner*> FoliageSpawners;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
UTextureRenderTarget2D* GlobalHeightmap;
|
||||
FSoilTerramechanicsProperties GeneralSoilType;
|
||||
|
||||
// UPROPERTY(BlueprintReadWrite)
|
||||
// UTextureRenderTarget2D* PROVISIONALROIHEIGHTMAP;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
UTextureRenderTarget2D* GlobalHeightmap;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TMap<FRoiTile, FTerrainROI> TerrainRoisMap;
|
||||
|
@ -51,6 +53,15 @@ struct CARLATOOLS_API FMapGeneratorMetaInfo
|
|||
UPROPERTY(BlueprintReadWrite)
|
||||
TMap<FRoiTile, FVegetationROI> VegetationRoisMap;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TMap<FRoiTile, FSoilTypeROI> SoilTypeRoisMap;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TMap<FRoiTile, FMiscSpecificLocationActorsROI> MiscSpecificLocationActorsRoisMap;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TMap<FRoiTile, FMiscSpreadedActorsROI> MiscSpreadedActorsRoisMap;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float RiverChanceFactor;
|
||||
|
||||
|
@ -163,6 +174,30 @@ struct CARLATOOLS_API FMapGeneratorWidgetState
|
|||
float TerrainDetailedInvert;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FMapGeneratorPreset
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MapGenerator|TerrainPresets")
|
||||
FString PresetName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MapGenerator|TerrainPresets")
|
||||
FMapGeneratorWidgetState WidgetState;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FTileBoundariesInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
TArray<uint16> RightHeightData;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<uint16> BottomHeightData;
|
||||
};
|
||||
|
||||
/// Class UMapGeneratorWidget extends the functionality of UEditorUtilityWidget
|
||||
/// to be able to generate and manage maps and largemaps tiles for procedural
|
||||
/// map generation
|
||||
|
@ -186,6 +221,9 @@ public:
|
|||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void UpdateTileRoiRT(const FMapGeneratorTileMetaInfo& TileMetaInfo, UMaterialInstanceDynamic* RoiMeterialInstance);
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void UpdateRiverActorSplinesEvent(AActor* RiverActor);
|
||||
|
||||
/// Function called by Widget Blueprint which generates all tiles of map
|
||||
/// @a mapName, and saves them in @a destinationPath
|
||||
/// Returns a void string is success and an error message if the process failed
|
||||
|
@ -194,9 +232,21 @@ public:
|
|||
|
||||
/// Function called by Widget Blueprint used to start the whole vegetation
|
||||
/// process for map defined in @a MetaInfo
|
||||
UFUNCTION(Category="Map Generator",BlueprintCallable)
|
||||
UFUNCTION(Category="Map Generator|Vegetation",BlueprintCallable)
|
||||
void CookVegetation(const FMapGeneratorMetaInfo& MetaInfo);
|
||||
|
||||
UFUNCTION(Category="Map Generator|Soil Terramechanics", BlueprintCallable)
|
||||
void CookSoilTypeToMaps(const FMapGeneratorMetaInfo& MetaInfo);
|
||||
|
||||
UFUNCTION(Category="Map Generator|Miscellaneous", BlueprintCallable)
|
||||
void CookMiscSpreadedInformationToTiles(const FMapGeneratorMetaInfo& MetaInfo);
|
||||
|
||||
UFUNCTION(Category="Map Generator|Miscellaneous", BlueprintCallable)
|
||||
void CookMiscSpecificLocationInformationToTiles(const FMapGeneratorMetaInfo& MetaInfo);
|
||||
|
||||
UFUNCTION(Category="Map Generator|Miscellaneous", BlueprintCallable)
|
||||
void DeleteAllSpreadedActors(const FMapGeneratorMetaInfo& MetaInfo);
|
||||
|
||||
/// Function invoked by the widget that cooks the vegetation defined in
|
||||
/// @a FoliageSpawners only in the world opened in the editor
|
||||
UFUNCTION(Category="Map Generator", BlueprintCallable)
|
||||
|
@ -223,10 +273,10 @@ public:
|
|||
bool LoadMapInfoFromPath(FString InDirectory, int& OutMapSize, FString& OutFoundMapName);
|
||||
|
||||
/// Spawns rivers of types @a RiverClass
|
||||
UFUNCTION(Category="MapGenerator", BlueprintCallable)
|
||||
UFUNCTION(Category="MapGenerator|Water", BlueprintCallable)
|
||||
AActor* GenerateWater(TSubclassOf<class AActor> RiverClass);
|
||||
|
||||
UFUNCTION(Category="MapGenerator", BlueprintCallable)
|
||||
UFUNCTION(Category="MapGenerator|Water", BlueprintCallable)
|
||||
bool GenerateWaterFromWorld(UWorld* RiversWorld, TSubclassOf<class AActor> RiverClass);
|
||||
|
||||
UFUNCTION(Category="MapGenerator", BlueprintCallable)
|
||||
|
@ -235,17 +285,26 @@ public:
|
|||
/// Adds weather actor of type @a WeatherActorClass and sets the @a SelectedWeather
|
||||
/// to the map specified in @a MetaInfo. Ifthe actor already exists on the map
|
||||
/// then it is returned so only one weather actor is spawned in each map
|
||||
UFUNCTION(Category="MapGenerator", BlueprintCallable)
|
||||
UFUNCTION(Category="MapGenerator|Weather", BlueprintCallable)
|
||||
AActor* AddWeatherToExistingMap(TSubclassOf<class AActor> WeatherActorClass,
|
||||
const FMapGeneratorMetaInfo& MetaInfo, const FString SelectedWeather);
|
||||
|
||||
UFUNCTION(Category="MapGenerator", BlueprintCallable)
|
||||
UFUNCTION(Category="MapGenerator|ROIs", BlueprintCallable)
|
||||
TMap<FRoiTile, FVegetationROI> CreateVegetationRoisMap(TArray<FVegetationROI> VegetationRoisArray);
|
||||
|
||||
UFUNCTION(Category="MapGenerator", BlueprintCallable)
|
||||
UFUNCTION(Category="MapGenerator|ROIs", BlueprintCallable)
|
||||
TMap<FRoiTile, FTerrainROI> CreateTerrainRoisMap(TArray<FTerrainROI> TerrainRoisArray);
|
||||
|
||||
UFUNCTION(Category="MapGenerator", BlueprintCallable)
|
||||
UFUNCTION(Category="MapGenerator|ROIs", BlueprintCallable)
|
||||
TMap<FRoiTile, FMiscSpreadedActorsROI> CreateMiscSpreadedActorsRoisMap(TArray<FMiscSpreadedActorsROI> SpreadedActorsRoisArray);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|ROIs", BlueprintCallable)
|
||||
TMap<FRoiTile, FMiscSpecificLocationActorsROI> CreateMiscSpecificLocationActorsRoisMap(TArray<FMiscSpecificLocationActorsROI> SpecificLocationActorsRoisArray);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|ROIs", BlueprintCallable)
|
||||
TMap<FRoiTile, FSoilTypeROI> CreateSoilTypeRoisMap(TArray<FSoilTypeROI> SoilTypeRoisArray);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|Vegetation", BlueprintCallable)
|
||||
bool DeleteAllVegetationInMap(const FString Path, const FString MapName);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|JsonLibrary", BlueprintCallable)
|
||||
|
@ -254,7 +313,22 @@ public:
|
|||
UFUNCTION(Category="MapGenerator|JsonLibrary", BlueprintCallable)
|
||||
FMapGeneratorWidgetState LoadWidgetStateStructFromFile(const FString JsonPath);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|JsonLibrary|Misc", BlueprintCallable)
|
||||
bool GenerateMiscStateFileFromStruct(FMiscWidgetState MiscState, const FString JsonPath);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|JsonLibrary|Misc", BlueprintCallable)
|
||||
FMiscWidgetState LoadMiscStateStructFromFile(const FString JsonPath);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|TerrainPresets", BlueprintCallable)
|
||||
bool GenerateTerrainPresetFileFromStruct(FMapGeneratorPreset Preset, const FString JsonPath);
|
||||
|
||||
UFUNCTION(Category="MapGenerator|TerrainPresets", BlueprintCallable)
|
||||
FMapGeneratorPreset LoadTerrainPresetStructFromFile(const FString JsonPath);
|
||||
|
||||
private:
|
||||
UPROPERTY()
|
||||
TMap<FRoiTile, FTileBoundariesInfo> BoundariesInfo;
|
||||
|
||||
/// Loads a bunch of world objects located in @a BaseMapPath and
|
||||
/// returns them in @a WorldAssetsData.
|
||||
/// The function returns true if success, otherwise false
|
||||
|
@ -299,6 +373,9 @@ private:
|
|||
UFUNCTION()
|
||||
bool CookVegetationToWorld(UWorld* World, const TArray<UProceduralFoliageSpawner*> FoliageSpawners);
|
||||
|
||||
UFUNCTION()
|
||||
bool CookMiscSpreadedActors(const FMapGeneratorMetaInfo& MetaInfo);
|
||||
|
||||
/// Returns the world object in @a WorldAssetData
|
||||
UFUNCTION()
|
||||
UWorld* GetWorldFromAssetData(FAssetData& WorldAssetData);
|
||||
|
@ -308,9 +385,22 @@ private:
|
|||
UFUNCTION()
|
||||
float GetLandscapeSurfaceHeight(UWorld* World, float x, float y, bool bDrawDebugLines);
|
||||
|
||||
UFUNCTION()
|
||||
float GetLandscapeSurfaceHeightFromRayCast(UWorld* World, float x, float y, bool bDrawDebugLines);
|
||||
|
||||
UFUNCTION()
|
||||
void ExtractCoordinatedFromMapName(const FString MapName, int& X, int& Y);
|
||||
|
||||
UFUNCTION()
|
||||
void SmoothHeightmap(TArray<uint16> HeightData, TArray<uint16>& OutHeightData);
|
||||
|
||||
UFUNCTION()
|
||||
void SewUpperAndLeftTiles(TArray<uint16> HeightData, TArray<uint16>& OutHeightData, int IndexX, int IndexY);
|
||||
|
||||
// Converting a 2D coordinate to a 1D coordinate.
|
||||
UFUNCTION()
|
||||
FORCEINLINE int Convert2DTo1DCoord(int IndexX, int IndexY, int TileSize)
|
||||
{
|
||||
return (IndexX * TileSize) + IndexY;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -116,4 +116,10 @@ private:
|
|||
/// Return the Z value
|
||||
UFUNCTION()
|
||||
float GetLandscapeSurfaceHeight(float x, float y, bool bDrawDebugLines = false);
|
||||
|
||||
|
||||
/************ RIVER PRESETS GENERATOR ************/
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable)
|
||||
bool CreateRiverPresetFiles(TSubclassOf<AActor> RiverParentClass);
|
||||
};
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "Carla/MapGen/SoilTypeManager.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Containers/EnumAsByte.h"
|
||||
#include "Materials/MaterialInstanceDynamic.h"
|
||||
#include "Math/IntPoint.h"
|
||||
#include "ProceduralFoliageSpawner.h"
|
||||
#include "Templates/UnrealTypeTraits.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
|
@ -17,10 +19,21 @@
|
|||
UENUM(BlueprintType)
|
||||
enum ERegionOfInterestType
|
||||
{
|
||||
NONE,
|
||||
NONE_REGION,
|
||||
TERRAIN_REGION,
|
||||
WATERBODIES_REGION, // Not Supported yet
|
||||
VEGETATION_REGION
|
||||
VEGETATION_REGION,
|
||||
MISC_SPREADED_ACTORS_REGION,
|
||||
MISC_SPECIFIC_LOCATION_ACTORS_REGION,
|
||||
SOIL_TYPE_REGION
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum ESpreadedActorsDensity
|
||||
{
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
|
@ -56,8 +69,38 @@ public:
|
|||
{
|
||||
return (this->X == Other.X) && (this->Y == Other.Y);
|
||||
}
|
||||
|
||||
/// A function that returns the tile that is above the current tile.
|
||||
FORCEINLINE FRoiTile Up()
|
||||
{
|
||||
// return FRoiTile(X, Y-1);
|
||||
return FRoiTile(X-1, Y);
|
||||
}
|
||||
|
||||
/// A function that returns the tile that is below the current tile.
|
||||
FORCEINLINE FRoiTile Down()
|
||||
{
|
||||
// return FRoiTile(X, Y+1);
|
||||
return FRoiTile(X+1, Y);
|
||||
}
|
||||
|
||||
/// A function that returns the tile that is to the left of the current tile.
|
||||
FORCEINLINE FRoiTile Left()
|
||||
{
|
||||
// return FRoiTile(X-1, Y);
|
||||
return FRoiTile(X, Y+1);
|
||||
}
|
||||
|
||||
/// A function that returns the tile that is to the right of the current tile.
|
||||
FORCEINLINE FRoiTile Right()
|
||||
{
|
||||
// return FRoiTile(X+1, Y);
|
||||
return FRoiTile(X, Y-1);
|
||||
}
|
||||
};
|
||||
|
||||
/// A function that is used to hash the FRoiTile struct.
|
||||
/// It is used to hash the struct so that it can be used as a key in a TMap.
|
||||
FORCEINLINE uint32 GetTypeHash(const FRoiTile& Thing)
|
||||
{
|
||||
uint32 Hash = FCrc::MemCrc32(&Thing, sizeof(FRoiTile));
|
||||
|
@ -76,7 +119,7 @@ struct CARLATOOLS_API FRegionOfInterest
|
|||
TArray<FRoiTile> TilesList;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TEnumAsByte<ERegionOfInterestType> RegionType = ERegionOfInterestType::NONE;
|
||||
TEnumAsByte<ERegionOfInterestType> RegionType = ERegionOfInterestType::NONE_REGION;
|
||||
|
||||
FRegionOfInterest()
|
||||
{
|
||||
|
@ -94,6 +137,7 @@ struct CARLATOOLS_API FRegionOfInterest
|
|||
return this->RegionType;
|
||||
}
|
||||
|
||||
// A template function that checks if a tile is in a map of regions.
|
||||
template <typename R>
|
||||
static FORCEINLINE bool IsTileInRegionsSet(FRoiTile RoiTile, TMap<FRoiTile, R> RoisMap)
|
||||
{
|
||||
|
@ -102,6 +146,42 @@ struct CARLATOOLS_API FRegionOfInterest
|
|||
return RoisMap.Contains(RoiTile);
|
||||
}
|
||||
|
||||
/// Checking if two regions of interest are equal.
|
||||
bool Equals(const FRegionOfInterest& Other)
|
||||
{
|
||||
// Checking if the number of tiles in the two regions is the same.
|
||||
if(this->TilesList.Num() != Other.TilesList.Num())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checking if the two regions have the same tiles.
|
||||
TMap<FRoiTile, int> TileCount;
|
||||
for(FRoiTile Tile : Other.TilesList)
|
||||
{
|
||||
if(TileCount.Contains(Tile))
|
||||
TileCount[Tile]++;
|
||||
else
|
||||
TileCount.Add(Tile, 1);
|
||||
}
|
||||
|
||||
for(FRoiTile Tile : TilesList)
|
||||
{
|
||||
if(!TileCount.Contains(Tile))
|
||||
return false;
|
||||
|
||||
TileCount[Tile]--;
|
||||
|
||||
if(TileCount[Tile] == 0)
|
||||
TileCount.Remove(Tile);
|
||||
}
|
||||
|
||||
if(TileCount.Num() == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
|
@ -122,12 +202,13 @@ struct CARLATOOLS_API FVegetationROI : public FRegionOfInterest
|
|||
FoliageSpawners.Add(Spawner);
|
||||
}
|
||||
|
||||
// A function that adds a list of spawners to the list of spawners of the ROI.
|
||||
void AddFoliageSpawners(TArray<UProceduralFoliageSpawner*> Spawners)
|
||||
{
|
||||
for(UProceduralFoliageSpawner* Spawner : Spawners)
|
||||
{
|
||||
AddFoliageSpawner(Spawner);
|
||||
}
|
||||
{
|
||||
AddFoliageSpawner(Spawner);
|
||||
}
|
||||
}
|
||||
|
||||
TArray<UProceduralFoliageSpawner*> GetFoliageSpawners()
|
||||
|
@ -141,14 +222,103 @@ struct CARLATOOLS_API FTerrainROI : public FRegionOfInterest
|
|||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// A pointer to a material instance that is used to change the heightmap material of the ROI.
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
UMaterialInstanceDynamic* RoiMaterialInstance;
|
||||
|
||||
// A render target that is used to store the heightmap of the ROI.
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
UTextureRenderTarget2D* RoiHeightmapRenderTarget;
|
||||
|
||||
FTerrainROI() : FRegionOfInterest(), RoiMaterialInstance()
|
||||
{}
|
||||
|
||||
// TODO: IsEdge() funtion to avoid transition between tiles that belongs to the same ROI
|
||||
/**
|
||||
* This function checks if a tile is on the boundary of a region of interest
|
||||
*
|
||||
* @param RoiTile The tile we're checking
|
||||
* @param RoisMap The map of RoiTiles to Rois.
|
||||
* @param OutUp Is there a tile above this one?
|
||||
* @param OutRight Is there a ROI to the right of this tile?
|
||||
* @param OutDown Is there a ROI tile below this one?
|
||||
* @param OutLeft Is the tile to the left of the current tile in the RoiMap?
|
||||
*
|
||||
* return true if the tile is in a boundary
|
||||
*/
|
||||
template <typename R>
|
||||
static bool IsTileInRoiBoundary(FRoiTile RoiTile, TMap<FRoiTile, R> RoisMap, bool& OutUp, bool& OutRight, bool& OutDown, bool& OutLeft)
|
||||
{
|
||||
FTerrainROI ThisRoi = RoisMap[RoiTile];
|
||||
OutUp = RoisMap.Contains(RoiTile.Up()) && ThisRoi.Equals(RoisMap[RoiTile.Up()]);
|
||||
OutDown = RoisMap.Contains(RoiTile.Down()) && ThisRoi.Equals(RoisMap[RoiTile.Down()]);
|
||||
OutLeft = RoisMap.Contains(RoiTile.Left()) && ThisRoi.Equals(RoisMap[RoiTile.Left()]);
|
||||
OutRight = RoisMap.Contains(RoiTile.Right()) && ThisRoi.Equals(RoisMap[RoiTile.Right()]);
|
||||
|
||||
return !OutUp || !OutDown || !OutLeft || !OutRight;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FMiscSpreadedActorsROI : public FRegionOfInterest
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TSubclassOf<AActor> ActorClass;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float Probability;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TEnumAsByte<ESpreadedActorsDensity> ActorsDensity;
|
||||
|
||||
FMiscSpreadedActorsROI() : FRegionOfInterest(), ActorClass(), Probability(0.0f), ActorsDensity(ESpreadedActorsDensity::LOW)
|
||||
{}
|
||||
};
|
||||
|
||||
/// A struct that is used to store the information of a region of interest that is used to
|
||||
/// spawn actors in specific locations.
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FMiscSpecificLocationActorsROI : public FRegionOfInterest
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
TSubclassOf<AActor> ActorClass;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FVector ActorLocation;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float MinRotationRange;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float MaxRotationRange;
|
||||
|
||||
FMiscSpecificLocationActorsROI() : FRegionOfInterest(), ActorClass(), ActorLocation(0.0f)
|
||||
{}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FSoilTypeROI : public FRegionOfInterest
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FSoilTerramechanicsProperties SoilProperties;
|
||||
|
||||
FSoilTypeROI() : SoilProperties()
|
||||
{}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FMiscWidgetState
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MapGenerator|JsonLibrary|Misc")
|
||||
bool IsPersistentState;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MapGenerator|JsonLibrary|Misc")
|
||||
FIntPoint InTileCoordinates;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue