From d76f682005ec2a8a3e2adfbaad7f1fc06307d29c Mon Sep 17 00:00:00 2001 From: Roel Algaba Brizuela Date: Mon, 22 Mar 2021 10:28:41 +0100 Subject: [PATCH] make import road painter materials for maps First implementation for applying road painter materials to imported maps. However, the user still has to access the road painter blueprint and click on the "Paint all roads button" --- .../LoadAssetMaterialsCommandlet.cpp | 122 ++++++++++++++++++ .../Commandlet/LoadAssetMaterialsCommandlet.h | 109 ++++++++++++++++ .../PrepareAssetsForCookingCommandlet.cpp | 43 ++---- .../PrepareAssetsForCookingCommandlet.h | 17 +-- .../Source/Carla/Util/RoadPainterWrapper.cpp | 1 + .../Source/Carla/Util/RoadPainterWrapper.h | 3 + Util/BuildTools/Import.py | 8 ++ 7 files changed, 256 insertions(+), 47 deletions(-) create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.cpp create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.h diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.cpp new file mode 100644 index 000000000..f3fcbb33e --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.cpp @@ -0,0 +1,122 @@ +// Copyright (c) 2019 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 . + +#include "LoadAssetMaterialsCommandlet.h" + +#if WITH_EDITOR +#include "FileHelpers.h" +#endif +#include "Engine/StaticMeshActor.h" +#include "HAL/PlatformFilemanager.h" +#include "Materials/MaterialInstanceConstant.h" +#include "Materials/MaterialInstanceDynamic.h" +#include "UObject/ConstructorHelpers.h" +#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h" +#include "Engine/StreamableManager.h" + +ULoadAssetMaterialsCommandlet::ULoadAssetMaterialsCommandlet() +{ + // Set necessary flags to run commandlet + IsClient = false; + IsEditor = true; + IsServer = false; + LogToConsole = true; + +#if WITH_EDITORONLY_DATA + + static ConstructorHelpers::FObjectFinder RoadPainterBlueprint(TEXT( + "Blueprint'/Game/Carla/Blueprints/LevelDesign/RoadPainterPreset.RoadPainterPreset'")); + static ConstructorHelpers::FObjectFinder RoadPainterTexRenderTarget(TEXT( + "TextureRenderTarget2D'/Game/Carla/Blueprints/LevelDesign/RoadPainterAssets/RenderTexture.RenderTexture'")); + + RoadPainterSubclass = (UClass*)RoadPainterBlueprint.Object->GeneratedClass; + RoadPainterTexture = RoadPainterTexRenderTarget.Object; + +#endif +} + +#if WITH_EDITORONLY_DATA + +void ULoadAssetMaterialsCommandlet::ApplyRoadPainterMaterials() +{ + // ImportedMap path from import process + const FString ImportedMap = TEXT("/Game/map_package/Maps/TestOSM"); + + ARoadPainterWrapper *RoadPainterBp = World->SpawnActor(RoadPainterSubclass); + if (RoadPainterBp) + { + //Needed to call events in editor-mode + FEditorScriptExecutionGuard ScriptGuard; + RoadPainterBp->ZSizeEvent(); + RoadPainterBp->ClearAllEvent(); + RoadPainterBp->PaintAllRoadsEvent(); + + //TArray FoundActors; + //UGameplayStatics::GetAllActorsOfClass(World, AStaticMeshActor::StaticClass(), FoundActors); + // + //AStaticMeshActor *RoadMeshActor = nullptr; + // + //bool FoundRoadActor = false; + //for(int32 i = 0; i < FoundActors.Num() && FoundRoadActor == false; ++i) + //{ + // RoadMeshActor = Cast(FoundActors[i]); + // if(RoadMeshActor) + // { + // if(RoadMeshActor->GetName().Equals("Roads_RoadNode") == true) + // { + // UE_LOG(LogTemp, Log, TEXT("Got it!"), *FoundActors[i]->GetName()); + // + // UMaterialInstanceDynamic *MI = UMaterialInstanceDynamic::Create(RoadNodeMaterialMaster, this, FName(TEXT("Road Painter Material Dynamic"))); + // MI->CopyParameterOverrides((UMaterialInstance*)RoadMeshActor->GetStaticMeshComponent()->GetMaterial(0)); + // RoadMeshActor->GetStaticMeshComponent()->SetMaterial(0, MI); + // MI->SetScalarParameterValue(TEXT("Map units (CM)"), RoadPainterBp->MapSize); + // MI->SetTextureParameterValue(TEXT("Texture Mask"), RoadPainterTexture); + // FoundRoadActor = true; + // } + // } + //} + + //FTimerHandle Handle; + //World->GetTimerManager().SetTimer(Handle, [=]() { RoadPainterBp->PaintAllRoadsEvent(); }, 5.0f, 1); + } +} + +void ULoadAssetMaterialsCommandlet::LoadImportedMapWorld(FAssetData &AssetData) +{ + // ImportedMap path from import process + const FString ImportedMap = TEXT("/Game/map_package/Maps/TestOSM"); + + // Load Map folder using object library + MapObjectLibrary = UObjectLibrary::CreateLibrary(UWorld::StaticClass(), false, GIsEditor); + MapObjectLibrary->AddToRoot(); + MapObjectLibrary->LoadAssetDataFromPath(*ImportedMap); + MapObjectLibrary->LoadAssetsFromAssetData(); + MapObjectLibrary->GetAssetDataList(AssetDatas); + + if (AssetDatas.Num() > 0) + { + // Extract first asset found in folder path (i.e. the imported map) + AssetData = AssetDatas.Pop(); + UE_LOG(LogTemp, Log, TEXT("The name of the asset : %s"), *AssetData.GetFullName()); + } +} + +int32 ULoadAssetMaterialsCommandlet::Main(const FString &Params) +{ + FAssetData AssetData; + LoadImportedMapWorld(AssetData); + World = CastChecked(AssetData.GetAsset()); + World->InitWorld(); + ApplyRoadPainterMaterials(); + +#if WITH_EDITOR + UEditorLoadingAndSavingUtils::SaveDirtyPackages(true, true); +#endif + + return 0; +} + +#endif \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.h new file mode 100644 index 000000000..34a22bfa3 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/LoadAssetMaterialsCommandlet.h @@ -0,0 +1,109 @@ +// Copyright (c) 2019 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 . + +#pragma once +#include "Commandlets/Commandlet.h" +#include "Util/RoadPainterWrapper.h" +#include "Runtime/Engine/Classes/Engine/ObjectLibrary.h" +#include "LoadAssetMaterialsCommandlet.generated.h" + +UCLASS() +class CARLA_API ULoadAssetMaterialsCommandlet + : public UCommandlet +{ + GENERATED_BODY() + +public: + + /// Default constructor. + ULoadAssetMaterialsCommandlet(); + +#if WITH_EDITORONLY_DATA + + /// Parses the command line parameters provided through @a InParams + //FPackageParams ParseParams(const FString &InParams) const; + + /// Loads a UWorld object contained in Carla BaseMap into @a AssetData data + /// structure. + //void LoadWorld(FAssetData &AssetData); + + /// Spawns all the static meshes located in @a AssetsPaths inside the World. + /// There is an option to use Carla materials by setting @a bUseCarlaMaterials + /// to true, otherwise it will use RoadRunner materials. + /// If meshes are been added to a PropsMap, set @a bIsPropMap to true. + /// + /// @pre World is expected to be previously loaded + //TArray SpawnMeshesToWorld( + // const TArray &AssetsPaths, + // bool bUseCarlaMaterials); + + /// Saves the current World, contained in @a AssetData, into @a DestPath + /// composed of @a PackageName and with @a WorldName. + //bool SaveWorld( + // FAssetData &AssetData, + // const FString &PackageName, + // const FString &DestPath, + // const FString &WorldName); + + /// Destroys all the previously spawned actors stored in @a SpawnedActors + //void DestroySpawnedActorsInWorld(TArray &SpawnedActors); + + /// Gets the Path of all the Assets contained in the package to cook with name + /// @a PackageName + //FAssetsPaths GetAssetsPathFromPackage(const FString &PackageName) const; + + /// Generates the MapPaths file provided @a AssetsPaths and @a PropsMapPath + //void GenerateMapPathsFile(const FAssetsPaths &AssetsPaths, const FString &PropsMapPath); + + /// Generates the PackagePat file that contains the path of a package with @a + /// PackageName + //void GeneratePackagePathFile(const FString &PackageName); + + /// For each Map data contained in @MapsPaths, it creates a World, spawn its + /// actors inside the world and saves it in .umap format + /// in a destination path built from @a PackageName. + //void PrepareMapsForCooking(const FString &PackageName, const TArray &MapsPaths); + + /// For all the props inside @a PropsPaths, it creates a single World, spawn + /// all the props inside the world and saves it in .umap format + /// in a destination path built from @a PackageName and @a MapDestPath. + //void PreparePropsForCooking(FString &PackageName, const TArray &PropsPaths, FString &MapDestPath); + + void ApplyRoadPainterMaterials(); + + void LoadImportedMapWorld(FAssetData &AssetData); + +public: + + /// Main method and entry of the commandlet, taking as input parameters @a + /// Params. + virtual int32 Main(const FString &Params) override; + +#endif // WITH_EDITORONLY_DATA + +private: + + /// Loaded assets from any object library + UPROPERTY() + TArray AssetDatas; + + UPROPERTY() + UWorld *World; + + /// Used for loading maps in object library. Loaded Data is stored in + /// AssetDatas. + UPROPERTY() + UObjectLibrary *MapObjectLibrary; + + /// Texture used for painting roads with road painter + UPROPERTY() + UTextureRenderTarget2D *RoadPainterTexture; + + /// Subclass for acquiring the RoadPainter blueprint + UPROPERTY() + TSubclassOf RoadPainterSubclass; + +}; \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.cpp index e26f57b22..84898a844 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.cpp @@ -49,34 +49,21 @@ UPrepareAssetsForCookingCommandlet::UPrepareAssetsForCookingCommandlet() #if WITH_EDITORONLY_DATA // Get Carla Default materials, these will be used for maps that need to use // Carla materials - static ConstructorHelpers::FObjectFinder MarkingNode(TEXT( - "Material'/Game/Carla/Static/GenericMaterials/LaneMarking/M_MarkingLane_W.M_MarkingLane_W'")); + static ConstructorHelpers::FObjectFinder MarkingNode(TEXT( + "MaterialInstanceConstant'/Game/Carla/Static/GenericMaterials/RoadPainterMaterials/M_Road_03_LMW.M_Road_03_LMW'")); static ConstructorHelpers::FObjectFinder RoadNode(TEXT( "MaterialInstanceConstant'/Game/Carla/Static/GenericMaterials/RoadPainterMaterials/M_Road_03.M_Road_03'")); - if (RoadNode.Object == NULL) { - - static ConstructorHelpers::FObjectFinder RoadNode(TEXT( - "Material'/Game/Carla/Static/GenericMaterials/Masters/LowComplexity/M_Road1.M_Road1'")); - RoadNodeMaterial = (UMaterial *)RoadNode.Object; - } - else { - - RoadNodeMaterialInstance = (UMaterialInstance *)RoadNode.Object; - } - - static ConstructorHelpers::FObjectFinder RoadNodeAux(TEXT( - "Material'/Game/Carla/Static/GenericMaterials/LaneMarking/M_MarkingLane_Y.M_MarkingLane_Y'")); + static ConstructorHelpers::FObjectFinder RoadNodeAux(TEXT( + "MaterialInstanceConstant'/Game/Carla/Static/GenericMaterials/RoadPainterMaterials/M_Road_03_LMY.M_Road_03_LMY'")); static ConstructorHelpers::FObjectFinder TerrainNodeMaterial(TEXT( "Material'/Game/Carla/Static/GenericMaterials/Grass/M_Grass01.M_Grass01'")); static ConstructorHelpers::FObjectFinder SidewalkNode(TEXT( "Material'/Game/Carla/Static/GenericMaterials/CheapMaterials/M_SideWalkCheap01'")); - static ConstructorHelpers::FObjectFinder RoadPainterBlueprint(TEXT( - "Blueprint'/Game/Carla/Blueprints/LevelDesign/RoadPainterPreset.RoadPainterPreset_C'")); - MarkingNodeMaterial = (UMaterial *) MarkingNode.Object; - MarkingNodeMaterialAux = (UMaterial *) RoadNodeAux.Object; + MarkingNodeMaterial = (UMaterialInstance *) MarkingNode.Object; + RoadNodeMaterial = (UMaterialInstance *) RoadNode.Object; + MarkingNodeMaterialAux = (UMaterialInstance *) RoadNodeAux.Object; SidewalkNodeMaterial = (UMaterial *) SidewalkNode.Object; - RoadPainterSubclass = RoadPainterBlueprint.Object; #endif } #if WITH_EDITORONLY_DATA @@ -185,10 +172,6 @@ TArray UPrepareAssetsForCookingCommandlet::SpawnMeshesToWorl SpawnedMeshes.Add(MeshActor); - ARoadPainterWrapper *RoadPainterBp = World->SpawnActor(RoadPainterSubclass); - RoadPainterBp->PaintAllRoadsEvent(); - RoadPainterBp->Destroy(); - if (bUseCarlaMaterials) { // Set Carla Materials depending on RoadRunner's Semantic Segmentation @@ -200,15 +183,7 @@ TArray UPrepareAssetsForCookingCommandlet::SpawnMeshesToWorl } else if (AssetName.Contains(SSTags::R_ROAD1) || AssetName.Contains(SSTags::R_ROAD2)) { - - if(RoadNodeMaterialInstance != NULL){ - - MeshActor->GetStaticMeshComponent()->SetMaterial(0, RoadNodeMaterialInstance); - } - else { - - MeshActor->GetStaticMeshComponent()->SetMaterial(0, RoadNodeMaterial); - } + MeshActor->GetStaticMeshComponent()->SetMaterial(0, RoadNodeMaterial); } else if (AssetName.Contains(SSTags::R_TERRAIN)) { @@ -551,4 +526,4 @@ int32 UPrepareAssetsForCookingCommandlet::Main(const FString &Params) return 0; } -#endif +#endif \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.h index 4fb1fdf1c..db82bc77a 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Commandlet/PrepareAssetsForCookingCommandlet.h @@ -9,7 +9,6 @@ #include "Carla/OpenDrive/OpenDriveActor.h" #include "Commandlets/Commandlet.h" #include "Runtime/Engine/Classes/Engine/ObjectLibrary.h" -#include "Util/RoadPainterWrapper.h" #include "Runtime/Engine/Classes/Engine/StaticMeshActor.h" #include "PrepareAssetsForCookingCommandlet.generated.h" @@ -151,19 +150,15 @@ private: /// Workaround material for MarkingNodes mesh UPROPERTY() - UMaterial *MarkingNodeMaterial; - - /// Material used by RoadPainter - UPROPERTY() - UMaterialInstance *RoadNodeMaterialInstance; + UMaterialInstance *MarkingNodeMaterial; /// Workaround material for the RoadNode mesh UPROPERTY() - UMaterial *RoadNodeMaterial; + UMaterialInstance *RoadNodeMaterial; /// Workaround material for the second material for the MarkingNodes UPROPERTY() - UMaterial *MarkingNodeMaterialAux; + UMaterialInstance *MarkingNodeMaterialAux; /// Workaround material for the TerrainNodes UPROPERTY() @@ -173,10 +168,6 @@ private: UPROPERTY() UMaterial *SidewalkNodeMaterial; - /// Subclass for acquiring the RoadPainter blueprint - UPROPERTY() - TSubclassOf RoadPainterSubclass; - /// Saves @a Package in .umap format in path @a PackagePath inside Unreal /// Content folder bool SavePackage(const FString &PackagePath, UPackage *Package) const; @@ -185,4 +176,4 @@ private: /// @a PackageName FString GetFirstPackagePath(const FString &PackageName) const; -}; +}; \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.cpp index d16c2f0c2..ef149b7e9 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.cpp @@ -8,4 +8,5 @@ ARoadPainterWrapper::ARoadPainterWrapper(){ + MapSize = 0.0f; } \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.h index 9f794c86d..1a35258ad 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/RoadPainterWrapper.h @@ -53,4 +53,7 @@ public: UFUNCTION(BlueprintImplementableEvent, Category = "ARoadPainterWrapper") void ClearAllEvent(); + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "ARoadPainterWrapper") + float MapSize; }; diff --git a/Util/BuildTools/Import.py b/Util/BuildTools/Import.py index 503f40d1c..a79db3950 100755 --- a/Util/BuildTools/Import.py +++ b/Util/BuildTools/Import.py @@ -281,8 +281,16 @@ def import_assets_from_json_list(json_list): # We prepare only the maps for cooking after moving them. Props cooking will be done from Package.sh script. prepare_maps_commandlet_for_cooking(package_name, only_prepare_maps=True) + + # We apply the carla materials to the imported maps + load_asset_materials_commandlet(package_name) +def load_asset_materials_commandlet(package_name): + commandlet_name = "LoadAssetMaterials" + commandlet_arguments = ["-PackageName=%s" % package_name] + invoke_commandlet(commandlet_name, commandlet_arguments) + def prepare_maps_commandlet_for_cooking(package_name, only_prepare_maps): commandlet_name = "PrepareAssetsForCooking" commandlet_arguments = ["-PackageName=%s" % package_name]