171 lines
5.9 KiB
C++
171 lines
5.9 KiB
C++
// Portage UE 5.5 - voir LPConvertAtmosphericFogCommandlet.h
|
|
|
|
#include "LPConvertAtmosphericFogCommandlet.h"
|
|
|
|
#include "Atmosphere/AtmosphericFog.h"
|
|
#include "Atmosphere/AtmosphericFogComponent.h"
|
|
#include "Components/SkyAtmosphereComponent.h"
|
|
#include "Engine/Level.h"
|
|
#include "Engine/World.h"
|
|
#include "Misc/PackageName.h"
|
|
#include "UObject/Package.h"
|
|
#include "UObject/SavePackage.h"
|
|
#include "UObject/UnrealType.h"
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogLPConvertAtmo, Log, All);
|
|
|
|
namespace
|
|
{
|
|
FString ExportProp(const FProperty* Prop, const UObject* Obj)
|
|
{
|
|
FString Text;
|
|
Prop->ExportTextItem_Direct(Text, Prop->ContainerPtrToValuePtr<void>(Obj), nullptr, nullptr, PPF_None);
|
|
return Text;
|
|
}
|
|
}
|
|
|
|
ULPConvertAtmosphericFogCommandlet::ULPConvertAtmosphericFogCommandlet()
|
|
{
|
|
IsClient = false;
|
|
IsServer = false;
|
|
IsEditor = true;
|
|
LogToConsole = true;
|
|
}
|
|
|
|
int32 ULPConvertAtmosphericFogCommandlet::Main(const FString& Params)
|
|
{
|
|
TArray<FString> Tokens, Switches;
|
|
TMap<FString, FString> ParamsMap;
|
|
ParseCommandLine(*Params, Tokens, Switches, ParamsMap);
|
|
const bool bDryRun = Switches.Contains(TEXT("DryRun"));
|
|
const FString MapPath = ParamsMap.FindRef(TEXT("Map"));
|
|
if (MapPath.IsEmpty())
|
|
{
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT("Usage : -Map=/Game/Scenes/X [-DryRun]"));
|
|
return 1;
|
|
}
|
|
|
|
const FString WorldPath = MapPath + TEXT(".") + FPackageName::GetShortName(MapPath);
|
|
UWorld* World = LoadObject<UWorld>(nullptr, *WorldPath);
|
|
if (!World || !World->PersistentLevel)
|
|
{
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT("Carte introuvable : %s"), *WorldPath);
|
|
return 1;
|
|
}
|
|
World->AddToRoot();
|
|
if (!World->bIsWorldInitialized)
|
|
{
|
|
World->InitWorld(UWorld::InitializationValues().AllowAudioPlayback(false).CreatePhysicsScene(false).CreateNavigation(false).CreateAISystem(false).ShouldSimulatePhysics(false).EnableTraceCollision(false).SetTransactional(false).CreateFXSystem(false));
|
|
}
|
|
|
|
UE_LOG(LogLPConvertAtmo, Warning, TEXT("=== AtmosphericFog -> SkyAtmosphere : %s%s ==="), *MapPath, bDryRun ? TEXT(" [DRY RUN]") : TEXT(""));
|
|
|
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
|
TArray<AAtmosphericFog*> Fogs;
|
|
for (AActor* Actor : World->PersistentLevel->Actors)
|
|
{
|
|
if (AAtmosphericFog* Fog = Cast<AAtmosphericFog>(Actor))
|
|
{
|
|
Fogs.Add(Fog);
|
|
}
|
|
}
|
|
|
|
int32 Mismatches = 0;
|
|
int32 Converted = 0;
|
|
for (AAtmosphericFog* Fog : Fogs)
|
|
{
|
|
UAtmosphericFogComponent* OldComp = Fog->GetAtmosphericFogComponent();
|
|
UE_LOG(LogLPConvertAtmo, Warning, TEXT(" %s (%s), transformation %s"), *Fog->GetName(), *Fog->GetActorLabel(), *Fog->GetActorTransform().ToString());
|
|
if (!OldComp)
|
|
{
|
|
++Mismatches;
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT(" composant absent"));
|
|
continue;
|
|
}
|
|
if (bDryRun)
|
|
{
|
|
for (TFieldIterator<FProperty> It(USkyAtmosphereComponent::StaticClass(), EFieldIteratorFlags::ExcludeSuper); It; ++It)
|
|
{
|
|
UE_LOG(LogLPConvertAtmo, Display, TEXT(" %s = %s"), *It->GetName(), *ExportProp(*It, OldComp));
|
|
}
|
|
continue;
|
|
}
|
|
|
|
FActorSpawnParameters SpawnParams;
|
|
SpawnParams.OverrideLevel = World->PersistentLevel;
|
|
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
|
ASkyAtmosphere* Sky = World->SpawnActor<ASkyAtmosphere>(ASkyAtmosphere::StaticClass(), Fog->GetActorTransform(), SpawnParams);
|
|
USkyAtmosphereComponent* NewComp = Sky ? Sky->GetComponent() : nullptr;
|
|
if (!NewComp)
|
|
{
|
|
++Mismatches;
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT(" creation du SkyAtmosphere impossible"));
|
|
continue;
|
|
}
|
|
|
|
// Valeurs effectives de toutes les proprietes declarees par USkyAtmosphereComponent.
|
|
int32 Copied = 0;
|
|
for (TFieldIterator<FProperty> It(USkyAtmosphereComponent::StaticClass(), EFieldIteratorFlags::ExcludeSuper); It; ++It)
|
|
{
|
|
It->CopyCompleteValue_InContainer(NewComp, OldComp);
|
|
++Copied;
|
|
}
|
|
NewComp->SetRelativeTransform(OldComp->GetRelativeTransform());
|
|
NewComp->SetMobility(OldComp->Mobility);
|
|
// Hors monde enregistre (commandlet), la transformation monde n'est pas recalculee d'elle-meme.
|
|
NewComp->UpdateComponentToWorld();
|
|
OldComp->UpdateComponentToWorld();
|
|
Sky->SetActorLabel(Fog->GetActorLabel());
|
|
Sky->SetFolderPath(Fog->GetFolderPath());
|
|
|
|
for (TFieldIterator<FProperty> It(USkyAtmosphereComponent::StaticClass(), EFieldIteratorFlags::ExcludeSuper); It; ++It)
|
|
{
|
|
const FString A = ExportProp(*It, OldComp);
|
|
const FString B = ExportProp(*It, NewComp);
|
|
if (A != B)
|
|
{
|
|
++Mismatches;
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT(" ECART %s : %s / %s"), *It->GetName(), *A, *B);
|
|
}
|
|
}
|
|
if (!NewComp->GetRelativeTransform().Equals(OldComp->GetRelativeTransform())
|
|
|| !NewComp->GetComponentTransform().Equals(OldComp->GetComponentTransform()))
|
|
{
|
|
++Mismatches;
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT(" ECART transformation : %s / %s"), *OldComp->GetComponentTransform().ToString(), *NewComp->GetComponentTransform().ToString());
|
|
}
|
|
UE_LOG(LogLPConvertAtmo, Warning, TEXT(" -> %s : %d propriete(s) copiee(s) et verifiee(s)"), *Sky->GetName(), Copied);
|
|
|
|
World->DestroyActor(Fog);
|
|
++Converted;
|
|
}
|
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
|
|
|
int32 Result = 0;
|
|
if (!bDryRun && Converted > 0 && Mismatches == 0)
|
|
{
|
|
UPackage* Package = World->GetOutermost();
|
|
const FString Filename = FPackageName::LongPackageNameToFilename(Package->GetName(), FPackageName::GetMapPackageExtension());
|
|
FSavePackageArgs SaveArgs;
|
|
SaveArgs.TopLevelFlags = RF_Standalone;
|
|
SaveArgs.Error = GWarn;
|
|
if (!UPackage::SavePackage(Package, World, *Filename, SaveArgs))
|
|
{
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT(" ECHEC de sauvegarde de %s"), *Filename);
|
|
Result = 1;
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogLPConvertAtmo, Warning, TEXT(" -> %s sauvegardee"), *Filename);
|
|
}
|
|
}
|
|
else if (Mismatches > 0)
|
|
{
|
|
UE_LOG(LogLPConvertAtmo, Error, TEXT(" %d ecart(s) : carte NON sauvegardee"), Mismatches);
|
|
Result = 1;
|
|
}
|
|
|
|
UE_LOG(LogLPConvertAtmo, Warning, TEXT("=== Termine : %d AtmosphericFog trouve(s), %d converti(s), %d ecart(s) ==="), Fogs.Num(), Converted, Mismatches);
|
|
World->RemoveFromRoot();
|
|
return Result;
|
|
}
|