diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp index ef1ba4f..8a1f4cd 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp @@ -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(*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(*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(*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(*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(*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; } diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebug.h b/Plugins/Cog/Source/CogDebug/Public/CogDebug.h index 395968c..a2875a3 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebug.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebug.h @@ -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; diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebugGizmo.h b/Plugins/Cog/Source/CogDebug/Public/CogDebugGizmo.h index 215e8a5..f418b49 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebugGizmo.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebugGizmo.h @@ -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; diff --git a/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs b/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs index 9109015..38b9ffa 100644 --- a/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs +++ b/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs @@ -23,15 +23,15 @@ public class CogEngine : ModuleRules PublicDependencyModuleNames.AddRange( new string[] { + "CogDebug", } - ); + ); PrivateDependencyModuleNames.AddRange( new string[] { "CogCommon", - "CogDebug", "CogImgui", "CogWindow", "Core", diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineCollisionTester.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineCollisionTester.cpp new file mode 100644 index 0000000..7e7172a --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineCollisionTester.cpp @@ -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(TEXT("Start")); + RootComponent = StartComponent; + + EndComponent = CreateDefaultSubobject(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 Hits; + TArray 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; + } + } +} diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp index 8915ca8..988fc7b 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp @@ -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(SpawnInfo); + FCogDebug::SetSelection(GetWorld(), Actor); + } + + ACogEngineCollisionTester* CollisionTester = Cast(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 Hits; - TArray 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) { diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp index e657c61..f1ccf3b 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp @@ -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"); diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Transform.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Transform.cpp new file mode 100644 index 0000000..635442d --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Transform.cpp @@ -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(); + 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; +} diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineCollisionTester.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineCollisionTester.h new file mode 100644 index 0000000..0610053 --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineCollisionTester.h @@ -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 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 AlreadyDrawnActors; + + TSet AlreadyDrawnComponents; + + UPROPERTY(EditAnywhere) + USceneComponent* StartComponent = nullptr; + + UPROPERTY(EditAnywhere) + USceneComponent* EndComponent = nullptr; +}; diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h index 4aa99a9..a4636cc 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h @@ -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 Config = nullptr; - TSet AlreadyDrawnActors; - - TSet AlreadyDrawnComponents; - - bool IsDragging = false; - - FCogDebug_Gizmo GizmoStart; - FCogDebug_Gizmo GizmoEnd; - - FTransform StartTransform; - + FCogDebug_Gizmo EndGizmo; }; //-------------------------------------------------------------------------------------------------------------------------- diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Transform.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Transform.h new file mode 100644 index 0000000..c0ad37b --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Transform.h @@ -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 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; + } +}; \ No newline at end of file diff --git a/Source/CogSample/CogSampleGameState.cpp b/Source/CogSample/CogSampleGameState.cpp index 2b2ab61..41bfb4d 100644 --- a/Source/CogSample/CogSampleGameState.cpp +++ b/Source/CogSample/CogSampleGameState.cpp @@ -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("Engine.Time Scale"); + CogWindowManager->AddWindow("Engine.Transform"); + //--------------------------------------- // Abilities //---------------------------------------