197 lines
5.8 KiB
C++
197 lines
5.8 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "TrackInstances/MovieSceneCameraCutViewportPreviewer.h"
|
|
|
|
#if WITH_EDITOR
|
|
|
|
#include "Engine/PostProcessUtils.h"
|
|
#include "Evaluation/CameraCutPlaybackCapability.h"
|
|
#include "LevelEditorViewport.h"
|
|
#include "MovieSceneCommonHelpers.h"
|
|
#include "TrackInstances/MovieSceneCameraCutEditorHandler.h"
|
|
|
|
namespace UE::MovieScene
|
|
{
|
|
|
|
void FCameraCutViewportPreviewerTarget::Get(FLevelEditorViewportClient* InClient, FVector& OutLocation, FRotator& OutRotation, float& OutFOV, const FPostProcessSettings*& OutPP, float& OutPPWeight) const
|
|
{
|
|
if (CameraComponent)
|
|
{
|
|
OutLocation = CameraComponent->GetComponentLocation();
|
|
OutRotation = CameraComponent->GetComponentRotation();
|
|
OutFOV = CameraComponent->FieldOfView;
|
|
OutPP = &CameraComponent->PostProcessSettings;
|
|
OutPPWeight = CameraComponent->PostProcessBlendWeight;
|
|
return;
|
|
}
|
|
|
|
if (CameraActor)
|
|
{
|
|
OutLocation = CameraActor->GetActorLocation();
|
|
OutRotation = CameraActor->GetActorRotation();
|
|
OutFOV = -1.f;
|
|
OutPP = nullptr;
|
|
OutPPWeight = 0.f;
|
|
return;
|
|
}
|
|
|
|
if (PreAnimatedStorage)
|
|
{
|
|
FPreAnimatedStorageIndex StorageIndex = PreAnimatedStorage->FindStorageIndex(InClient);
|
|
if (ensureMsgf(StorageIndex.IsValid(), TEXT("Blending camera to or from editor but can't find pre-animated viewport info!")))
|
|
{
|
|
FPreAnimatedCameraCutEditorState CachedValue = PreAnimatedStorage->GetCachedValue(StorageIndex);
|
|
OutLocation = CachedValue.ViewportLocation;
|
|
OutRotation = CachedValue.ViewportRotation;
|
|
OutFOV = InClient->FOVAngle;
|
|
OutPP = nullptr;
|
|
OutPPWeight = 0.f;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Provide sensible defaults even if we somehow have incorrect data.
|
|
ensureMsgf(CameraComponent || CameraActor || PreAnimatedStorage, TEXT("Invalid viewport preview target: nothing was set!"));
|
|
OutLocation = InClient->GetViewLocation();
|
|
OutRotation = InClient->GetViewRotation();
|
|
OutFOV = InClient->ViewFOV;
|
|
OutPP = nullptr;
|
|
OutPPWeight = 0.f;
|
|
}
|
|
|
|
FCameraCutViewportPreviewer::FCameraCutViewportPreviewer()
|
|
{
|
|
}
|
|
|
|
FCameraCutViewportPreviewer::~FCameraCutViewportPreviewer()
|
|
{
|
|
if (!ensure(!bViewportModifiersRegistered))
|
|
{
|
|
ToggleViewportPreviewModifiers(false);
|
|
}
|
|
}
|
|
|
|
void FCameraCutViewportPreviewer::ToggleViewportPreviewModifiers(bool bEnabled)
|
|
{
|
|
if (GEditor == nullptr || bViewportModifiersRegistered == bEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bViewportModifiersRegistered = bEnabled;
|
|
|
|
if (bEnabled)
|
|
{
|
|
// We aren't registered with any viewport client, let's grab them all.
|
|
RegisteredViewportClients = GEditor->GetLevelViewportClients();
|
|
for (FLevelEditorViewportClient* LevelVC : RegisteredViewportClients)
|
|
{
|
|
LevelVC->ViewModifiers.AddRaw(this, &FCameraCutViewportPreviewer::ModifyViewportClientView);
|
|
}
|
|
|
|
// Also listen to viewports changing.
|
|
GEditor->OnLevelViewportClientListChanged().AddRaw(this, &FCameraCutViewportPreviewer::OnLevelViewportClientListChanged);
|
|
}
|
|
else
|
|
{
|
|
// Unregister from all the viewport clients we know of.
|
|
for (FLevelEditorViewportClient* LevelVC : RegisteredViewportClients)
|
|
{
|
|
LevelVC->ViewModifiers.RemoveAll(this);
|
|
}
|
|
RegisteredViewportClients.Reset();
|
|
|
|
// Stop listening to viewports changing.
|
|
GEditor->OnLevelViewportClientListChanged().RemoveAll(this);
|
|
}
|
|
}
|
|
|
|
void FCameraCutViewportPreviewer::SetupBlend(const FCameraCutViewportPreviewerTarget& From, const FCameraCutViewportPreviewerTarget& To, float InBlendFactor)
|
|
{
|
|
FromTarget = From;
|
|
ToTarget = To;
|
|
BlendFactor = InBlendFactor;
|
|
bApplyViewModifier = true;
|
|
}
|
|
|
|
void FCameraCutViewportPreviewer::TeardownBlend()
|
|
{
|
|
bApplyViewModifier = false;
|
|
}
|
|
|
|
void FCameraCutViewportPreviewer::ModifyViewportClientView(FEditorViewportViewModifierParams& Params)
|
|
{
|
|
if (!bApplyViewModifier)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!Params.ViewportClient->AllowsCinematicControl() || Params.ViewportClient->GetViewMode() == VMI_Unknown)
|
|
{
|
|
return;
|
|
}
|
|
|
|
FVector FromViewLocation, ToViewLocation;
|
|
FRotator FromViewRotation, ToViewRotation;
|
|
float FromViewFOV, ToViewFOV;
|
|
const FPostProcessSettings* FromPP; const FPostProcessSettings* ToPP;
|
|
float FromPPWeight, ToPPWeight;
|
|
FLevelEditorViewportClient* ViewportClient = static_cast<FLevelEditorViewportClient*>(Params.ViewportClient);
|
|
|
|
FromTarget.Get(ViewportClient, FromViewLocation, FromViewRotation, FromViewFOV, FromPP, FromPPWeight);
|
|
ToTarget.Get(ViewportClient, ToViewLocation, ToViewRotation, ToViewFOV, ToPP, ToPPWeight);
|
|
|
|
const FVector BlendedLocation = FMath::Lerp(FromViewLocation, ToViewLocation, BlendFactor);
|
|
const FRotator BlendedRotation = FMath::Lerp(FromViewRotation, ToViewRotation, BlendFactor);
|
|
const float BlendedFOV = FMath::Lerp(FromViewFOV, ToViewFOV, BlendFactor);
|
|
|
|
Params.ViewInfo.Location = BlendedLocation;
|
|
Params.ViewInfo.Rotation = BlendedRotation;
|
|
Params.ViewInfo.FOV = BlendedFOV;
|
|
|
|
if (FromPP)
|
|
{
|
|
FPostProcessUtils::OverridePostProcessSettings(Params.ViewInfo.PostProcessSettings, *FromPP);
|
|
}
|
|
if (ToPP)
|
|
{
|
|
FPostProcessUtils::BlendPostProcessSettings(Params.ViewInfo.PostProcessSettings, *ToPP, BlendFactor);
|
|
}
|
|
|
|
if (FromPP && !ToPP)
|
|
{
|
|
Params.ViewInfo.PostProcessBlendWeight = (1.f - BlendFactor);
|
|
}
|
|
else if (!FromPP && ToPP)
|
|
{
|
|
Params.ViewInfo.PostProcessBlendWeight = BlendFactor;
|
|
}
|
|
else if (FromPP && ToPP)
|
|
{
|
|
Params.ViewInfo.PostProcessBlendWeight = 1.f;
|
|
}
|
|
}
|
|
|
|
void FCameraCutViewportPreviewer::OnLevelViewportClientListChanged()
|
|
{
|
|
TSet<FLevelEditorViewportClient*> NewVCs(GEditor->GetLevelViewportClients());
|
|
TSet<FLevelEditorViewportClient*> OldVCs(RegisteredViewportClients);
|
|
|
|
// Register our callback on the new clients, remove it from the retired clients.
|
|
for (FLevelEditorViewportClient* NewVC : NewVCs.Difference(OldVCs))
|
|
{
|
|
NewVC->ViewModifiers.AddRaw(this, &FCameraCutViewportPreviewer::ModifyViewportClientView);
|
|
}
|
|
for (FLevelEditorViewportClient* OldVC : OldVCs.Difference(NewVCs))
|
|
{
|
|
OldVC->ViewModifiers.RemoveAll(this);
|
|
}
|
|
|
|
RegisteredViewportClients = NewVCs.Array();
|
|
}
|
|
|
|
} // namespace UE::MovieScene
|
|
|
|
#endif // WITH_EDITOR
|
|
|