.cpp
#include "PDIdrawingComponent.h"
#include "PrimitiveViewRelevance.h"
#include "SceneManagement.h"
#include "PrimitiveSceneProxy.h"
UPDIdrawingComponent::UPDIdrawingComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bHiddenInGame = false;
bCastDynamicShadow = false;
bDrawOnlyIfSelected = false;
}
FPrimitiveSceneProxy* UPDIdrawingComponent::CreateSceneProxy()
{
/** Represents 'How to draw primitives' to the scene manager. */
class FDraw3DAgentSceneProxy : public FPrimitiveSceneProxy
{
public:
FDraw3DAgentSceneProxy(UPDIdrawingComponent* InComponent)
: FPrimitiveSceneProxy(InComponent)
, InComponent(InComponent)
{
bWillEverBeLit = false;
}
// FPrimitiveSceneProxy interface.
virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override
{
QUICK_SCOPE_CYCLE_COUNTER(STAT_Draw3DAgentSceneProxy_GetDynamicMeshElements);
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
{
if (VisibilityMap & (1 << ViewIndex))
{
const FSceneView* View = Views[ViewIndex];
FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex);
const FMatrix& LocalToWorld = GetLocalToWorld();
// Taking into account the min and maximum drawing distance
const float DistanceSqr = (View->ViewMatrices.GetViewOrigin() - LocalToWorld.GetOrigin()).SizeSquared();
if (DistanceSqr < FMath::Square(GetMinDrawDistance()) || DistanceSqr > FMath::Square(GetMaxDrawDistance()))
{
continue;
}
InComponent->CreateDynMeshElemDelegate.ExecuteIfBound(View, PDI, LocalToWorld);
InComponent->CreateDynamicElem(PDI);
}
}
}
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override
{
const bool bVisibleForSelection = !InComponent->bDrawOnlyIfSelected || IsSelected();
const bool bShowForCollision = View->Family->EngineShowFlags.Collision && IsCollisionEnabled();
FPrimitiveViewRelevance Result;
Result.bDrawRelevance = (IsShown(View) && bVisibleForSelection) || bShowForCollision;
Result.bDynamicRelevance = true;
Result.bShadowRelevance = IsShadowCast(View);
Result.bEditorPrimitiveRelevance = UseEditorCompositing(View);
return Result;
}
virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); }
uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); }
private:
UPDIdrawingComponent* InComponent;
};
return new FDraw3DAgentSceneProxy(this);
}
FBoxSphereBounds UPDIdrawingComponent::CalcBounds(const FTransform & LocalToWorld) const
{
FBoxSphereBounds NewBounds;
NewBounds.Origin = FVector::ZeroVector;
NewBounds.BoxExtent = FVector(HALF_WORLD_MAX, HALF_WORLD_MAX, HALF_WORLD_MAX);
NewBounds.SphereRadius = FMath::Sqrt(3.0f * FMath::Square(HALF_WORLD_MAX));
return NewBounds;
}
void UPDIdrawingComponent::Refresh()
{
MarkRenderStateDirty();
}
void UPDIdrawingComponent::CreateDynamicElem_Implementation(FPrimitiveDrawProxy PrimitiveDrawProxy)
{
// Do nothing.
}
// ===================================
void UPDIdrawingComponent::DrawLine(
FPrimitiveDrawProxy PrimitiveDrawProxy,
const FVector& Start, const FVector& End, const FLinearColor& Color,
ESceneDepthPriorityGroupProxy DepthPriorityGroup, float Thickness, float DepthBias, bool bScreenSpace)
{
PrimitiveDrawProxy.PDI->DrawLine(Start, End, Color, (uint8)DepthPriorityGroup, Thickness, DepthBias, bScreenSpace);
}
void UPDIdrawingComponent::DrawPoint(
FPrimitiveDrawProxy PrimitiveDrawProxy,
const FVector& Position, const FLinearColor& Color, float PointSize,
ESceneDepthPriorityGroupProxy DepthPriorityGroup)
{
PrimitiveDrawProxy.PDI->DrawPoint(Position, Color, PointSize, (uint8)DepthPriorityGroup);
}
void UPDIdrawingComponent::DrawCircle(
FPrimitiveDrawProxy PrimitiveDrawProxy,
const FVector& Base, const FVector& X, const FVector& Y,
const FLinearColor& Color, float Radius, int32 NumSides,
ESceneDepthPriorityGroupProxy DepthPriority,
float Thickness, float DepthBias, bool bScreenSpace)
{
::DrawCircle(PrimitiveDrawProxy.PDI, Base, X, Y, Color, Radius, NumSides, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
}
void UPDIdrawingComponent::DrawDashedLine(
FPrimitiveDrawProxy PrimitiveDrawProxy,
const FVector& Start,
const FVector& End,
const FLinearColor& Color,
ESceneDepthPriorityGroupProxy DepthPriority,
float Thickness,
float DashSize,
float DepthBias,
bool bScreenSpace)
{
FVector LineDir = End - Start;
float LineLeft = (End - Start).Size();
if (LineLeft)
{
LineDir /= LineLeft;
}
const int32 nLines = FMath::CeilToInt(LineLeft / (DashSize * 2));
PrimitiveDrawProxy.PDI->AddReserveLines((uint8)DepthPriority, nLines, DepthBias != 0);
const FVector Dash = (DashSize * LineDir);
FVector DrawStart = Start;
while (LineLeft > DashSize)
{
const FVector DrawEnd = DrawStart + Dash;
PrimitiveDrawProxy.PDI->DrawLine(DrawStart, DrawEnd, Color, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
LineLeft -= 2 * DashSize;
DrawStart = DrawEnd + Dash;
}
if (LineLeft > 0.0f)
{
const FVector DrawEnd = End;
PrimitiveDrawProxy.PDI->DrawLine(DrawStart, DrawEnd, Color, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
}
}
void UPDIdrawingComponent::DrawGrid(FPrimitiveDrawProxy PrimitiveDrawProxy, const FVector & Base, float GridInterval, int32 Size, const FLinearColor & Color, ESceneDepthPriorityGroupProxy DepthPriority, float Thickness,float DepthBias, bool bScreenSpace)
{
//---x
PrimitiveDrawProxy.PDI->DrawLine(FVector(Base.X + (-1 * GridInterval*Size), Base.Y, Base.Z), FVector(Base.X + (GridInterval*Size), Base.Y, Base.Z), FLinearColor::Red, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
//----
//---y
PrimitiveDrawProxy.PDI->DrawLine(FVector(Base.X, Base.Y + (-1 * GridInterval*Size), Base.Z), FVector(Base.X, Base.Y + (GridInterval*Size), Base.Z), FLinearColor::Green, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
//----
for (int32 i = 1; i < Size; ++i)
{
FVector Stx = FVector(Base.X + (GridInterval*i),Base.Y - (GridInterval*Size),Base.Z);
PrimitiveDrawProxy.PDI->DrawLine(Stx, FVector(Stx.X, Stx.Y+2*(GridInterval*Size), Base.Z), Color, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
FVector St_x = FVector(Base.X + (GridInterval*i*-1), Base.Y - (GridInterval*Size), Base.Z);
PrimitiveDrawProxy.PDI->DrawLine(St_x, FVector(St_x.X, St_x.Y + 2 * (GridInterval*Size), Base.Z), Color, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
FVector Sty = FVector(Base.X - (GridInterval*Size), Base.Y + (GridInterval*i), Base.Z);
PrimitiveDrawProxy.PDI->DrawLine( FVector(Sty.X+ 2 * (GridInterval*Size), Sty.Y , Base.Z),Sty, Color, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
FVector St_y = FVector(Base.X - (GridInterval*Size) , Base.Y+ (GridInterval*i*-1), Base.Z);
PrimitiveDrawProxy.PDI->DrawLine(FVector(St_y.X + 2 * (GridInterval*Size), St_y.Y, Base.Z),St_y , Color, (uint8)DepthPriority, Thickness, DepthBias, bScreenSpace);
}
}