Skip to main content
added 273 characters in body
Source Link
arthur.sw
  • 291
  • 9
  • 24

Update 2

If I use

LineBatchComponent = NewObject<ULineBatchComponent>();

instead of

LineBatchComponent = CreateDefaultSubobject<ULineBatchComponent>(TEXT("LineBatcher"));

I can focus properly on the actor, but I can't see the lines anymore.

Update 2

If I use

LineBatchComponent = NewObject<ULineBatchComponent>();

instead of

LineBatchComponent = CreateDefaultSubobject<ULineBatchComponent>(TEXT("LineBatcher"));

I can focus properly on the actor, but I can't see the lines anymore.

added 3612 characters in body
Source Link
arthur.sw
  • 291
  • 9
  • 24

Update

I implemented a custom component which delegates all drawing functions to an internal ULineBatchComponent member. I unregistered this ULineBatchComponent member. The custom component is not even attached to the actor root component.

But its bounding box is still taken into account when focusing on the actor.

UPBLineBatchComponent.h

UCLASS()
class UPBLineBatchComponent : public UObject
{
    GENERATED_UCLASS_BODY()
public:
    virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const;
    void SetTransform(const FTransform &Transform);
    virtual void DrawLine(...);
    virtual void DrawPoint(...);
    void Flush();
    ULineBatchComponent* LineBatchComponent;
    FBox LocalBounds;
};

UPBLineBatchComponent.cpp

UPBLineBatchComponent::UPBLineBatchComponent( const FObjectInitializer& ObjectInitializer )
        : Super( ObjectInitializer )
{
    LineBatchComponent = CreateDefaultSubobject<ULineBatchComponent>(TEXT("LineBatcher"));
    LineBatchComponent->UnregisterComponent();
    LocalBounds = FBox(0);
    LineBatchComponent->Bounds = FBoxSphereBounds(EForceInit::ForceInitToZero);
}

FBoxSphereBounds UPBLineBatchComponent::CalcBounds(const FTransform& LocalToWorld) const
{
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds.TransformBy(LocalToWorld));
    return FBoxSphereBounds(LocalBounds.TransformBy(LocalToWorld));
}

void UPBLineBatchComponent::SetTransform(const FTransform& Transform)
{
    LocalBounds = LocalBounds.TransformBy(Transform);
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds);

    bool bDirty = false;
    for (FBatchedLine& Line : LineBatchComponent->BatchedLines)
    {
        Line.Start = Transform.TransformPosition(Line.Start);
        Line.End = Transform.TransformPosition(Line.End);
        bDirty = true;
    }

    for (FBatchedPoint& Point : LineBatchComponent->BatchedPoints)
    {
        Point.Position = Transform.TransformPosition(Point.Position);
        bDirty = true;
    }

    for (FBatchedMesh& Mesh : LineBatchComponent->BatchedMeshes)
    {
        for (FVector& Vert : Mesh.MeshVerts)
        {
            Vert = Transform.TransformPosition(Vert);
            bDirty = true;
        }
    }

    if (bDirty)
    {
        LineBatchComponent->MarkRenderStateDirty();
    }
}

void UPBLineBatchComponent::DrawLine(const FVector &Start, const FVector &End, const FLinearColor &Color, uint8 DepthPriority, float Thickness, float LifeTime)
{
    LineBatchComponent->DrawLine(Start, End, Color, DepthPriority, Thickness, LifeTime);
    LocalBounds += Start;
    LocalBounds += End;
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds);
}

void UPBLineBatchComponent::DrawPoint(const FVector &Position, const FLinearColor &Color, float PointSize, uint8 DepthPriority, float LifeTime)
{
    LineBatchComponent->DrawPoint(Position, Color, PointSize, DepthPriority, LifeTime);
    LocalBounds += Position;
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds);
}

void UPBLineBatchComponent::Flush()
{
    LineBatchComponent->Flush();
    LocalBounds = FBox(0);
    LineBatchComponent->Bounds = FBoxSphereBounds(EForceInit::ForceInitToZero);
}

Update

I implemented a custom component which delegates all drawing functions to an internal ULineBatchComponent member. I unregistered this ULineBatchComponent member. The custom component is not even attached to the actor root component.

But its bounding box is still taken into account when focusing on the actor.

UPBLineBatchComponent.h

UCLASS()
class UPBLineBatchComponent : public UObject
{
    GENERATED_UCLASS_BODY()
public:
    virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const;
    void SetTransform(const FTransform &Transform);
    virtual void DrawLine(...);
    virtual void DrawPoint(...);
    void Flush();
    ULineBatchComponent* LineBatchComponent;
    FBox LocalBounds;
};

UPBLineBatchComponent.cpp

UPBLineBatchComponent::UPBLineBatchComponent( const FObjectInitializer& ObjectInitializer )
        : Super( ObjectInitializer )
{
    LineBatchComponent = CreateDefaultSubobject<ULineBatchComponent>(TEXT("LineBatcher"));
    LineBatchComponent->UnregisterComponent();
    LocalBounds = FBox(0);
    LineBatchComponent->Bounds = FBoxSphereBounds(EForceInit::ForceInitToZero);
}

FBoxSphereBounds UPBLineBatchComponent::CalcBounds(const FTransform& LocalToWorld) const
{
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds.TransformBy(LocalToWorld));
    return FBoxSphereBounds(LocalBounds.TransformBy(LocalToWorld));
}

void UPBLineBatchComponent::SetTransform(const FTransform& Transform)
{
    LocalBounds = LocalBounds.TransformBy(Transform);
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds);

    bool bDirty = false;
    for (FBatchedLine& Line : LineBatchComponent->BatchedLines)
    {
        Line.Start = Transform.TransformPosition(Line.Start);
        Line.End = Transform.TransformPosition(Line.End);
        bDirty = true;
    }

    for (FBatchedPoint& Point : LineBatchComponent->BatchedPoints)
    {
        Point.Position = Transform.TransformPosition(Point.Position);
        bDirty = true;
    }

    for (FBatchedMesh& Mesh : LineBatchComponent->BatchedMeshes)
    {
        for (FVector& Vert : Mesh.MeshVerts)
        {
            Vert = Transform.TransformPosition(Vert);
            bDirty = true;
        }
    }

    if (bDirty)
    {
        LineBatchComponent->MarkRenderStateDirty();
    }
}

void UPBLineBatchComponent::DrawLine(const FVector &Start, const FVector &End, const FLinearColor &Color, uint8 DepthPriority, float Thickness, float LifeTime)
{
    LineBatchComponent->DrawLine(Start, End, Color, DepthPriority, Thickness, LifeTime);
    LocalBounds += Start;
    LocalBounds += End;
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds);
}

void UPBLineBatchComponent::DrawPoint(const FVector &Position, const FLinearColor &Color, float PointSize, uint8 DepthPriority, float LifeTime)
{
    LineBatchComponent->DrawPoint(Position, Color, PointSize, DepthPriority, LifeTime);
    LocalBounds += Position;
    LineBatchComponent->Bounds = FBoxSphereBounds(LocalBounds);
}

void UPBLineBatchComponent::Flush()
{
    LineBatchComponent->Flush();
    LocalBounds = FBox(0);
    LineBatchComponent->Bounds = FBoxSphereBounds(EForceInit::ForceInitToZero);
}
Source Link
arthur.sw
  • 291
  • 9
  • 24

How to handle focus on a custom actor in Unreal Engine?

I created a custom actor, placed it on my scene and selected it.

When I press "F" to focus on it, the camera zoom back very far from the scene, probably because I didn't implement the method supposed to return the bounding box of my actor.

How can I do that?