10 #include "FileHelpers.h" 12 #include "Misc/FileHelper.h" 13 #include "JsonObject.h" 14 #include "JsonSerializer.h" 15 #include "UObject/ConstructorHelpers.h" 16 #include "Runtime/Engine/Classes/Kismet/GameplayStatics.h" 17 #include "Engine/StreamableManager.h" 18 #include "Engine/StaticMeshActor.h" 20 #include "Engine/DecalActor.h" 21 #include "Components/DecalComponent.h" 33 #if WITH_EDITORONLY_DATA 35 static ConstructorHelpers::FObjectFinder<UBlueprint> RoadPainterBlueprint(TEXT(
36 "Blueprint'/Game/Carla/Blueprints/LevelDesign/RoadPainterPreset.RoadPainterPreset'"));
41 DecalNamesMap.Add(
"dirt1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_01.DI_RoadDirt_01'");
42 DecalNamesMap.Add(
"dirt2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_02.DI_RoadDirt_02'");
43 DecalNamesMap.Add(
"dirt3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_03.DI_RoadDirt_03'");
44 DecalNamesMap.Add(
"dirt4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_04.DI_RoadDirt_04'");
45 DecalNamesMap.Add(
"dirt5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_05.DI_RoadDirt_05'");
48 DecalNamesMap.Add(
"drip1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDrip_01.DI_RoadDrip_01'");
49 DecalNamesMap.Add(
"drip2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDrip_02.DI_RoadDrip_02'");
50 DecalNamesMap.Add(
"drip3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDrip_03.DI_RoadDrip_03'");
53 DecalNamesMap.Add(
"roadline1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_01.DI_RoadLine_01'");
54 DecalNamesMap.Add(
"roadline2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_02.DI_RoadLine_02'");
55 DecalNamesMap.Add(
"roadline3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_03.DI_RoadLine_03'");
56 DecalNamesMap.Add(
"roadline4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_04.DI_RoadLine_04'");
57 DecalNamesMap.Add(
"roadline5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_05.DI_RoadLine_05'");
60 DecalNamesMap.Add(
"tiremark1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_TireMark_01.DI_TireMark_01'");
61 DecalNamesMap.Add(
"tiremark2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_TireMark_02.DI_TireMark_02'");
62 DecalNamesMap.Add(
"tiremark3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_TireMark_03.DI_TireMark_03'");
65 DecalNamesMap.Add(
"tarsnake1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake1.DI_tarsnake1'");
66 DecalNamesMap.Add(
"tarsnake2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake2.DI_tarsnake2'");
67 DecalNamesMap.Add(
"tarsnake3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake3.DI_tarsnake3'");
68 DecalNamesMap.Add(
"tarsnake4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake4.DI_tarsnake4'");
69 DecalNamesMap.Add(
"tarsnake5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake5.DI_tarsnake5'");
70 DecalNamesMap.Add(
"tarsnake6",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake6.DI_tarsnake6'");
71 DecalNamesMap.Add(
"tarsnake7",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake7.DI_tarsnake7'");
72 DecalNamesMap.Add(
"tarsnake8",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake8.DI_tarsnake8'");
73 DecalNamesMap.Add(
"tarsnake9",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake9.DI_tarsnake9'");
74 DecalNamesMap.Add(
"tarsnake10",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake10.DI_tarsnake10'");
75 DecalNamesMap.Add(
"tarsnake11",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake11.DI_tarsnake11'");
78 DecalNamesMap.Add(
"cracksbig1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig1.DI_cracksBig1'");
79 DecalNamesMap.Add(
"cracksbig2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig2.DI_cracksBig2'");
80 DecalNamesMap.Add(
"cracksbig3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig3.DI_cracksBig3'");
81 DecalNamesMap.Add(
"cracksbig4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig4.DI_cracksBig4'");
82 DecalNamesMap.Add(
"cracksbig5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig5.DI_cracksBig5'");
83 DecalNamesMap.Add(
"cracksbig6",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig6.DI_cracksBig6'");
84 DecalNamesMap.Add(
"cracksbig7",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig7.DI_cracksBig7'");
85 DecalNamesMap.Add(
"cracksbig8",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig8.DI_cracksBig8'");
88 DecalNamesMap.Add(
"crack1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack01.DI_RoadCrack01'");
89 DecalNamesMap.Add(
"crack2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack02.DI_RoadCrack02'");
90 DecalNamesMap.Add(
"crack3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack05.DI_RoadCrack05'");
91 DecalNamesMap.Add(
"crack4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack09.DI_RoadCrack09'");
92 DecalNamesMap.Add(
"crack5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack11.DI_RoadCrack11'");
93 DecalNamesMap.Add(
"crack6",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack13.DI_RoadCrack13'");
94 DecalNamesMap.Add(
"crack7",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack15.DI_RoadCrack15'");
95 DecalNamesMap.Add(
"crack8",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack16.DI_RoadCrack16'");
98 DecalNamesMap.Add(
"manhole1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Manhole01.DI_Manhole01'");
99 DecalNamesMap.Add(
"manhole2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Manhole02.DI_Manhole02'");
100 DecalNamesMap.Add(
"manhole3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Manhole03.DI_Manhole03'");
103 DecalNamesMap.Add(
"mud1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_1.DI_Mud_1'");
104 DecalNamesMap.Add(
"mud2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_2.DI_Mud_2'");
105 DecalNamesMap.Add(
"mud3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_3.DI_Mud_3'");
106 DecalNamesMap.Add(
"mud4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_4.DI_Mud_4'");
107 DecalNamesMap.Add(
"mud5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_5.DI_Mud_5'");
110 DecalNamesMap.Add(
"oilsplat1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat1.DI_OilSplat1'");
111 DecalNamesMap.Add(
"oilsplat2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat2.DI_OilSplat2'");
112 DecalNamesMap.Add(
"oilsplat3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat3.DI_OilSplat3'");
113 DecalNamesMap.Add(
"oilsplat4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat4.DI_OilSplat4'");
114 DecalNamesMap.Add(
"oilsplat5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat5.DI_OilSplat5'");
117 DecalNamesMap.Add(
"gum",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_Gum.DI_Gum'");
118 DecalNamesMap.Add(
"grate",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Grate_01_v2.DI_Grate_01_v2'");
123 #if WITH_EDITORONLY_DATA 125 void ULoadAssetMaterialsCommandlet::ApplyRoadPainterMaterials(
const FString &LoadedMapName,
const FString &PackageName,
bool IsInTiles)
127 if (IsInTiles ==
true) {
133 FString MapName = LoadedMapName;
136 int32 idx = MapName.Find(
"_Tile_");
139 MapName = MapName.Mid(0, idx);
146 TArray<FString> FileList;
147 IFileManager::Get().FindFilesRecursive(FileList, *(FPaths::ProjectContentDir() +
"/" + PackageName +
"/Maps/" + MapName), *(FString(
"TilesInfo.txt")),
true,
false,
false);
150 if (FFileHelper::LoadFileToString(TxtFile, *FileList[0]) ==
true) {
153 TxtFile.ParseIntoArray(Out, TEXT(
","),
true);
160 UE_LOG(LogTemp, Warning, TEXT(
"Could not read TilesInfo.txt file"));
167 TArray<FString> StringArray = {};
168 LoadedMapName.ParseIntoArray(StringArray, TEXT(
"_"),
false);
170 int32 XIndex = FCString::Atoi(*StringArray[StringArray.Num() - 2]);
171 int32 YIndex = FCString::Atoi(*StringArray[StringArray.Num() - 1]);
172 FVector TilePosition;
177 TilePosition.Z = 0.0f;
181 float MinXSize = (TilePosition.X - HalfSize);
182 float MaxXSize = (TilePosition.X + HalfSize);
184 float MinYSize = (TilePosition.Y - HalfSize);
185 float MaxYSize = (TilePosition.Y + HalfSize);
196 float MinXSizeCm = MinXSize * 100.0f;
197 float MaxXSizeCm = MaxXSize * 100.0f;
198 float MinYSizeCm = MinYSize * 100.0f;
199 float MaxYSizeCm = MaxYSize * 100.0f;
205 float CenterOfTileX = FirstTileWorldLocationX + (XIndex * TileSizeCm);
206 float CenterOfTileY = FirstTileWorldLocationY - (YIndex * TileSizeCm);
212 DecalLocation.
x = FMath::RandRange(MinXSize, MaxXSize);
213 DecalLocation.
y = FMath::RandRange(MinYSize, MaxYSize);
214 DecalLocation.
z = 0.0f;
217 auto Wp =
XODRMap->GetClosestWaypointOnRoad(DecalLocation);
219 FVector FinalLocation(RoadLocation);
222 if (FinalLocation.X > MinXSizeCm && FinalLocation.X < MaxXSizeCm) {
224 if (FinalLocation.Y > MinYSizeCm && FinalLocation.Y < MaxYSizeCm) {
226 FRotator FinalRotation(
XODRMap->ComputeTransform(Wp.get()).rotation);
232 FinalLocation.X -= CenterOfTileX;
233 FinalLocation.Y -= CenterOfTileY;
235 FActorSpawnParameters SpawnParams;
236 SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
237 SpawnParams.bNoFail =
true;
238 ADecalActor* Decal =
World->SpawnActor<ADecalActor>(FinalLocation, FRotator(), SpawnParams);
243 FVector FinalDecalScale;
246 FinalDecalScale.Z = 1.0f;
247 Decal->SetActorScale3D(FinalDecalScale);
251 FinalRotation.Yaw += RandomYaw;
252 FinalRotation.Pitch = -90.0f;
253 Decal->SetActorRotation(FinalRotation);
254 Decal->SetActorLabel(
"RoadDecal",
true);
261 UEditorLoadingAndSavingUtils::SaveDirtyPackages(
true,
true);
266 FDecalsProperties ULoadAssetMaterialsCommandlet::ReadDecalsConfigurationFile(
const FString &PackageName) {
269 FString JsonConfigFile;
271 TArray<FString> FileList;
272 IFileManager::Get().FindFilesRecursive(FileList, *(FPaths::ProjectContentDir() +
"/" + PackageName),
273 *(FString(
"roadpainter_decals.json")),
true,
false,
false);
276 if (FFileHelper::LoadFileToString(JsonConfigFile, *(
IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*FileList[0]))))
278 TSharedPtr<FJsonObject> JsonParsed;
279 TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonConfigFile);
280 if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
283 auto DecalJsonArray = JsonParsed->GetArrayField(TEXT(
"decals"));
284 for (
auto &DecalJsonValue : DecalJsonArray)
286 const auto DecalJsonObject = DecalJsonValue->AsObject();
291 if (DecalJsonObject->HasField(Pair.Key) ==
true) {
292 DecalConfiguration.
DecalMaterials.Add(LoadObject<UMaterialInstanceConstant>(
nullptr, *Pair.Value));
293 DecalConfiguration.
DecalNumToSpawn.Add(DecalJsonObject->GetIntegerField(Pair.Key));
297 TSharedPtr<FJsonObject> VectorObject = DecalJsonObject->GetObjectField(TEXT(
"decal_scale"));
299 DecalScale.X = (float)VectorObject->GetNumberField(TEXT(
"x_axis"));
300 DecalScale.Y = (float)VectorObject->GetNumberField(TEXT(
"y_axis"));
301 DecalScale.Z = (float)VectorObject->GetNumberField(TEXT(
"z_axis"));
304 DecalConfiguration.
DecalMinScale = (float)DecalJsonObject->GetNumberField(TEXT(
"decal_min_scale"));
305 DecalConfiguration.
DecalMaxScale = (float)DecalJsonObject->GetNumberField(TEXT(
"decal_max_scale"));
306 DecalConfiguration.
DecalRandomYaw = (float)DecalJsonObject->GetNumberField(TEXT(
"decal_random_yaw"));
307 DecalConfiguration.
RandomOffset = (float)DecalJsonObject->GetNumberField(TEXT(
"random_offset"));
311 return DecalConfiguration;
317 TArray<FString> PackageList;
318 IFileManager::Get().FindFilesRecursive(PackageList, *(FPaths::ProjectContentDir()),
319 *(PackageName + TEXT(
".Package.json")),
true,
false,
false);
321 if (PackageList.Num() == 0)
323 UE_LOG(LogTemp, Error, TEXT(
"Package json file not found."));
327 return IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*PackageList[0]);
330 void ULoadAssetMaterialsCommandlet::LoadAssetsMaterials(
const FString &PackageName,
const TArray<FMapData> &MapsPaths)
333 FAssetData AssetData;
334 MapObjectLibrary = UObjectLibrary::CreateLibrary(UWorld::StaticClass(),
false, GIsEditor);
335 const FString DefaultPath = TEXT(
"/Game/") + PackageName + TEXT(
"/Maps/");
337 for (
auto &&data : MapsPaths)
348 for (int32 i = 0; i < NumAssets; ++i) {
352 World = Cast<UWorld>(AssetData.GetAsset());
353 if (
World !=
nullptr) {
358 TArray<AActor*> FoundActors;
359 UGameplayStatics::GetAllActorsOfClass(
World, AStaticMeshActor::StaticClass(), FoundActors);
360 bool HasRoadMesh =
false;
361 for (int32 j = 0; j < FoundActors.Num() && HasRoadMesh ==
false; ++j) {
363 AStaticMeshActor *MeshActor = Cast<AStaticMeshActor>(FoundActors[j]);
364 if (MeshActor->GetName().Contains(
"Roads") || MeshActor->GetName().Contains(
"Road")){
370 if (HasRoadMesh ==
true) {
372 bool IsTiledMap =
World->GetName().Contains(
"_Tile_", ESearchCase::Type::CaseSensitive);
373 ApplyRoadPainterMaterials(
World->GetName(), PackageName, IsTiledMap);
377 UEditorLoadingAndSavingUtils::SaveDirtyPackages(
true,
true);
384 FPackageParams ULoadAssetMaterialsCommandlet::ParseParams(
const FString &InParams)
const 386 TArray<FString> Tokens;
387 TArray<FString> Params;
388 TMap<FString, FString> ParamVals;
390 ParseCommandLine(*InParams, Tokens, Params);
395 FParse::Value(*InParams, TEXT(
"PackageName="), PackageParams.
Name);
397 return PackageParams;
400 FAssetsPaths ULoadAssetMaterialsCommandlet::GetAssetsPathFromPackage(
const FString &PackageName)
const 407 FString MapsFileJsonContent;
408 if (FFileHelper::LoadFileToString(MapsFileJsonContent, *PackageJsonFilePath))
410 TSharedPtr<FJsonObject> JsonParsed;
411 TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(MapsFileJsonContent);
412 if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
415 auto MapsJsonArray = JsonParsed->GetArrayField(TEXT(
"maps"));
417 for (
auto &MapJsonValue : MapsJsonArray)
419 TSharedPtr<FJsonObject> MapJsonObject = MapJsonValue->AsObject();
422 MapData.
Name = MapJsonObject->GetStringField(TEXT(
"name"));
423 MapData.
Path = MapJsonObject->GetStringField(TEXT(
"path"));
426 AssetsPaths.
MapsPaths.Add(std::move(MapData));
430 auto PropJsonArray = JsonParsed->GetArrayField(TEXT(
"props"));
432 for (
auto &PropJsonValue : PropJsonArray)
434 TSharedPtr<FJsonObject> PropJsonObject = PropJsonValue->AsObject();
436 const FString PropAssetPath = PropJsonObject->GetStringField(TEXT(
"path"));
438 AssetsPaths.
PropsPaths.Add(std::move(PropAssetPath));
445 int32 ULoadAssetMaterialsCommandlet::Main(
const FString &Params)
452 LoadAssetsMaterials(PackageParams.
Name, AssetsPaths.
MapsPaths);
455 UEditorLoadingAndSavingUtils::SaveDirtyPackages(
true,
true);
float DecalMaxScale
Maximum scale to be applied to the decals.
FVector FixedDecalOffset
Min offset from one decal to another.
float DecalRandomYaw
The decal yaw to be applied randomly.
TArray< FMapData > MapsPaths
Struct containing Package with Name and bOnlyPrepareMaps flag used to separate the cooking of maps an...
static FString LoadXODR(const FString &MapName)
FLargeMapTileData TileData
TArray< UMaterialInstance * > DecalMaterials
The decals used on the road.
Struct containing map data read from .Package.json file.
TArray< FString > PropsPaths
TArray< FAssetData > AssetDatas
Loaded assets from any object library.
ULoadAssetMaterialsCommandlet()
Default constructor.
static T Get(carla::rpc::Response< T > &response)
UObjectLibrary * MapObjectLibrary
Used for loading maps in object library.
static boost::optional< road::Map > Load(const std::string &opendrive)
Struct containing all assets data read from .Package.json file.
boost::optional< carla::road::Map > XODRMap
TArray< int32 > DecalNumToSpawn
How many decals (or material instances) of each, should be applied to the road.
FString GetFirstPackagePath(const FString &PackageName) const
Gets the first .Package.json file found in Unreal Content Directory with PackageName.
FDecalsProperties DecalsProperties
TMap< FString, FString > DecalNamesMap
Dictionary for translating the JSON file "decal_names" array to already loaded Material Instances...
float DecalMinScale
Min scale to be applied to the decals.
TSubclassOf< ARoadPainterWrapper > RoadPainterSubclass
Subclass for acquiring the RoadPainter blueprint.
float RandomOffset
Random offset from one decal to another.
FVector DecalScale
Scale of each decal on the road.
bool bUseCarlaMapMaterials