159 lines
5.2 KiB
C++
159 lines
5.2 KiB
C++
// Portage UE 5.5 - voir LPFixSceneCaptureCommandlet.h
|
|
|
|
#include "LPFixSceneCaptureCommandlet.h"
|
|
|
|
#include "Components/SceneCaptureComponent2D.h"
|
|
#include "Engine/Level.h"
|
|
#include "Engine/SceneCapture2D.h"
|
|
#include "Engine/World.h"
|
|
#include "Misc/PackageName.h"
|
|
#include "UObject/Package.h"
|
|
#include "UObject/SavePackage.h"
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogLPFixSceneCapture, Log, All);
|
|
|
|
namespace
|
|
{
|
|
AActor* FindActorByLabelOrName(ULevel* Level, const FString& Name)
|
|
{
|
|
for (AActor* Actor : Level->Actors)
|
|
{
|
|
if (Actor && (Actor->GetActorLabel() == Name || Actor->GetName() == Name))
|
|
{
|
|
return Actor;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
ULPFixSceneCaptureCommandlet::ULPFixSceneCaptureCommandlet()
|
|
{
|
|
IsClient = false;
|
|
IsServer = false;
|
|
IsEditor = true;
|
|
LogToConsole = true;
|
|
}
|
|
|
|
int32 ULPFixSceneCaptureCommandlet::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"));
|
|
const FString ActorName = ParamsMap.FindRef(TEXT("Actor"));
|
|
const FString FromName = ParamsMap.FindRef(TEXT("From"));
|
|
FVector Offset = FVector::ZeroVector;
|
|
{
|
|
TArray<FString> Parts;
|
|
ParamsMap.FindRef(TEXT("Offset")).ParseIntoArray(Parts, TEXT(","), true);
|
|
if (Parts.Num() == 3)
|
|
{
|
|
Offset = FVector(FCString::Atod(*Parts[0]), FCString::Atod(*Parts[1]), FCString::Atod(*Parts[2]));
|
|
}
|
|
}
|
|
if (MapPath.IsEmpty() || ActorName.IsEmpty() || FromName.IsEmpty())
|
|
{
|
|
UE_LOG(LogLPFixSceneCapture, Error, TEXT("Usage : -Map=/Game/Scenes/X -Actor=<capture> -From=<acteur de reference> [-Offset=x,y,z] [-DryRun]"));
|
|
return 1;
|
|
}
|
|
|
|
const FString WorldPath = MapPath + TEXT(".") + FPackageName::GetShortName(MapPath);
|
|
UWorld* World = LoadObject<UWorld>(nullptr, *WorldPath);
|
|
if (!World || !World->PersistentLevel)
|
|
{
|
|
UE_LOG(LogLPFixSceneCapture, Error, TEXT("Carte introuvable : %s"), *WorldPath);
|
|
return 1;
|
|
}
|
|
World->AddToRoot();
|
|
|
|
ASceneCapture2D* Capture = Cast<ASceneCapture2D>(FindActorByLabelOrName(World->PersistentLevel, ActorName));
|
|
AActor* From = FindActorByLabelOrName(World->PersistentLevel, FromName);
|
|
if (!Capture || !From || !From->GetRootComponent())
|
|
{
|
|
UE_LOG(LogLPFixSceneCapture, Error, TEXT("Acteur introuvable : %s (capture) ou %s (reference, avec racine)"), *ActorName, *FromName);
|
|
World->RemoveFromRoot();
|
|
return 1;
|
|
}
|
|
|
|
USceneCaptureComponent2D* CaptureComp = Capture->GetCaptureComponent2D();
|
|
USceneComponent* NewRoot = nullptr;
|
|
for (UActorComponent* Comp : Capture->GetComponents())
|
|
{
|
|
USceneComponent* SceneComp = Cast<USceneComponent>(Comp);
|
|
if (SceneComp && SceneComp != CaptureComp && SceneComp->GetClass() == USceneComponent::StaticClass())
|
|
{
|
|
NewRoot = SceneComp;
|
|
break;
|
|
}
|
|
}
|
|
if (!NewRoot)
|
|
{
|
|
NewRoot = CaptureComp;
|
|
}
|
|
|
|
const FTransform FromTransform = From->GetRootComponent()->GetRelativeTransform();
|
|
const FTransform Target(FromTransform.GetRotation(), FromTransform.GetLocation() + Offset, FVector::OneVector);
|
|
|
|
UE_LOG(LogLPFixSceneCapture, Warning, TEXT("=== %s : racine %s -> %s, cible %s (= %s + %s)%s ==="),
|
|
*Capture->GetActorLabel(), *GetNameSafe(Capture->GetRootComponent()), *GetNameSafe(NewRoot),
|
|
*Target.ToString(), *FromName, *Offset.ToString(), bDryRun ? TEXT(" [DRY RUN]") : TEXT(""));
|
|
if (bDryRun)
|
|
{
|
|
World->RemoveFromRoot();
|
|
return 0;
|
|
}
|
|
|
|
Capture->Modify();
|
|
Capture->SetRootComponent(NewRoot);
|
|
if (CaptureComp && CaptureComp != NewRoot)
|
|
{
|
|
CaptureComp->AttachToComponent(NewRoot, FAttachmentTransformRules::KeepRelativeTransform);
|
|
CaptureComp->SetRelativeTransform(FTransform::Identity);
|
|
}
|
|
NewRoot->SetRelativeTransform(Target);
|
|
NewRoot->UpdateComponentToWorld();
|
|
if (CaptureComp && CaptureComp != NewRoot)
|
|
{
|
|
CaptureComp->UpdateComponentToWorld();
|
|
}
|
|
|
|
// Verification : racine, rattachement, position monde de la capture.
|
|
int32 Errors = 0;
|
|
if (Capture->GetRootComponent() != NewRoot) { ++Errors; UE_LOG(LogLPFixSceneCapture, Error, TEXT(" racine non affectee")); }
|
|
if (CaptureComp && CaptureComp != NewRoot && CaptureComp->GetAttachParent() != NewRoot) { ++Errors; UE_LOG(LogLPFixSceneCapture, Error, TEXT(" capture non rattachee")); }
|
|
const FTransform Final = CaptureComp ? CaptureComp->GetComponentTransform() : NewRoot->GetComponentTransform();
|
|
if (!Final.Equals(Target, 0.01))
|
|
{
|
|
++Errors;
|
|
UE_LOG(LogLPFixSceneCapture, Error, TEXT(" position finale %s differente de la cible %s"), *Final.ToString(), *Target.ToString());
|
|
}
|
|
UE_LOG(LogLPFixSceneCapture, Warning, TEXT(" capture : position monde %s"), *Final.ToString());
|
|
|
|
int32 Result = 0;
|
|
if (Errors == 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(LogLPFixSceneCapture, Warning, TEXT(" -> carte sauvegardee"));
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogLPFixSceneCapture, Error, TEXT(" ECHEC de sauvegarde"));
|
|
Result = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogLPFixSceneCapture, Error, TEXT(" %d ecart(s) : carte NON sauvegardee"), Errors);
|
|
Result = 1;
|
|
}
|
|
World->RemoveFromRoot();
|
|
return Result;
|
|
}
|