Unreal/CarlaUE4/Plugins/RoadRunnerImporter/Source/RoadRunnerImporter/Private/RoadRunnerImporter.cpp
////////////////////////////////////////////////////////////////////////////////
// Replaces the created/existing Unreal material with a material instance from the
// RoadRunnerMaterials plugin
Replaces the created/existing Unreal material with a material instance from the
RoadRunnerMaterials plugin
Replaces the created / existing Unreal material with a material instance from the RoadRunnerMaterials plugin
void CreateRoadRunnerMaterial(FString sourceFilePath, FString packagePath,
		FRoadRunnerImportUtil::MaterialInfo materialInfo, int metadataVersion, TMap<FString, int32>& materialToLayerMap)
	{
		FString materialFullName = materialInfo.Name;
		FString basePackageName = FPackageName::GetLongPackagePath(packagePath) / materialFullName;
		basePackageName = PackageTools::SanitizePackageName(basePackageName);
		const FString Suffix(TEXT(""));
		UPackage* package = CreatePackage(NULL, *basePackageName);
		FText materialSearchError;
		UMaterialInterface* baseMaterial = nullptr;
		float alphaVal = 1.0f; 
		float transparency = 0.0f;
		if (!materialInfo.TransparencyFactor.IsEmpty())
		{
			transparency = FCString::Atof(*(materialInfo.TransparencyFactor));
		}
		bool isTransparent = !materialInfo.TransparencyMap.IsEmpty() || transparency > 0;
		FString materialName = "BaseMaterial";
		alphaVal = 1.0f - transparency;
		if (metadataVersion >= 1)
		{
			if (materialInfo.IsDecal.Equals("true") || !materialInfo.DrawQueue.Equals("0"))
			{
				materialName = "BaseDecalMaterial";
			}
			else if (isTransparent) 
			{
				if (materialInfo.TwoSided.Equals("true"))
				{
					if (materialInfo.ShadowCaster.Equals("false"))
					{
						materialName = "BaseTransparentMaterialTwoSided";
					}
					else
					{
						materialName = "BaseCutoutMaterialTwoSided";
					}
				}
				else
				{
					if (materialInfo.ShadowCaster.Equals("false"))
					{
						materialName = "BaseTransparentMaterial";
					}
					else
					{
						materialName = "BaseCutoutMaterial";
					}
				}
			}
		}
		else 
		{
			if (isTransparent)
			{
				if (materialInfo.TwoSided.Equals("true"))
				{
					if (transparency > 0.0f)
					{
						materialName = "BaseTransparentMaterialTwoSided";
					}
					else
					{
						materialName = "BaseCutoutMaterialTwoSided";
					}
				}
				else
				{
					if (transparency > 0.0f)
					{
						materialName = "BaseTransparentMaterial";
					}
					else
					{
						materialName = "BaseCutoutMaterial";
					}
				}
			}
		}
		baseMaterial = UMaterialImportHelpers::FindExistingMaterialFromSearchLocation(materialName, "/RoadRunnerMaterials/", EMaterialSearchLocation::UnderParent, materialSearchError);
		if (!materialSearchError.IsEmpty() || baseMaterial == nullptr)
		{
			UE_LOG(RoadRunnerImporter, Error, TEXT("Base material not found: %s"), *(materialSearchError.ToString()));
			return;
		}
		auto materialInstanceFactory = NewObject<UMaterialInstanceConstantFactoryNew>();
		materialInstanceFactory->InitialParent = baseMaterial;
		UMaterialInstanceConstant* unrealMaterial = (UMaterialInstanceConstant*)materialInstanceFactory->FactoryCreateNew(UMaterialInstanceConstant::StaticClass(), package, *materialFullName, RF_Standalone | RF_Public, NULL, GWarn);
		if (unrealMaterial == NULL)
		{
			UE_LOG(RoadRunnerImporter, Error, TEXT("Material %s could not be created."), *materialInfo.Name);
			return;
		}
		FAssetRegistryModule::AssetCreated(unrealMaterial);
		package->SetDirtyFlag(true);
		FRoadRunnerImportUtil::SetTextureParameter(unrealMaterial, FName(TEXT("DiffuseMap")), sourceFilePath, materialInfo.DiffuseMap, packagePath);
		FRoadRunnerImportUtil::SetTextureParameter(unrealMaterial, FName(TEXT("NormalMap")), sourceFilePath, materialInfo.NormalMap, packagePath);
		FRoadRunnerImportUtil::SetTextureParameter(unrealMaterial, FName(TEXT("RoughnessMap")), sourceFilePath, materialInfo.SpecularMap, packagePath);
		FRoadRunnerImportUtil::SetColorParameter(unrealMaterial, FName(TEXT("DiffuseColor")), materialInfo.DiffuseColor, alphaVal);
		FRoadRunnerImportUtil::SetScalarParameter(unrealMaterial, FName(TEXT("Emission")), materialInfo.Emission);
		FRoadRunnerImportUtil::SetScalarParameter(unrealMaterial, FName(TEXT("ScalingU")), materialInfo.TextureScaleU);
		FRoadRunnerImportUtil::SetScalarParameter(unrealMaterial, FName(TEXT("ScalingV")), materialInfo.TextureScaleV);
		unrealMaterial->PreEditChange(nullptr);
		unrealMaterial->PostEditChange();
		int32 adjustedDrawQueue = FCString::Atoi(*materialInfo.DrawQueue);
		if (isTransparent && materialInfo.IsDecal.Equals("false"))
		{
			adjustedDrawQueue = FRoadRunnerImporterModule::TransparentRenderQueue;
		}
		materialToLayerMap.Add(materialFullName, adjustedDrawQueue);
	}
