CogEngine: move CollisionTester logic inside an actor

This commit is contained in:
Arnaud Jamin
2024-01-02 00:57:02 -05:00
parent 65bd2150de
commit 7dd4922b01
12 changed files with 1118 additions and 667 deletions
@@ -1,17 +1,12 @@
#include "CogDebugGizmo.h"
#include "CogDebug.h"
#include "CogDebugDraw.h"
#include "CogDebugDrawHelper.h"
#include "CogDebugDrawImGui.h"
#include "CogImGuiHelper.h"
#include "CogWindowWidgets.h"
#include "CogWindowWidgets.h"
#include "Components/PrimitiveComponent.h"
#include "Components/SceneComponent.h"
#include "GameFramework/PlayerController.h"
#include "imgui.h"
#include "../../ThirdParty/ImGui/imgui.h"
#include "Kismet/GameplayStatics.h"
//--------------------------------------------------------------------------------------------------------------------------
@@ -163,7 +158,7 @@ void DrawGizmoText(const ImVec2& Position, ImU32 Color, const char* Text)
}
//--------------------------------------------------------------------------------------------------------------------------
bool AddTransformComponent(const char* Label, double* Value, double Reset)
bool RenderComponent(const char* Label, double* Value, double Reset)
{
ImGui::TableNextColumn();
ImGui::PushItemWidth(-1);
@@ -178,7 +173,7 @@ bool AddTransformComponent(const char* Label, double* Value, double Reset)
}
//--------------------------------------------------------------------------------------------------------------------------
void AddTransformSnap(bool* SnapEnable, float* Snap)
void RenderSnap(bool* SnapEnable, float* Snap)
{
ImGui::TableNextColumn();
ImGui::PushItemWidth(-1);
@@ -192,14 +187,14 @@ void AddTransformSnap(bool* SnapEnable, float* Snap)
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerController, FTransform& InOutTransform, ECogDebug_GizmoFlags Flags)
bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerController, FTransform& InOutTransform, ECogDebug_GizmoFlags Flags)
{
UWorld* World = InPlayerController.GetWorld();
const ImGuiViewport* Viewport = ImGui::GetMainViewport();
if (Viewport == nullptr)
{
return;
return false;
}
const FVector GizmoCenter = InOutTransform.GetTranslation();
@@ -210,11 +205,14 @@ void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
if (DraggedElementType != ECogDebug_GizmoElementType::MAX)
{
InOutTransform = InitialTransform;
return true;
}
return;
return false;
}
bool Result = false;
const ImGuiIO& IO = ImGui::GetIO();
FCogDebugSettings& Settings = FCogDebug::Settings;
@@ -420,9 +418,10 @@ void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
{
const FVector CursorOnLine = GetMouseCursorOnLine(InPlayerController, InitialTransform.GetTranslation(), DraggedElement.Direction, MousePos - CursorOffset);
const float Delta = FVector::DotProduct(DraggedElement.Direction, CursorOnLine - InitialTransform.GetTranslation());
const float SnappedDelta = FMath::GridSnap(Delta, Settings.GizmoTranslationSnapEnable ? Settings.GizmoTranslationSnap : 0.0f);
const float SnappedDelta = FMath::GridSnap(Delta, Settings.GizmoTranslationSnapEnable ? Settings.GizmoTranslationSnapValue : 0.0f);
const FVector NewLocation = InitialTransform.GetTranslation() + DraggedElement.Direction * SnappedDelta;
InOutTransform.SetLocation(NewLocation);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
@@ -446,12 +445,13 @@ void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
const FVector V = DraggedElement.Rotation.GetAxisY();
const float DeltaU = FVector::DotProduct(U, CursorOnPlane - InitialTransform.GetTranslation());
const float DeltaV = FVector::DotProduct(V, CursorOnPlane - InitialTransform.GetTranslation());
const float SnappedDeltaU = FMath::GridSnap(DeltaU, Settings.GizmoTranslationSnapEnable ? Settings.GizmoTranslationSnap : 0.0f);
const float SnappedDeltaV = FMath::GridSnap(DeltaV, Settings.GizmoTranslationSnapEnable ? Settings.GizmoTranslationSnap : 0.0f);
const float SnappedDeltaU = FMath::GridSnap(DeltaU, Settings.GizmoTranslationSnapEnable ? Settings.GizmoTranslationSnapValue : 0.0f);
const float SnappedDeltaV = FMath::GridSnap(DeltaV, Settings.GizmoTranslationSnapEnable ? Settings.GizmoTranslationSnapValue : 0.0f);
const FVector WorldDeltaU = U * SnappedDeltaU;
const FVector WorldDeltaV = V * SnappedDeltaV;
const FVector NewLocation = InitialTransform.GetTranslation() + WorldDeltaU + WorldDeltaV;
InOutTransform.SetLocation(NewLocation);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f %0.1f"), SnappedDeltaU, SnappedDeltaV);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
@@ -468,10 +468,11 @@ void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
const FVector2D DragDelta = FCogImguiHelper::ToFVector2D(ImGui::GetMouseDragDelta(ImGuiMouseButton_Left));
const float DragAmount = DragDelta.X - DragDelta.Y;
const float NormalizedAngle = FRotator::NormalizeAxis(DragAmount * Settings.GizmoRotationSpeed);
const float SnappedAngle = FMath::GridSnap(NormalizedAngle, Settings.GizmoRotationSnapEnable ? Settings.GizmoRotationSnap : 0.0f);
const float SnappedAngle = FMath::GridSnap(NormalizedAngle, Settings.GizmoRotationSnapEnable ? Settings.GizmoRotationSnapValue : 0.0f);
const FQuat RotDelta(-DraggedElement.Axis, FMath::DegreesToRadians(SnappedAngle));
const FQuat NewRot = (Settings.GizmoUseLocalSpace) ? InitialTransform.GetRotation() * RotDelta : RotDelta * InitialTransform.GetRotation();
InOutTransform.SetRotation(NewRot);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedAngle);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
@@ -484,9 +485,10 @@ void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
const FVector Point = GetMouseCursorOnLine(InPlayerController, GizmoCenter, DraggedElement.Direction, MousePos - CursorOffset);
const float Sign = FMath::Sign(FVector::DotProduct(DraggedElement.Direction, Point - GizmoCenter));
const float Delta = (Point - GizmoCenter).Length() * Sign;
const float SnappedDelta = FMath::GridSnap(Delta, Settings.GizmoScaleSnapEnable ? Settings.GizmoScaleSnap : 0.0f);
const float SnappedDelta = FMath::GridSnap(Delta, Settings.GizmoScaleSnapEnable ? Settings.GizmoScaleSnapValue : 0.0f);
const FVector NewScale = VectorMax(InitialTransform.GetScale3D() + (DraggedElement.Axis * SnappedDelta * Settings.GizmoScaleSpeed), Settings.GizmoScaleMin);
InOutTransform.SetScale3D(NewScale);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
@@ -498,9 +500,10 @@ void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
{
const FVector2D DragDelta = FCogImguiHelper::ToFVector2D(ImGui::GetMouseDragDelta(ImGuiMouseButton_Left));
const float Delta = DragDelta.X - DragDelta.Y;
const float SnappedDelta = FMath::GridSnap(Delta, Settings.GizmoScaleSnapEnable ? Settings.GizmoScaleSnap : 0.0f);
const float SnappedDelta = FMath::GridSnap(Delta, Settings.GizmoScaleSnapEnable ? Settings.GizmoScaleSnapValue : 0.0f);
const FVector NewScale = VectorMax(InitialTransform.GetScale3D() + (DraggedElement.Axis * SnappedDelta * Settings.GizmoScaleSpeed), Settings.GizmoScaleMin);
InOutTransform.SetScale3D(NewScale);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
@@ -522,69 +525,70 @@ void FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
CursorOffset = MousePos - Center2D;
InitialTransform = InOutTransform;
}
else if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
{
ImGui::OpenPopup(Id);
}
//else if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
//{
// ImGui::OpenPopup(Id);
//}
}
if (ImGui::BeginPopup(Id))
{
FVector Translation = InOutTransform.GetTranslation();
FRotator Rotation = InOutTransform.GetRotation().Rotator();
FVector Scale = InOutTransform.GetScale3D();
//if (ImGui::BeginPopup(Id))
//{
// FVector Translation = InOutTransform.GetTranslation();
// FRotator Rotation = InOutTransform.GetRotation().Rotator();
// FVector Scale = InOutTransform.GetScale3D();
ImGui::Checkbox("Local Space", &Settings.GizmoUseLocalSpace);
// ImGui::Checkbox("Local Space", &Settings.GizmoUseLocalSpace);
ImGui::Separator();
// ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(1.0f, 1.0f));
// ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(1.0f, 1.0f));
if (ImGui::BeginTable("Pools", 6, ImGuiTableFlags_SizingFixedFit))
{
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 5);
ImGui::TableSetupColumn("X", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("Y", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("Z", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("SnapEnable", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("Snap", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 3);
// if (ImGui::BeginTable("Pools", 6, ImGuiTableFlags_SizingFixedFit))
// {
// ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 5);
// ImGui::TableSetupColumn("X", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("Y", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("Z", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("SnapEnable", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("Snap", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 3);
ImGui::PushID("Location");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Location");
if (AddTransformComponent("##X", &Translation.X, 0.0)) { InOutTransform.SetTranslation(Translation); }
if (AddTransformComponent("##Y", &Translation.Y, 0.0)) { InOutTransform.SetTranslation(Translation); }
if (AddTransformComponent("##Z", &Translation.Z, 0.0)) { InOutTransform.SetTranslation(Translation); }
AddTransformSnap(&Settings.GizmoTranslationSnapEnable, &Settings.GizmoTranslationSnap);
ImGui::PopID();
// ImGui::PushID("Location");
// ImGui::TableNextRow();
// ImGui::TableNextColumn();
// ImGui::Text("Location");
// if (RenderComponent("##X", &Translation.X, 0.0)) { InOutTransform.SetTranslation(Translation); }
// if (RenderComponent("##Y", &Translation.Y, 0.0)) { InOutTransform.SetTranslation(Translation); }
// if (RenderComponent("##Z", &Translation.Z, 0.0)) { InOutTransform.SetTranslation(Translation); }
// RenderSnap(&Settings.GizmoTranslationSnapEnable, &Settings.GizmoTranslationSnapValue);
// ImGui::PopID();
ImGui::PushID("Rotation");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Rotation");
if (AddTransformComponent("##X", &Rotation.Yaw, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
if (AddTransformComponent("##Y", &Rotation.Pitch, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
if (AddTransformComponent("##Z", &Rotation.Roll, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
AddTransformSnap(&Settings.GizmoRotationSnapEnable, &Settings.GizmoRotationSnap);
ImGui::PopID();
// ImGui::PushID("Rotation");
// ImGui::TableNextRow();
// ImGui::TableNextColumn();
// ImGui::Text("Rotation");
// if (RenderComponent("##X", &Rotation.Yaw, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
// if (RenderComponent("##Y", &Rotation.Pitch, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
// if (RenderComponent("##Z", &Rotation.Roll, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
// RenderSnap(&Settings.GizmoRotationSnapEnable, &Settings.GizmoRotationSnapValue);
// ImGui::PopID();
ImGui::PushID("Scale");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Scale");
if (AddTransformComponent("##X", &Scale.X, 0.0)) { InOutTransform.SetScale3D(Scale); }
if (AddTransformComponent("##Y", &Scale.Y, 0.0)) { InOutTransform.SetScale3D(Scale); }
if (AddTransformComponent("##Z", &Scale.Z, 0.0)) { InOutTransform.SetScale3D(Scale); }
AddTransformSnap(&Settings.GizmoScaleSnapEnable, &Settings.GizmoScaleSnap);
ImGui::PopID();
// ImGui::PushID("Scale");
// ImGui::TableNextRow();
// ImGui::TableNextColumn();
// ImGui::Text("Scale");
// if (RenderComponent("##X", &Scale.X, 0.0)) { InOutTransform.SetScale3D(Scale); }
// if (RenderComponent("##Y", &Scale.Y, 0.0)) { InOutTransform.SetScale3D(Scale); }
// if (RenderComponent("##Z", &Scale.Z, 0.0)) { InOutTransform.SetScale3D(Scale); }
// RenderSnap(&Settings.GizmoScaleSnapEnable, &Settings.GizmoScaleSnapValue);
// ImGui::PopID();
ImGui::EndTable();
}
// ImGui::EndTable();
// }
ImGui::PopStyleVar();
// ImGui::PopStyleVar();
ImGui::EndPopup();
}
// ImGui::EndPopup();
//}
return Result;
}
@@ -89,7 +89,7 @@ struct FCogDebugSettings
bool GizmoTranslationSnapEnable = true;
UPROPERTY(Config)
float GizmoTranslationSnap = 10.0f;
float GizmoTranslationSnapValue = 10.0f;
UPROPERTY(Config)
float GizmoTranslationPlaneOffset = 25.0f;
@@ -101,7 +101,7 @@ struct FCogDebugSettings
bool GizmoRotationSnapEnable = true;
UPROPERTY(Config)
float GizmoRotationSnap = 10.0f;
float GizmoRotationSnapValue = 10.0f;
UPROPERTY(Config)
float GizmoRotationSpeed = 0.01f;
@@ -116,7 +116,7 @@ struct FCogDebugSettings
bool GizmoScaleSnapEnable = true;
UPROPERTY(Config)
float GizmoScaleSnap = 1.0f;
float GizmoScaleSnapValue = 1.0f;
UPROPERTY(Config)
float GizmoScaleBoxOffset = 50.0f;
@@ -75,7 +75,7 @@ struct FCogDebug_GizmoElement
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebug_Gizmo
{
void Draw(const char* Id, const APlayerController& InPlayerController, FTransform& InOutTransform, ECogDebug_GizmoFlags Flags = ECogDebug_GizmoFlags::None);
bool Draw(const char* Id, const APlayerController& InPlayerController, FTransform& InOutTransform, ECogDebug_GizmoFlags Flags = ECogDebug_GizmoFlags::None);
ECogDebug_GizmoElementType DraggedElementType = ECogDebug_GizmoElementType::MAX;
FVector2D CursorOffset = FVector2D::ZeroVector;
@@ -23,15 +23,15 @@ public class CogEngine : ModuleRules
PublicDependencyModuleNames.AddRange(
new string[]
{
"CogDebug",
}
);
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CogCommon",
"CogDebug",
"CogImgui",
"CogWindow",
"Core",
@@ -0,0 +1,509 @@
#include "CogEngineCollisionTester.h"
#include "CogDebugDrawHelper.h"
#include "CogDebug.h"
#include "Components/PrimitiveComponent.h"
#include "Components/SceneComponent.h"
//--------------------------------------------------------------------------------------------------------------------------
ACogEngineCollisionTester::ACogEngineCollisionTester(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
StartComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Start"));
RootComponent = StartComponent;
EndComponent = CreateDefaultSubobject<USceneComponent>(TEXT("End"));
EndComponent->SetupAttachment(RootComponent);
EndComponent->SetRelativeLocation(FVector(1000, 0, 0));
}
//--------------------------------------------------------------------------------------------------------------------------
bool ACogEngineCollisionTester::ShouldTickIfViewportsOnly() const
{
if (GetWorld() != nullptr && GetWorld()->WorldType == EWorldType::Editor && TickInEditor)
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineCollisionTester::Tick(float DeltaSeconds)
{
Query();
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineCollisionTester::Query()
{
AlreadyDrawnActors.Empty();
AlreadyDrawnComponents.Empty();
FVector QueryStart = StartComponent->GetComponentLocation();
FVector QueryEnd = EndComponent->GetComponentLocation();
FQuat QueryRotation = StartComponent->GetComponentQuat();
TArray<FHitResult> Hits;
TArray<FOverlapResult> Overlaps;
bool HasHits = false;
static const FName TraceTag(TEXT("FCogWindow_Collision"));
const FCollisionQueryParams QueryParams(TraceTag, SCENE_QUERY_STAT_ONLY(CogHitDetection), TraceComplex);
const FCollisionResponseTemplate* Profile = UCollisionProfile::Get()->GetProfileByIndex(ProfileIndex);
const FName ProfileName = Profile != nullptr ? Profile->Name : FName();
FCollisionShape QueryShape;
const bool bIsUsingShape = Type == ECogEngine_CollisionQueryType::Overlap || Type == ECogEngine_CollisionQueryType::Sweep;
if (bIsUsingShape)
{
switch (Shape)
{
case ECogEngine_CollisionQueryShape::Sphere: QueryShape.SetSphere(ShapeExtent.X); break;
case ECogEngine_CollisionQueryShape::Capsule: QueryShape.SetCapsule(ShapeExtent.X, ShapeExtent.Z); break;
case ECogEngine_CollisionQueryShape::Box: QueryShape.SetBox(FVector3f(ShapeExtent)); break;
}
}
switch (Type)
{
case ECogEngine_CollisionQueryType::Overlap:
{
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
HasHits = GetWorld()->OverlapMultiByChannel(Overlaps, QueryStart, QueryRotation, Channel, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
HasHits = GetWorld()->OverlapMultiByObjectType(Overlaps, QueryStart, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
HasHits = GetWorld()->OverlapMultiByProfile(Overlaps, QueryStart, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryType::LineTrace:
{
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByChannel(Hit, QueryStart, QueryEnd, Channel, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByChannel(Hits, QueryStart, QueryEnd, Channel, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByChannel(QueryStart, QueryEnd, Channel, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByObjectType(Hit, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByObjectType(Hits, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByObjectType(QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByProfile(Hit, QueryStart, QueryEnd, ProfileName, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByProfile(Hits, QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByProfile(QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
}
break;
}
}
break;
}
case ECogEngine_CollisionQueryType::Sweep:
{
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByChannel(Hit, QueryStart, QueryEnd, QueryRotation, Channel, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByChannel(Hits, QueryStart, QueryEnd, QueryRotation, Channel, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByChannel(QueryStart, QueryEnd, QueryRotation, Channel, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByObjectType(Hit, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByObjectType(Hits, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByObjectType(QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByProfile(Hit, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByProfile(Hits, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByProfile(QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
}
break;
}
}
break;
}
}
const FColor Color = HasHits ? FLinearColor(HitColor).ToFColor(true) : FLinearColor(NoHitColor).ToFColor(true);
const bool bUseTrace = Type == ECogEngine_CollisionQueryType::LineTrace || Type == ECogEngine_CollisionQueryType::Sweep;
if (bUseTrace)
{
DrawDebugDirectionalArrow(
GetWorld(),
QueryStart,
QueryEnd,
FCogDebug::Settings.ArrowSize,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
}
if (bIsUsingShape)
{
DrawShape(QueryShape, QueryStart, QueryRotation, FVector::OneVector, Color, false);
}
for (const FOverlapResult& Overlap : Overlaps)
{
if (DrawHitPrimitives)
{
DrawPrimitive(Overlap.GetComponent());
}
}
for (const FHitResult& Hit : Hits)
{
if (DrawHitLocations)
{
DrawDebugPoint(
GetWorld(),
Hit.Location,
HitPointSize,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0));
}
if (DrawHitImpactPoints)
{
DrawDebugPoint(
GetWorld(),
Hit.ImpactPoint,
HitPointSize,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0));
}
if (bIsUsingShape && DrawHitShapes)
{
DrawShape(QueryShape, Hit.Location, QueryRotation, FVector::OneVector, Color, false);
}
if (DrawHitNormals)
{
DrawDebugDirectionalArrow(
GetWorld(),
Hit.Location,
Hit.Location + Hit.Normal * 20.0f,
FCogDebug::Settings.ArrowSize,
FLinearColor(NormalColor).ToFColor(true),
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
}
if (DrawHitImpactNormals)
{
DrawDebugDirectionalArrow(
GetWorld(),
Hit.ImpactPoint,
Hit.ImpactPoint + Hit.ImpactNormal * 20.0f,
FCogDebug::Settings.ArrowSize,
FLinearColor(ImpactNormalColor).ToFColor(true),
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
}
if (DrawHitPrimitives)
{
DrawPrimitive(Hit.GetComponent());
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineCollisionTester::DrawPrimitive(const UPrimitiveComponent* PrimitiveComponent)
{
//-------------------------------------------------------
// Don't draw same primitives multiple times (for bones)
//-------------------------------------------------------
if (AlreadyDrawnComponents.Contains(PrimitiveComponent))
{
return;
}
AlreadyDrawnComponents.Add(PrimitiveComponent);
ECollisionChannel CollisionObjectType = PrimitiveComponent->GetCollisionObjectType();
FColor Color = FColor::Green; // Channels[CollisionObjectType].Color;
//-------------------------------------------------------
// Draw Name
//-------------------------------------------------------
if (DrawHitActorsNames)
{
const AActor* Actor = PrimitiveComponent->GetOwner();
if (Actor != nullptr)
{
if (AlreadyDrawnActors.Contains(Actor) == false)
{
FColor TextColor = Color.WithAlpha(255);
DrawDebugString(GetWorld(), Actor->GetActorLocation(), GetNameSafe(Actor->GetClass()), nullptr, FColor::White, 0.0f, FCogDebug::Settings.TextShadow, FCogDebug::Settings.TextSize);
AlreadyDrawnActors.Add(Actor);
}
}
}
const FVector Location = PrimitiveComponent->GetComponentLocation();
const FQuat Rotation = PrimitiveComponent->GetComponentQuat();
const FVector Scale = PrimitiveComponent->GetComponentScale();
const FCollisionShape PrimitiveShape = PrimitiveComponent->GetCollisionShape();
DrawShape(PrimitiveShape, Location, Rotation, Scale, Color, true);
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineCollisionTester::DrawShape(const FCollisionShape& InShape, const FVector& InLocation, const FQuat& InRotation, const FVector& InScale, const FColor& InColor, bool InDrawSolid) const
{
switch (InShape.ShapeType)
{
case ECollisionShape::Box:
{
//--------------------------------------------------
// see UBoxComponent::GetScaledBoxExtent()
//--------------------------------------------------
const FVector HalfExtent(InShape.Box.HalfExtentX * InScale.X, InShape.Box.HalfExtentY * InScale.Y, InShape.Box.HalfExtentZ * InScale.Z);
if (InDrawSolid)
{
DrawDebugSolidBox(
GetWorld(),
InLocation,
HalfExtent,
InRotation,
InColor,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0));
}
DrawDebugBox(
GetWorld(),
InLocation,
HalfExtent,
InRotation,
InColor,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
break;
}
case ECollisionShape::Sphere:
{
//--------------------------------------------------
// see USphereComponent::GetScaledSphereRadius()
//--------------------------------------------------
const float RadiusScale = FMath::Min(InScale.X, FMath::Min(InScale.Y, InScale.Z));
const float Radius = InShape.Sphere.Radius * RadiusScale;
FCogDebugDrawHelper::DrawSphere(
GetWorld(),
InLocation,
Radius,
FCogDebug::GetCircleSegments(),
InColor,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
break;
}
case ECollisionShape::Capsule:
{
//--------------------------------------------------
// see UCapsuleComponent::GetScaledCapsuleRadius()
//--------------------------------------------------
const float Radius = InShape.Capsule.Radius * FMath::Min(InScale.X, InScale.Y);
const float HalfHeight = InShape.Capsule.HalfHeight * UE_REAL_TO_FLOAT(InScale.Z);
DrawDebugCapsule(
GetWorld(),
InLocation,
HalfHeight,
Radius,
InRotation,
InColor,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
break;
}
}
}
@@ -1,6 +1,5 @@
#include "CogEngineWindow_CollisionTester.h"
#include "CogDebugDrawHelper.h"
#include "CogDebug.h"
#include "CogEngineDataAsset.h"
#include "CogImGuiHelper.h"
@@ -109,16 +108,6 @@ void FCogEngineWindow_CollisionTester::RenderContent()
{
Super::RenderContent();
//-------------------------------------------------
// Query Profile
//-------------------------------------------------
const UCollisionProfile* CollisionProfile = UCollisionProfile::Get();
if (CollisionProfile == nullptr)
{
return;
}
//-------------------------------------------------
// Menu
//-------------------------------------------------
@@ -148,33 +137,63 @@ void FCogEngineWindow_CollisionTester::RenderContent()
ImGui::EndMenuBar();
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Type", Config->Type);
if (ImGui::Button("Spawn Collision Tester", ImVec2(-1, 0)))
{
const FActorSpawnParameters SpawnInfo;
ACogEngineCollisionTester* Actor = GetWorld()->SpawnActor<ACogEngineCollisionTester>(SpawnInfo);
FCogDebug::SetSelection(GetWorld(), Actor);
}
ACogEngineCollisionTester* CollisionTester = Cast<ACogEngineCollisionTester>(GetSelection());
if (CollisionTester == nullptr)
{
ImGui::TextDisabled("Spawn or select a Collision Tester actor");
return;
}
const UCollisionProfile* CollisionProfile = UCollisionProfile::Get();
if (CollisionProfile == nullptr)
{
ImGui::TextDisabled("No CollisionProfile");
return;
}
if (const APlayerController* LocalPlayerController = GetLocalPlayerController())
{
FTransform Transform = CollisionTester->EndComponent->GetComponentTransform();
if (EndGizmo.Draw("CollisionTesterEndGizmo", *LocalPlayerController, Transform, ECogDebug_GizmoFlags::NoRotation | ECogDebug_GizmoFlags::NoScale))
{
CollisionTester->EndComponent->SetWorldTransform(Transform);
}
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Mode", Config->Mode);
FCogWindowWidgets::ComboboxEnum("Type", CollisionTester->Type);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("By", Config->By);
FCogWindowWidgets::ComboboxEnum("Mode", CollisionTester->Mode);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("By", CollisionTester->By);
//-------------------------------------------------
// Channel
//-------------------------------------------------
if (Config->By == ECogEngine_CollisionQueryBy::Channel)
if (CollisionTester->By == ECogEngine_CollisionQueryBy::Channel)
{
FCogWindowWidgets::SetNextItemToShortWidth();
ECollisionChannel Channel = Config->Channel.GetValue();
ECollisionChannel Channel = CollisionTester->Channel.GetValue();
if (RenderComboCollisionChannel("Channel", *CollisionProfile, Channel, Asset->Channels))
{
Config->Channel = Channel;
CollisionTester->Channel = Channel;
}
}
//-------------------------------------------------
// Profile
//-------------------------------------------------
else if (Config->By == ECogEngine_CollisionQueryBy::Profile)
else if (CollisionTester->By == ECogEngine_CollisionQueryBy::Profile)
{
const FCollisionResponseTemplate* SelectedProfile = CollisionProfile->GetProfileByIndex(Config->ProfileIndex);
const FCollisionResponseTemplate* SelectedProfile = CollisionProfile->GetProfileByIndex(CollisionTester->ProfileIndex);
const FName SelectedProfileName = SelectedProfile != nullptr ? SelectedProfile->Name : FName("Custom");
FCogWindowWidgets::SetNextItemToShortWidth();
@@ -185,9 +204,9 @@ void FCogEngineWindow_CollisionTester::RenderContent()
const FCollisionResponseTemplate* Profile = CollisionProfile->GetProfileByIndex(i);
if (ImGui::Selectable(TCHAR_TO_ANSI(*Profile->Name.ToString()), false))
{
Config->ProfileIndex = i;
Config->ObjectTypesToQuery = 0;
SelectedProfile = CollisionProfile->GetProfileByIndex(Config->ProfileIndex);
CollisionTester->ProfileIndex = i;
CollisionTester->ObjectTypesToQuery = 0;
SelectedProfile = CollisionProfile->GetProfileByIndex(CollisionTester->ProfileIndex);
if (Profile->CollisionEnabled != ECollisionEnabled::NoCollision)
{
@@ -196,7 +215,7 @@ void FCogEngineWindow_CollisionTester::RenderContent()
const ECollisionResponse Response = Profile->ResponseToChannels.GetResponse((ECollisionChannel)j);
if (Response != ECR_Ignore)
{
Config->ObjectTypesToQuery |= ECC_TO_BITFIELD(j);
CollisionTester->ObjectTypesToQuery |= ECC_TO_BITFIELD(j);
}
}
}
@@ -206,40 +225,40 @@ void FCogEngineWindow_CollisionTester::RenderContent()
}
}
ImGui::Checkbox("Complex", &Config->TraceComplex);
ImGui::Checkbox("Complex", &CollisionTester->TraceComplex);
//-------------------------------------------------
// Shape
//-------------------------------------------------
if (Config->Type != ECogEngine_CollisionQueryType::LineTrace)
if (CollisionTester->Type != ECogEngine_CollisionQueryType::LineTrace)
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Shape", Config->Shape);
FCogWindowWidgets::ComboboxEnum("Shape", CollisionTester->Shape);
switch (Config->Shape)
switch (CollisionTester->Shape)
{
case ECogEngine_CollisionQueryShape::Sphere:
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragDouble("Sphere Radius", &Config->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f");
FCogImguiHelper::DragDouble("Sphere Radius", &CollisionTester->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f");
break;
}
case ECogEngine_CollisionQueryShape::Box:
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragFVector("Box Extent", Config->ShapeExtent, 0.1f, 0, FLT_MAX, "%.1f");
FCogImguiHelper::DragFVector("Box Extent", CollisionTester->ShapeExtent, 0.1f, 0, FLT_MAX, "%.1f");
break;
}
case ECogEngine_CollisionQueryShape::Capsule:
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragDouble("Capsule Radius", &Config->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f");
FCogImguiHelper::DragDouble("Capsule Radius", &CollisionTester->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragDouble("Capsule Half Height", &Config->ShapeExtent.Z, 0.1f, 0, FLT_MAX, "%.1f");
FCogImguiHelper::DragDouble("Capsule Half Height", &CollisionTester->ShapeExtent.Z, 0.1f, 0, FLT_MAX, "%.1f");
break;
}
}
@@ -250,517 +269,18 @@ void FCogEngineWindow_CollisionTester::RenderContent()
//-------------------------------------------------
// Channels
//-------------------------------------------------
if (Config->By == ECogEngine_CollisionQueryBy::Profile)
if (CollisionTester->By == ECogEngine_CollisionQueryBy::Profile)
{
ImGui::BeginDisabled();
RenderCollisionProfileChannels(*CollisionProfile, Config->ObjectTypesToQuery, Asset->Channels);
RenderCollisionProfileChannels(*CollisionProfile, CollisionTester->ObjectTypesToQuery, Asset->Channels);
ImGui::EndDisabled();
}
else if (Config->By == ECogEngine_CollisionQueryBy::ObjectType)
else if (CollisionTester->By == ECogEngine_CollisionQueryBy::ObjectType)
{
RenderCollisionProfileChannels(*CollisionProfile, Config->ObjectTypesToQuery, Asset->Channels);
}
Query();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionTester::Query()
{
AlreadyDrawnActors.Empty();
AlreadyDrawnComponents.Empty();
const APlayerController* PlayerController = GetLocalPlayerController();
if (PlayerController == nullptr)
{
return;
}
FVector QueryStart = Config->LocationStart;
FVector QueryEnd = Config->LocationEnd;
FQuat QueryRotation = FQuat(Config->Rotation);
TArray<FHitResult> Hits;
TArray<FOverlapResult> Overlaps;
bool HasHits = false;
static const FName TraceTag(TEXT("FCogWindow_Collision"));
const FCollisionQueryParams QueryParams(TraceTag, SCENE_QUERY_STAT_ONLY(CogHitDetection), Config->TraceComplex);
const FCollisionResponseTemplate* Profile = UCollisionProfile::Get()->GetProfileByIndex(Config->ProfileIndex);
const FName ProfileName = Profile != nullptr ? Profile->Name : FName();
FCollisionShape QueryShape;
const bool bIsUsingShape = Config->Type == ECogEngine_CollisionQueryType::Overlap || Config->Type == ECogEngine_CollisionQueryType::Sweep;
if (bIsUsingShape)
{
switch (Config->Shape)
{
case ECogEngine_CollisionQueryShape::Sphere: QueryShape.SetSphere(Config->ShapeExtent.X); break;
case ECogEngine_CollisionQueryShape::Capsule: QueryShape.SetCapsule(Config->ShapeExtent.X, Config->ShapeExtent.Z); break;
case ECogEngine_CollisionQueryShape::Box: QueryShape.SetBox(FVector3f(Config->ShapeExtent)); break;
}
}
switch (Config->Type)
{
case ECogEngine_CollisionQueryType::Overlap:
{
switch (Config->By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
HasHits = GetWorld()->OverlapMultiByChannel(Overlaps, QueryStart, QueryRotation, Config->Channel, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery;
HasHits = GetWorld()->OverlapMultiByObjectType(Overlaps, QueryStart, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
HasHits = GetWorld()->OverlapMultiByProfile(Overlaps, QueryStart, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryType::LineTrace:
{
switch (Config->By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (Config->Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByChannel(Hit, QueryStart, QueryEnd, Config->Channel, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByChannel(Hits, QueryStart, QueryEnd, Config->Channel, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByChannel(QueryStart, QueryEnd, Config->Channel, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery;
switch (Config->Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByObjectType(Hit, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByObjectType(Hits, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByObjectType(QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
switch (Config->Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByProfile(Hit, QueryStart, QueryEnd, ProfileName, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByProfile(Hits, QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByProfile(QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
}
break;
}
}
break;
}
case ECogEngine_CollisionQueryType::Sweep:
{
switch (Config->By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (Config->Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByChannel(Hit, QueryStart, QueryEnd, QueryRotation, Config->Channel, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByChannel(Hits, QueryStart, QueryEnd, QueryRotation, Config->Channel, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByChannel(QueryStart, QueryEnd, QueryRotation, Config->Channel, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery;
switch (Config->Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByObjectType(Hit, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByObjectType(Hits, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByObjectType(QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
switch (Config->Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByProfile(Hit, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByProfile(Hits, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByProfile(QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
}
break;
}
}
break;
}
}
const FColor Color = HasHits ? FLinearColor(Config->HitColor).ToFColor(true) : FLinearColor(Config->NoHitColor).ToFColor(true);
const bool bUseTrace = Config->Type == ECogEngine_CollisionQueryType::LineTrace || Config->Type == ECogEngine_CollisionQueryType::Sweep;
if (bUseTrace)
{
DrawDebugDirectionalArrow(
GetWorld(),
QueryStart,
QueryEnd,
FCogDebug::Settings.ArrowSize,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
}
if (bIsUsingShape)
{
DrawShape(QueryShape, QueryStart, QueryRotation, FVector::OneVector, Color, false);
}
for (const FOverlapResult& Overlap : Overlaps)
{
if (Config->DrawHitPrimitives)
{
DrawPrimitive(Overlap.GetComponent());
}
}
for (const FHitResult& Hit : Hits)
{
if (Config->DrawHitLocations)
{
DrawDebugPoint(
GetWorld(),
Hit.Location,
Config->HitPointSize,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0));
}
if (Config->DrawHitImpactPoints)
{
DrawDebugPoint(
GetWorld(),
Hit.ImpactPoint,
Config->HitPointSize,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0));
}
if (bIsUsingShape && Config->DrawHitShapes)
{
DrawShape(QueryShape, Hit.Location, QueryRotation, FVector::OneVector, Color, false);
}
if (Config->DrawHitNormals)
{
DrawDebugDirectionalArrow(
GetWorld(),
Hit.Location,
Hit.Location + Hit.Normal * 20.0f,
FCogDebug::Settings.ArrowSize,
FLinearColor(Config->NormalColor).ToFColor(true),
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
}
if (Config->DrawHitImpactNormals)
{
DrawDebugDirectionalArrow(
GetWorld(),
Hit.ImpactPoint,
Hit.ImpactPoint + Hit.ImpactNormal * 20.0f,
FCogDebug::Settings.ArrowSize,
FLinearColor(Config->ImpactNormalColor).ToFColor(true),
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
}
if (Config->DrawHitPrimitives)
{
DrawPrimitive(Hit.GetComponent());
}
}
if (const APlayerController* LocalPlayerController = GetLocalPlayerController())
{
FVector ScaleStart(Config->ShapeExtent);
FTransform TransformStart(QueryRotation, QueryStart, ScaleStart);
GizmoStart.Draw("Query Start", *LocalPlayerController, TransformStart);
Config->LocationStart = TransformStart.GetLocation();
Config->Rotation = FRotator(TransformStart.GetRotation());
Config->ShapeExtent = TransformStart.GetScale3D();
if (Config->Type != ECogEngine_CollisionQueryType::Overlap)
{
FTransform TransformEnd(FRotator::ZeroRotator, QueryEnd, FVector::OneVector);
GizmoEnd.Draw("Query End", *LocalPlayerController, TransformEnd, ECogDebug_GizmoFlags::NoRotation | ECogDebug_GizmoFlags::NoScale);
Config->LocationEnd = TransformEnd.GetLocation();
}
RenderCollisionProfileChannels(*CollisionProfile, CollisionTester->ObjectTypesToQuery, Asset->Channels);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionTester::DrawPrimitive(const UPrimitiveComponent* PrimitiveComponent)
{
//-------------------------------------------------------
// Don't draw same primitives multiple times (for bones)
//-------------------------------------------------------
if (AlreadyDrawnComponents.Contains(PrimitiveComponent))
{
return;
}
AlreadyDrawnComponents.Add(PrimitiveComponent);
ECollisionChannel CollisionObjectType = PrimitiveComponent->GetCollisionObjectType();
FColor Color = Channels[CollisionObjectType].Color;
//-------------------------------------------------------
// Draw Name
//-------------------------------------------------------
if (Config->DrawHitActorsNames)
{
const AActor* Actor = PrimitiveComponent->GetOwner();
if (Actor != nullptr)
{
if (AlreadyDrawnActors.Contains(Actor) == false)
{
FColor TextColor = Color.WithAlpha(255);
DrawDebugString(GetWorld(), Actor->GetActorLocation(), GetNameSafe(Actor->GetClass()), nullptr, FColor::White, 0.0f, FCogDebug::Settings.TextShadow, FCogDebug::Settings.TextSize);
AlreadyDrawnActors.Add(Actor);
}
}
}
const FVector Location = PrimitiveComponent->GetComponentLocation();
const FQuat Rotation = PrimitiveComponent->GetComponentQuat();
const FVector Scale = PrimitiveComponent->GetComponentScale();
const FCollisionShape Shape = PrimitiveComponent->GetCollisionShape();
DrawShape(Shape, Location, Rotation, Scale, Color, true);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionTester::DrawShape(const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, const FVector& Scale, const FColor& Color, bool DrawSolid) const
{
switch (Shape.ShapeType)
{
case ECollisionShape::Box:
{
//--------------------------------------------------
// see UBoxComponent::GetScaledBoxExtent()
//--------------------------------------------------
const FVector HalfExtent(Shape.Box.HalfExtentX * Scale.X, Shape.Box.HalfExtentY * Scale.Y, Shape.Box.HalfExtentZ * Scale.Z);
if (DrawSolid)
{
DrawDebugSolidBox(
GetWorld(),
Location,
HalfExtent,
Rotation,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0));
}
DrawDebugBox(
GetWorld(),
Location,
HalfExtent,
Rotation,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
break;
}
case ECollisionShape::Sphere:
{
//--------------------------------------------------
// see USphereComponent::GetScaledSphereRadius()
//--------------------------------------------------
const float RadiusScale = FMath::Min(Scale.X, FMath::Min(Scale.Y, Scale.Z));
const float Radius = Shape.Sphere.Radius * RadiusScale;
FCogDebugDrawHelper::DrawSphere(
GetWorld(),
Location,
Radius,
FCogDebug::GetCircleSegments(),
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
break;
}
case ECollisionShape::Capsule:
{
//--------------------------------------------------
// see UCapsuleComponent::GetScaledCapsuleRadius()
//--------------------------------------------------
const float Radius = Shape.Capsule.Radius * FMath::Min(Scale.X, Scale.Y);
const float HalfHeight = Shape.Capsule.HalfHeight * UE_REAL_TO_FLOAT(Scale.Z);
DrawDebugCapsule(
GetWorld(),
Location,
HalfHeight,
Radius,
Rotation,
Color,
false,
0.0f,
FCogDebug::GetDebugDepthPriority(0),
FCogDebug::GetDebugThickness(0.0f));
break;
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionTester::SetAsset(const UCogEngineDataAsset* Value)
{
@@ -205,7 +205,7 @@ void FCogEngineWindow_DebugSettings::RenderContent()
ImGui::Checkbox("Gizmo Translation Snap Enable", &Settings.GizmoTranslationSnapEnable);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Gizmo Translation Snap", &Settings.GizmoTranslationSnap, 0.1f, 0.0f, 1000.0f, "%.1f");
ImGui::DragFloat("Gizmo Translation Snap", &Settings.GizmoTranslationSnapValue, 0.1f, 0.0f, 1000.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Gizmo Translation Axis Length", &Settings.GizmoTranslationAxisLength, 0.1f, 0.1f, 500.0f, "%.1f");
@@ -220,7 +220,7 @@ void FCogEngineWindow_DebugSettings::RenderContent()
ImGui::Checkbox("Gizmo Rotation Snap Enable", &Settings.GizmoRotationSnapEnable);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Gizmo Rotation Snap", &Settings.GizmoRotationSnap, 0.1f, 0.0f, 360.0f, "%.1f");
ImGui::DragFloat("Gizmo Rotation Snap", &Settings.GizmoRotationSnapValue, 0.1f, 0.0f, 360.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Gizmo Rotation Speed", &Settings.GizmoRotationSpeed, 0.01f, 0.01f, 100.0f, "%.2f");
@@ -235,7 +235,7 @@ void FCogEngineWindow_DebugSettings::RenderContent()
ImGui::Checkbox("Gizmo Scale Snap Enable", &Settings.GizmoScaleSnapEnable);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Gizmo Scale Snap", &Settings.GizmoScaleSnap, 0.1f, 0.0f, 10.0f, "%.1f");
ImGui::DragFloat("Gizmo Scale Snap", &Settings.GizmoScaleSnapValue, 0.1f, 0.0f, 10.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Gizmo Scale Box Offset", &Settings.GizmoScaleBoxOffset, 0.0f, 0.0f, 500.0f, "%.1f");
@@ -0,0 +1,256 @@
#include "CogEngineWindow_Transform.h"
#include "CogDebug.h"
#include "CogImGuiHelper.h"
#include "CogWindowWidgets.h"
#include "imgui.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Transform::Initialize()
{
Super::Initialize();
Config = GetConfig<UCogEngineConfig_Transform>();
bHasMenu = true;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Transform::RenderHelp()
{
ImGui::Text(
"This window can be used to modify the transform of the selected actor."
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Transform::RenderContent()
{
Super::RenderContent();
AActor* Selection = GetSelection();
if (Selection == nullptr)
{
ImGui::TextDisabled("No Selection");
return;
}
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
{
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Drag Speed Location", &Config->LocationSpeed, 0.1f, 0.1f, 100.0f);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Drag Speed Rotation", &Config->RotationSpeed, 0.1f, 0.1f, 100.0f);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Drag Speed Scale", &Config->ScaleSpeed, 0.1f, 0.1f, 100.0f);
ImGui::SeparatorText("Gizmo");
FCogDebugSettings& Settings = FCogDebug::Settings;
ImGui::Checkbox("Local Space Gizmo", &Settings.GizmoUseLocalSpace);
RenderSnap("##Location", "Snap Location", &Settings.GizmoTranslationSnapEnable, &Settings.GizmoTranslationSnapValue);
RenderSnap("##Rotation", "Snap Rotation", &Settings.GizmoRotationSnapEnable, &Settings.GizmoRotationSnapValue);
RenderSnap("##Scale", "Snap Scale", &Settings.GizmoScaleSnapEnable, &Settings.GizmoScaleSnapValue);
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
FTransform Transform = Selection->GetActorTransform();
if (RenderTransform(Transform))
{
Selection->SetActorTransform(Transform);
}
if (const APlayerController* LocalPlayerController = GetLocalPlayerController())
{
if (Gizmo.Draw("Transform", *LocalPlayerController, Transform))
{
Selection->SetActorTransform(Transform);
}
}
ImGui::PopStyleVar();
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Transform::RenderComponent(const char* Label, double* Value, float Speed, double Min, double Max, double Reset)
{
ImGui::PushItemWidth(-1);
bool Result = FCogImguiHelper::DragDouble(Label, Value, Speed, Min, Max, "%.2f");
if (ImGui::IsItemActive() && ImGui::TempInputIsActive(ImGui::GetActiveID()))
{
Result = false;
}
if (ImGui::BeginItemTooltip())
{
ImGui::Text("%.2f", *Value);
ImGui::TextDisabled("Reset [RMB]");
ImGui::EndTooltip();
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
*Value = Reset;
Result = true;
}
ImGui::PopItemWidth();
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Transform::RenderSnap(const char* CheckboxLabel, const char* InputLabel, bool* SnapEnable, float* Snap)
{
ImGui::Checkbox(CheckboxLabel, SnapEnable);
ImGui::SameLine();
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat(InputLabel, Snap, 0.1f, 0.1f, 1000.0f, "%.1f");
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Transform::RenderLocation(FTransform& InOutTransform)
{
ImGui::PushID("Location");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Location");
FVector Location = InOutTransform.GetTranslation();
bool Result = false;
ImGui::TableNextColumn();
if (RenderComponent("##X", &Location.X, Config->LocationSpeed, 0.0, 0.0, 0.0))
{
InOutTransform.SetTranslation(Location);
Result = true;
}
ImGui::TableNextColumn();
if (RenderComponent("##Y", &Location.Y, Config->LocationSpeed, 0.0, 0.0, 0.0))
{
InOutTransform.SetTranslation(Location);
Result = true;
}
ImGui::TableNextColumn();
if (RenderComponent("##Z", &Location.Z, Config->LocationSpeed, 0.0, 0.0, 0.0))
{
InOutTransform.SetTranslation(Location);
Result = true;
}
ImGui::PopID();
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Transform::RenderRotation(FTransform& InOutTransform)
{
ImGui::PushID("Rotation");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Rotation");
FRotator Rotation = InOutTransform.GetRotation().Rotator();
bool Result = false;
ImGui::TableNextColumn();
if (RenderComponent("##X", &Rotation.Yaw, Config->RotationSpeed, 0.0, 0.0, 0.0))
{
InOutTransform.SetRotation(Rotation.Quaternion());
Result = true;
}
ImGui::TableNextColumn();
if (RenderComponent("##Y", &Rotation.Pitch, Config->RotationSpeed, 0.0, 0.0, 0.0))
{
InOutTransform.SetRotation(Rotation.Quaternion());
Result = true;
}
ImGui::TableNextColumn();
if (RenderComponent("##Z", &Rotation.Roll, Config->RotationSpeed, 0.0, 0.0, 0.0))
{
InOutTransform.SetRotation(Rotation.Quaternion());
Result = true;
}
ImGui::PopID();
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Transform::RenderScale(FTransform& InOutTransform)
{
ImGui::PushID("Scale");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Scale");
FVector Scale = InOutTransform.GetScale3D();
bool Result = false;
ImGui::TableNextColumn();
if (RenderComponent("##X", &Scale.X, Config->ScaleSpeed, 0.01, 1000.0, 1.0))
{
InOutTransform.SetScale3D(Scale);
Result = true;
}
ImGui::TableNextColumn();
if (RenderComponent("##Y", &Scale.Y, Config->ScaleSpeed, 0.01, 1000.0, 1.0))
{
InOutTransform.SetScale3D(Scale);
Result = true;
}
ImGui::TableNextColumn();
if (RenderComponent("##Z", &Scale.Z, Config->ScaleSpeed, 0.01, 1000.0, 1.0))
{
InOutTransform.SetScale3D(Scale);
Result = true;
}
ImGui::PopID();
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Transform::RenderTransform(FTransform& InOutTransform)
{
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(1.0f, 1.0f));
bool Result = false;
if (ImGui::BeginTable("Pools", 4, ImGuiTableFlags_SizingFixedFit))
{
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 5);
ImGui::TableSetupColumn("X", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Y", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Z", ImGuiTableColumnFlags_WidthStretch);
Result |= RenderLocation(InOutTransform);
Result |= RenderRotation(InOutTransform);
Result |= RenderScale(InOutTransform);
ImGui::EndTable();
}
return Result;
}
@@ -0,0 +1,140 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/HitResult.h"
#include "CogEngineCollisionTester.generated.h"
class UCogEngineEditAnywhere_CollisionViewer;
class UCogEngineDataAsset;
class UPrimitiveComponent;
struct FCollisionShape;
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryType : uint8
{
Overlap,
LineTrace,
Sweep,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryMode : uint8
{
Single,
Multi,
Test,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryBy : uint8
{
Channel,
ObjectType,
Profile,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryShape : uint8
{
Sphere,
Box,
Capsule,
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS()
class COGENGINE_API ACogEngineCollisionTester : public AActor
{
GENERATED_BODY()
public:
ACogEngineCollisionTester(const FObjectInitializer& ObjectInitializer);
virtual void Tick(float DeltaSeconds) override;
virtual bool ShouldTickIfViewportsOnly() const override;
void Query();
void DrawPrimitive(const UPrimitiveComponent* PrimitiveComponent);
void DrawShape(const FCollisionShape& Shape, const FVector& InLocation, const FQuat& InRotation, const FVector& InScale,
const FColor& InColor, bool InDrawSolid) const;
UPROPERTY(EditAnywhere)
bool TickInEditor = false;
UPROPERTY(EditAnywhere)
ECogEngine_CollisionQueryType Type = ECogEngine_CollisionQueryType::LineTrace;
UPROPERTY(EditAnywhere)
ECogEngine_CollisionQueryMode Mode = ECogEngine_CollisionQueryMode::Multi;
UPROPERTY(EditAnywhere)
ECogEngine_CollisionQueryBy By = ECogEngine_CollisionQueryBy::Channel;
UPROPERTY(EditAnywhere)
ECogEngine_CollisionQueryShape Shape = ECogEngine_CollisionQueryShape::Sphere;
UPROPERTY(EditAnywhere)
bool TraceComplex = false;
UPROPERTY()
int32 ObjectTypesToQuery = 0;
UPROPERTY(EditAnywhere)
TEnumAsByte<ECollisionChannel> Channel = ECC_WorldStatic;
UPROPERTY()
int32 ProfileIndex = 0;
UPROPERTY(EditAnywhere)
FVector ShapeExtent = FVector::One();
UPROPERTY(EditAnywhere)
bool DrawHitLocations = true;
UPROPERTY(EditAnywhere)
bool DrawHitImpactPoints = true;
UPROPERTY(EditAnywhere)
bool DrawHitShapes = true;
UPROPERTY(EditAnywhere)
bool DrawHitNormals = true;
UPROPERTY(EditAnywhere)
bool DrawHitImpactNormals = true;
UPROPERTY(EditAnywhere)
bool DrawHitPrimitives = true;
UPROPERTY(EditAnywhere)
bool DrawHitActorsNames = false;
UPROPERTY(EditAnywhere)
float HitPointSize = 5.0f;
UPROPERTY(EditAnywhere)
FColor NoHitColor = FColor::Red;
UPROPERTY(EditAnywhere)
FColor HitColor = FColor::Green;
UPROPERTY(EditAnywhere)
FColor NormalColor = FColor::Yellow;
UPROPERTY(EditAnywhere)
FColor ImpactNormalColor = FColor::Cyan;
TSet<const AActor*> AlreadyDrawnActors;
TSet<const UPrimitiveComponent*> AlreadyDrawnComponents;
UPROPERTY(EditAnywhere)
USceneComponent* StartComponent = nullptr;
UPROPERTY(EditAnywhere)
USceneComponent* EndComponent = nullptr;
};
@@ -5,6 +5,7 @@
#include "CogWindow.h"
#include "CogWindowConfig.h"
#include "Engine/HitResult.h"
#include "CogEngineCollisionTester.h"
#include "CogEngineWindow_CollisionTester.generated.h"
class UCogEngineConfig_CollisionViewer;
@@ -12,43 +13,6 @@ class UCogEngineDataAsset;
class UPrimitiveComponent;
struct FCollisionShape;
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryType : uint8
{
Overlap,
LineTrace,
Sweep,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryMode : uint8
{
Single,
Multi,
Test,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryBy : uint8
{
Channel,
ObjectType,
Profile,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryShape : uint8
{
Sphere,
Box,
Capsule,
};
enum class ECogDebug_GizmoTransformSpace : uint8;
//--------------------------------------------------------------------------------------------------------------------------
@@ -70,13 +34,6 @@ protected:
virtual void SetAsset(const UCogEngineDataAsset* Value);
void Query();
void DrawPrimitive(const UPrimitiveComponent* PrimitiveComponent);
void DrawShape(const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, const FVector& Scale, const FColor& Color, bool DrawSolid) const;
struct FChannel
{
bool IsValid = false;
@@ -89,17 +46,7 @@ protected:
TObjectPtr<UCogEngineConfig_CollisionTester> Config = nullptr;
TSet<const AActor*> AlreadyDrawnActors;
TSet<const UPrimitiveComponent*> AlreadyDrawnComponents;
bool IsDragging = false;
FCogDebug_Gizmo GizmoStart;
FCogDebug_Gizmo GizmoEnd;
FTransform StartTransform;
FCogDebug_Gizmo EndGizmo;
};
//--------------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,72 @@
#pragma once
#include "CoreMinimal.h"
#include "CogDebugGizmo.h"
#include "CogWindow.h"
#include "CogWindowConfig.h"
#include "CogEngineWindow_Transform.generated.h"
class UCogEngineConfig_Transform;
class COGENGINE_API FCogEngineWindow_Transform : public FCogWindow
{
typedef FCogWindow Super;
public:
virtual void Initialize() override;
protected:
virtual void RenderHelp() override;
virtual void RenderContent() override;
bool RenderComponent(const char* Label, double* Value, float Speed, double Min, double Max, double Reset);
void RenderSnap(const char* CheckboxLabel, const char* InputLabel, bool* SnapEnable, float* Snap);
bool RenderLocation(FTransform& InOutTransform);
bool RenderRotation(FTransform& InOutTransform);
bool RenderScale(FTransform& InOutTransform);
bool RenderTransform(FTransform& InOutTransform);
private:
FCogDebug_Gizmo Gizmo;
TWeakObjectPtr<UCogEngineConfig_Transform> Config = nullptr;
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(Config = Cog)
class UCogEngineConfig_Transform : public UCogWindowConfig
{
GENERATED_BODY()
public:
UPROPERTY(Config)
bool ShowGizmo = true;
UPROPERTY(Config)
float LocationSpeed = 10.0f;
UPROPERTY(Config)
float RotationSpeed = 1.0f;
UPROPERTY(Config)
float ScaleSpeed = 0.1f;
virtual void Reset() override
{
Super::Reset();
ShowGizmo = true;
LocationSpeed = 10.0f;
RotationSpeed = 1.0f;
ScaleSpeed = 0.1f;
}
};
+3
View File
@@ -41,6 +41,7 @@
#include "CogEngineWindow_Spawns.h"
#include "CogEngineWindow_Stats.h"
#include "CogEngineWindow_TimeScale.h"
#include "CogEngineWindow_Transform.h"
#include "CogImguiModule.h"
#include "CogInputDataAsset.h"
#include "CogInputWindow_Actions.h"
@@ -174,6 +175,8 @@ void ACogSampleGameState::InitializeCog()
CogWindowManager->AddWindow<FCogEngineWindow_TimeScale>("Engine.Time Scale");
CogWindowManager->AddWindow<FCogEngineWindow_Transform>("Engine.Transform");
//---------------------------------------
// Abilities
//---------------------------------------