RealtimeStyleTransferRuntime/Source/LyraGame/UI/IndicatorSystem/IndicatorDescriptor.cpp

124 lines
4.2 KiB
C++
Raw Permalink Normal View History

2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "IndicatorDescriptor.h"
2022-09-13 07:18:28 +00:00
2022-05-23 18:41:30 +00:00
#include "Engine/LocalPlayer.h"
2022-09-13 07:18:28 +00:00
#include "GameFramework/Actor.h"
#include "Math/Box.h"
#include "Math/BoxSphereBounds.h"
#include "Math/Transform.h"
#include "Misc/AssertionMacros.h"
#include "Misc/Optional.h"
#include "SceneView.h"
#include "UI/IndicatorSystem/LyraIndicatorManagerComponent.h"
2022-05-23 18:41:30 +00:00
bool FIndicatorProjection::Project(const UIndicatorDescriptor& IndicatorDescriptor, const FSceneViewProjectionData& InProjectionData, const FVector2D& ScreenSize, FVector& OutScreenPositionWithDepth)
{
if (USceneComponent* Component = IndicatorDescriptor.GetSceneComponent())
{
TOptional<FVector> WorldLocation;
if (IndicatorDescriptor.GetComponentSocketName() != NAME_None)
{
WorldLocation = Component->GetSocketTransform(IndicatorDescriptor.GetComponentSocketName()).GetLocation();
}
else
{
WorldLocation = Component->GetComponentLocation();
}
const FVector ProjectWorldLocation = WorldLocation.GetValue() + IndicatorDescriptor.GetWorldPositionOffset();
const EActorCanvasProjectionMode ProjectionMode = IndicatorDescriptor.GetProjectionMode();
switch (ProjectionMode)
{
case EActorCanvasProjectionMode::ComponentPoint:
{
if (WorldLocation.IsSet())
{
FVector2D OutScreenSpacePosition;
if (ULocalPlayer::GetPixelPoint(InProjectionData, ProjectWorldLocation, OutScreenSpacePosition, &ScreenSize))
{
OutScreenSpacePosition += IndicatorDescriptor.GetScreenSpaceOffset();
OutScreenPositionWithDepth = FVector(OutScreenSpacePosition.X, OutScreenSpacePosition.Y, FVector::Dist(InProjectionData.ViewOrigin, ProjectWorldLocation));
return true;
}
}
return false;
}
case EActorCanvasProjectionMode::ComponentScreenBoundingBox:
case EActorCanvasProjectionMode::ActorScreenBoundingBox:
{
FBox IndicatorBox;
if (ProjectionMode == EActorCanvasProjectionMode::ActorScreenBoundingBox)
{
IndicatorBox = Component->GetOwner()->GetComponentsBoundingBox();
}
else
{
IndicatorBox = Component->Bounds.GetBox();
}
FVector2D LL, UR;
if (ULocalPlayer::GetPixelBoundingBox(InProjectionData, IndicatorBox, LL, UR, &ScreenSize))
{
const FVector& BoundingBoxAnchor = IndicatorDescriptor.GetBoundingBoxAnchor();
const FVector2D& ScreenSpaceOffset = IndicatorDescriptor.GetScreenSpaceOffset();
OutScreenPositionWithDepth.X = FMath::Lerp(LL.X, UR.X, BoundingBoxAnchor.X) + ScreenSpaceOffset.X;
OutScreenPositionWithDepth.Y = FMath::Lerp(LL.Y, UR.Y, BoundingBoxAnchor.Y) + ScreenSpaceOffset.Y;
OutScreenPositionWithDepth.Z = FVector::Dist(InProjectionData.ViewOrigin, ProjectWorldLocation);
return true;
}
return false;
}
case EActorCanvasProjectionMode::ActorBoundingBox:
case EActorCanvasProjectionMode::ComponentBoundingBox:
{
FBox IndicatorBox;
if (ProjectionMode == EActorCanvasProjectionMode::ActorBoundingBox)
{
IndicatorBox = Component->GetOwner()->GetComponentsBoundingBox();
}
else
{
IndicatorBox = Component->Bounds.GetBox();
}
const FVector ProjectBoxPoint = IndicatorBox.GetCenter() + (IndicatorBox.GetSize() * (IndicatorDescriptor.GetBoundingBoxAnchor() - FVector(0.5)));
FVector2D OutScreenSpacePosition;
if (ULocalPlayer::GetPixelPoint(InProjectionData, ProjectBoxPoint, OutScreenSpacePosition, &ScreenSize))
{
OutScreenSpacePosition += IndicatorDescriptor.GetScreenSpaceOffset();
OutScreenPositionWithDepth = FVector(OutScreenSpacePosition.X, OutScreenSpacePosition.Y, FVector::Dist(InProjectionData.ViewOrigin, ProjectBoxPoint));
return true;
}
return false;
}
}
}
return false;
}
void UIndicatorDescriptor::SetIndicatorManagerComponent(ULyraIndicatorManagerComponent* InManager)
{
// Make sure nobody has set this.
if (ensure(ManagerPtr.IsExplicitlyNull()))
{
ManagerPtr = InManager;
}
}
void UIndicatorDescriptor::UnregisterIndicator()
{
if (ULyraIndicatorManagerComponent* Manager = ManagerPtr.Get())
{
Manager->RemoveIndicator(this);
}
}