void CreateRoadRunnerMaterial ( FString sourceFilePath , FString packagePath , FRoadRunnerImportUtil :: MaterialInfo materialInfo , int metadataVersion , TMap < FString , int32 > & materialToLayerMap ) { FString materialFullName = materialInfo . Name ; FString basePackageName = FPackageName :: GetLongPackagePath ( packagePath ) / materialFullName ; basePackageName = PackageTools :: SanitizePackageName ( basePackageName ) ; const FString Suffix ( TEXT ( " " ) ) ; UPackage * package = CreatePackage ( NULL , * basePackageName ) ; FText materialSearchError ; UMaterialInterface * baseMaterial = nullptr ; float alphaVal = 1.0f ; float transparency = 0.0f ; if ( ! materialInfo . TransparencyFactor . IsEmpty ( ) ) { transparency = FCString :: Atof ( * ( materialInfo . TransparencyFactor ) ) ; } bool isTransparent = ! materialInfo . TransparencyMap . IsEmpty ( ) || transparency > 0 ; FString materialName = " " ; alphaVal = 1.0f - transparency ; if ( metadataVersion >= 1 ) { if ( materialInfo . IsDecal . Equals ( " " ) || ! materialInfo . DrawQueue . Equals ( " " ) ) { materialName = " " ; } else if ( isTransparent ) { if ( materialInfo . TwoSided . Equals ( " " ) ) { if ( materialInfo . ShadowCaster . Equals ( " " ) ) { materialName = " " ; } else { materialName = " " ; } } else { if ( materialInfo . ShadowCaster . Equals ( " " ) ) { materialName = " " ; } else { materialName = " " ; } } } } else { if ( isTransparent ) { if ( materialInfo . TwoSided . Equals ( " " ) ) { if ( transparency > 0.0f ) { materialName = " " ; } else { materialName = " " ; } } else { if ( transparency > 0.0f ) { materialName = " " ; } else { materialName = " " ; } } } } baseMaterial = UMaterialImportHelpers :: FindExistingMaterialFromSearchLocation ( materialName , " " , EMaterialSearchLocation :: UnderParent , materialSearchError ) ; if ( ! materialSearchError . IsEmpty ( ) || baseMaterial == nullptr ) { UE_LOG ( RoadRunnerImporter , Error , TEXT ( " " ) , * ( materialSearchError . ToString ( ) ) ) ; return ; } auto materialInstanceFactory = NewObject < UMaterialInstanceConstantFactoryNew > ( ) ; materialInstanceFactory -> InitialParent = baseMaterial ; UMaterialInstanceConstant * unrealMaterial = ( UMaterialInstanceConstant * ) materialInstanceFactory -> FactoryCreateNew ( UMaterialInstanceConstant :: StaticClass ( ) , package , * materialFullName , RF_Standalone | RF_Public , NULL , GWarn ) ; if ( unrealMaterial == NULL ) { UE_LOG ( RoadRunnerImporter , Error , TEXT ( " " ) , * materialInfo . Name ) ; return ; } FAssetRegistryModule :: AssetCreated ( unrealMaterial ) ; package -> SetDirtyFlag ( true ) ; FRoadRunnerImportUtil :: SetTextureParameter ( unrealMaterial , FName ( TEXT ( " " ) ) , sourceFilePath , materialInfo . DiffuseMap , packagePath ) ; FRoadRunnerImportUtil :: SetTextureParameter ( unrealMaterial , FName ( TEXT ( " " ) ) , sourceFilePath , materialInfo . NormalMap , packagePath ) ; FRoadRunnerImportUtil :: SetTextureParameter ( unrealMaterial , FName ( TEXT ( " " ) ) , sourceFilePath , materialInfo . SpecularMap , packagePath ) ; FRoadRunnerImportUtil :: SetColorParameter ( unrealMaterial , FName ( TEXT ( " " ) ) , materialInfo . DiffuseColor , alphaVal ) ; FRoadRunnerImportUtil :: SetScalarParameter ( unrealMaterial , FName ( TEXT ( " " ) ) , materialInfo . Emission ) ; FRoadRunnerImportUtil :: SetScalarParameter ( unrealMaterial , FName ( TEXT ( " " ) ) , materialInfo . TextureScaleU ) ; FRoadRunnerImportUtil :: SetScalarParameter ( unrealMaterial , FName ( TEXT ( " " ) ) , materialInfo . TextureScaleV ) ; unrealMaterial -> PreEditChange ( nullptr ) ; unrealMaterial -> PostEditChange ( ) ; int32 adjustedDrawQueue = FCString :: Atoi ( * materialInfo . DrawQueue ) ; if ( isTransparent && materialInfo . IsDecal . Equals ( " " ) ) { adjustedDrawQueue = FRoadRunnerImporterModule :: TransparentRenderQueue ; } materialToLayerMap . Add ( materialFullName , adjustedDrawQueue ) ; }
Replaces the created/existing Unreal material with a material instance from the
RoadRunnerMaterials plugin
Replaces the created / existing Unreal material with a material instance from the RoadRunnerMaterials plugin
// Create new package // Re-create package for new material instance // Find our base material to instance from // Default to opaque // Version 1 adds DrawQueue and ShadowCaster fields // Decals and markings always use decal material // Choose base material based off transparency // Translucent blend mode // Masked blend mode // Translucent blend mode // Masked blend mode // Backwards compatibility // Choose base material based off transparency // Translucent blend mode // Masked blend mode // Translucent blend mode // Masked blend mode // Create material instance from our base material // Modified: always create a material instance from our base material // Notify the asset registry // Set the dirty flag so this package will get saved later // Set parameters // Modified: set parameters based off imported material info // Note: RoadRunner is in the middle of converting to a roughness-metallic setup, so some material may not look right // Note: The default RoadRunner materials have not been tuned to the new setup yet // FRoadRunnerImportUtil::SetScalarParameter(unrealMaterial, FName(TEXT("RoughnessFactor")), materialInfo.Roughness);  // let the material update itself if necessary // Render other transparent objects after decals