You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Update registration flow since CreateRenderState_Concurrent can't be used to register our delegate since it needs to be initialized first (CreateSceneProxy) and in some code paths for loaded actors the call order might be different since primitive registration gets deferred (i.e. FRegisterComponentContext != nullptr). In that case initialization won't called and an ensure will fire in UnregisterDebugDrawDelegate since registration failed (was not initialized). Case 1: FRegisterComponentContext == nullptr ==> Super::CreateRenderState_Concurrent + sync CreateSceneProxy (init) + RegisterDebugDrawDelegate ==> works fine Case 2: FRegisterComponentContext != nullptr ==> Super::CreateRenderState_Concurrent + deferred CreateSceneProxy + RegisterDebugDrawDelegate (skipped since not init) + CreateSceneProxy ==> ensures in UnregisterDebugDrawDelegate Bonus: - some code analysis fixes - removed some 'CoreMinimal.h' includes - exported log category 'LogVisual' - fixed some uninitialized properties (FNavTestDebugDrawDelegateHelper, UNavMeshRenderingComponent, FNavMeshSceneProxyData) - fixed some methods hiding non-virtual from base class (GetAllocatedSize) - fixed FGameplayDebuggerCompositeSceneProxy::GetMemoryFootprint that was not considering base class allocations #rnx #jira UE-125097 #preflight 614362684778fa00016a8cad #rb mieszko.zielinski #ROBOMERGE-AUTHOR: yoan.stamant #ROBOMERGE-SOURCE: CL 17544171 in //UE5/Main/... #ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v870-17433530) [CL 17544199 by yoan stamant in ue5-release-engine-test branch]
539 lines
19 KiB
C++
539 lines
19 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "VisualLoggerRenderingActorBase.h"
|
|
#include "LogVisualizerSettings.h"
|
|
#if WITH_EDITOR
|
|
#include "GeomTools.h"
|
|
#endif // WITH_EDITOR
|
|
#include "VisualLoggerRenderingComponent.h"
|
|
#include "VisualLogger/VisualLogger.h"
|
|
|
|
namespace FDebugDrawing
|
|
{
|
|
const FVector NavOffset(0, 0, 15);
|
|
}
|
|
|
|
class UVisualLoggerRenderingComponent;
|
|
class FVisualLoggerSceneProxy final : public FDebugRenderSceneProxy
|
|
{
|
|
public:
|
|
virtual SIZE_T GetTypeHash() const override
|
|
{
|
|
static size_t UniquePointer;
|
|
return reinterpret_cast<size_t>(&UniquePointer);
|
|
}
|
|
|
|
FVisualLoggerSceneProxy(const UVisualLoggerRenderingComponent* InComponent)
|
|
: FDebugRenderSceneProxy(InComponent)
|
|
{
|
|
DrawType = SolidAndWireMeshes;
|
|
ViewFlagName = TEXT("VisLog");
|
|
ViewFlagIndex = uint32(FEngineShowFlags::FindIndexByName(*ViewFlagName));
|
|
bWantsSelectionOutline = false;
|
|
}
|
|
|
|
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override
|
|
{
|
|
FPrimitiveViewRelevance Result;
|
|
Result.bDrawRelevance = IsShown(View);
|
|
Result.bDynamicRelevance = true;
|
|
// ideally the TranslucencyRelevance should be filled out by the material, here we do it conservative
|
|
Result.bSeparateTranslucency = Result.bNormalTranslucency = IsShown(View) && GIsEditor;
|
|
return Result;
|
|
}
|
|
|
|
virtual uint32 GetMemoryFootprint(void) const override { return sizeof(*this) + GetAllocatedSize(); }
|
|
};
|
|
|
|
UVisualLoggerRenderingComponent::UVisualLoggerRenderingComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
|
|
{
|
|
}
|
|
|
|
FPrimitiveSceneProxy* UVisualLoggerRenderingComponent::CreateSceneProxy()
|
|
{
|
|
AVisualLoggerRenderingActorBase* RenderingActor = Cast<AVisualLoggerRenderingActorBase>(GetOuter());
|
|
if (RenderingActor == nullptr)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
ULogVisualizerSettings *Settings = ULogVisualizerSettings::StaticClass()->GetDefaultObject<ULogVisualizerSettings>();
|
|
FVisualLoggerSceneProxy *VLogSceneProxy = new FVisualLoggerSceneProxy(this);
|
|
VLogSceneProxy->SolidMeshMaterial = Settings->GetDebugMeshMaterial();
|
|
|
|
RenderingActor->IterateDebugShapes([VLogSceneProxy] (const AVisualLoggerRenderingActorBase::FTimelineDebugShapes& Shapes)
|
|
{
|
|
VLogSceneProxy->Spheres.Append(Shapes.Points);
|
|
VLogSceneProxy->Lines.Append(Shapes.Lines);
|
|
VLogSceneProxy->Boxes.Append(Shapes.Boxes);
|
|
VLogSceneProxy->Meshes.Append(Shapes.Meshes);
|
|
VLogSceneProxy->Cones.Append(Shapes.Cones);
|
|
VLogSceneProxy->Texts.Append(Shapes.Texts);
|
|
VLogSceneProxy->Cylinders.Append(Shapes.Cylinders);
|
|
VLogSceneProxy->ArrowLines.Append(Shapes.Arrows);
|
|
VLogSceneProxy->Capsules.Append(Shapes.Capsules);
|
|
});
|
|
|
|
#if WITH_EDITOR
|
|
if (VLogSceneProxy)
|
|
{
|
|
DebugDrawDelegateHelper.InitDelegateHelper(VLogSceneProxy);
|
|
DebugDrawDelegateHelper.RegisterDebugDrawDelegate();
|
|
}
|
|
#endif
|
|
return VLogSceneProxy;
|
|
}
|
|
|
|
FBoxSphereBounds UVisualLoggerRenderingComponent::CalcBounds(const FTransform& LocalToWorld) const
|
|
{
|
|
FBox MyBounds;
|
|
MyBounds.Init();
|
|
|
|
MyBounds = FBox(FVector(-HALF_WORLD_MAX, -HALF_WORLD_MAX, -HALF_WORLD_MAX), FVector(HALF_WORLD_MAX, HALF_WORLD_MAX, HALF_WORLD_MAX));
|
|
|
|
return MyBounds;
|
|
}
|
|
|
|
void UVisualLoggerRenderingComponent::DestroyRenderState_Concurrent()
|
|
{
|
|
#if WITH_EDITOR
|
|
DebugDrawDelegateHelper.UnregisterDebugDrawDelegate();
|
|
#endif
|
|
|
|
Super::DestroyRenderState_Concurrent();
|
|
}
|
|
|
|
AVisualLoggerRenderingActorBase::AVisualLoggerRenderingActorBase(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
USceneComponent* SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComp"));
|
|
RootComponent = SceneComponent;
|
|
|
|
RenderingComponent = CreateDefaultSubobject<UVisualLoggerRenderingComponent>(TEXT("RenderingComponent"));
|
|
}
|
|
|
|
AVisualLoggerRenderingActorBase::~AVisualLoggerRenderingActorBase()
|
|
{
|
|
}
|
|
|
|
namespace
|
|
{
|
|
static bool IsPolygonWindingCorrect(const TArray<FVector>& Verts)
|
|
{
|
|
// this will work only for convex polys, but we're assuming that all logged polygons are convex in the first place
|
|
if (Verts.Num() >= 3)
|
|
{
|
|
const FVector SurfaceNormal = FVector::CrossProduct(Verts[1] - Verts[0], Verts[2] - Verts[0]);
|
|
const float TestDot = FVector::DotProduct(SurfaceNormal, FVector(0, 0, 1));
|
|
return TestDot > 0;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static void GetPolygonMesh(const FVisualLogShapeElement* ElementToDraw, FDebugRenderSceneProxy::FMesh& TestMesh, const FVector3f& VertexOffset = FVector3f::ZeroVector)
|
|
{
|
|
TestMesh.Color = ElementToDraw->GetFColor();
|
|
|
|
FClipSMPolygon InPoly(ElementToDraw->Points.Num());
|
|
InPoly.FaceNormal = FVector(0, 0, 1);
|
|
|
|
const bool bHasCorrectWinding = IsPolygonWindingCorrect(ElementToDraw->Points);
|
|
if (bHasCorrectWinding)
|
|
{
|
|
for (int32 Index = 0; Index < ElementToDraw->Points.Num(); Index++)
|
|
{
|
|
FClipSMVertex v1;
|
|
v1.Pos = ElementToDraw->Points[Index];
|
|
InPoly.Vertices.Add(v1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 Index = ElementToDraw->Points.Num() - 1; Index >= 0; Index--)
|
|
{
|
|
FClipSMVertex v1;
|
|
v1.Pos = ElementToDraw->Points[Index];
|
|
InPoly.Vertices.Add(v1);
|
|
}
|
|
}
|
|
|
|
TArray<FClipSMTriangle> OutTris;
|
|
|
|
const bool bTriangulated = FGeomTools::TriangulatePoly(OutTris, InPoly, false);
|
|
if (bTriangulated)
|
|
{
|
|
int32 LastIndex = 0;
|
|
|
|
FGeomTools::RemoveRedundantTriangles(OutTris);
|
|
for (const auto& CurrentTri : OutTris)
|
|
{
|
|
TestMesh.Vertices.Add(FDynamicMeshVertex(CurrentTri.Vertices[0].Pos + VertexOffset));
|
|
TestMesh.Vertices.Add(FDynamicMeshVertex(CurrentTri.Vertices[1].Pos + VertexOffset));
|
|
TestMesh.Vertices.Add(FDynamicMeshVertex(CurrentTri.Vertices[2].Pos + VertexOffset));
|
|
TestMesh.Indices.Add(LastIndex++);
|
|
TestMesh.Indices.Add(LastIndex++);
|
|
TestMesh.Indices.Add(LastIndex++);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void AVisualLoggerRenderingActorBase::GetDebugShapes(const FVisualLogEntry& InEntry, bool bAddEntryLocationPointer, AVisualLoggerRenderingActorBase::FTimelineDebugShapes& DebugShapes)
|
|
{
|
|
const FVisualLogEntry* Entry = &InEntry;
|
|
const FVisualLogShapeElement* ElementToDraw = Entry->ElementsToDraw.GetData();
|
|
const int32 ElementsCount = Entry->ElementsToDraw.Num();
|
|
|
|
if (bAddEntryLocationPointer)
|
|
{
|
|
constexpr float Length = 100;
|
|
const FVector DirectionNorm = FVector(0, 0, 1).GetSafeNormal();
|
|
FVector YAxis, ZAxis;
|
|
DirectionNorm.FindBestAxisVectors(YAxis, ZAxis);
|
|
DebugShapes.Cones.Add(FDebugRenderSceneProxy::FCone(FScaleMatrix(FVector(Length)) * FMatrix(DirectionNorm, YAxis, ZAxis, Entry->Location), 5, 5, FColor::Red));
|
|
}
|
|
|
|
if (DebugShapes.LogEntriesPath.Num())
|
|
{
|
|
FVector Location = DebugShapes.LogEntriesPath[0];
|
|
for (int32 Index = 1; Index < DebugShapes.LogEntriesPath.Num(); ++Index)
|
|
{
|
|
const FVector CurrentLocation = DebugShapes.LogEntriesPath[Index];
|
|
DebugShapes.Lines.Add(FDebugRenderSceneProxy::FDebugLine(Location, CurrentLocation, FColor(160, 160, 240), 2.0));
|
|
Location = CurrentLocation;
|
|
}
|
|
}
|
|
|
|
for (int32 ElementIndex = 0; ElementIndex < ElementsCount; ++ElementIndex, ++ElementToDraw)
|
|
{
|
|
if (!FVisualLoggerFilters::Get().MatchCategoryFilters(ElementToDraw->Category.ToString(), ElementToDraw->Verbosity))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
const FVector3f CorridorOffset = FDebugDrawing::NavOffset * 1.25f;
|
|
const FColor Color = ElementToDraw->GetFColor();
|
|
|
|
switch (ElementToDraw->GetType())
|
|
{
|
|
case EVisualLoggerShapeElement::SinglePoint:
|
|
{
|
|
const float Radius = float(ElementToDraw->Radius);
|
|
const bool bDrawLabel = (ElementToDraw->Description.IsEmpty() == false);
|
|
const int32 NumPoints = ElementToDraw->Points.Num();
|
|
|
|
for (int32 Index = 0; Index < NumPoints; ++Index)
|
|
{
|
|
const FVector& Point = ElementToDraw->Points[Index];
|
|
DebugShapes.Points.Add(FDebugRenderSceneProxy::FSphere(Radius, Point, Color));
|
|
if (bDrawLabel)
|
|
{
|
|
const FString PrintString = NumPoints == 1 ? ElementToDraw->Description : FString::Printf(TEXT("%s_%d"), *ElementToDraw->Description, Index);
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(PrintString, Point, Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Polygon:
|
|
{
|
|
FDebugRenderSceneProxy::FMesh TestMesh;
|
|
GetPolygonMesh(ElementToDraw, TestMesh, CorridorOffset);
|
|
DebugShapes.Meshes.Add(TestMesh);
|
|
|
|
for (int32 VIdx = 0; VIdx < ElementToDraw->Points.Num(); VIdx++)
|
|
{
|
|
DebugShapes.Lines.Add(FDebugRenderSceneProxy::FDebugLine(
|
|
ElementToDraw->Points[VIdx] + CorridorOffset,
|
|
ElementToDraw->Points[(VIdx + 1) % ElementToDraw->Points.Num()] + CorridorOffset,
|
|
FColor::Cyan,
|
|
2)
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Mesh:
|
|
{
|
|
struct FHeaderData
|
|
{
|
|
float VerticesNum, FacesNum;
|
|
FHeaderData(const FVector& InVector) : VerticesNum(InVector.X), FacesNum(InVector.Y) {}
|
|
};
|
|
const FHeaderData HeaderData(ElementToDraw->Points[0]);
|
|
|
|
FDebugRenderSceneProxy::FMesh TestMesh;
|
|
TestMesh.Color = ElementToDraw->GetFColor();
|
|
int32 StartIndex = 1;
|
|
int32 EndIndex = StartIndex + HeaderData.VerticesNum;
|
|
for (int32 VIdx = StartIndex; VIdx < EndIndex; VIdx++)
|
|
{
|
|
TestMesh.Vertices.Add(FVector3f(ElementToDraw->Points[VIdx]));
|
|
}
|
|
|
|
|
|
StartIndex = EndIndex;
|
|
EndIndex = StartIndex + HeaderData.FacesNum;
|
|
for (int32 VIdx = StartIndex; VIdx < EndIndex; VIdx++)
|
|
{
|
|
const FVector &CurrentFace = ElementToDraw->Points[VIdx];
|
|
TestMesh.Indices.Add(CurrentFace.X);
|
|
TestMesh.Indices.Add(CurrentFace.Y);
|
|
TestMesh.Indices.Add(CurrentFace.Z);
|
|
}
|
|
DebugShapes.Meshes.Add(TestMesh);
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Segment:
|
|
{
|
|
const float Thickness = float(ElementToDraw->Thicknes);
|
|
const bool bDrawLabel = (ElementToDraw->Description.IsEmpty() == false);
|
|
const FVector* Location = ElementToDraw->Points.GetData();
|
|
const int32 NumPoints = ElementToDraw->Points.Num();
|
|
|
|
for (int32 Index = 0; Index + 1 < NumPoints; Index += 2, Location += 2)
|
|
{
|
|
DebugShapes.Lines.Add(FDebugRenderSceneProxy::FDebugLine(*Location, *(Location + 1), Color, Thickness));
|
|
|
|
if (bDrawLabel)
|
|
{
|
|
const FString PrintString = NumPoints == 2 ? ElementToDraw->Description : FString::Printf(TEXT("%s_%d"), *ElementToDraw->Description, Index / 2);
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(PrintString, (*Location + (*(Location + 1) - *Location) / 2), Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Path:
|
|
{
|
|
const float Thickness = float(ElementToDraw->Thicknes);
|
|
FVector Location = ElementToDraw->Points[0];
|
|
for (int32 Index = 1; Index < ElementToDraw->Points.Num(); ++Index)
|
|
{
|
|
const FVector CurrentLocation = ElementToDraw->Points[Index];
|
|
DebugShapes.Lines.Add(FDebugRenderSceneProxy::FDebugLine(Location, CurrentLocation, Color, Thickness));
|
|
Location = CurrentLocation;
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Box:
|
|
{
|
|
const float Thickness = float(ElementToDraw->Thicknes);
|
|
const bool bDrawLabel = (ElementToDraw->Description.IsEmpty() == false);
|
|
const FVector* BoxExtent = ElementToDraw->Points.GetData();
|
|
const int32 NumPoints = ElementToDraw->Points.Num();
|
|
|
|
for (int32 Index = 0; Index + 1 < NumPoints; Index += 2, BoxExtent += 2)
|
|
{
|
|
const FBox Box = FBox(*BoxExtent, *(BoxExtent + 1));
|
|
DebugShapes.Boxes.Add(FDebugRenderSceneProxy::FDebugBox(Box, Color, FTransform(ElementToDraw->TransformationMatrix)));
|
|
|
|
if (bDrawLabel)
|
|
{
|
|
const FString PrintString = NumPoints == 2 ? ElementToDraw->Description : FString::Printf(TEXT("%s_%d"), *ElementToDraw->Description, Index / 2);
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(PrintString, Box.GetCenter(), Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Cone:
|
|
{
|
|
const float Thickness = float(ElementToDraw->Thicknes);
|
|
const bool bDrawLabel = ElementToDraw->Description.IsEmpty() == false;
|
|
for (int32 Index = 0; Index + 2 < ElementToDraw->Points.Num(); Index += 3)
|
|
{
|
|
const FVector Origin = ElementToDraw->Points[Index];
|
|
const FVector Direction = ElementToDraw->Points[Index + 1].GetSafeNormal();
|
|
const FVector Angles = ElementToDraw->Points[Index + 2];
|
|
const float Length = Angles.X;
|
|
|
|
FVector YAxis, ZAxis;
|
|
Direction.FindBestAxisVectors(YAxis, ZAxis);
|
|
DebugShapes.Cones.Add(FDebugRenderSceneProxy::FCone(FScaleMatrix(FVector(Length)) * FMatrix(Direction, YAxis, ZAxis, Origin), Angles.Y, Angles.Z, Color));
|
|
|
|
if (bDrawLabel)
|
|
{
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(ElementToDraw->Description, Origin, Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Cylinder:
|
|
{
|
|
const float Thickness = float(ElementToDraw->Thicknes);
|
|
const bool bDrawLabel = ElementToDraw->Description.IsEmpty() == false;
|
|
for (int32 Index = 0; Index + 2 < ElementToDraw->Points.Num(); Index += 3)
|
|
{
|
|
const FVector Start = ElementToDraw->Points[Index];
|
|
const FVector End = ElementToDraw->Points[Index + 1];
|
|
const FVector OtherData = ElementToDraw->Points[Index + 2];
|
|
const float HalfHeight = 0.5f * (End - Start).Size();
|
|
const FVector Center = 0.5f * (Start + End);
|
|
DebugShapes.Cylinders.Add(FDebugRenderSceneProxy::FWireCylinder(Center, OtherData.X, HalfHeight, Color)); // Base parameter is the center of the cylinder
|
|
if (bDrawLabel)
|
|
{
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(ElementToDraw->Description, Center, Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Capsule:
|
|
{
|
|
const float Thickness = float(ElementToDraw->Thicknes);
|
|
const bool bDrawLabel = ElementToDraw->Description.IsEmpty() == false;
|
|
for (int32 Index = 0; Index + 2 < ElementToDraw->Points.Num(); Index += 3)
|
|
{
|
|
const FVector Base = ElementToDraw->Points[Index + 0];
|
|
const FVector FirstData = ElementToDraw->Points[Index + 1];
|
|
const FVector SecondData = ElementToDraw->Points[Index + 2];
|
|
const float HalfHeight = FirstData.X;
|
|
const float Radius = FirstData.Y;
|
|
const FQuat Rotation = FQuat(FirstData.Z, SecondData.X, SecondData.Y, SecondData.Z);
|
|
|
|
const FMatrix Axes = FQuatRotationTranslationMatrix(Rotation, FVector::ZeroVector);
|
|
const FVector XAxis = Axes.GetScaledAxis(EAxis::X);
|
|
const FVector YAxis = Axes.GetScaledAxis(EAxis::Y);
|
|
const FVector ZAxis = Axes.GetScaledAxis(EAxis::Z);
|
|
|
|
DebugShapes.Capsules.Add(FDebugRenderSceneProxy::FCapsule(Base, Radius, XAxis, YAxis, ZAxis, HalfHeight, Color));
|
|
if (bDrawLabel)
|
|
{
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(ElementToDraw->Description, Base + HalfHeight * FVector::UpVector, Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::NavAreaMesh:
|
|
{
|
|
if (ElementToDraw->Points.Num() == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
struct FHeaderData
|
|
{
|
|
float MinZ, MaxZ;
|
|
FHeaderData(const FVector& InVector) : MinZ(InVector.X), MaxZ(InVector.Y) {}
|
|
};
|
|
const FHeaderData HeaderData(ElementToDraw->Points[0]);
|
|
|
|
TArray<FVector> AreaMeshPoints = ElementToDraw->Points;
|
|
AreaMeshPoints.RemoveAt(0, 1, false);
|
|
AreaMeshPoints.Add(ElementToDraw->Points[1]);
|
|
TArray<FVector> Vertices;
|
|
TNavStatArray<FVector> Faces;
|
|
int32 CurrentIndex = 0;
|
|
FDebugRenderSceneProxy::FMesh TestMesh;
|
|
TestMesh.Color = ElementToDraw->GetFColor();
|
|
|
|
for (int32 PointIndex = 0; PointIndex < AreaMeshPoints.Num() - 1; PointIndex++)
|
|
{
|
|
FVector Point = AreaMeshPoints[PointIndex];
|
|
FVector NextPoint = AreaMeshPoints[PointIndex + 1];
|
|
|
|
FVector3f P1(Point.X, Point.Y, HeaderData.MinZ);
|
|
FVector3f P2(Point.X, Point.Y, HeaderData.MaxZ);
|
|
FVector3f P3(NextPoint.X, NextPoint.Y, HeaderData.MinZ);
|
|
FVector3f P4(NextPoint.X, NextPoint.Y, HeaderData.MaxZ);
|
|
|
|
TestMesh.Vertices.Add(P1); TestMesh.Vertices.Add(P2); TestMesh.Vertices.Add(P3);
|
|
TestMesh.Indices.Add(CurrentIndex + 0);
|
|
TestMesh.Indices.Add(CurrentIndex + 1);
|
|
TestMesh.Indices.Add(CurrentIndex + 2);
|
|
CurrentIndex += 3;
|
|
TestMesh.Vertices.Add(P3); TestMesh.Vertices.Add(P2); TestMesh.Vertices.Add(P4);
|
|
TestMesh.Indices.Add(CurrentIndex + 0);
|
|
TestMesh.Indices.Add(CurrentIndex + 1);
|
|
TestMesh.Indices.Add(CurrentIndex + 2);
|
|
CurrentIndex += 3;
|
|
}
|
|
DebugShapes.Meshes.Add(TestMesh);
|
|
|
|
{
|
|
FDebugRenderSceneProxy::FMesh PolygonMesh;
|
|
FVisualLogShapeElement PolygonToDraw(EVisualLoggerShapeElement::Polygon);
|
|
PolygonToDraw.SetColor(ElementToDraw->GetFColor());
|
|
PolygonToDraw.Points.Reserve(AreaMeshPoints.Num());
|
|
PolygonToDraw.Points = AreaMeshPoints;
|
|
GetPolygonMesh(&PolygonToDraw, PolygonMesh, FVector3f(0, 0, HeaderData.MaxZ));
|
|
DebugShapes.Meshes.Add(PolygonMesh);
|
|
}
|
|
|
|
for (int32 VIdx = 0; VIdx < AreaMeshPoints.Num(); VIdx++)
|
|
{
|
|
DebugShapes.Lines.Add(FDebugRenderSceneProxy::FDebugLine(
|
|
AreaMeshPoints[VIdx] + FVector(0, 0, HeaderData.MaxZ),
|
|
AreaMeshPoints[(VIdx + 1) % AreaMeshPoints.Num()] + FVector(0, 0, HeaderData.MaxZ),
|
|
ElementToDraw->GetFColor(),
|
|
2)
|
|
);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case EVisualLoggerShapeElement::Arrow:
|
|
{
|
|
const bool bDrawLabel = (ElementToDraw->Description.IsEmpty() == false);
|
|
const FVector* Location = ElementToDraw->Points.GetData();
|
|
const int32 NumPoints = ElementToDraw->Points.Num();
|
|
|
|
for (int32 Index = 0; Index + 1 < NumPoints; Index += 2, Location += 2)
|
|
{
|
|
DebugShapes.Arrows.Add(FDebugRenderSceneProxy::FArrowLine(*Location, *(Location + 1), Color));
|
|
|
|
if (bDrawLabel)
|
|
{
|
|
const FString PrintString = NumPoints == 2 ? ElementToDraw->Description : FString::Printf(TEXT("%s_%d"), *ElementToDraw->Description, Index / 2);
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(PrintString, (*Location + (*(Location + 1) - *Location) / 2), Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case EVisualLoggerShapeElement::Circle:
|
|
{
|
|
const bool bDrawLabel = (ElementToDraw->Description.IsEmpty() == false);
|
|
const int32 NumPoints = ElementToDraw->Points.Num();
|
|
|
|
for (int32 Index = 0; Index + 2 < NumPoints; Index += 3)
|
|
{
|
|
const FVector Center = ElementToDraw->Points[Index + 0];
|
|
const FVector UpAxis = ElementToDraw->Points[Index + 1];
|
|
const float Radius = ElementToDraw->Points[Index + 2].X;
|
|
const float Thickness = float(ElementToDraw->Thicknes);
|
|
|
|
const FQuat Rotation = FQuat::FindBetweenNormals(FVector::UpVector, UpAxis);
|
|
const FVector XAxis = Rotation.RotateVector(FVector::XAxisVector);
|
|
const FVector YAxis = Rotation.RotateVector(FVector::YAxisVector);
|
|
|
|
static constexpr int32 CircleDivs = 12;
|
|
FVector PrevPosition = FVector::ZeroVector;
|
|
for (int32 Div = 0; Div <= CircleDivs; Div++)
|
|
{
|
|
const float Angle = (float)Div / (float)CircleDivs * PI * 2.0f;
|
|
const FVector Position = Center + (FMath::Cos(Angle) * XAxis + FMath::Sin(Angle) * YAxis) * Radius;
|
|
if (Div > 0)
|
|
{
|
|
DebugShapes.Lines.Add(FDebugRenderSceneProxy::FDebugLine(PrevPosition, Position, Color, Thickness));
|
|
}
|
|
PrevPosition = Position;
|
|
}
|
|
|
|
if (bDrawLabel)
|
|
{
|
|
const FString PrintString = NumPoints == 3 ? ElementToDraw->Description : FString::Printf(TEXT("%s_%d"), *ElementToDraw->Description, Index / 3);
|
|
DebugShapes.Texts.Add(FDebugRenderSceneProxy::FText3d(PrintString, Center, Color));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EVisualLoggerShapeElement::Invalid:
|
|
UE_LOG(LogVisual, Warning, TEXT("Invalid element type"));
|
|
break;
|
|
|
|
default:
|
|
UE_LOG(LogVisual, Warning, TEXT("Unhandled element type: %s"), ElementToDraw->GetType());
|
|
}
|
|
}
|
|
}
|