mirror of
https://github.com/Ed94/Cog.git
synced 2026-07-29 19:00:05 +00:00
First Submit
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"FileVersion": 1,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "CogEngine",
|
||||
"Description": "",
|
||||
"Category": "Other",
|
||||
"CreatedBy": "Arnaud Jamin",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": true,
|
||||
"IsBetaVersion": false,
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": false,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "CogEngine",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
],
|
||||
"Plugins": [
|
||||
{
|
||||
"Name": "CogImgui",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Name": "CogDebug",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Name": "CogWindow",
|
||||
"Enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,50 @@
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class CogEngine : ModuleRules
|
||||
{
|
||||
public CogEngine(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"CogImgui",
|
||||
"CogDebug",
|
||||
"CogWindow",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"NetCore",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "CogEngineModule.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FCogEngineModule"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogEngineModule::StartupModule()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogEngineModule::ShutdownModule()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ACogEngineReplicator* FCogEngineModule::GetLocalReplicator()
|
||||
{
|
||||
return LocalReplicator;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogEngineModule::SetLocalReplicator(ACogEngineReplicator* Value)
|
||||
{
|
||||
LocalReplicator = Value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ACogEngineReplicator* FCogEngineModule::GetRemoteReplicator(const APlayerController* PlayerController)
|
||||
{
|
||||
for (ACogEngineReplicator* Replicator : RemoteReplicators)
|
||||
{
|
||||
if (Replicator->GetPlayerController() == PlayerController)
|
||||
{
|
||||
return Replicator;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogEngineModule::AddRemoteReplicator(ACogEngineReplicator* Value)
|
||||
{
|
||||
RemoteReplicators.Add(Value);
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FCogEngineModule, CogEngine)
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "CogEngineReplicator.h"
|
||||
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "GameFramework/WorldSettings.h"
|
||||
#include "Net/Core/PushModel/PushModel.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogEngineReplicator::Create(APlayerController* Controller)
|
||||
{
|
||||
if (Controller->GetWorld()->GetNetMode() != NM_Client)
|
||||
{
|
||||
FActorSpawnParameters SpawnInfo;
|
||||
SpawnInfo.Owner = Controller;
|
||||
Controller->GetWorld()->SpawnActor<ACogEngineReplicator>(SpawnInfo);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ACogEngineReplicator::ACogEngineReplicator(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
#if !UE_BUILD_SHIPPING
|
||||
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.bAllowTickOnDedicatedServer = true;
|
||||
PrimaryActorTick.bTickEvenWhenPaused = true;
|
||||
PrimaryActorTick.bStartWithTickEnabled = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
|
||||
bHasAuthority = false;
|
||||
bIsLocal = false;
|
||||
bReplicates = true;
|
||||
bOnlyRelevantToOwner = true;
|
||||
|
||||
#endif // !UE_BUILD_SHIPPING
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogEngineReplicator::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
check(World);
|
||||
const ENetMode NetMode = World->GetNetMode();
|
||||
bHasAuthority = NetMode != NM_Client;
|
||||
bIsLocal = NetMode != NM_DedicatedServer;
|
||||
|
||||
OwnerPlayerController = Cast<APlayerController>(GetOwner());
|
||||
|
||||
if (OwnerPlayerController->IsLocalController())
|
||||
{
|
||||
FCogEngineModule::Get().SetLocalReplicator(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
FCogEngineModule::Get().AddRemoteReplicator(this);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACogEngineReplicator::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||
{
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
|
||||
FDoRepLifetimeParams Params;
|
||||
Params.bIsPushBased = true;
|
||||
|
||||
DOREPLIFETIME_WITH_PARAMS_FAST(ACogEngineReplicator, TimeDilation, Params);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogEngineReplicator::TickSpawnActions()
|
||||
{
|
||||
#if !UE_BUILD_SHIPPING
|
||||
|
||||
if (OwnerPlayerController == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32 i = SpawnActions.Num() - 1; i >= 0; --i)
|
||||
{
|
||||
const FCogEngineReplicatorSpawnAction& SpawnInfo = SpawnActions[i];
|
||||
SpawnActions.RemoveAt(i);
|
||||
}
|
||||
|
||||
#endif // !UE_BUILD_SHIPPING
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogEngineReplicator::Server_SetTimeDilation_Implementation(float Value)
|
||||
{
|
||||
#if !UE_BUILD_SHIPPING
|
||||
|
||||
COMPARE_ASSIGN_AND_MARK_PROPERTY_DIRTY(ACogEngineReplicator, TimeDilation, Value, this);
|
||||
OnRep_TimeDilation();
|
||||
|
||||
#endif // !UE_BUILD_SHIPPING
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogEngineReplicator::OnRep_TimeDilation()
|
||||
{
|
||||
#if !UE_BUILD_SHIPPING
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
if (World == nullptr)
|
||||
return;
|
||||
|
||||
AWorldSettings* WorldSettings = World->GetWorldSettings();
|
||||
if (WorldSettings == nullptr)
|
||||
return;
|
||||
|
||||
WorldSettings->SetTimeDilation(TimeDilation);
|
||||
|
||||
#endif // !UE_BUILD_SHIPPING
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
#include "CogEngineWindow_Collisions.h"
|
||||
|
||||
#include "CogDebugDrawHelper.h"
|
||||
#include "CogDebugSettings.h"
|
||||
#include "CogImGuiHelper.h"
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "Components/CapsuleComponent.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "Components/SphereComponent.h"
|
||||
#include "imgui.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_Collisions::UCogEngineWindow_Collisions()
|
||||
{
|
||||
ObjectTypesToQuery = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Collisions::SetCollisionsAsset(const UCogEngineDataAsset_Collisions* Asset)
|
||||
{
|
||||
if (Asset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (FChannel& Channel : Channels)
|
||||
{
|
||||
Channel.IsValid = false;
|
||||
}
|
||||
|
||||
for (const FCogCollisionChannel& AssetChannel : Asset->Channels)
|
||||
{
|
||||
FChannel& Channel = Channels[(uint8)AssetChannel.Channel];
|
||||
Channel.IsValid = true;
|
||||
Channel.Color = AssetChannel.Color.ToFColor(true);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void UCogEngineWindow_Collisions::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
const APlayerController* PlayerController = GetLocalPlayerController();
|
||||
if (PlayerController == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Query Profile
|
||||
//-------------------------------------------------
|
||||
|
||||
const UCollisionProfile* CollisionProfile = UCollisionProfile::Get();
|
||||
if (CollisionProfile == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FCollisionResponseTemplate* SelectedProfile = CollisionProfile->GetProfileByIndex(ProfileIndex);
|
||||
FName SelectedProfileName = SelectedProfile != nullptr ? SelectedProfile->Name : FName("Custom");
|
||||
|
||||
if (ImGui::BeginCombo("Profile", TCHAR_TO_ANSI(*SelectedProfileName.ToString()), ImGuiComboFlags_HeightLargest))
|
||||
{
|
||||
for (int i = 0; i < CollisionProfile->GetNumOfProfiles(); ++i)
|
||||
{
|
||||
const FCollisionResponseTemplate* Profile = CollisionProfile->GetProfileByIndex(i);
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*Profile->Name.ToString()), false))
|
||||
{
|
||||
ProfileIndex = i;
|
||||
ObjectTypesToQuery = 0;
|
||||
SelectedProfile = CollisionProfile->GetProfileByIndex(ProfileIndex);
|
||||
|
||||
if (Profile->CollisionEnabled != ECollisionEnabled::NoCollision)
|
||||
{
|
||||
for (int j = 0; j < ECC_MAX; ++j)
|
||||
{
|
||||
ECollisionResponse Response = Profile->ResponseToChannels.GetResponse((ECollisionChannel)j);
|
||||
if (Response != ECR_Ignore)
|
||||
{
|
||||
ObjectTypesToQuery |= ECC_TO_BITFIELD(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
//-------------------------------------------------
|
||||
// Query Filtering
|
||||
//-------------------------------------------------
|
||||
for (int ChannelIndex = 0; ChannelIndex < (int32)ECC_MAX; ++ChannelIndex)
|
||||
{
|
||||
ImGui::PushID(ChannelIndex);
|
||||
|
||||
const FChannel& Channel = Channels[ChannelIndex];
|
||||
if (Channel.IsValid == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImColor Color = FCogImguiHelper::ToImColor(Channel.Color);
|
||||
ImGui::ColorEdit4("Color", (float*)&Color.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::SameLine();
|
||||
|
||||
bool IsCollisionActive = (ObjectTypesToQuery & ECC_TO_BITFIELD(ChannelIndex)) > 0;
|
||||
const FName ChannelName = CollisionProfile->ReturnChannelNameFromContainerIndex(ChannelIndex);
|
||||
if (ImGui::Checkbox(TCHAR_TO_ANSI(*ChannelName.ToString()), &IsCollisionActive))
|
||||
{
|
||||
if (IsCollisionActive)
|
||||
{
|
||||
ObjectTypesToQuery |= ECC_TO_BITFIELD(ChannelIndex);
|
||||
ProfileIndex = INDEX_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjectTypesToQuery &= ~ECC_TO_BITFIELD(ChannelIndex);
|
||||
ProfileIndex = INDEX_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
//-------------------------------------------------
|
||||
// Query Mode
|
||||
//-------------------------------------------------
|
||||
static int QueryType = 0;
|
||||
ImGui::Combo("Query", &QueryType,
|
||||
"Sphere\0"
|
||||
"Raycast Crosshair\0"
|
||||
"Raycast Cursor\0"
|
||||
"\0"
|
||||
);
|
||||
|
||||
//-------------------------------------------------
|
||||
// Query Distance
|
||||
//-------------------------------------------------
|
||||
static float QueryDistance = 5000.0f;
|
||||
ImGui::SliderFloat("Distance", &QueryDistance, 0.0f, 20000.0f, "%0.f");
|
||||
|
||||
//-------------------------------------------------
|
||||
// Query Thickness
|
||||
//-------------------------------------------------
|
||||
static float QueryThickness = 0.0f;
|
||||
if (QueryType == 1 || QueryType == 2)
|
||||
{
|
||||
ImGui::SliderFloat("Thickness", &QueryThickness, 0.0f, 1000.0f, "%0.f");
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Query Use Complex Collisions
|
||||
//-------------------------------------------------
|
||||
static bool UseComplexCollisions = false;
|
||||
ImGui::Checkbox("Use Complex Collisions", &UseComplexCollisions);
|
||||
|
||||
//-------------------------------------------------
|
||||
// Show Names
|
||||
//-------------------------------------------------
|
||||
static bool ShowActorsNames = false;
|
||||
ImGui::Checkbox("Show Actors Names", &ShowActorsNames);
|
||||
|
||||
//-------------------------------------------------
|
||||
// Show Query
|
||||
//-------------------------------------------------
|
||||
static bool ShowQuery = false;
|
||||
ImGui::Checkbox("Show Query", &ShowQuery);
|
||||
|
||||
//-------------------------------------------------
|
||||
// Perform Query
|
||||
//-------------------------------------------------
|
||||
if (ObjectTypesToQuery == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
|
||||
FVector QueryStart;
|
||||
FVector QueryEnd;
|
||||
float QueryRadius = 0.0f;
|
||||
|
||||
switch (QueryType)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
FVector Location = FVector::ZeroVector;
|
||||
if (APawn* Pawn = PlayerController->GetPawn())
|
||||
{
|
||||
Location = Pawn->GetActorLocation();
|
||||
}
|
||||
|
||||
QueryRadius = QueryDistance;
|
||||
QueryStart = Location;
|
||||
QueryEnd = QueryStart;
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
FVector Location;
|
||||
FRotator Rotation;
|
||||
PlayerController->GetPlayerViewPoint(Location, Rotation);
|
||||
QueryStart = Location;
|
||||
QueryEnd = QueryStart + Rotation.Vector() * QueryDistance;
|
||||
QueryRadius = QueryThickness;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
FVector Direction;
|
||||
UGameplayStatics::DeprojectScreenToWorld(PlayerController, FCogImguiHelper::ToVector2D(ImGui::GetMousePos()), QueryStart, Direction);
|
||||
QueryEnd = QueryStart + Direction * QueryDistance;
|
||||
QueryRadius = QueryThickness;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const FName TraceTag(TEXT("FCogWindow_Collision"));
|
||||
FCollisionQueryParams QueryParams(TraceTag, SCENE_QUERY_STAT_ONLY(CogHitDetection), UseComplexCollisions);
|
||||
|
||||
FCollisionObjectQueryParams QueryObjectParams;
|
||||
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
|
||||
|
||||
FCollisionShape QueryShape;
|
||||
QueryShape.SetSphere(QueryRadius);
|
||||
|
||||
TArray<FHitResult> QueryHits;
|
||||
World->SweepMultiByObjectType(
|
||||
QueryHits,
|
||||
QueryStart,
|
||||
QueryEnd,
|
||||
FQuat::Identity,
|
||||
QueryObjectParams,
|
||||
QueryShape,
|
||||
QueryParams);
|
||||
|
||||
if (ShowQuery)
|
||||
{
|
||||
FCogDebugDrawHelper::DrawCapsuleCastMulti(World, QueryStart, QueryEnd, FQuat::Identity, 0.0f, QueryRadius, EDrawDebugTrace::ForOneFrame, false, QueryHits, FLinearColor::White, FLinearColor::Red, FCogDebugSettings::GetDebugDuration(true));
|
||||
}
|
||||
|
||||
TSet<const AActor*> AlreadyDrawnActors;
|
||||
TSet<const UPrimitiveComponent*> AlreadyDrawnComponents;
|
||||
|
||||
for (const FHitResult& HitResult : QueryHits)
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// Don't draw same primitives multiple times (for bones)
|
||||
//-------------------------------------------------------
|
||||
const UPrimitiveComponent* PrimitiveComponent = HitResult.GetComponent();
|
||||
if (AlreadyDrawnComponents.Contains(PrimitiveComponent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AlreadyDrawnComponents.Add(PrimitiveComponent);
|
||||
|
||||
ECollisionChannel CollisionObjectType = PrimitiveComponent->GetCollisionObjectType();
|
||||
FColor Color = Channels[CollisionObjectType].Color;
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Draw Name
|
||||
//-------------------------------------------------------
|
||||
if (ShowActorsNames)
|
||||
{
|
||||
const AActor* Actor = HitResult.GetActor();
|
||||
if (Actor != nullptr)
|
||||
{
|
||||
if (AlreadyDrawnActors.Contains(Actor) == false)
|
||||
{
|
||||
FColor TextColor = Color.WithAlpha(255);
|
||||
DrawDebugString(World, Actor->GetActorLocation(), GetNameSafe(Actor->GetClass()), nullptr, FColor::White, 0.0f, FCogDebugSettings::TextShadow, FCogDebugSettings::TextSize);
|
||||
AlreadyDrawnActors.Add(Actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Draw Shape
|
||||
//-------------------------------------------------------
|
||||
FCollisionShape Shape = PrimitiveComponent->GetCollisionShape();
|
||||
switch (Shape.ShapeType)
|
||||
{
|
||||
case ECollisionShape::Box:
|
||||
{
|
||||
FVector Location;
|
||||
FVector Extent;
|
||||
FQuat Rotation;
|
||||
|
||||
if (const UBoxComponent* BoxComponent = Cast<UBoxComponent>(PrimitiveComponent))
|
||||
{
|
||||
Location = BoxComponent->GetComponentLocation();
|
||||
Extent = BoxComponent->GetScaledBoxExtent();
|
||||
Rotation = BoxComponent->GetComponentQuat();
|
||||
}
|
||||
else
|
||||
{
|
||||
PrimitiveComponent->Bounds.GetBox().GetCenterAndExtents(Location, Extent);
|
||||
Extent += FVector::OneVector;
|
||||
Rotation = FQuat::Identity;
|
||||
}
|
||||
|
||||
DrawDebugSolidBox(
|
||||
World,
|
||||
Location,
|
||||
Extent,
|
||||
Rotation,
|
||||
Color,
|
||||
false,
|
||||
0.0f,
|
||||
FCogDebugSettings::GetDebugDepthPriority(0));
|
||||
|
||||
DrawDebugBox(
|
||||
World,
|
||||
Location,
|
||||
Extent,
|
||||
Rotation,
|
||||
Color,
|
||||
false,
|
||||
0.0f,
|
||||
FCogDebugSettings::GetDebugDepthPriority(0),
|
||||
FCogDebugSettings::GetDebugThickness(0.0f));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ECollisionShape::Sphere:
|
||||
{
|
||||
if (const USphereComponent* SphereComponent = Cast<USphereComponent>(PrimitiveComponent))
|
||||
{
|
||||
FCogDebugDrawHelper::DrawSphere(
|
||||
World,
|
||||
SphereComponent->GetComponentLocation(),
|
||||
SphereComponent->GetScaledSphereRadius(),
|
||||
FCogDebugSettings::GetCircleSegments(),
|
||||
Color,
|
||||
false,
|
||||
0.0f,
|
||||
FCogDebugSettings::GetDebugDepthPriority(0),
|
||||
FCogDebugSettings::GetDebugThickness(0.0f));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ECollisionShape::Capsule:
|
||||
{
|
||||
if (const UCapsuleComponent* CapsuleComponent = Cast<UCapsuleComponent>(PrimitiveComponent))
|
||||
{
|
||||
DrawDebugCapsule(World,
|
||||
CapsuleComponent->GetComponentLocation(),
|
||||
CapsuleComponent->GetScaledCapsuleHalfHeight(),
|
||||
CapsuleComponent->GetScaledCapsuleRadius(),
|
||||
CapsuleComponent->GetComponentQuat(),
|
||||
Color,
|
||||
false,
|
||||
0.0f,
|
||||
FCogDebugSettings::GetDebugDepthPriority(0),
|
||||
FCogDebugSettings::GetDebugThickness(0.0f));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "CogEngineWindow_DebugSettings.h"
|
||||
|
||||
#include "CogDebugSettings.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_DebugSettings::UCogEngineWindow_DebugSettings()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_DebugSettings::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_DebugSettings::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::MenuItem("Reset"))
|
||||
{
|
||||
FCogDebugSettings::Reset();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Filter by selection", &FCogDebugSettings::FilterBySelection);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("If checked, only show the debug of the currently selected actor. Otherwise show the debug of all actors.");
|
||||
|
||||
ImGui::Checkbox("Persistent", &FCogDebugSettings::Persistent);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("Make debug draw always persist");
|
||||
|
||||
ImGui::Checkbox("Text Shadow", &FCogDebugSettings::TextShadow);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("Show a shadow below debug text.");
|
||||
|
||||
const float ItemsWidth = FCogWindowWidgets::TextBaseWidth * 10;
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::Checkbox("Fade 2D", &FCogDebugSettings::Fade2D);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("Does the 2D debug is fading out.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Duration", &FCogDebugSettings::Duration, 0.01f, 0.0f, 100.0f, "%.1f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The duration of debug elements.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Thickness", &FCogDebugSettings::Thickness, 0.05f, 0.0f, 5.0f, "%.1f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The thickness of debug lines.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Server Thickness", &FCogDebugSettings::ServerThickness, 0.05f, 0.0f, 5.0f, "%.1f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The thickness the server debug lines.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Server Color Mult", &FCogDebugSettings::ServerColorMultiplier, 0.01f, 0.0f, 1.0f, "%.1f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The color multiplier applied to the server debug lines.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragInt("Depth Priority", &FCogDebugSettings::DepthPriority, 0.1f, 0, 100);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The depth priority of debug elements.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragInt("Segments", &FCogDebugSettings::Segments, 0.1f, 4, 20.0f);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The number of segments used for circular shapes.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Axes Scale", &FCogDebugSettings::AxesScale, 0.1f, 0, 10.0f, "%.1f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The scaling debug axis.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Arrow Size", &FCogDebugSettings::ArrowSize, 1.0f, 0.0f, 200.0f, "%.0f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The size of debug arrows.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Gradient Intensity", &FCogDebugSettings::GradientColorIntensity, 0.01f, 0.0f, 1.0f, "%.2f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("How much the debug elements color should be changed by a gradient color over time.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Gradient Speed", &FCogDebugSettings::GradientColorSpeed, 0.1f, 0.0f, 10.0f, "%.1f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The speed of the gradient color change.");
|
||||
|
||||
ImGui::SetNextItemWidth(ItemsWidth);
|
||||
ImGui::DragFloat("Text Size", &FCogDebugSettings::TextSize, 0.1f, 0.1f, 5.0f, "%.1f");
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("The size of the debug texts.");
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "CogEngineWindow_ImGui.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "implot.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_ImGui::UCogEngineWindow_ImGui()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_ImGui::RenderTick(float DeltaTime)
|
||||
{
|
||||
Super::RenderTick(DeltaTime);
|
||||
|
||||
if (bShowImguiDemo)
|
||||
{
|
||||
ImGui::ShowDemoWindow(&bShowImguiDemo);
|
||||
}
|
||||
|
||||
if (bShowImguiMetric)
|
||||
{
|
||||
ImGui::ShowMetricsWindow(&bShowImguiMetric);
|
||||
}
|
||||
|
||||
if (bShowImguiDebugLog)
|
||||
{
|
||||
ImGui::ShowDebugLogWindow(&bShowImguiDebugLog);
|
||||
}
|
||||
|
||||
if (bShowImguiStyleEditor)
|
||||
{
|
||||
ImGui::Begin("Dear ImGui Style Editor", &bShowImguiStyleEditor);
|
||||
ImGui::ShowStyleEditor();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (bShowImguiPlot)
|
||||
{
|
||||
ImPlot::ShowDemoWindow(&bShowImguiPlot);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_ImGui::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
ImGui::MenuItem("ImGui Demo", nullptr, &bShowImguiDemo);
|
||||
ImGui::MenuItem("ImGui Metric", nullptr, &bShowImguiMetric);
|
||||
ImGui::MenuItem("ImGui Debug Log", nullptr, &bShowImguiDebugLog);
|
||||
ImGui::MenuItem("ImGui Style Editor", nullptr, &bShowImguiStyleEditor);
|
||||
ImGui::MenuItem("Plot Demo", "", &bShowImguiPlot);
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
#include "CogEngineWindow_LogCategories.h"
|
||||
|
||||
#include "CogDebugHelper.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "CogDebugLogCategoryManager.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_LogCategories::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_LogCategories::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
if (World == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static bool bShowAllVerbosity = false;
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
ImGui::Checkbox("Show detailed verbosity", &bShowAllVerbosity);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::HelpMarker("Show the verbosity level of each log category.");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Reset"))
|
||||
{
|
||||
FCogDebugLogCategoryManager::DeactivateAllLogCateories(*World);
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Deactivate all the log categories");
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Flush"))
|
||||
{
|
||||
FlushPersistentDebugLines(World);
|
||||
FlushDebugStrings(GWorld);
|
||||
GEngine->ClearOnScreenDebugMessages();
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Clear all the debug drawn on screen");
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
const bool IsClient = World->GetNetMode() == NM_Client;
|
||||
|
||||
ImGuiStyle& Style = ImGui::GetStyle();
|
||||
|
||||
int Index = 0;
|
||||
for (const auto& Entry : FCogDebugLogCategoryManager::GetLogCategories())
|
||||
{
|
||||
FName CategoryName = Entry.Key;
|
||||
const FCogDebugLogCategoryInfo& CategoryInfo = Entry.Value;
|
||||
FLogCategoryBase* Category = CategoryInfo.LogCategory;
|
||||
|
||||
ImGui::PushID(Index);
|
||||
FString CategoryFriendlyName = Category->GetCategoryName().ToString();
|
||||
|
||||
if (bShowAllVerbosity == false)
|
||||
{
|
||||
const bool IsControlDown = ImGui::GetIO().KeyCtrl;
|
||||
if (IsClient)
|
||||
{
|
||||
ELogVerbosity::Type Verbosity = FCogDebugLogCategoryManager::GetServerVerbosity(CategoryName);
|
||||
bool IsActive = FCogDebugLogCategoryManager::IsVerbosityActive(Verbosity);
|
||||
|
||||
if (Verbosity == ELogVerbosity::VeryVerbose)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, IM_COL32(255, 0, 0, 200));
|
||||
}
|
||||
|
||||
if (ImGui::Checkbox("##Server", &IsActive))
|
||||
{
|
||||
ELogVerbosity::Type NewVerbosity = IsActive ? (IsControlDown ? ELogVerbosity::VeryVerbose : ELogVerbosity::Verbose) : ELogVerbosity::Warning;
|
||||
FCogDebugLogCategoryManager::SetServerVerbosity(CategoryName, NewVerbosity);
|
||||
}
|
||||
|
||||
if (Verbosity == ELogVerbosity::VeryVerbose)
|
||||
{
|
||||
ImGui::PopStyleColor(1);
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Server");
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsControlDown ? 1.0f : 0.5f), "Very Verbose [CTRL]");
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
{
|
||||
ELogVerbosity::Type Verbosity = Category->GetVerbosity();
|
||||
bool IsActive = FCogDebugLogCategoryManager::IsVerbosityActive(Verbosity);
|
||||
|
||||
if (Verbosity == ELogVerbosity::VeryVerbose)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, IM_COL32(255, 0, 0, 200));
|
||||
}
|
||||
|
||||
if (ImGui::Checkbox(TCHAR_TO_ANSI(*CategoryFriendlyName), &IsActive))
|
||||
{
|
||||
ELogVerbosity::Type NewVerbosity = IsActive ? (IsControlDown ? ELogVerbosity::VeryVerbose : ELogVerbosity::Verbose) : ELogVerbosity::Warning;
|
||||
Category->SetVerbosity(NewVerbosity);
|
||||
}
|
||||
|
||||
if (Verbosity == ELogVerbosity::VeryVerbose)
|
||||
{
|
||||
ImGui::PopStyleColor(1);
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
if (IsClient)
|
||||
{
|
||||
ImGui::Text("Local Client");
|
||||
}
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsControlDown ? 1.0f : 0.5f), "Very Verbose [CTRL]");
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsClient)
|
||||
{
|
||||
ELogVerbosity::Type CurrentVerbosity = FCogDebugLogCategoryManager::GetServerVerbosity(CategoryName);
|
||||
ImGui::SetNextItemWidth(FCogWindowWidgets::TextBaseWidth * 12);
|
||||
if (ImGui::BeginCombo("##Server", FCogDebugHelper::VerbosityToString(CurrentVerbosity)))
|
||||
{
|
||||
for (int32 i = (int32)ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
|
||||
{
|
||||
bool IsSelected = i == (int32)CurrentVerbosity;
|
||||
ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i;
|
||||
|
||||
if (ImGui::Selectable(FCogDebugHelper::VerbosityToString(Verbosity), IsSelected))
|
||||
{
|
||||
FCogDebugLogCategoryManager::SetServerVerbosity(CategoryName, Verbosity);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Server");
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
{
|
||||
ELogVerbosity::Type CurrentVerbosity = Category->GetVerbosity();
|
||||
ImGui::SetNextItemWidth(FCogWindowWidgets::TextBaseWidth * 12);
|
||||
if (ImGui::BeginCombo("##Local", FCogDebugHelper::VerbosityToString(CurrentVerbosity)))
|
||||
{
|
||||
for (int32 i = (int32)ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
|
||||
{
|
||||
bool IsSelected = i == (int32)CurrentVerbosity;
|
||||
ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i;
|
||||
|
||||
if (ImGui::Selectable(FCogDebugHelper::VerbosityToString(Verbosity), IsSelected))
|
||||
{
|
||||
Category->SetVerbosity(Verbosity);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (IsClient && ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Local Client");
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*CategoryFriendlyName));
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
#include "CogEngineWindow_NetEmulation.h"
|
||||
|
||||
#include "CogEngineWindow_Stats.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Engine/NetDriver.h"
|
||||
#include "Engine/NetConnection.h"
|
||||
#include "Engine/World.h"
|
||||
#include "GameFramework/PlayerState.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void DrawControls(UWorld* World)
|
||||
{
|
||||
FWorldContext& WorldContext = GEngine->GetWorldContextFromWorldChecked(World);
|
||||
|
||||
if (WorldContext.ActiveNetDrivers.Num() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int32 SelectedIndex = 0;
|
||||
|
||||
if (SelectedIndex >= WorldContext.ActiveNetDrivers.Num())
|
||||
{
|
||||
SelectedIndex = 0;
|
||||
}
|
||||
|
||||
FNamedNetDriver* SelectedNetDriver = &WorldContext.ActiveNetDrivers[SelectedIndex];
|
||||
if (SelectedNetDriver == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Driver", TCHAR_TO_ANSI(*SelectedNetDriver->NetDriver->GetName())))
|
||||
{
|
||||
int i = 0;
|
||||
for (FNamedNetDriver& NamedNetDriver : WorldContext.ActiveNetDrivers)
|
||||
{
|
||||
if (NamedNetDriver.NetDriver != nullptr)
|
||||
{
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*NamedNetDriver.NetDriver->GetName())))
|
||||
{
|
||||
SelectedIndex = i;
|
||||
SelectedNetDriver = &WorldContext.ActiveNetDrivers[i];
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (SelectedNetDriver == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if DO_ENABLE_NET_TEST
|
||||
|
||||
FPacketSimulationSettings Settings = SelectedNetDriver->NetDriver->PacketSimulationSettings;
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
if (ImGui::DragInt("Lag Min", &Settings.PktLagMin, 1.0f, 0, INT_MAX, "%d ms"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"If set lag values will randomly fluctuate between Min and Max.");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
if (ImGui::DragInt("Lag Max", &Settings.PktLagMax, 1.0f, 0, INT_MAX, "%d ms"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"If set lag values will randomly fluctuate between Min and Max.");
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Packet Loss", &Settings.PktLoss, 0, 100, "%d%%"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"When set, will cause calls to FlushNet to drop packets.\n"
|
||||
"Value is treated as %% of packets dropped (i.e. 0 = None, 100 = All).\n"
|
||||
"No general pattern / ordering is guaranteed.\n"
|
||||
"Clamped between 0 and 100.\n"
|
||||
"Works with all other settings.");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
if (ImGui::SliderInt("Packet Order", &Settings.PktOrder, 0, 100, "%d%%"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"When set, will cause calls to FlushNet to change ordering of packets at random.\n"
|
||||
"Value is treated as a bool(i.e. 0 = False, anything else = True). \n"
|
||||
"This works by randomly selecting packets to be delayed until a subsequent call to FlushNet.\n"
|
||||
"Takes precedence over PktDup and PktLag.");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
if (ImGui::SliderInt("Packet Dup", &Settings.PktDup, 0, 100, "%d%%"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"When set, will cause calls to FlushNet to duplicate packets.\n"
|
||||
"Value is treated as %% of packets duplicated(i.e. 0 = None, 100 = All).\n"
|
||||
"No general pattern / ordering is guaranteed.\n"
|
||||
"Clamped between 0 and 100.\n"
|
||||
"Cannot be used with PktOrder or PktLag.");
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
if (ImGui::DragInt("Incoming Lag Min", &Settings.PktIncomingLagMin, 1.0f, 0, INT_MAX, "%d ms"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"The minimum delay in milliseconds to incoming packets before they are processed");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
if (ImGui::DragInt("Incoming Lag Max", &Settings.PktIncomingLagMax, 1.0f, 0, INT_MAX, "%d ms"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"The maximum delay in milliseconds to add to incoming packets before they are processed");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
if (ImGui::SliderInt("Incoming Packet Loss", &Settings.PktIncomingLoss, 0, 100, "%d%%"))
|
||||
{
|
||||
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip(
|
||||
"The ratio of incoming packets that will be dropped to simulate packet loss");
|
||||
}
|
||||
|
||||
#endif //DO_ENABLE_NET_TEST
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_NetEmulation::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
const APlayerController* PlayerController = GetLocalPlayerController();
|
||||
if (PlayerController == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (const APlayerState* PlayerState = PlayerController->GetPlayerState<APlayerState>())
|
||||
{
|
||||
const float Ping = PlayerState->GetPingInMilliseconds();
|
||||
ImGui::Text("Ping ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(UCogEngineWindow_Stats::GetPingColor(Ping), "%0.0fms", Ping);
|
||||
}
|
||||
|
||||
if (UNetConnection* Connection = PlayerController->GetNetConnection())
|
||||
{
|
||||
const float OutPacketLost = Connection->GetOutLossPercentage().GetAvgLossPercentage() * 100.0f;
|
||||
ImGui::Text("Packet Loss Out ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(UCogEngineWindow_Stats::GetPacketLossColor(OutPacketLost), "%0.0f%%", OutPacketLost);
|
||||
|
||||
const float InPacketLost = Connection->GetInLossPercentage().GetAvgLossPercentage() * 100.0f;
|
||||
ImGui::Text("Packet Loss In ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(UCogEngineWindow_Stats::GetPacketLossColor(InPacketLost), "%0.0f%%", InPacketLost);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
DrawControls(GetWorld());
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
#include "CogEngineWindow_OutputLog.h"
|
||||
|
||||
#include "CogDebugHelper.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Misc/StringBuilder.h"
|
||||
|
||||
char ImGuiTextBuffer::EmptyString[1] = { 0 };
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
// FCogLogOutputDevice
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogLogOutputDevice::UCogLogOutputDevice()
|
||||
{
|
||||
GLog->AddOutputDevice(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogLogOutputDevice::~UCogLogOutputDevice()
|
||||
{
|
||||
if (GLog != nullptr)
|
||||
{
|
||||
GLog->RemoveOutputDevice(this);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogLogOutputDevice::Serialize(const TCHAR* Message, ELogVerbosity::Type Verbosity, const class FName& Category)
|
||||
{
|
||||
if (OutputLog != nullptr)
|
||||
{
|
||||
OutputLog->AddLog(Message, Verbosity, Category);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
// FCogWindow_Log
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_OutputLog::UCogEngineWindow_OutputLog()
|
||||
{
|
||||
OutputDevice.OutputLog = this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_OutputLog::Clear()
|
||||
{
|
||||
TextBuffer.clear();
|
||||
LineInfos.Empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_OutputLog::AddLog(const TCHAR* Message, ELogVerbosity::Type Verbosity, const class FName& Category)
|
||||
{
|
||||
static TAnsiStringBuilder<512> Format;
|
||||
|
||||
Format.Reset();
|
||||
|
||||
if (Message)
|
||||
{
|
||||
Format.Append(Message);
|
||||
}
|
||||
|
||||
FLineInfo& LineInfo = LineInfos.AddDefaulted_GetRef();
|
||||
LineInfo.Frame = GFrameCounter % 1000;
|
||||
LineInfo.Verbosity = Verbosity;
|
||||
LineInfo.Category = Category;
|
||||
LineInfo.Start = TextBuffer.size();
|
||||
|
||||
TextBuffer.append(Format.GetData(), Format.GetData() + Format.Len());
|
||||
|
||||
LineInfo.End = TextBuffer.size();
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_OutputLog::DrawRow(const char* BufferStart, const FLineInfo& LineInfo, bool IsTableShown)
|
||||
{
|
||||
ImU32 Color;
|
||||
switch (LineInfo.Verbosity)
|
||||
{
|
||||
case ELogVerbosity::Error: Color = IM_COL32(255, 0, 0, 255); break;
|
||||
case ELogVerbosity::Warning: Color = IM_COL32(255, 200, 0, 255); break;
|
||||
default: Color = IM_COL32(200, 200, 200, 255); break;
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
|
||||
if (IsTableShown)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
|
||||
if (ShowFrame)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%3d", LineInfo.Frame);
|
||||
}
|
||||
|
||||
if (ShowCategory)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*LineInfo.Category.ToString()));
|
||||
}
|
||||
|
||||
if (ShowVerbosity)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(ToString(LineInfo.Verbosity)));
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
const char* LineStart = BufferStart + LineInfo.Start;
|
||||
const char* LineEnd = BufferStart + LineInfo.End;
|
||||
ImGui::TextUnformatted(LineStart, LineEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ShowFrame)
|
||||
{
|
||||
ImGui::Text("[%3d] ", LineInfo.Frame);
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
if (ShowCategory)
|
||||
{
|
||||
ImGui::Text("%s: ", TCHAR_TO_ANSI(*LineInfo.Category.ToString()));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
if (ShowVerbosity)
|
||||
{
|
||||
ImGui::Text("%s: ", TCHAR_TO_ANSI(ToString(LineInfo.Verbosity)));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
const char* LineStart = BufferStart + LineInfo.Start;
|
||||
const char* LineEnd = BufferStart + LineInfo.End;
|
||||
ImGui::TextUnformatted(LineStart, LineEnd);
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_OutputLog::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_OutputLog::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
bool ClearPressed = false;
|
||||
bool CopyPressed = false;
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
if (ImGui::MenuItem("Copy"))
|
||||
{
|
||||
ImGui::LogToClipboard();
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Checkbox("Auto Scroll", &AutoScroll);
|
||||
ImGui::Checkbox("Show Frame", &ShowFrame);
|
||||
ImGui::Checkbox("Show Category", &ShowCategory);
|
||||
ImGui::Checkbox("Show Verbosity", &ShowVerbosity);
|
||||
ImGui::Checkbox("Show As Table", &ShowAsTable);
|
||||
|
||||
//if (ImGui::SmallButton("Add Log"))
|
||||
//{
|
||||
// AddLog(TEXT("ABCD"), ELogVerbosity::Verbose, FName("Test"));
|
||||
// AddLog(TEXT("EFGH"), ELogVerbosity::Warning, FName("Test"));
|
||||
// AddLog(TEXT("WXYZ"), ELogVerbosity::Error, FName("Test"));
|
||||
//}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::MenuItem("Clear"))
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 9);
|
||||
if (ImGui::BeginCombo("##Verbosity", FCogDebugHelper::VerbosityToString((ELogVerbosity::Type)VerbosityFilter)))
|
||||
{
|
||||
for (int32 i = (int32)ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
|
||||
{
|
||||
bool IsSelected = i == VerbosityFilter;
|
||||
ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i;
|
||||
|
||||
if (ImGui::Selectable(FCogDebugHelper::VerbosityToString(Verbosity), IsSelected))
|
||||
{
|
||||
VerbosityFilter = i;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
FCogWindowWidgets::MenuSearchBar(Filter);
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
int32 ColumnCount = 1;
|
||||
ColumnCount += (int32)ShowFrame;
|
||||
ColumnCount += (int32)ShowCategory;
|
||||
ColumnCount += (int32)ShowVerbosity;
|
||||
|
||||
bool IsTableShown = false;
|
||||
if (ShowAsTable)
|
||||
{
|
||||
if (ImGui::BeginTable("LogTable", ColumnCount, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ScrollX))
|
||||
{
|
||||
IsTableShown = true;
|
||||
if (ShowFrame)
|
||||
{
|
||||
ImGui::TableSetupColumn("Frame", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::TextBaseWidth * 4);
|
||||
}
|
||||
|
||||
if (ShowCategory)
|
||||
{
|
||||
ImGui::TableSetupColumn("Category", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::TextBaseWidth * 10);
|
||||
}
|
||||
|
||||
if (ShowVerbosity)
|
||||
{
|
||||
ImGui::TableSetupColumn("Verbosity", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::TextBaseWidth * 10);
|
||||
}
|
||||
|
||||
ImGui::TableSetupColumn("Message", ImGuiTableColumnFlags_WidthStretch);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsTableShown == false)
|
||||
{
|
||||
ImGui::BeginChild("Scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||
}
|
||||
|
||||
const char* BufferStart = TextBuffer.begin();
|
||||
|
||||
if (Filter.IsActive())
|
||||
{
|
||||
for (int32 LineIndex = 0; LineIndex < LineInfos.Num(); LineIndex++)
|
||||
{
|
||||
const FLineInfo& LineInfo = LineInfos[LineIndex];
|
||||
const char* LineStart = BufferStart + LineInfo.Start;
|
||||
const char* LineEnd = BufferStart + LineInfo.End;
|
||||
if (Filter.PassFilter(LineStart, LineEnd))
|
||||
{
|
||||
DrawRow(BufferStart, LineInfo, IsTableShown);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (VerbosityFilter != ELogVerbosity::VeryVerbose)
|
||||
{
|
||||
for (int32 LineIndex = 0; LineIndex < LineInfos.Num(); LineIndex++)
|
||||
{
|
||||
const FLineInfo& LineInfo = LineInfos[LineIndex];
|
||||
|
||||
if (LineInfo.Verbosity <= (ELogVerbosity::Type)VerbosityFilter)
|
||||
{
|
||||
const char* LineStart = BufferStart + LineInfo.Start;
|
||||
const char* LineEnd = BufferStart + LineInfo.End;
|
||||
DrawRow(BufferStart, LineInfo, IsTableShown);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiListClipper Clipper;
|
||||
Clipper.Begin(LineInfos.Num());
|
||||
while (Clipper.Step())
|
||||
{
|
||||
for (int32 LineIndex = Clipper.DisplayStart; LineIndex < Clipper.DisplayEnd; LineIndex++)
|
||||
{
|
||||
if (LineInfos.IsValidIndex(LineIndex))
|
||||
{
|
||||
const FLineInfo& LineInfo = LineInfos[LineIndex];
|
||||
DrawRow(BufferStart, LineInfo, IsTableShown);
|
||||
}
|
||||
}
|
||||
}
|
||||
Clipper.End();
|
||||
}
|
||||
|
||||
if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
|
||||
{
|
||||
ImGui::SetScrollHereY(1.0f);
|
||||
}
|
||||
|
||||
if (IsTableShown)
|
||||
{
|
||||
ImGui::EndTable();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
#include "CogEngineWindow_Plots.h"
|
||||
|
||||
#include "CogImGuiHelper.h"
|
||||
#include "CogDebugPlot.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "imgui.h"
|
||||
#include "implot_internal.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_Plots::UCogEngineWindow_Plots()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Plots::RenderTick(float DeltaTime)
|
||||
{
|
||||
Super::RenderTick(DeltaTime);
|
||||
FCogDebugPlot::IsVisible = GetIsVisible();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Plots::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
static int Rows = 1;
|
||||
static int Cols = 1;
|
||||
|
||||
if (ImGui::BeginTable("PlotTable", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable))
|
||||
{
|
||||
ImGui::TableSetupColumn("Settings", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::TextBaseWidth * 20.0f);
|
||||
ImGui::TableSetupColumn("Graph", ImGuiTableColumnFlags_WidthStretch, 0.0f);
|
||||
ImGui::TableNextRow();
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Settings and Entries
|
||||
//--------------------------------------------------------------------------------------
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Settings"))
|
||||
{
|
||||
ImGui::OpenPopup("SettingsPopup");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::ToggleButton(&FCogDebugPlot::Pause, "Pause", "Pause", ImVec4(1.0f, 0.0f, 0.0f, 1.0f), ImVec4(0.5f, 0.5f, 0.5f, 1.0f));
|
||||
|
||||
if (ImGui::BeginPopup("SettingsPopup"))
|
||||
{
|
||||
ImGui::SliderInt("Rows", &Rows, 1, 5);
|
||||
|
||||
if (ImGui::Button("Clear Data", ImVec2(-1, 0)))
|
||||
{
|
||||
FCogDebugPlot::Clear();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Reset Layout", ImVec2(-1, 0)))
|
||||
{
|
||||
FCogDebugPlot::Pause = false;
|
||||
Rows = 1;
|
||||
|
||||
FCogDebugPlot::Reset();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui::BeginChild("Separator", ImVec2(0, 2)))
|
||||
{
|
||||
ImGui::Separator();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
TArray<FCogDebugPlotEntry*> VisiblePlots;
|
||||
if (ImGui::BeginChild("Plots", ImVec2(0, -1)))
|
||||
{
|
||||
int Index = 0;
|
||||
|
||||
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
|
||||
{
|
||||
const auto Label = StringCast<ANSICHAR>(*Plot.Name.ToString());
|
||||
|
||||
if (Plot.CurrentYAxis != ImAxis_COUNT && Plot.CurrentRow != INDEX_NONE)
|
||||
{
|
||||
VisiblePlots.Add(&Plot);
|
||||
}
|
||||
|
||||
ImGui::PushID(Index);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Plot.IsEventPlot ? IM_COL32(128, 128, 255, 255) : IM_COL32(255, 255, 255, 255));
|
||||
ImGui::Selectable(Label.Get(), false, 0);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
|
||||
{
|
||||
ImGui::SetDragDropPayload("DragAndDrop", Label.Get(), Label.Length() + 1);
|
||||
ImGui::TextUnformatted(Label.Get());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
|
||||
{
|
||||
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data)))
|
||||
{
|
||||
Plot->ResetAxis();
|
||||
}
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Graph
|
||||
//--------------------------------------------------------------------------------------
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::BeginChild("Graph", ImVec2(0, -1)))
|
||||
{
|
||||
static float RowRatios[] = { 1, 1, 1, 1, 1, 1 };
|
||||
static float ColRatios[] = { 1 };
|
||||
static ImPlotSubplotFlags SubplotsFlags = ImPlotSubplotFlags_LinkCols;
|
||||
if (ImPlot::BeginSubplots("", Rows, Cols, ImVec2(-1, -1), SubplotsFlags, RowRatios, ColRatios))
|
||||
{
|
||||
for (int PlotIndex = 0; PlotIndex < Rows; ++PlotIndex)
|
||||
{
|
||||
if (ImPlot::BeginPlot("##Plot", ImVec2(-1, 250)))
|
||||
{
|
||||
ImPlotAxisFlags HasPlotOnAxisY1 = false;
|
||||
ImPlotAxisFlags HasPlotOnAxisY2 = false;
|
||||
ImPlotAxisFlags HasPlotOnAxisY3 = false;
|
||||
|
||||
for (FCogDebugPlotEntry* PlotPtr : VisiblePlots)
|
||||
{
|
||||
HasPlotOnAxisY1 |= PlotPtr->CurrentYAxis == ImAxis_Y1 && PlotPtr->CurrentRow == PlotIndex;
|
||||
HasPlotOnAxisY2 |= PlotPtr->CurrentYAxis == ImAxis_Y2 && PlotPtr->CurrentRow == PlotIndex;
|
||||
HasPlotOnAxisY3 |= PlotPtr->CurrentYAxis == ImAxis_Y3 && PlotPtr->CurrentRow == PlotIndex;
|
||||
}
|
||||
|
||||
ImPlot::SetupAxis(ImAxis_X1, NULL, ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines);
|
||||
ImPlot::SetupAxis(ImAxis_Y1, HasPlotOnAxisY1 ? "" : "[drop here]", (HasPlotOnAxisY1 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit);
|
||||
ImPlot::SetupAxis(ImAxis_Y2, HasPlotOnAxisY2 ? "" : "[drop here]", (HasPlotOnAxisY2 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_Opposite);
|
||||
ImPlot::SetupAxis(ImAxis_Y3, HasPlotOnAxisY3 ? "" : "[drop here]", (HasPlotOnAxisY3 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_Opposite);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Set the initial X axis range. After it is automatically updated to move with the current time.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ImPlot::SetupAxisLimits(ImAxis_X1, 0, 10.0f, ImGuiCond_Appearing);
|
||||
|
||||
const ImPlotRange& Range = ImPlot::GetCurrentPlot()->Axes[ImAxis_X1].Range;
|
||||
const float AxisXRange = Range.Max - Range.Min;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Draw a vertical lines representing the current time and the mouse time
|
||||
//----------------------------------------------------------------
|
||||
ImDrawList* PlotDrawList = ImPlot::GetPlotDrawList();
|
||||
const ImVec2 PlotMin = ImPlot::GetPlotPos();
|
||||
const ImVec2 PlotSize = ImPlot::GetPlotSize();
|
||||
const ImVec2 PlotMax = ImVec2(PlotMin.x + PlotSize.x, PlotMin.y + PlotSize.y);
|
||||
const float PlotTop = PlotMin.y;
|
||||
const float TimeBarBottom = PlotTop + PlotSize.y;
|
||||
|
||||
ImPlot::PushPlotClipRect();
|
||||
PlotDrawList->AddLine(ImVec2(ImGui::GetMousePos().x, PlotTop), ImVec2(ImGui::GetMousePos().x, TimeBarBottom), IM_COL32(128, 128, 128, 64));
|
||||
if (FCogDebugPlot::Pause)
|
||||
{
|
||||
const float Time = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0;
|
||||
const float TimeBarX = ImPlot::PlotToPixels(Time, 0.0f).x;
|
||||
PlotDrawList->AddLine(ImVec2(TimeBarX, PlotTop), ImVec2(TimeBarX, TimeBarBottom), IM_COL32(255, 255, 255, 64));
|
||||
}
|
||||
ImPlot::PopPlotClipRect();
|
||||
|
||||
for (FCogDebugPlotEntry* PlotPtr : VisiblePlots)
|
||||
{
|
||||
if (PlotPtr == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FCogDebugPlotEntry& Entry = *PlotPtr;
|
||||
|
||||
if (Entry.CurrentRow == PlotIndex)
|
||||
{
|
||||
//--------------------------------------------------------------------------------
|
||||
// Make the time axis move forward automatically, unless the user pauses or zoom.
|
||||
//--------------------------------------------------------------------------------
|
||||
if (FCogDebugPlot::Pause == false && ImGui::GetIO().MouseWheel == 0)
|
||||
{
|
||||
ImPlot::SetupAxisLimits(ImAxis_X1, Entry.Time - AxisXRange, Entry.Time, ImGuiCond_Always);
|
||||
}
|
||||
|
||||
ImPlot::SetAxis(Entry.CurrentYAxis);
|
||||
|
||||
ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL);
|
||||
const auto Label = StringCast<ANSICHAR>(*Entry.Name.ToString());
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Pause the scrolling if the user drag inside
|
||||
//----------------------------------------------------------------
|
||||
ImVec2 Mouse = ImGui::GetMousePos();
|
||||
if (Mouse.x > PlotMin.x
|
||||
&& Mouse.y > PlotMin.y
|
||||
&& Mouse.x < PlotMax.x
|
||||
&& Mouse.y < PlotMax.y
|
||||
&& ImGui::GetDragDropPayload() == nullptr)
|
||||
{
|
||||
ImVec2 Drag = ImGui::GetMouseDragDelta(0);
|
||||
if (FMath::Abs(Drag.x) > 10)
|
||||
{
|
||||
FCogDebugPlot::Pause = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Plot Events
|
||||
//-------------------------------------------------------
|
||||
const bool IsEventPlot = Entry.Events.Num() > 0;
|
||||
if (IsEventPlot)
|
||||
{
|
||||
//--------------------------------------------------------------------
|
||||
// Update plot time for events as events are not pushed every frames
|
||||
//--------------------------------------------------------------------
|
||||
Entry.UpdateTime(GetWorld());
|
||||
|
||||
ImPlot::SetupAxisLimits(Entry.CurrentYAxis, 0, Entry.MaxRow + 2, ImGuiCond_Always);
|
||||
|
||||
ImPlot::PushPlotClipRect();
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Plot line only to make the plotter move in time and auto scale
|
||||
//----------------------------------------------------------------
|
||||
ImVector<ImVec2> DummyData;
|
||||
DummyData.push_back(ImVec2(0, 0));
|
||||
DummyData.push_back(ImVec2(0, 8));
|
||||
ImPlot::PlotLine(Label.Get(), &DummyData[0].x, &DummyData[0].y, DummyData.size(), Entry.ValueOffset, 2 * sizeof(float));
|
||||
|
||||
const FCogDebugPlotEvent* HoveredEvent = nullptr;
|
||||
|
||||
for (const FCogDebugPlotEvent& Event : Entry.Events)
|
||||
{
|
||||
const ImVec2 PosBot = ImPlot::PlotToPixels(ImPlotPoint(Event.StartTime, Event.Row + 0.8f));
|
||||
const ImVec2 PosTop = ImPlot::PlotToPixels(ImPlotPoint(Event.StartTime, Event.Row + 0.2f));
|
||||
const ImVec2 PosMid(PosBot.x, PosBot.y + (PosTop.y - PosBot.y) * 0.5f);
|
||||
|
||||
const bool IsInstant = Event.StartTime == Event.EndTime;
|
||||
if (IsInstant)
|
||||
{
|
||||
const float Radius = 10.0f;
|
||||
PlotDrawList->AddNgon(PosMid, 10, Event.BorderColor, 4);
|
||||
PlotDrawList->AddNgonFilled(PosMid, 10, Event.FillColor, 4);
|
||||
PlotDrawList->AddText(ImVec2(PosMid.x + 15, PosMid.y - 6), IM_COL32(255, 255, 255, 255), TCHAR_TO_ANSI(*Event.DisplayName));
|
||||
|
||||
if ((Mouse.x > PosMid.x - Radius) && (Mouse.x < PosMid.x + Radius) && (Mouse.y > PosMid.y - Radius) && (Mouse.y < PosMid.y + Radius))
|
||||
{
|
||||
HoveredEvent = &Event;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const float ActualEndTime = Event.GetActualEndTime(Entry);
|
||||
const ImVec2 PosEnd = ImPlot::PlotToPixels(ImPlotPoint(ActualEndTime, 0));
|
||||
const ImVec2 Min = ImVec2(PosBot.x, PosBot.y);
|
||||
const ImVec2 Max = ImVec2(PosEnd.x, PosTop.y);
|
||||
|
||||
ImDrawFlags Flags = Event.EndTime == 0.0f ? ImDrawFlags_RoundCornersLeft : ImDrawFlags_RoundCornersAll;
|
||||
PlotDrawList->AddRect(Min, Max, Event.BorderColor, 6.0f, Flags);
|
||||
PlotDrawList->AddRectFilled(Min, Max, Event.FillColor, 6.0f, Flags);
|
||||
PlotDrawList->PushClipRect(ImMax(Min, PlotMin), ImMin(Max, PlotMax));
|
||||
PlotDrawList->AddText(ImVec2(PosMid.x + 5, PosMid.y - 7), IM_COL32(255, 255, 255, 255), TCHAR_TO_ANSI(*Event.DisplayName));
|
||||
PlotDrawList->PopClipRect();
|
||||
|
||||
if (Mouse.x > Min.x && Mouse.x < Max.x && Mouse.y > Min.y && Mouse.y < Max.y)
|
||||
{
|
||||
HoveredEvent = &Event;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Write info on the graph to help debugging
|
||||
//-------------------------------------------------------
|
||||
//char Buffer[64];
|
||||
//ImFormatString(Buffer, 64, "%0.1f %0.1f", Mouse.x, Mouse.y);
|
||||
//PlotDrawList->AddText(ImVec2(PlotMin.x + 50, PlotMin.y + 100), IM_COL32(255, 255, 255, 255), Buffer);
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Hovered event tooltip
|
||||
//-------------------------------------------------------
|
||||
if (ImPlot::IsPlotHovered() && HoveredEvent != nullptr)
|
||||
{
|
||||
FCogWindowWidgets::BeginTableTooltip();
|
||||
if (ImGui::BeginTable("Params", 2, ImGuiTableFlags_Borders))
|
||||
{
|
||||
//------------------------
|
||||
// Event Name
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Name");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*HoveredEvent->DisplayName));
|
||||
|
||||
//------------------------
|
||||
// Owner Name
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Owner");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*HoveredEvent->OwnerName));
|
||||
|
||||
//------------------------
|
||||
// Times
|
||||
//------------------------
|
||||
if (HoveredEvent->EndTime != HoveredEvent->StartTime)
|
||||
{
|
||||
const float ActualEndTime = HoveredEvent->GetActualEndTime(Entry);
|
||||
const uint64 ActualEndFrame = HoveredEvent->GetActualEndFrame(Entry);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Duration");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%0.2fs", ActualEndTime - HoveredEvent->StartTime);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Frames");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d [%d-%d]",
|
||||
(int32)(ActualEndFrame - HoveredEvent->StartFrame),
|
||||
(int32)(HoveredEvent->StartFrame % 1000),
|
||||
(int32)(ActualEndFrame % 1000));
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Frame");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", (int32)(HoveredEvent->StartFrame % 1000));
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Params
|
||||
//------------------------
|
||||
for (FCogDebugPlotEventParams Param : HoveredEvent->Params)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Param.Name.ToString()));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Param.Value));
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
FCogWindowWidgets::EndTableTooltip();
|
||||
}
|
||||
|
||||
ImPlot::PopPlotClipRect();
|
||||
}
|
||||
//-------------------------------------------------------
|
||||
// Plot Values
|
||||
//-------------------------------------------------------
|
||||
else
|
||||
{
|
||||
//----------------------------------------------------------------
|
||||
// Custom tooltip
|
||||
//----------------------------------------------------------------
|
||||
if (ImPlot::IsPlotHovered())
|
||||
{
|
||||
float Value;
|
||||
if (Entry.FindValue(ImPlot::GetPlotMousePos().x, Value))
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s: %0.1f", Label.Get(), Value);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
if (Entry.ShowValuesMarkers)
|
||||
{
|
||||
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
|
||||
}
|
||||
|
||||
ImPlot::PlotLine(Label.Get(), &Entry.Values[0].x, &Entry.Values[0].y, Entry.Values.size(), ImPlotLineFlags_None, Entry.ValueOffset, 2 * sizeof(float));
|
||||
|
||||
if (ImPlot::BeginLegendPopup(Label.Get()))
|
||||
{
|
||||
if (ImGui::Button("Clear"))
|
||||
{
|
||||
Entry.Clear();
|
||||
}
|
||||
ImGui::Checkbox("Show Markers", &Entry.ShowValuesMarkers);
|
||||
ImPlot::EndLegendPopup();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Allow legend item labels to be drag and drop sources
|
||||
//-------------------------------------------------------
|
||||
if (ImPlot::BeginDragDropSourceItem(Label.Get()))
|
||||
{
|
||||
ImGui::SetDragDropPayload("DragAndDrop", Label.Get(), Label.Length() + 1);
|
||||
ImGui::TextUnformatted(Label.Get());
|
||||
ImPlot::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Allow the main plot area to be a drag and drop target
|
||||
//-------------------------------------------------------
|
||||
if (ImPlot::BeginDragDropTargetPlot())
|
||||
{
|
||||
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
|
||||
{
|
||||
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data)))
|
||||
{
|
||||
Plot->AssignAxis(PlotIndex, ImAxis_Y1);
|
||||
}
|
||||
}
|
||||
ImPlot::EndDragDropTarget();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Allow each y-axis to be a drag and drop target
|
||||
//-------------------------------------------------------
|
||||
for (int y = ImAxis_Y1; y <= ImAxis_Y3; ++y)
|
||||
{
|
||||
if (ImPlot::BeginDragDropTargetAxis(y))
|
||||
{
|
||||
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
|
||||
{
|
||||
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data)))
|
||||
{
|
||||
Plot->AssignAxis(PlotIndex, y);
|
||||
}
|
||||
}
|
||||
ImPlot::EndDragDropTarget();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Allow the legend to be a drag and drop target
|
||||
//-------------------------------------------------------
|
||||
if (ImPlot::BeginDragDropTargetLegend())
|
||||
{
|
||||
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
|
||||
{
|
||||
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data)))
|
||||
{
|
||||
Plot->AssignAxis(PlotIndex, ImAxis_Y1);
|
||||
}
|
||||
}
|
||||
ImPlot::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
ImPlot::EndSubplots();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "CogEngineWindow_Scalability.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "CogImguiHelper.h"
|
||||
#include "Engine/Engine.h"
|
||||
|
||||
#define SCALABILITY_NUM_LEVELS 5
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_Scalability::UCogEngineWindow_Scalability()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Scalability::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
Scalability::FQualityLevels Levels = Scalability::GetQualityLevels();
|
||||
FString CurrentQualityName = Scalability::GetQualityLevelText(Levels.GetMinQualityLevel(), SCALABILITY_NUM_LEVELS).ToString();
|
||||
if (ImGui::BeginCombo("Scalability", TCHAR_TO_ANSI(*CurrentQualityName)))
|
||||
{
|
||||
for (int32 i = 0; i < SCALABILITY_NUM_LEVELS; ++i)
|
||||
{
|
||||
FString QualityName = Scalability::GetQualityLevelText(i, SCALABILITY_NUM_LEVELS).ToString();
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*QualityName)))
|
||||
{
|
||||
Levels.SetFromSingleQualityLevel(i);
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
|
||||
ImGui::LogToClipboard();
|
||||
ImGui::LogText("%s", TCHAR_TO_ANSI(*FString::Printf(TEXT("Setting Quality Level to %s"), *QualityName)));
|
||||
ImGui::LogFinish();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::SliderFloat("Resolution", &Levels.ResolutionQuality, 10.0f, 100.0f, "%0.f"))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("View Distance", &Levels.ViewDistanceQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Anti Aliasing", &Levels.AntiAliasingQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Shadow", &Levels.ShadowQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Global Illumination", &Levels.GlobalIlluminationQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Reflection", &Levels.ReflectionQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Post Process", &Levels.PostProcessQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Texture", &Levels.TextureQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Effects", &Levels.EffectsQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Foliage", &Levels.FoliageQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
|
||||
if (ImGui::SliderInt("Shading", &Levels.ShadingQuality, 0, SCALABILITY_NUM_LEVELS - 1))
|
||||
{
|
||||
Scalability::SetQualityLevels(Levels);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,485 @@
|
||||
#include "CogEngineWindow_Selection.h"
|
||||
|
||||
#include "CogDebugDraw.h"
|
||||
#include "CogImguiModule.h"
|
||||
#include "CogWindowManager.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "imgui.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_Selection::UCogEngineWindow_Selection()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::ToggleSelectionMode()
|
||||
{
|
||||
if (bSelectionModeActive)
|
||||
{
|
||||
DeactivateSelectionMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSelectionMode();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::ActivateSelectionMode()
|
||||
{
|
||||
bSelectionModeActive = true;
|
||||
bImGuiHadInputBeforeEnteringSelectionMode = FCogImguiModule::Get().GetEnableInput();
|
||||
FCogImguiModule::Get().SetEnableInput(true);
|
||||
GetOwner()->SetHideAllWindows(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void UCogEngineWindow_Selection::HackWaitInputRelease()
|
||||
{
|
||||
WaitInputReleased = 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::DeactivateSelectionMode()
|
||||
{
|
||||
bSelectionModeActive = false;
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// We can enter selection mode by a command, and imgui might not have the input focus
|
||||
// When in selection mode we need imgui to have the input focus
|
||||
// When leaving selection mode we want to leave it as is was before
|
||||
//--------------------------------------------------------------------------------------------
|
||||
if (bImGuiHadInputBeforeEnteringSelectionMode == false)
|
||||
{
|
||||
FCogImguiModule::Get().SetEnableInput(false);
|
||||
}
|
||||
|
||||
GetOwner()->SetHideAllWindows(false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::RenderTick(float DeltaTime)
|
||||
{
|
||||
Super::RenderTick(DeltaTime);
|
||||
|
||||
if (FCogDebugSettings::GetSelection() == nullptr)
|
||||
{
|
||||
FCogDebugSettings::SetSelection(GetLocalPlayerPawn());
|
||||
}
|
||||
|
||||
if (bSelectionModeActive)
|
||||
{
|
||||
TickSelectionMode();
|
||||
}
|
||||
|
||||
if (AActor* Actor = GetSelection())
|
||||
{
|
||||
if (Actor != GetLocalPlayerPawn())
|
||||
{
|
||||
DrawActorFrame(Actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::MenuItem("Pick"))
|
||||
{
|
||||
ActivateSelectionMode();
|
||||
HackWaitInputRelease();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
DrawSelectionCombo();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
bool UCogEngineWindow_Selection::DrawSelectionCombo()
|
||||
{
|
||||
bool SelectionChanged = false;
|
||||
|
||||
APawn* LocalPlayerPawn = GetLocalPlayerPawn();
|
||||
|
||||
//------------------------
|
||||
// Actor Class Combo
|
||||
//------------------------
|
||||
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::BeginCombo("##SelectionType", TCHAR_TO_ANSI(*GetNameSafe(SelectedSubClass))))
|
||||
{
|
||||
for (TSubclassOf<AActor> ItSubClass : SubClasses)
|
||||
{
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(ItSubClass)), false))
|
||||
{
|
||||
SelectedSubClass = ItSubClass;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
//------------------------
|
||||
// Actor List
|
||||
//------------------------
|
||||
//ImGui::BeginChild("ActorList", ImVec2(-1, -1), false);
|
||||
|
||||
TArray<AActor*> Actors;
|
||||
for (TActorIterator<AActor> It(GetWorld(), SelectedSubClass); It; ++It)
|
||||
{
|
||||
AActor* Actor = *It;
|
||||
Actors.Add(Actor);
|
||||
}
|
||||
|
||||
ImGuiListClipper Clipper;
|
||||
Clipper.Begin(Actors.Num());
|
||||
while (Clipper.Step())
|
||||
{
|
||||
for (int32 i = Clipper.DisplayStart; i < Clipper.DisplayEnd; i++)
|
||||
{
|
||||
AActor* Actor = Actors[i];
|
||||
if (Actor == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Actor == LocalPlayerPawn ? IM_COL32(255, 255, 0, 255) : IM_COL32(255, 255, 255, 255));
|
||||
|
||||
bool bIsSelected = Actor == FCogDebugSettings::GetSelection();
|
||||
const FString ActorName = GetNameSafe(Actor);
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*ActorName), bIsSelected))
|
||||
{
|
||||
FCogDebugSettings::SetSelection(Actor);
|
||||
SelectionChanged = true;
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
DrawActorContextMenu(Actor);
|
||||
|
||||
//------------------------
|
||||
// Draw Frame
|
||||
//------------------------
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
DrawActorFrame(Actor);
|
||||
}
|
||||
|
||||
if (bIsSelected)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
Clipper.End();
|
||||
//ImGui::EndChild();
|
||||
|
||||
return SelectionChanged;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void UCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor)
|
||||
{
|
||||
//------------------------
|
||||
// ContextMenu
|
||||
//------------------------
|
||||
ImGui::SetNextWindowSize(ImVec2(FCogWindowWidgets::TextBaseWidth * 20, 0));
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
if (ImGui::Button("Reset Selection", ImVec2(-1, 0)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
FCogDebugSettings::SetSelection(GetLocalPlayerPawn());
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Reset the selection to the controlled actor.");
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::TickSelectionMode()
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
||||
{
|
||||
DeactivateSelectionMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AnyWindow))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
APlayerController* PlayerController = GetLocalPlayerController();
|
||||
if (PlayerController == nullptr)
|
||||
{
|
||||
DeactivateSelectionMode();
|
||||
return;
|
||||
}
|
||||
|
||||
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
|
||||
DrawList->AddRect(ImVec2(0, 0), ImGui::GetIO().DisplaySize, IM_COL32(255, 0, 0, 128), 0.0f, 0, 20.0f);
|
||||
FCogWindowWidgets::AddTextWithShadow(DrawList, ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel");
|
||||
|
||||
AActor* HoveredActor = nullptr;
|
||||
|
||||
FVector WorldOrigin, WorldDirection;
|
||||
if (UGameplayStatics::DeprojectScreenToWorld(PlayerController, FCogImguiHelper::ToVector2D(ImGui::GetMousePos()), WorldOrigin, WorldDirection))
|
||||
{
|
||||
TArray<AActor*> IgnoreList;
|
||||
|
||||
FHitResult HitResult;
|
||||
if (UKismetSystemLibrary::LineTraceSingle(GetWorld(), WorldOrigin, WorldOrigin + WorldDirection * 10000, TraceType, false, IgnoreList, EDrawDebugTrace::None, HitResult, true))
|
||||
{
|
||||
if (HitResult.GetActor() != nullptr)
|
||||
{
|
||||
if (HitResult.GetActor()->GetClass()->IsChildOf(SelectedSubClass))
|
||||
{
|
||||
HoveredActor = HitResult.GetActor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HoveredActor != nullptr)
|
||||
{
|
||||
DrawActorFrame(HoveredActor);
|
||||
}
|
||||
|
||||
if (bSelectionModeActive)
|
||||
{
|
||||
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||
{
|
||||
if (WaitInputReleased == 0)
|
||||
{
|
||||
if (HoveredActor != nullptr)
|
||||
{
|
||||
FCogDebugSettings::SetSelection(HoveredActor);
|
||||
}
|
||||
|
||||
DeactivateSelectionMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitInputReleased--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::DrawActorFrame(const AActor* Actor)
|
||||
{
|
||||
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
|
||||
if (PlayerController == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
|
||||
|
||||
FVector BoxOrigin, BoxExtent;
|
||||
|
||||
bool PrimitiveFound = false;
|
||||
FBox Bounds(ForceInit);
|
||||
|
||||
if (const UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(Actor->GetRootComponent()))
|
||||
{
|
||||
PrimitiveFound = true;
|
||||
Bounds += PrimitiveComponent->Bounds.GetBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
Actor->ForEachComponent<UPrimitiveComponent>(true, [&](const UPrimitiveComponent* InPrimComp)
|
||||
{
|
||||
if (InPrimComp->IsRegistered() && InPrimComp->IsCollisionEnabled())
|
||||
{
|
||||
Bounds += InPrimComp->Bounds.GetBox();
|
||||
PrimitiveFound = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (PrimitiveFound)
|
||||
{
|
||||
Bounds.GetCenterAndExtents(BoxOrigin, BoxExtent);
|
||||
}
|
||||
else
|
||||
{
|
||||
BoxOrigin = Actor->GetActorLocation();
|
||||
BoxExtent = FVector(50.f, 50.f, 50.f);
|
||||
}
|
||||
|
||||
FVector2D ScreenPosMin, ScreenPosMax;
|
||||
if (ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax))
|
||||
{
|
||||
const ImU32 Color = (Actor == GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128);
|
||||
DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin), FCogImguiHelper::ToImVec2(ScreenPosMax), Color, 0.0f, 0, 1.0f);
|
||||
FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)), Color, TCHAR_TO_ANSI(*Actor->GetName()));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
bool UCogEngineWindow_Selection::ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max)
|
||||
{
|
||||
FVector Corners[8];
|
||||
Corners[0].Set(-Extent.X, -Extent.Y, -Extent.Z); // - - -
|
||||
Corners[1].Set(Extent.X, -Extent.Y, -Extent.Z); // + - -
|
||||
Corners[2].Set(-Extent.X, Extent.Y, -Extent.Z); // - + -
|
||||
Corners[3].Set(-Extent.X, -Extent.Y, Extent.Z); // - - +
|
||||
Corners[4].Set(Extent.X, Extent.Y, -Extent.Z); // + + -
|
||||
Corners[5].Set(Extent.X, -Extent.Y, Extent.Z); // + - +
|
||||
Corners[6].Set(-Extent.X, Extent.Y, Extent.Z); // - + +
|
||||
Corners[7].Set(Extent.X, Extent.Y, Extent.Z); // + + +
|
||||
|
||||
Min.X = FLT_MAX;
|
||||
Min.Y = FLT_MAX;
|
||||
Max.X = -FLT_MAX;
|
||||
Max.Y = -FLT_MAX;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
FVector2D ScreenLocation;
|
||||
if (PlayerController->ProjectWorldLocationToScreen(Origin + Corners[i], ScreenLocation, false) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Min.X = FMath::Min(ScreenLocation.X, Min.X);
|
||||
Min.Y = FMath::Min(ScreenLocation.Y, Min.Y);
|
||||
Max.X = FMath::Max(ScreenLocation.X, Max.X);
|
||||
Max.Y = FMath::Max(ScreenLocation.Y, Max.Y);
|
||||
}
|
||||
|
||||
// Prevent getting large values when the camera get close to the target
|
||||
ImVec2 DisplaySize = ImGui::GetIO().DisplaySize;
|
||||
Min.X = FMath::Max(-DisplaySize.x, Min.X);
|
||||
Min.Y = FMath::Max(-DisplaySize.y, Min.Y);
|
||||
Max.X = FMath::Min(DisplaySize.x * 2, Max.X);
|
||||
Max.Y = FMath::Min(DisplaySize.y * 2, Max.Y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Selection::DrawMainMenuWidget(bool Draw, float& Width)
|
||||
{
|
||||
const float PickButtonWidth = FCogWindowWidgets::TextBaseWidth * 5;
|
||||
const float SelectionButtonWidth = FCogWindowWidgets::TextBaseWidth * 30;
|
||||
const float ResetButtonWidth = FCogWindowWidgets::TextBaseWidth * 2;
|
||||
Width = PickButtonWidth + SelectionButtonWidth + ResetButtonWidth;
|
||||
|
||||
if (Draw == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("SelectionPopup"))
|
||||
{
|
||||
ImGui::BeginChild("Popup", ImVec2(Width, FCogWindowWidgets::TextBaseWidth * 40), false);
|
||||
|
||||
if (DrawSelectionCombo())
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// Pick Button
|
||||
//-----------------------------------
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
|
||||
|
||||
if (ImGui::Button("Pick", ImVec2(PickButtonWidth, 0)))
|
||||
{
|
||||
ActivateSelectionMode();
|
||||
HackWaitInputRelease();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Enter picking mode to select an actor on screen.");
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
AActor* GlobalSelection = FCogDebugSettings::GetSelection();
|
||||
|
||||
//-----------------------------------
|
||||
// Selection
|
||||
//-----------------------------------
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4((ImGuiCol_FrameBg)));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4((ImGuiCol_FrameBgActive)));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyleColorVec4((ImGuiCol_FrameBgHovered)));
|
||||
ImGui::SameLine();
|
||||
FString SelectionName = GetNameSafe(GlobalSelection);
|
||||
|
||||
if (ImGui::Button(TCHAR_TO_ANSI(*SelectionName), ImVec2(SelectionButtonWidth, 0)))
|
||||
{
|
||||
ImGui::OpenPopup("SelectionPopup");
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Current Selection: %s", TCHAR_TO_ANSI(*SelectionName));
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
DrawActorContextMenu(GlobalSelection);
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// Reset Button
|
||||
//-----------------------------------
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4((ImGuiCol_FrameBg)));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4((ImGuiCol_FrameBgActive)));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyleColorVec4((ImGuiCol_FrameBgHovered)));
|
||||
ImGui::SameLine(ImGui::GetCursorPos().x - ResetButtonWidth + (ImGui::GetStyle().WindowPadding.x - 2) * ImGui::GetWindowDpiScale());
|
||||
if (ImGui::Button("X", ImVec2(ResetButtonWidth, 0)))
|
||||
{
|
||||
FCogDebugSettings::SetSelection(nullptr);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Reset the selection to the controlled actor.");
|
||||
}
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::PopStyleVar(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
#include "CogEngineWindow_Skeleton.h"
|
||||
|
||||
#include "CogDebugSettings.h"
|
||||
#include "Components/LineBatchComponent.h"
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
#include "Engine/SkeletalMesh.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_Skeleton::UCogEngineWindow_Skeleton()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::OnSelectionChanged(AActor* OldSelection, AActor* NewSelection)
|
||||
{
|
||||
RefreshSkeleton();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::RenderTick(float DeltaTime)
|
||||
{
|
||||
Super::RenderTick(DeltaTime);
|
||||
|
||||
if (GetIsVisible() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawSkeleton();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::RefreshSkeleton()
|
||||
{
|
||||
CurrentSkeleton = nullptr;
|
||||
BonesInfos.Empty();
|
||||
|
||||
|
||||
AActor* Selection = GetSelection();
|
||||
if (Selection == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentSkeleton = Selection->FindComponentByClass<USkeletalMeshComponent>();
|
||||
if (CurrentSkeleton == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FTransform WorldTransform = CurrentSkeleton->GetComponentTransform();
|
||||
const TArray<FTransform>& ComponentSpaceTransforms = CurrentSkeleton->GetComponentSpaceTransforms();
|
||||
BonesInfos.SetNum(ComponentSpaceTransforms.Num());
|
||||
|
||||
for (int32 BoneIndex = 0; BoneIndex < ComponentSpaceTransforms.Num(); ++BoneIndex)
|
||||
{
|
||||
const FReferenceSkeleton& ReferenceSkeleton = CurrentSkeleton->GetSkeletalMeshAsset()->GetRefSkeleton();
|
||||
|
||||
FBoneInfo& CurrentBoneInfo = BonesInfos[BoneIndex];
|
||||
CurrentBoneInfo.Index = BoneIndex;
|
||||
CurrentBoneInfo.Name = ReferenceSkeleton.GetBoneName(BoneIndex);
|
||||
const FTransform Transform = ComponentSpaceTransforms[BoneIndex] * WorldTransform;
|
||||
CurrentBoneInfo.LastLocation = Transform.GetLocation();
|
||||
CurrentBoneInfo.IsSecondaryBone = FCogDebugSettings::IsSecondarySkeletonBone(CurrentBoneInfo.Name);
|
||||
CurrentBoneInfo.ShowBone = !(HideSecondaryBones && CurrentBoneInfo.IsSecondaryBone);
|
||||
|
||||
const int32 ParentIndex = ReferenceSkeleton.GetParentIndex(BoneIndex);
|
||||
if (ParentIndex != INDEX_NONE)
|
||||
{
|
||||
FBoneInfo& ParentBoneInfo = BonesInfos[ParentIndex];
|
||||
ParentBoneInfo.Children.Add(BoneIndex);
|
||||
CurrentBoneInfo.ParentIndex = ParentIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
ImGui::Checkbox("Hide secondary bones", &HideSecondaryBones);
|
||||
ImGui::Separator();
|
||||
ImGui::Checkbox("Show bones", &ShowBones);
|
||||
ImGui::Checkbox("Show name", &ShowNames);
|
||||
ImGui::Checkbox("Show axes", &ShowAxes);
|
||||
ImGui::Checkbox("Show local velocity", &ShowVelocities);
|
||||
ImGui::Checkbox("Show trajectories", &ShowTrajectories);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
FCogWindowWidgets::MenuSearchBar(Filter);
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, FCogWindowWidgets::TextBaseWidth);
|
||||
|
||||
HoveredBoneIndex = INDEX_NONE;
|
||||
DrawBoneEntry(0, false);
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::DrawBoneEntry(int32 BoneIndex, bool OpenAllChildren)
|
||||
{
|
||||
if (BonesInfos.IsValidIndex(BoneIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FBoneInfo& BoneInfo = BonesInfos[BoneIndex];
|
||||
|
||||
if (HideSecondaryBones && BoneInfo.IsSecondaryBone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char* BoneName = TCHAR_TO_ANSI(*BoneInfo.Name.ToString());
|
||||
const bool ShowNode = Filter.PassFilter(BoneName);
|
||||
bool OpenChildren = false;
|
||||
|
||||
if (ShowNode)
|
||||
{
|
||||
ImGui::PushID(BoneIndex);
|
||||
|
||||
if (OpenAllChildren)
|
||||
{
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Always);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// TreeNode
|
||||
//------------------------
|
||||
if (BoneInfo.Children.Num() > 0 && Filter.IsActive() == false)
|
||||
{
|
||||
OpenChildren = ImGui::TreeNodeEx("##Bone", ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TreeNodeEx("##Bone", ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
}
|
||||
|
||||
const bool IsControlDown = ImGui::GetCurrentContext()->IO.KeyCtrl;
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left) && IsControlDown)
|
||||
{
|
||||
OpenAllChildren = true;
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// ContextMenu
|
||||
//------------------------
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
ImGui::Checkbox("Show Name", &BoneInfo.ShowName);
|
||||
ImGui::Checkbox("Show Axe", &BoneInfo.ShowAxes);
|
||||
ImGui::Checkbox("Show Local Velocity", &BoneInfo.ShowLocalVelocity);
|
||||
ImGui::Checkbox("Show Trajectory", &BoneInfo.ShowTrajectory);
|
||||
ImGui::EndPopup();
|
||||
HoveredBoneIndex = BoneIndex;
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Tooltip
|
||||
//------------------------
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Checkbox("Show Name", &BoneInfo.ShowName);
|
||||
ImGui::Checkbox("Show Axe", &BoneInfo.ShowAxes);
|
||||
ImGui::Checkbox("Show Local Velocity", &BoneInfo.ShowLocalVelocity);
|
||||
ImGui::Checkbox("Show Trajectory", &BoneInfo.ShowTrajectory);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::EndTooltip();
|
||||
HoveredBoneIndex = BoneIndex;
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Checkbox
|
||||
//------------------------
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox("##Visible", &BoneInfo.ShowBone))
|
||||
{
|
||||
if (IsControlDown)
|
||||
{
|
||||
SetChildrenVisibility(BoneIndex, BoneInfo.ShowBone);
|
||||
}
|
||||
|
||||
if (BoneInfo.ShowBone == false)
|
||||
{
|
||||
BoneInfo.ShowName = false;
|
||||
BoneInfo.ShowAxes = false;
|
||||
BoneInfo.ShowLocalVelocity = false;
|
||||
BoneInfo.ShowTrajectory = false;
|
||||
}
|
||||
}
|
||||
|
||||
const bool HasCustomVisiblity = BoneInfo.ShowName || BoneInfo.ShowAxes || BoneInfo.ShowLocalVelocity || BoneInfo.ShowTrajectory;
|
||||
if (HasCustomVisiblity)
|
||||
{
|
||||
BoneInfo.ShowBone = true;
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::SameLine();
|
||||
ImVec4 NameColor = HasCustomVisiblity ? ImVec4(1.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
ImGui::TextColored(NameColor, "%s", BoneName);
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Children
|
||||
//------------------------
|
||||
if (OpenChildren || Filter.IsActive())
|
||||
{
|
||||
for (int32 ChildIndex : BoneInfo.Children)
|
||||
{
|
||||
DrawBoneEntry(ChildIndex, OpenAllChildren);
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowNode)
|
||||
{
|
||||
if (OpenChildren && ShowNode)
|
||||
{
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::SetChildrenVisibility(int32 BoneIndex, bool IsVisible)
|
||||
{
|
||||
if (BonesInfos.IsValidIndex(BoneIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FBoneInfo& BoneInfo = BonesInfos[BoneIndex];
|
||||
for (int32 ChildIndex : BoneInfo.Children)
|
||||
{
|
||||
FBoneInfo& ChildBoneInfo = BonesInfos[ChildIndex];
|
||||
ChildBoneInfo.ShowBone = IsVisible && !(HideSecondaryBones && ChildBoneInfo.IsSecondaryBone);
|
||||
SetChildrenVisibility(ChildIndex, IsVisible);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Skeleton::DrawSkeleton()
|
||||
{
|
||||
if (CurrentSkeleton == nullptr || CurrentSkeleton->GetWorld() == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UWorld* World = CurrentSkeleton->GetWorld();
|
||||
const FTransform WorldTransform = CurrentSkeleton->GetComponentTransform();
|
||||
const TArray<FTransform>& ComponentSpaceTransforms = CurrentSkeleton->GetComponentSpaceTransforms();
|
||||
|
||||
for (int32 BoneIndex = 0; BoneIndex < ComponentSpaceTransforms.Num(); ++BoneIndex)
|
||||
{
|
||||
FBoneInfo& BoneInfo = BonesInfos[BoneIndex];
|
||||
|
||||
const FTransform Transform = ComponentSpaceTransforms[BoneIndex] * WorldTransform;
|
||||
FVector BoneLocation = Transform.GetLocation();
|
||||
FRotator BoneRotation = FRotator(Transform.GetRotation());
|
||||
|
||||
FVector ParentLocation;
|
||||
if (BoneInfo.ParentIndex >= 0)
|
||||
{
|
||||
ParentLocation = (ComponentSpaceTransforms[BoneInfo.ParentIndex] * WorldTransform).GetLocation();
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentLocation = WorldTransform.GetLocation();
|
||||
}
|
||||
|
||||
if (BoneInfo.ShowBone)
|
||||
{
|
||||
const bool IsHovered = BoneIndex == HoveredBoneIndex;
|
||||
|
||||
if (ShowBones)
|
||||
{
|
||||
::DrawDebugLine(World, ParentLocation, BoneLocation, IsHovered ? FColor::Red : FColor::White, false, 0.0f, 1, FCogDebugSettings::GetDebugThickness(IsHovered ? 0.5f : 0.0f));
|
||||
::DrawDebugPoint(World, BoneLocation, FCogDebugSettings::GetDebugThickness(IsHovered ? 6.0f : 4.0f), IsHovered ? FColor::Red : FColor::White, false, 0.0f, 1);
|
||||
}
|
||||
|
||||
if (ShowNames || BoneInfo.ShowName || IsHovered)
|
||||
{
|
||||
::DrawDebugString(World, BoneLocation, BoneInfo.Name.ToString(), nullptr, IsHovered ? FColor::Red : FColor::White, 0.0f, true, FCogDebugSettings::TextSize);
|
||||
}
|
||||
|
||||
if (ShowAxes || BoneInfo.ShowAxes)
|
||||
{
|
||||
::DrawDebugCoordinateSystem(
|
||||
World,
|
||||
BoneLocation,
|
||||
BoneRotation,
|
||||
10.0f * FCogDebugSettings::AxesScale,
|
||||
false,
|
||||
0.0f,
|
||||
1,
|
||||
FCogDebugSettings::GetDebugThickness(0.0f));
|
||||
}
|
||||
|
||||
if (ShowVelocities || BoneInfo.ShowLocalVelocity)
|
||||
{
|
||||
if (const FBodyInstance* ParentBodyInstance = CurrentSkeleton->GetBodyInstance(BoneInfo.Name))
|
||||
{
|
||||
DrawDebugDirectionalArrow(
|
||||
World,
|
||||
BoneLocation,
|
||||
BoneLocation + ParentBodyInstance->GetUnrealWorldVelocity() * World->GetDeltaSeconds(),
|
||||
FCogDebugSettings::ArrowSize,
|
||||
FCogDebugSettings::ModulateDebugColor(World, FColor::Cyan),
|
||||
FCogDebugSettings::GetDebugPersistent(true),
|
||||
FCogDebugSettings::GetDebugDuration(true),
|
||||
0,
|
||||
FCogDebugSettings::GetDebugThickness(0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowTrajectories || BoneInfo.ShowTrajectory)
|
||||
{
|
||||
const FColor Color = FCogDebugSettings::ModulateDebugColor(World, FColor::Yellow);
|
||||
DrawDebugLine(
|
||||
World,
|
||||
BoneInfo.LastLocation,
|
||||
BoneLocation,
|
||||
Color,
|
||||
FCogDebugSettings::GetDebugPersistent(true),
|
||||
FCogDebugSettings::GetDebugDuration(true),
|
||||
0,
|
||||
FCogDebugSettings::GetDebugThickness(0.0f));
|
||||
|
||||
DrawDebugPoint(
|
||||
World,
|
||||
BoneLocation,
|
||||
FCogDebugSettings::GetDebugThickness(2.0f),
|
||||
Color,
|
||||
FCogDebugSettings::GetDebugPersistent(true),
|
||||
FCogDebugSettings::GetDebugDuration(true),
|
||||
0);
|
||||
}
|
||||
|
||||
BoneInfo.LastLocation = BoneLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "CogEngineWindow_Stats.h"
|
||||
|
||||
#include "Engine/Engine.h"
|
||||
#include "Engine/NetConnection.h"
|
||||
#include "GameFramework/PlayerState.h"
|
||||
|
||||
ImVec4 StatRedColor(1.0f, 0.4f, 0.3f, 1.0f);
|
||||
ImVec4 StatOrangeColor(1.0f, 0.7f, 0.4f, 1.0f);
|
||||
ImVec4 StatGreenColor(0.5f, 1.0f, 0.6f, 1.0f);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Stats::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
extern ENGINE_API float GAverageFPS;
|
||||
ImGui::Text("FPS ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(GetFpsColor(GAverageFPS), "%0.0f", GAverageFPS);
|
||||
|
||||
if (const APlayerController* PlayerController = GetLocalPlayerController())
|
||||
{
|
||||
if (const APlayerState* PlayerState = PlayerController->GetPlayerState<APlayerState>())
|
||||
{
|
||||
const float Ping = PlayerState->GetPingInMilliseconds();
|
||||
ImGui::Text("Ping ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(GetPingColor(Ping), "%0.0fms", Ping);
|
||||
}
|
||||
|
||||
if (UNetConnection* Connection = PlayerController->GetNetConnection())
|
||||
{
|
||||
const float OutPacketLost = Connection->GetOutLossPercentage().GetAvgLossPercentage() * 100.0f;
|
||||
ImGui::Text("Packet Loss Out ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(GetPacketLossColor(OutPacketLost), "%0.0f%%", OutPacketLost);
|
||||
|
||||
const float InPacketLost = Connection->GetInLossPercentage().GetAvgLossPercentage() * 100.0f;
|
||||
ImGui::Text("Packet Loss In ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(GetPacketLossColor(InPacketLost), "%0.0f%%", InPacketLost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Stats::DrawMainMenuWidget(bool Draw, float& Width)
|
||||
{
|
||||
const float ResetButtonWidth = FCogWindowWidgets::TextBaseWidth * 5;
|
||||
Width = FCogWindowWidgets::TextBaseWidth * 15;
|
||||
|
||||
if (Draw == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
extern ENGINE_API float GAverageFPS;
|
||||
ImGui::TextColored(GetFpsColor(GAverageFPS), "%3dfps ", (int32)GAverageFPS);
|
||||
|
||||
if (const APlayerController* PlayerController = GetLocalPlayerController())
|
||||
{
|
||||
if (const APlayerState* PlayerState = PlayerController->GetPlayerState<APlayerState>())
|
||||
{
|
||||
const float Ping = PlayerState->GetPingInMilliseconds();
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(GetPingColor(Ping), "%3dms ", (int32)Ping);
|
||||
}
|
||||
|
||||
if (UNetConnection* Connection = PlayerController->GetNetConnection())
|
||||
{
|
||||
const float OutPacketLost = Connection->GetOutLossPercentage().GetAvgLossPercentage() * 100.0f;
|
||||
const float InPacketLost = Connection->GetInLossPercentage().GetAvgLossPercentage() * 100.0f;
|
||||
const float TotalPacketLost = OutPacketLost + InPacketLost;
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(GetPacketLossColor(TotalPacketLost), "%2d%% ", (int32)TotalPacketLost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ImVec4 UCogEngineWindow_Stats::GetFpsColor(float Value, float Good /*= 50.0f*/, float Medium /*= 30.0f*/)
|
||||
{
|
||||
if (Value > Good)
|
||||
{
|
||||
return StatGreenColor;
|
||||
}
|
||||
|
||||
if (Value > Medium)
|
||||
{
|
||||
return StatOrangeColor;
|
||||
}
|
||||
|
||||
return StatRedColor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ImVec4 UCogEngineWindow_Stats::GetPingColor(float Value, float Good /*= 100.0f*/, float Medium /*= 200.0f*/)
|
||||
{
|
||||
if (Value > Medium)
|
||||
{
|
||||
return StatRedColor;
|
||||
}
|
||||
|
||||
if (Value > Good)
|
||||
{
|
||||
return StatOrangeColor;
|
||||
}
|
||||
|
||||
return StatGreenColor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ImVec4 UCogEngineWindow_Stats::GetPacketLossColor(float Value, float Good /*= 10.0f*/, float Medium /*= 20.0f*/)
|
||||
{
|
||||
if (Value > Medium)
|
||||
{
|
||||
return StatRedColor;
|
||||
}
|
||||
|
||||
if (Value > Good)
|
||||
{
|
||||
return StatOrangeColor;
|
||||
}
|
||||
|
||||
return StatGreenColor;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "CogEngineWindow_Time.h"
|
||||
|
||||
#include "CogEngineReplicator.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Engine/World.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void DrawTimeButton(ACogEngineReplicator* Replicator, float Value)
|
||||
{
|
||||
const bool IsSelected = FMath::IsNearlyEqual(Replicator->GetTimeDilation(), Value, 0.0001f);
|
||||
if (IsSelected)
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(128, 128, 128, 50));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(128, 128, 128, 100));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(128, 128, 128, 150));
|
||||
}
|
||||
|
||||
const char* Text = TCHAR_TO_ANSI(*FString::Printf(TEXT("%g"), Value).Replace(TEXT("0."), TEXT(".")));
|
||||
if (ImGui::Button(Text, ImVec2(3.5f * FCogWindowWidgets::TextBaseWidth, 0)))
|
||||
{
|
||||
Replicator->Server_SetTimeDilation(Value);
|
||||
}
|
||||
|
||||
if (IsSelected)
|
||||
{
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PopStyleColor(3);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogEngineWindow_Time::UCogEngineWindow_Time()
|
||||
{
|
||||
TimingScales.Add(0.00f);
|
||||
TimingScales.Add(0.01f);
|
||||
TimingScales.Add(0.10f);
|
||||
TimingScales.Add(0.50f);
|
||||
TimingScales.Add(1.00f);
|
||||
TimingScales.Add(2.00f);
|
||||
TimingScales.Add(5.00f);
|
||||
TimingScales.Add(10.0f);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogEngineWindow_Time::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
ACogEngineReplicator* Replicator = FCogEngineModule::Get().GetLocalReplicator();
|
||||
if (Replicator == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiStyle& Style = ImGui::GetStyle();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(Style.WindowPadding.x * 0.40f, (float)(int)(Style.WindowPadding.y * 0.60f)));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(Style.FramePadding.x * 0.40f, (float)(int)(Style.FramePadding.y * 0.60f)));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(Style.ItemSpacing.x * 0.30f, (float)(int)(Style.ItemSpacing.y * 0.60f)));
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, IM_COL32(255, 255, 255, 180));
|
||||
|
||||
for (float TimeScale : TimingScales)
|
||||
{
|
||||
DrawTimeButton(Replicator, TimeScale);
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopStyleVar(3);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "CogEngineDataAsset_Collisions.generated.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct COGENGINE_API FCogCollisionChannel
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TEnumAsByte<ECollisionChannel> Channel = ECollisionChannel::ECC_WorldStatic;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FLinearColor Color = FLinearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(Blueprintable)
|
||||
class COGENGINE_API UCogEngineDataAsset_Collisions : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UCogEngineDataAsset_Collisions() {}
|
||||
|
||||
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Channel"))
|
||||
TArray<FCogCollisionChannel> Channels;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class ACogEngineReplicator;
|
||||
class APlayerController;
|
||||
|
||||
class COGENGINE_API FCogEngineModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
static inline FCogEngineModule& Get() { return FModuleManager::LoadModuleChecked<FCogEngineModule>("CogEngine"); }
|
||||
|
||||
virtual void StartupModule() override;
|
||||
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
ACogEngineReplicator* GetLocalReplicator();
|
||||
|
||||
void SetLocalReplicator(ACogEngineReplicator* Value);
|
||||
|
||||
ACogEngineReplicator* GetRemoteReplicator(const APlayerController* PlayerController);
|
||||
|
||||
TArray<TObjectPtr<ACogEngineReplicator>> GetRemoteReplicators() const { return RemoteReplicators; }
|
||||
|
||||
void AddRemoteReplicator(ACogEngineReplicator* Value);
|
||||
|
||||
private:
|
||||
TObjectPtr<ACogEngineReplicator> LocalReplicator;
|
||||
TArray<TObjectPtr<ACogEngineReplicator>> RemoteReplicators;
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "UObject/Class.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "CogEngineReplicator.generated.h"
|
||||
|
||||
class APlayerController;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct FCogEngineReplicatorSpawnAction
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
bool Control = false;
|
||||
bool Select = false;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(NotBlueprintable, NotBlueprintType, notplaceable, noteditinlinenew, hidedropdown, Transient)
|
||||
class COGENGINE_API ACogEngineReplicator : public AActor
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
static void Create(APlayerController* Controller);
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
APlayerController* GetPlayerController() const { return OwnerPlayerController.Get(); }
|
||||
|
||||
bool IsLocal() const { return bIsLocal; }
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_SetTimeDilation(float Value);
|
||||
|
||||
float GetTimeDilation() const { return TimeDilation; }
|
||||
|
||||
protected:
|
||||
|
||||
void TickSpawnActions();
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_TimeDilation();
|
||||
|
||||
UPROPERTY()
|
||||
TArray<FCogEngineReplicatorSpawnAction> SpawnActions;
|
||||
|
||||
TObjectPtr<APlayerController> OwnerPlayerController;
|
||||
|
||||
uint32 bHasAuthority : 1;
|
||||
uint32 bIsLocal : 1;
|
||||
|
||||
private:
|
||||
UPROPERTY(ReplicatedUsing = OnRep_TimeDilation)
|
||||
float TimeDilation = 1.0f;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_Collisions.generated.h"
|
||||
|
||||
class UCogEngineDataAsset_Collisions;
|
||||
|
||||
UCLASS(Config = Cog)
|
||||
class COGENGINE_API UCogEngineWindow_Collisions : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_Collisions();
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
void SetCollisionsAsset(const UCogEngineDataAsset_Collisions* Asset);
|
||||
|
||||
private:
|
||||
|
||||
struct FChannel
|
||||
{
|
||||
bool IsValid = false;
|
||||
FColor Color;
|
||||
};
|
||||
|
||||
TWeakObjectPtr<UCogEngineDataAsset_Collisions> CollisionsAsset;
|
||||
|
||||
FChannel Channels[ECC_MAX];
|
||||
|
||||
UPROPERTY(Config)
|
||||
int32 ObjectTypesToQuery;
|
||||
|
||||
UPROPERTY(Config)
|
||||
int32 ProfileIndex = 0;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_DebugSettings.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_DebugSettings : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_DebugSettings();
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
|
||||
virtual void RenderContent() override;
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_ImGui.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_ImGui : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_ImGui();
|
||||
|
||||
virtual void RenderTick(float DeltaTime) override;
|
||||
virtual void RenderContent() override;
|
||||
|
||||
private:
|
||||
bool bShowImguiDemo = false;
|
||||
bool bShowImguiPlot = false;
|
||||
bool bShowImguiMetric = false;
|
||||
bool bShowImguiDebugLog = false;
|
||||
bool bShowImguiStyleEditor = false;
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_LogCategories.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_LogCategories : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
|
||||
virtual void RenderContent() override;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_NetEmulation.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_NetEmulation : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "imgui.h"
|
||||
#include "Misc/OutputDevice.h"
|
||||
#include "CogEngineWindow_OutputLog.generated.h"
|
||||
|
||||
class UCogEngineWindow_OutputLog;
|
||||
|
||||
class UCogLogOutputDevice : public FOutputDevice
|
||||
{
|
||||
public:
|
||||
friend class UCogEngineWindow_OutputLog;
|
||||
|
||||
UCogLogOutputDevice();
|
||||
~UCogLogOutputDevice();
|
||||
|
||||
virtual void Serialize(const TCHAR* Message, ELogVerbosity::Type Verbosity, const FName& Category) override;
|
||||
|
||||
UCogEngineWindow_OutputLog* OutputLog = nullptr;
|
||||
};
|
||||
|
||||
UCLASS(Config = Cog)
|
||||
class COGENGINE_API UCogEngineWindow_OutputLog : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_OutputLog();
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
void Clear();
|
||||
|
||||
void AddLog(const TCHAR* Message, ELogVerbosity::Type Verbosity, const FName& Category);
|
||||
|
||||
private:
|
||||
|
||||
struct FLineInfo
|
||||
{
|
||||
int32 Start = 0;
|
||||
int32 End = 0;
|
||||
int32 Frame = 0;
|
||||
ELogVerbosity::Type Verbosity;
|
||||
FName Category;
|
||||
};
|
||||
|
||||
void DrawRow(const char* BufferStart, const FLineInfo& Info, bool IsTableShown);
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool AutoScroll = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool ShowFrame = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool ShowCategory = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool ShowVerbosity = false;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool ShowAsTable = false;
|
||||
|
||||
UPROPERTY(Config)
|
||||
int32 VerbosityFilter = ELogVerbosity::VeryVerbose;
|
||||
|
||||
ImGuiTextBuffer TextBuffer;
|
||||
|
||||
ImGuiTextFilter Filter;
|
||||
|
||||
TArray<FLineInfo> LineInfos;
|
||||
|
||||
UCogLogOutputDevice OutputDevice;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_Plots.generated.h"
|
||||
|
||||
class UCogEngineDataAsset_Collisions;
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_Plots : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_Plots();
|
||||
|
||||
virtual void RenderTick(float DeltaTime) override;
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_Scalability.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_Scalability : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_Scalability();
|
||||
|
||||
virtual void RenderContent() override;
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_Selection.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_Selection : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_Selection();
|
||||
|
||||
virtual void RenderTick(float DeltaTime);
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
virtual void DrawMainMenuWidget(bool Draw, float& Width) override;
|
||||
|
||||
bool DrawSelectionCombo();
|
||||
|
||||
void DrawActorContextMenu(AActor* Actor);
|
||||
|
||||
void ActivateSelectionMode();
|
||||
|
||||
void HackWaitInputRelease();
|
||||
|
||||
bool GetIsSelecting() const { return bSelectionModeActive; }
|
||||
|
||||
void SetCurrentActorSubClass(TSubclassOf<AActor> Value) { SelectedSubClass = Value; }
|
||||
|
||||
TSubclassOf<AActor> GetCurrentActorSubClass() const { return SelectedSubClass; }
|
||||
|
||||
const TArray<TSubclassOf<AActor>>& GetActorSubClasses() const { return SubClasses; }
|
||||
|
||||
void SetActorSubClasses(const TArray<TSubclassOf<AActor>>& Value) { SubClasses = Value; }
|
||||
|
||||
ETraceTypeQuery GetTraceType() const { return TraceType; }
|
||||
|
||||
void SetTraceType(ETraceTypeQuery Value) { TraceType = Value; }
|
||||
|
||||
private:
|
||||
|
||||
void TickSelectionMode();
|
||||
|
||||
void ToggleSelectionMode();
|
||||
|
||||
void DeactivateSelectionMode();
|
||||
|
||||
void DrawActorFrame(const AActor* Actor);
|
||||
|
||||
//void DrawActorDebug(const AActor* Actor);
|
||||
|
||||
bool ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max);
|
||||
|
||||
FVector LastSelectedActorLocation = FVector::ZeroVector;
|
||||
|
||||
bool bSelectionModeActive = false;
|
||||
|
||||
bool bImGuiHadInputBeforeEnteringSelectionMode = false;
|
||||
|
||||
int32 WaitInputReleased = 0;
|
||||
|
||||
TSubclassOf<AActor> SelectedSubClass;
|
||||
|
||||
TArray<TSubclassOf<AActor>> SubClasses;
|
||||
|
||||
ETraceTypeQuery TraceType = TraceTypeQuery1;
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_Skeleton.generated.h"
|
||||
|
||||
class USkeletalMeshComponent;
|
||||
|
||||
struct FBoneInfo
|
||||
{
|
||||
FName Name;
|
||||
TArray<int32> Children;
|
||||
int32 Index = 0;
|
||||
int32 ParentIndex = INDEX_NONE;
|
||||
FVector LastLocation = FVector::ZeroVector;
|
||||
bool IsSecondaryBone = false;
|
||||
|
||||
bool ShowBone = true;
|
||||
bool ShowName = false;
|
||||
bool ShowLocalVelocity = false;
|
||||
bool ShowAxes = false;
|
||||
bool ShowTrajectory = false;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_Skeleton : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_Skeleton();
|
||||
|
||||
virtual void RenderContent() override;
|
||||
virtual void RenderTick(float DeltaTime) override;
|
||||
|
||||
protected:
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) override;
|
||||
|
||||
private:
|
||||
void DrawBoneEntry(int32 BoneIndex, bool OpenAllChildren);
|
||||
void SetChildrenVisibility(int32 BoneIndex, bool IsVisible);
|
||||
void DrawSkeleton();
|
||||
void RefreshSkeleton();
|
||||
|
||||
TWeakObjectPtr<USkeletalMeshComponent> CurrentSkeleton = nullptr;
|
||||
bool ShowBones = true;
|
||||
bool ShowNames = false;
|
||||
bool ShowAxes = false;
|
||||
bool ShowVelocities = false;
|
||||
bool ShowTrajectories = false;
|
||||
bool HideSecondaryBones = true;
|
||||
int32 HoveredBoneIndex = INDEX_NONE;
|
||||
TArray<FBoneInfo> BonesInfos;
|
||||
ImGuiTextFilter Filter;
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_Stats.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_Stats : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
virtual void RenderContent() override;
|
||||
virtual void DrawMainMenuWidget(bool Draw, float& Width) override;
|
||||
|
||||
static ImVec4 GetFpsColor(float Value, float Good = 50.0f, float Medium = 30.0f);
|
||||
static ImVec4 GetPingColor(float Value, float Good = 100.0f, float Medium = 200.0f);
|
||||
static ImVec4 GetPacketLossColor(float Value, float Good = 10.0f, float Medium = 20.0f);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogEngineWindow_Time.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGENGINE_API UCogEngineWindow_Time : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogEngineWindow_Time();
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
TArray<float> TimingScales;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user