UE4选中对象后生成BoundingBox线框

(1)需要重写Pawn对象,因为有鼠标选中事件,用到InputComponent

(2)需要继承自DefaultPawn对象,因为这个Pawn里面包含W/S/A/D等键盘事件

(3)重写里面的virtual函数,需要加上Super::该函数。例如BegainPlay,如果不加上Super::BeginPlay()则W/S/A/D消息失效,因为很多操作初始化都在BeginPlay函数中。


// Fill out your copyright notice in the Description page of Project Settings.



#pragma once


#include "GameFramework/DefaultPawn.h"
#include "MyDefaultPawn.generated.h"


/**
 * 
 */
UCLASS()
class CANVAS_API AMyDefaultPawn : public ADefaultPawn
{
GENERATED_BODY()
public:


virtual void BeginPlay() override;


virtual void SetupPlayerInputComponent(UInputComponent* InInputComponent) override;


void OnMouseDoubleClick();


void DrawLine(FVector& vStart, FVector& vEnd);


void ClearBB();


void DrawBB(const TArray<FVector>& vertices);


public: 
TArray<FVector> MakeBBVertices(FVector& vStart, FVector& vEnd);


public:
UPROPERTY()
AActor* m_pSelectedActor;


};


// Fill out your copyright notice in the Description page of Project Settings.



#include "Canvas.h"
#include "MyDefaultPawn.h"


void AMyDefaultPawn::SetupPlayerInputComponent(UInputComponent* InInputComponent)
{
Super::SetupPlayerInputComponent(InputComponent);


FInputActionKeyMapping myDoubleClick("DoubleClick", EKeys::LeftMouseButton, 0, 0, 0, 0);






GetWorld()->GetFirstPlayerController()->PlayerInput->AddActionMapping(myDoubleClick);
InputComponent->BindAction("DoubleClick", IE_DoubleClick, this, &AMyDefaultPawn::OnMouseDoubleClick);
}


void AMyDefaultPawn::BeginPlay()
{
Super::BeginPlay();


m_pSelectedActor = nullptr;
}


void AMyDefaultPawn::DrawLine(FVector& vStart, FVector& vEnd)
{
FBatchedLine batchLine;
batchLine.Start = vStart;
batchLine.End = vEnd;
batchLine.Color = FLinearColor::Green;


ULineBatchComponent* const LineBatcher = GetWorld()->PersistentLineBatcher;
if (LineBatcher != NULL)
{

LineBatcher->DrawLine(vStart, vEnd, FLinearColor::Green, 10, 2);
}
}


void AMyDefaultPawn::ClearBB()
{
ULineBatchComponent* const LineBatcher = GetWorld()->PersistentLineBatcher;
if (LineBatcher != NULL)
{


LineBatcher->Flush();
}
}


void AMyDefaultPawn::DrawBB(const TArray<FVector>& vertices)
{
FVector v0 = vertices[0];
FVector v1 = vertices[1];
FVector v2 = vertices[2];
FVector v3 = vertices[3];


FVector v4 = vertices[4];
FVector v5 = vertices[5];
FVector v6 = vertices[6];
FVector v7 = vertices[7];


//top
DrawLine(v0, v1);
DrawLine(v1, v2);
DrawLine(v2, v3);
DrawLine(v3, v0);


//bottom
DrawLine(v4, v5);
DrawLine(v5, v6);
DrawLine(v6, v7);
DrawLine(v7, v4);


//left
DrawLine(v0, v1);
DrawLine(v1, v5);
DrawLine(v5, v4);
DrawLine(v4, v0);


//right
DrawLine(v3, v2);
DrawLine(v2, v6);
DrawLine(v6, v7);
DrawLine(v7, v3);


//front
DrawLine(v1, v2);
DrawLine(v2, v6);
DrawLine(v6, v5);
DrawLine(v5, v1);


//back
DrawLine(v0, v3);
DrawLine(v3, v7);
DrawLine(v7, v4);
DrawLine(v4, v0);
}


void AMyDefaultPawn::OnMouseDoubleClick()
{
UE_LOG(LogTemp, Warning, TEXT("OnLeftMouseButtonDoubleClick!"));
FHitResult HitResult;


Cast<APlayerController>(Controller)->GetHitResultUnderCursor(ECC_Visibility, false, HitResult);
if (HitResult.bBlockingHit)
{
if (HitResult.Actor != NULL)
{
FString strName = HitResult.GetActor()->GetName();
UE_LOG(LogTemp, Warning, TEXT("%s"), *strName);


AActor* pActor = HitResult.GetActor();

//如果选择对象发生变化,则需要重新绘制
if (pActor != m_pSelectedActor)
{
//重新画之前需要把原来绘制清掉
ClearBB();


FVector vOrigin;
FVector vBoxExtent;
HitResult.Actor->GetActorBounds(true, vOrigin, vBoxExtent);


TArray<FVector> vertices = MakeBBVertices(vOrigin, vBoxExtent);
DrawBB(vertices);


//保存选中对象
m_pSelectedActor = pActor;
}
}
else
{
ClearBB();
}
}
}


