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"
This commit is contained in:
Roel Algaba Brizuela 2021-03-22 10:28:41 +01:00 committed by bernat
parent 1f1c2798b2
commit d76f682005
7 changed files with 256 additions and 47 deletions

View File

@ -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 <https://opensource.org/licenses/MIT>.
#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<UBlueprint> RoadPainterBlueprint(TEXT(
"Blueprint'/Game/Carla/Blueprints/LevelDesign/RoadPainterPreset.RoadPainterPreset'"));
static ConstructorHelpers::FObjectFinder<UTextureRenderTarget2D> 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<ARoadPainterWrapper>(RoadPainterSubclass);
if (RoadPainterBp)
{
//Needed to call events in editor-mode
FEditorScriptExecutionGuard ScriptGuard;
RoadPainterBp->ZSizeEvent();
RoadPainterBp->ClearAllEvent();
RoadPainterBp->PaintAllRoadsEvent();
//TArray<AActor*> 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<AStaticMeshActor>(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<UWorld>(AssetData.GetAsset());
World->InitWorld();
ApplyRoadPainterMaterials();
#if WITH_EDITOR
UEditorLoadingAndSavingUtils::SaveDirtyPackages(true, true);
#endif
return 0;
}
#endif

View File

@ -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 <https://opensource.org/licenses/MIT>.
#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<AStaticMeshActor *> SpawnMeshesToWorld(
// const TArray<FString> &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<AStaticMeshActor *> &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<FMapData> &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<FString> &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<FAssetData> 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<ARoadPainterWrapper> RoadPainterSubclass;
};

View File

@ -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<UMaterial> MarkingNode(TEXT(
"Material'/Game/Carla/Static/GenericMaterials/LaneMarking/M_MarkingLane_W.M_MarkingLane_W'"));
static ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> MarkingNode(TEXT(
"MaterialInstanceConstant'/Game/Carla/Static/GenericMaterials/RoadPainterMaterials/M_Road_03_LMW.M_Road_03_LMW'"));
static ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> RoadNode(TEXT(
"MaterialInstanceConstant'/Game/Carla/Static/GenericMaterials/RoadPainterMaterials/M_Road_03.M_Road_03'"));
if (RoadNode.Object == NULL) {
static ConstructorHelpers::FObjectFinder<UMaterial> 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<UMaterial> RoadNodeAux(TEXT(
"Material'/Game/Carla/Static/GenericMaterials/LaneMarking/M_MarkingLane_Y.M_MarkingLane_Y'"));
static ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> RoadNodeAux(TEXT(
"MaterialInstanceConstant'/Game/Carla/Static/GenericMaterials/RoadPainterMaterials/M_Road_03_LMY.M_Road_03_LMY'"));
static ConstructorHelpers::FObjectFinder<UMaterial> TerrainNodeMaterial(TEXT(
"Material'/Game/Carla/Static/GenericMaterials/Grass/M_Grass01.M_Grass01'"));
static ConstructorHelpers::FObjectFinder<UMaterial> SidewalkNode(TEXT(
"Material'/Game/Carla/Static/GenericMaterials/CheapMaterials/M_SideWalkCheap01'"));
static ConstructorHelpers::FObjectFinder<UClass> 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<AStaticMeshActor *> UPrepareAssetsForCookingCommandlet::SpawnMeshesToWorl
SpawnedMeshes.Add(MeshActor);
ARoadPainterWrapper *RoadPainterBp = World->SpawnActor<ARoadPainterWrapper>(RoadPainterSubclass);
RoadPainterBp->PaintAllRoadsEvent();
RoadPainterBp->Destroy();
if (bUseCarlaMaterials)
{
// Set Carla Materials depending on RoadRunner's Semantic Segmentation
@ -200,15 +183,7 @@ TArray<AStaticMeshActor *> 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

View File

@ -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<ARoadPainterWrapper> 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;
};
};

View File

@ -8,4 +8,5 @@
ARoadPainterWrapper::ARoadPainterWrapper(){
MapSize = 0.0f;
}

View File

@ -53,4 +53,7 @@ public:
UFUNCTION(BlueprintImplementableEvent, Category = "ARoadPainterWrapper")
void ClearAllEvent();
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "ARoadPainterWrapper")
float MapSize;
};

View File

@ -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]