CARLA
 
载入中...
搜索中...
未找到
LoadAssetMaterialsCommandlet.cpp
浏览该文件的文档.
1// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
8
9#if WITH_EDITOR
10#include "FileHelpers.h"
11#endif
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"
22
24{
25 // Set necessary flags to run commandlet
26 IsClient = false;
27 IsEditor = true;
28 IsServer = false;
29 LogToConsole = true;
30 FilledData = false;
31 ReadConfigFile = true;
32
33#if WITH_EDITORONLY_DATA
34
35 static ConstructorHelpers::FObjectFinder<UBlueprint> RoadPainterBlueprint(TEXT(
36 "Blueprint'/Game/Carla/Blueprints/LevelDesign/RoadPainterPreset.RoadPainterPreset'"));
37
38 RoadPainterSubclass = (UClass*)RoadPainterBlueprint.Object->GeneratedClass;
39
40 // Dirt
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'");
46
47 // Drip
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'");
51
52 // Road lines
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'");
58
59 // Tiremarks
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'");
63
64 // Tarsnakes
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'");
76
77 // Cracks big
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'");
86
87 // Cracks
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'");
96
97 // Manholes
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'");
101
102 // Mud
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'");
108
109 // Oil splats
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'");
115
116 // Misc
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'");
119
120#endif
121}
122
123#if WITH_EDITORONLY_DATA
124
125void ULoadAssetMaterialsCommandlet::ApplyRoadPainterMaterials(const FString &LoadedMapName, const FString &PackageName, bool IsInTiles)
126{
127 if (IsInTiles == true) {
128
129 if (FilledData == false) {
130
131 // As the OpenDrive file has the same name as level, build the path to the
132 // xodr file using the label name and the game content directory.
133 FString MapName = LoadedMapName;
134 if (IsInTiles)
135 {
136 int32 idx = MapName.Find("_Tile_");
137 if(idx > -1)
138 {
139 MapName = MapName.Mid(0, idx);
140 }
141 }
142 const FString XodrContent = UOpenDrive::LoadXODR(MapName);
143 XODRMap = carla::opendrive::OpenDriveParser::Load(carla::rpc::FromLongFString(XodrContent));
144
145 // Acquire the TilesInfo.txt file for storing the tile data (offset and size)
146 TArray<FString> FileList;
147 IFileManager::Get().FindFilesRecursive(FileList, *(FPaths::ProjectContentDir() + "/" + PackageName + "/Maps/" + MapName), *(FString("TilesInfo.txt")), true, false, false);
148
149 FString TxtFile;
150 if (FFileHelper::LoadFileToString(TxtFile, *FileList[0]) == true) {
151
152 TArray<FString> Out;
153 TxtFile.ParseIntoArray(Out, TEXT(","), true);
154
155 TileData.FirstTileCenterX = (float) FCString::Atoi(*Out[0]);
156 TileData.FirstTileCenterY = (float) FCString::Atoi(*Out[1]);
157 TileData.Size = (float) FCString::Atoi(*Out[2]);
158 }
159 else {
160 UE_LOG(LogTemp, Warning, TEXT("Could not read TilesInfo.txt file"));
161 return;
162 }
163
164 FilledData = true;
165 }
166
167 TArray<FString> StringArray = {};
168 LoadedMapName.ParseIntoArray(StringArray, TEXT("_"), false);
169 // From the loaded map name (in style mymap_Tile_200_400) get the X and the Y (Tile_200_400 -> X = 200, Y = 400)
170 int32 XIndex = FCString::Atoi(*StringArray[StringArray.Num() - 2]);
171 int32 YIndex = FCString::Atoi(*StringArray[StringArray.Num() - 1]);
172 FVector TilePosition;
173 // This means it's the initial tile (mymap_Tile_0_0)
174 // This is in RELATIVE coords
175 TilePosition.X = TileData.FirstTileCenterX + (TileData.Size * (float)XIndex);
176 TilePosition.Y = TileData.FirstTileCenterY - (TileData.Size * (float)YIndex);
177 TilePosition.Z = 0.0f;
178
179 float HalfSize = TileData.Size / 2.0f;
180
181 float MinXSize = (TilePosition.X - HalfSize);
182 float MaxXSize = (TilePosition.X + HalfSize);
183
184 float MinYSize = (TilePosition.Y - HalfSize);
185 float MaxYSize = (TilePosition.Y + HalfSize);
186
187 if (ReadConfigFile == true) {
188
189 DecalsProperties = ReadDecalsConfigurationFile(PackageName);
190 ReadConfigFile = false;
191 }
192
193 carla::geom::Location DecalLocation;
194
195 //Store results for avoiding excessive calculations
196 float MinXSizeCm = MinXSize * 100.0f;
197 float MaxXSizeCm = MaxXSize * 100.0f;
198 float MinYSizeCm = MinYSize * 100.0f;
199 float MaxYSizeCm = MaxYSize * 100.0f;
200
201 float TileSizeCm = TileData.Size * 100.0f;
202 float FirstTileWorldLocationX = TileData.FirstTileCenterX * 100.0f;
203 float FirstTileWorldLocationY = TileData.FirstTileCenterY * 100.0f;
204
205 float CenterOfTileX = FirstTileWorldLocationX + (XIndex * TileSizeCm);
206 float CenterOfTileY = FirstTileWorldLocationY - (YIndex * TileSizeCm);
207
208 for (int32 i = 0; i < DecalsProperties.DecalMaterials.Num(); ++i) {
209
210 for (int32 j = 0; j < DecalsProperties.DecalNumToSpawn[i]; ++j) {
211
212 DecalLocation.x = FMath::RandRange(MinXSize, MaxXSize);
213 DecalLocation.y = FMath::RandRange(MinYSize, MaxYSize);
214 DecalLocation.z = 0.0f;
215
216 // Get the closest road waypoint from the random location calculated
217 auto Wp = XODRMap->GetClosestWaypointOnRoad(DecalLocation);
218 carla::geom::Location RoadLocation = XODRMap->ComputeTransform(Wp.get()).location;
219 FVector FinalLocation(RoadLocation);
220
221 // Check we don't exceed the map boundaries
222 if (FinalLocation.X > MinXSizeCm && FinalLocation.X < MaxXSizeCm) {
223
224 if (FinalLocation.Y > MinYSizeCm && FinalLocation.Y < MaxYSizeCm) {
225
226 FRotator FinalRotation(XODRMap->ComputeTransform(Wp.get()).rotation);
227
228 // Transform the location from world coords to tile coordinates.
229 // The location we get is the location of the XODR waypoint, which is in WORLD coordinates
230 // The Y coordinates are reversed! -Y = Y and Y = -Y
231
232 FinalLocation.X -= CenterOfTileX;
233 FinalLocation.Y -= CenterOfTileY;
234
235 FActorSpawnParameters SpawnParams;
236 SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
237 SpawnParams.bNoFail = true;
238 ADecalActor* Decal = World->SpawnActor<ADecalActor>(FinalLocation, FRotator(), SpawnParams);
239 Decal->SetDecalMaterial(DecalsProperties.DecalMaterials[i]);
240
241 // Calculate random scale for decal
242 float RandScale = FMath::RandRange(DecalsProperties.DecalMinScale, DecalsProperties.DecalMaxScale);
243 FVector FinalDecalScale;
244 FinalDecalScale.X = DecalsProperties.DecalScale.X + RandScale;
245 FinalDecalScale.Y = DecalsProperties.DecalScale.Y + RandScale;
246 FinalDecalScale.Z = 1.0f;
247 Decal->SetActorScale3D(FinalDecalScale);
248
249 // Calculate random yaw for decal
250 float RandomYaw = FMath::RandRange(0.0f, DecalsProperties.DecalRandomYaw);
251 FinalRotation.Yaw += RandomYaw;
252 FinalRotation.Pitch = -90.0f;
253 Decal->SetActorRotation(FinalRotation);
254 Decal->SetActorLabel("RoadDecal", true);
255 }
256 }
257 }
258 }
259
260#if WITH_EDITOR
261 UEditorLoadingAndSavingUtils::SaveDirtyPackages(true, true);
262#endif
263 }
264}
265
266FDecalsProperties ULoadAssetMaterialsCommandlet::ReadDecalsConfigurationFile(const FString &PackageName) {
267
268 // Get road painter configuration file
269 FString JsonConfigFile;
270
271 TArray<FString> FileList;
272 IFileManager::Get().FindFilesRecursive(FileList, *(FPaths::ProjectContentDir() + "/" + PackageName),
273 *(FString("roadpainter_decals.json")), true, false, false);
274
275 FDecalsProperties DecalConfiguration;
276 if (FFileHelper::LoadFileToString(JsonConfigFile, *(IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*FileList[0]))))
277 {
278 TSharedPtr<FJsonObject> JsonParsed;
279 TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonConfigFile);
280 if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
281 {
282 // Get decals object array
283 auto DecalJsonArray = JsonParsed->GetArrayField(TEXT("decals"));
284 for (auto &DecalJsonValue : DecalJsonArray)
285 {
286 const auto DecalJsonObject = DecalJsonValue->AsObject();
287
288 // With the decal name array we created earlier, we traverse it
289 // and look up it's name in the .json file
290 for (const TPair<FString, FString>& Pair : DecalNamesMap) {
291 if (DecalJsonObject->HasField(Pair.Key) == true) {
292 DecalConfiguration.DecalMaterials.Add(LoadObject<UMaterialInstanceConstant>(nullptr, *Pair.Value));
293 DecalConfiguration.DecalNumToSpawn.Add(DecalJsonObject->GetIntegerField(Pair.Key));
294 }
295 }
296
297 TSharedPtr<FJsonObject> VectorObject = DecalJsonObject->GetObjectField(TEXT("decal_scale"));
298 FVector DecalScale;
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"));
302 DecalConfiguration.DecalScale = DecalScale;
303 DecalConfiguration.FixedDecalOffset = DecalScale;
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"));
308 }
309 }
310 }
311 return DecalConfiguration;
312}
313
314FString ULoadAssetMaterialsCommandlet::GetFirstPackagePath(const FString &PackageName) const
315{
316 // Get all Package names
317 TArray<FString> PackageList;
318 IFileManager::Get().FindFilesRecursive(PackageList, *(FPaths::ProjectContentDir()),
319 *(PackageName + TEXT(".Package.json")), true, false, false);
320
321 if (PackageList.Num() == 0)
322 {
323 UE_LOG(LogTemp, Error, TEXT("Package json file not found."));
324 return {};
325 }
326
327 return IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*PackageList[0]);
328}
329
330void ULoadAssetMaterialsCommandlet::LoadAssetsMaterials(const FString &PackageName, const TArray<FMapData> &MapsPaths)
331{
332 // Load World
333 FAssetData AssetData;
334 MapObjectLibrary = UObjectLibrary::CreateLibrary(UWorld::StaticClass(), false, GIsEditor);
335 const FString DefaultPath = TEXT("/Game/") + PackageName + TEXT("/Maps/");
336 MapObjectLibrary->AddToRoot();
337 for (auto &&data : MapsPaths)
338 {
339 MapObjectLibrary->LoadAssetDataFromPath(*data.Path);
340 }
341 MapObjectLibrary->LoadAssetsFromAssetData();
342 MapObjectLibrary->GetAssetDataList(AssetDatas);
343
344 if (AssetDatas.Num() > 0)
345 {
346 int32 NumAssets = AssetDatas.Num();
347 //If the map is tiled, there will be several umaps in the same folder
348 for (int32 i = 0; i < NumAssets; ++i) {
349
350 // Extract first asset found in folder path (i.e. the imported map)
351 AssetData = AssetDatas.Pop();
352 World = Cast<UWorld>(AssetData.GetAsset());
353 if (World != nullptr) {
354
355 World->InitWorld();
356
357 // Check if there's any road meshes in the world for spawning the decals.
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) {
362
363 AStaticMeshActor *MeshActor = Cast<AStaticMeshActor>(FoundActors[j]);
364 if (MeshActor->GetName().Contains("Roads") || MeshActor->GetName().Contains("Road")){
365
366 HasRoadMesh = true;
367 }
368 }
369
370 if (HasRoadMesh == true) {
371
372 bool IsTiledMap = World->GetName().Contains("_Tile_", ESearchCase::Type::CaseSensitive);
373 ApplyRoadPainterMaterials(World->GetName(), PackageName, IsTiledMap);
374 }
375
376#if WITH_EDITOR
377 UEditorLoadingAndSavingUtils::SaveDirtyPackages(true, true);
378#endif
379 }
380 }
381 }
382}
383
384FPackageParams ULoadAssetMaterialsCommandlet::ParseParams(const FString &InParams) const
385{
386 TArray<FString> Tokens;
387 TArray<FString> Params;
388 TMap<FString, FString> ParamVals;
389
390 ParseCommandLine(*InParams, Tokens, Params);
391
392 FPackageParams PackageParams;
393
394 // Parse and store Package name
395 FParse::Value(*InParams, TEXT("PackageName="), PackageParams.Name);
396
397 return PackageParams;
398}
399
400FAssetsPaths ULoadAssetMaterialsCommandlet::GetAssetsPathFromPackage(const FString &PackageName) const
401{
402 const FString PackageJsonFilePath = GetFirstPackagePath(PackageName);
403
404 FAssetsPaths AssetsPaths;
405
406 // Get All Maps Path
407 FString MapsFileJsonContent;
408 if (FFileHelper::LoadFileToString(MapsFileJsonContent, *PackageJsonFilePath))
409 {
410 TSharedPtr<FJsonObject> JsonParsed;
411 TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(MapsFileJsonContent);
412 if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
413 {
414 // Add Maps Path
415 auto MapsJsonArray = JsonParsed->GetArrayField(TEXT("maps"));
416
417 for (auto &MapJsonValue : MapsJsonArray)
418 {
419 TSharedPtr<FJsonObject> MapJsonObject = MapJsonValue->AsObject();
420
421 FMapData MapData;
422 MapData.Name = MapJsonObject->GetStringField(TEXT("name"));
423 MapData.Path = MapJsonObject->GetStringField(TEXT("path"));
424 MapData.bUseCarlaMapMaterials = MapJsonObject->GetBoolField(TEXT("use_carla_materials"));
425
426 AssetsPaths.MapsPaths.Add(std::move(MapData));
427 }
428
429 // Add Props Path
430 auto PropJsonArray = JsonParsed->GetArrayField(TEXT("props"));
431
432 for (auto &PropJsonValue : PropJsonArray)
433 {
434 TSharedPtr<FJsonObject> PropJsonObject = PropJsonValue->AsObject();
435
436 const FString PropAssetPath = PropJsonObject->GetStringField(TEXT("path"));
437
438 AssetsPaths.PropsPaths.Add(std::move(PropAssetPath));
439 }
440 }
441 }
442 return AssetsPaths;
443}
444
445int32 ULoadAssetMaterialsCommandlet::Main(const FString &Params)
446{
447 FPackageParams PackageParams = ParseParams(Params);
448
449 // Get Props and Maps Path
450 FAssetsPaths AssetsPaths = GetAssetsPathFromPackage(PackageParams.Name);
451
452 LoadAssetsMaterials(PackageParams.Name, AssetsPaths.MapsPaths);
453
454#if WITH_EDITOR
455 UEditorLoadingAndSavingUtils::SaveDirtyPackages(true, true);
456#endif
457
458 return 0;
459}
460
461#endif
TArray< FAssetData > AssetDatas
Loaded assets from any object library
UObjectLibrary * MapObjectLibrary
Used for loading maps in object library.
TMap< FString, FString > DecalNamesMap
Dictionary for translating the JSON file "decal_names" array to already loaded Material Instances,...
boost::optional< carla::road::Map > XODRMap
FString GetFirstPackagePath(const FString &PackageName) const
Gets the first .Package.json file found in Unreal Content Directory with PackageName
TSubclassOf< ARoadPainterWrapper > RoadPainterSubclass
Subclass for acquiring the RoadPainter blueprint
static boost::optional< road::Map > Load(const std::string &opendrive)
Struct containing all assets data read from .Package.json file.
float DecalRandomYaw
The decal yaw to be applied randomly
float DecalMaxScale
Maximum scale to be applied to the decals
TArray< int32 > DecalNumToSpawn
How many decals (or material instances) of each, should be applied to the road
float RandomOffset
Random offset from one decal to another
TArray< UMaterialInstance * > DecalMaterials
The decals used on the road
float DecalMinScale
Min scale to be applied to the decals
FVector DecalScale
Scale of each decal on the road
FVector FixedDecalOffset
Min offset from one decal to another
Struct containing map data read from .Package.json file.
Struct containing Package with Name and bOnlyPrepareMaps flag used to separate the cooking of maps an...