TArray<FVector> AMyDefaultPawn::MakeBBVertices(FVector& vOrigin, FVector& vBoxExent)
{
TArray<FVector> result;


FVector v0;
v0.X = vOrigin.X - vBoxExent.X;
v0.Y = vOrigin.Y + vBoxExent.Y;
v0.Z = vOrigin.Z + vBoxExent.Z;


result.Add(v0);


FVector v1;
v1.X = vOrigin.X + vBoxExent.X;
v1.Y = vOrigin.Y + vBoxExent.Y;
v1.Z = vOrigin.Z + vBoxExent.Z;


result.Add(v1);


FVector v2;
v2.X = vOrigin.X + vBoxExent.X;
v2.Y = vOrigin.Y - vBoxExent.Y;
v2.Z = vOrigin.Z + vBoxExent.Z;


result.Add(v2);


FVector v3;
v3.X = vOrigin.X - vBoxExent.X;
v3.Y = vOrigin.Y - vBoxExent.Y;
v3.Z = vOrigin.Z + vBoxExent.Z;


result.Add(v3);


FVector v4;
v4.X = vOrigin.X - vBoxExent.X;
v4.Y = vOrigin.Y + vBoxExent.Y;
v4.Z = vOrigin.Z - vBoxExent.Z;


result.Add(v4);


FVector v5;
v5.X = vOrigin.X + vBoxExent.X;
v5.Y = vOrigin.Y + vBoxExent.Y;
v5.Z = vOrigin.Z - vBoxExent.Z;


result.Add(v5);


FVector v6;
v6.X = vOrigin.X + vBoxExent.X;
v6.Y = vOrigin.Y - vBoxExent.Y;
v6.Z = vOrigin.Z - vBoxExent.Z;


result.Add(v6);


FVector v7;
v7.X = vOrigin.X - vBoxExent.X;
v7.Y = vOrigin.Y - vBoxExent.Y;
v7.Z = vOrigin.Z - vBoxExent.Z;


result.Add(v7);


return result;
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要根据bounding box生成mask,可以使用VTK的`vtkExtractVOI`滤波器提取感兴趣的区域,然后将提取的区域转换为二值化的mask。 以下是一个简单的示例代码: ```c++ #include <vtkSmartPointer.h> #include <vtkExtractVOI.h> #include <vtkImageData.h> #include <vtkImageThreshold.h> #include <vtkMetaImageWriter.h> int main(int argc, char* argv[]) { // 读取图像数据 vtkSmartPointer<vtkMetaImageReader> reader = vtkSmartPointer<vtkMetaImageReader>::New(); reader->SetFileName("input.mhd"); reader->Update(); // 获取图像数据范围 double bounds[6]; reader->GetOutput()->GetBounds(bounds); // 计算bounding box的范围 double bb[6] = {xmin, xmax, ymin, ymax, zmin, zmax}; // 提取bounding box的区域 vtkSmartPointer<vtkExtractVOI> extractVOI = vtkSmartPointer<vtkExtractVOI>::New(); extractVOI->SetInputData(reader->GetOutput()); extractVOI->SetVOI(bb[0], bb[1], bb[2], bb[3], bb[4], bb[5]); extractVOI->Update(); // 将提取的区域转换为二值化的mask vtkSmartPointer<vtkImageThreshold> threshold = vtkSmartPointer<vtkImageThreshold>::New(); threshold->SetInputData(extractVOI->GetOutput()); threshold->ThresholdByLower(1); threshold->SetInValue(255); threshold->SetOutValue(0); threshold->Update(); // 输出mask数据 vtkSmartPointer<vtkMetaImageWriter> writer = vtkSmartPointer<vtkMetaImageWriter>::New(); writer->SetInputData(threshold->GetOutput()); writer->SetFileName("output.mhd"); writer->Write(); return EXIT_SUCCESS; } ``` 需要注意的是,这只是一个简单的示例代码,实际使用中需要根据具体情况进行修改和完善。另外,需要根据具体的bounding box坐标系进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值