From 2a5677656c8aa4ce7bfa2c7a18c11e66d18e9fcb Mon Sep 17 00:00:00 2001 From: Oleg Petruny Date: Mon, 20 May 2024 23:02:13 +0200 Subject: [PATCH] SawInteractable, InteractableScreenCapturer optimizations --- .../Private/CustomGameInstanceBase.cpp | 3 +- .../Private/CustomGameInstanceBase.h | 2 +- .../InCameraInteractableActivator.cpp | 45 +++++++++++ .../InCameraInteractableActivator.h | 19 ++++- .../Interactable/InteractableActivator.cpp | 1 - .../Interactable/InteractableActivator.h | 1 - .../Interactable/InteractableComponent.h | 28 +------ .../InteractableScreenCapturer.cpp | 78 +++++++------------ .../Interactable/InteractableScreenCapturer.h | 8 +- .../Private/Interactable/SawInteractable.cpp | 21 +++++ .../Private/Interactable/SawInteractable.h | 23 ++++++ .../Interactable/UsableInteractable.cpp | 7 +- .../Private/Interactable/UsableInteractable.h | 4 +- Source/Lost_Edge/Private/PlayerBase.cpp | 43 +++------- Source/Lost_Edge/Private/PlayerBase.h | 4 - 15 files changed, 163 insertions(+), 124 deletions(-) create mode 100644 Source/Lost_Edge/Private/Interactable/SawInteractable.cpp create mode 100644 Source/Lost_Edge/Private/Interactable/SawInteractable.h diff --git a/Source/Lost_Edge/Private/CustomGameInstanceBase.cpp b/Source/Lost_Edge/Private/CustomGameInstanceBase.cpp index 0236018..791bf1d 100644 --- a/Source/Lost_Edge/Private/CustomGameInstanceBase.cpp +++ b/Source/Lost_Edge/Private/CustomGameInstanceBase.cpp @@ -7,12 +7,13 @@ #include "InputMappingContext.h" #include "CustomGameUserSettings.h" +#include "Interactable/SawInteractable.h" #include "Interactable/UsableInteractable.h" void UCustomGameInstanceBase::Init() { // IN FUTURE ASSIGN FROM CONTENT LOADER MEMBER - interactionsCollection = { {UUsableInteractable::StaticClass()} }; + interactionsActivators = { {UUsableInteractable::StaticClass()}, {USawInteractable::StaticClass()} }; UGameInstance::Init(); diff --git a/Source/Lost_Edge/Private/CustomGameInstanceBase.h b/Source/Lost_Edge/Private/CustomGameInstanceBase.h index 1753c45..7b78065 100644 --- a/Source/Lost_Edge/Private/CustomGameInstanceBase.h +++ b/Source/Lost_Edge/Private/CustomGameInstanceBase.h @@ -19,7 +19,7 @@ public: void ApplyMouseSettings(); UPROPERTY(EditDefaultsOnly) - TArray> interactionsCollection; + TArray> interactionsActivators; protected: UPROPERTY(EditDefaultsOnly) diff --git a/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.cpp b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.cpp index 2b1c289..21b1096 100644 --- a/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.cpp +++ b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.cpp @@ -3,3 +3,48 @@ #include "Interactable/InCameraInteractableActivator.h" +#include "Interactable.h" +#include "InteractableScreenCapturer.h" + +UInCameraInteractableActivator::UInCameraInteractableActivator(const FObjectInitializer& ObjectInitializer) + : UInteractableActivator(ObjectInitializer) +{ + if(!world || !player) + { + return; + } + + _capturer = CreateDefaultSubobject(TEXT("UInCameraInteractableActivator_UInteractableScreenCapturer")); + _capturer->interactableInScreenDelegate.BindUObject(this, &UInCameraInteractableActivator::NewSeenInteractable_Implementation); + _capturer->SetupAttachment(this); + + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = false; +} + +void UInCameraInteractableActivator::OnRegister() +{ + UInteractableActivator::OnRegister(); + _capturer->RegisterComponent(); + _capturer->Activate(); +} + +void UInCameraInteractableActivator::NewSeenInteractable_Implementation(AInteractable* interactable) +{ + _interactablesToActivate.Enqueue(interactable); + SetComponentTickEnabled(true); +} + +void UInCameraInteractableActivator::Scan_Implementation() +{ + SetComponentTickEnabled(false); + while(!_interactablesToActivate.IsEmpty()) + { + AInteractable* interactable; + _interactablesToActivate.Dequeue(interactable); + if(interactableActivatedDelegate.IsBound()) + { + interactableActivatedDelegate.Execute(interactable); + } + } +} \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.h b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.h index 2961490..022a9d5 100644 --- a/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.h +++ b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.h @@ -3,13 +3,30 @@ #pragma once #include "CoreMinimal.h" + #include "InteractableActivator.h" #include "InCameraInteractableActivator.generated.h" -UCLASS() +UCLASS(Blueprintable, BlueprintType) class UInCameraInteractableActivator : public UInteractableActivator { GENERATED_BODY() +public: + UInCameraInteractableActivator(const FObjectInitializer& ObjectInitializer); + +protected: + virtual void OnRegister() override; + + void Scan(); + virtual void Scan_Implementation() override; + + UFUNCTION(BlueprintNativeEvent, BlueprintCallable) + void NewSeenInteractable(class AInteractable* interactable); + virtual void NewSeenInteractable_Implementation(class AInteractable* interactable); + +private: + class UInteractableScreenCapturer* _capturer; + TQueue _interactablesToActivate; }; diff --git a/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp b/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp index f706301..350eb52 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp +++ b/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp @@ -39,7 +39,6 @@ UInteractableActivator::UInteractableActivator(const FObjectInitializer& ObjectI PrimaryComponentTick.TickInterval = 0.05f; PrimaryComponentTick.bCanEverTick = true; PrimaryComponentTick.bStartWithTickEnabled = true; - RegisterComponent(); } void UInteractableActivator::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) diff --git a/Source/Lost_Edge/Private/Interactable/InteractableActivator.h b/Source/Lost_Edge/Private/Interactable/InteractableActivator.h index 6db0a17..3b31f83 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableActivator.h +++ b/Source/Lost_Edge/Private/Interactable/InteractableActivator.h @@ -32,6 +32,5 @@ protected: class UWorld* world; class APlayerBase* player; - bool isTrace = true; enum ECollisionChannel collisionChannel; }; diff --git a/Source/Lost_Edge/Private/Interactable/InteractableComponent.h b/Source/Lost_Edge/Private/Interactable/InteractableComponent.h index 3a1aa2d..1514f7d 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableComponent.h +++ b/Source/Lost_Edge/Private/Interactable/InteractableComponent.h @@ -7,29 +7,9 @@ #include "UObject/Interface.h" #include "InteractableActivator.h" -#include "InteractableCaller.h" #include "InteractableComponent.generated.h" -USTRUCT(BlueprintType) -struct FActivatorCallerPair -{ - GENERATED_BODY() - -public: - FActivatorCallerPair() {} - - FActivatorCallerPair(TSubclassOf a, TSubclassOf c) - : activator(a), caller(c) - {} - - UPROPERTY(EditAnywhere) - TSubclassOf activator; - - UPROPERTY(EditAnywhere) - TSubclassOf caller; -}; - UCLASS(Abstract, Blueprintable, BlueprintType) class UInteractableComponent : public UActorComponent { @@ -42,8 +22,8 @@ public: PURE_VIRTUAL(UInteractableComponent::GetInteractionName_Implementation, return "NONE";); UFUNCTION(BlueprintNativeEvent, BlueprintCallable) - const TArray GetActivatorsAndCallers(); - virtual const TArray GetActivatorsAndCallers_Implementation() - PURE_VIRTUAL(UInteractableComponent::GetActivatorsAndCallers_Implementation, - TArray _activatorsAndCallers{}; return _activatorsAndCallers;); + const TArray> GetActivators(); + virtual const TArray> GetActivators_Implementation() + PURE_VIRTUAL(UInteractableComponent::GetActivatorsZ_Implementation, + TArray> _activators{}; return _activators;); }; diff --git a/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.cpp b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.cpp index 2991cf6..ccc3797 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.cpp +++ b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.cpp @@ -4,51 +4,39 @@ #include "InteractableScreenCapturer.h" #include "Engine/Texture.h" -#include "Interactable.h" +#include "Engine/TextureRenderTarget2D.h" #include "Kismet/GameplayStatics.h" #include "opencv2/imgproc.hpp" #include "RHIResources.h" #include "SceneView.h" #include "TextureCompressorModule.h" +#include "Interactable.h" + constexpr float tickInterval = 1.0f / 5; +constexpr float textureWidth = 1280 / 2; +constexpr float textureHeight = 720 / 2; +constexpr float rayDistance = 7000; UInteractableScreenCapturer::UInteractableScreenCapturer(const FObjectInitializer& ObjectInitializer) : USceneCaptureComponent2D(ObjectInitializer) { - //TextureTarget = CreateDefaultSubobject(TEXT("TextureTarget")); - //TextureTarget->InitAutoFormat(textureWidth, textureHeight); - //TextureTarget->RenderTargetFormat = ETextureRenderTargetFormat::RTF_RGBA16f; PrimaryComponentTick.bCanEverTick = false; PrimaryComponentTick.bStartWithTickEnabled = false; - auto input = LoadObject(nullptr, TEXT("/Game/tempStaff/Input")); - if(!input) - { - return; - } - - _capture = input->GetResource()->TextureRHI; - if(!_capture) - { - return; - } - - switch(_capture->GetFormat()) - { - case EPixelFormat::PF_R8G8B8A8: - case EPixelFormat::PF_B8G8R8A8: - break; - default: - return; - } - - _world = GetWorld(); + TextureTarget = LoadObject(this, TEXT("/Game/tempStaff/Input")); + //TextureTarget = ObjectInitializer.CreateDefaultSubobject(this, TEXT("UInteractableScreenCapturer_TextureRenderTarget")); + //TextureTarget->RenderTargetFormat = ETextureRenderTargetFormat::RTF_RGBA8; + //TextureTarget->ClearColor = FLinearColor::Black; + //TextureTarget->bAutoGenerateMips = false; + //TextureTarget->bCanCreateUAV = false; + //TextureTarget->InitAutoFormat(textureWidth, textureHeight); + //TextureTarget->UpdateResourceImmediate(true); PrimitiveRenderMode = ESceneCapturePrimitiveRenderMode::PRM_LegacySceneCapture; bCaptureEveryFrame = 0; bCaptureOnMovement = 0; - LODDistanceFactor = 100; + LODDistanceFactor = 10000; bUseRayTracingIfEnabled = false; CaptureSource = ESceneCaptureSource::SCS_BaseColor; @@ -102,10 +90,10 @@ void UInteractableScreenCapturer::Process() running = true; ENQUEUE_RENDER_COMMAND(GetInteractablesFromScreen)( [ - capture = _capture, - output = _output, - world = _world, - view = _view + capture = TextureTarget->GetResource()->TextureRHI, + world = GetWorld(), + view = _view, + this ] (FRHICommandListImmediate& RHICmdList) { @@ -113,7 +101,6 @@ void UInteractableScreenCapturer::Process() static FIntPoint _extent = capture->GetDesc().Extent; static uint32 _size = _extent.X * _extent.Y; - static TArray _capturePixels; static uint8* _bitMap = new uint8[_size]; // cv::Mat allocation is weird sometimes... uint32 stride = 0; @@ -180,7 +167,7 @@ void UInteractableScreenCapturer::Process() * (FInverseRotationMatrix(view.Rotation) * FMatrix(FPlane(0, 0, 1, 0), FPlane(1, 0, 0, 0), FPlane(0, 1, 0, 0), FPlane(0, 0, 0, 1))) * view.CalculateProjectionMatrix()) .InverseFast(); - + GEngine->AddOnScreenDebugMessage(60, 0.5f, FColor::Yellow, FString::Printf(TEXT("x:%f, y:%f"), view.Rotation.Yaw, view.Rotation.Roll)); FVector worldLoc, worldDir; for(int i = 1; i < components; ++i) { @@ -190,38 +177,33 @@ void UInteractableScreenCapturer::Process() FHitResult result{}; FVector startLocation = view.Location; - FVector endLocation = worldLoc + worldDir * 1000000; + FVector endLocation = worldLoc + worldDir * rayDistance; world->LineTraceSingleByChannel( result, startLocation, endLocation, ECC_GameTraceChannel1 ); - static AInteractable* _last = nullptr; - static bool _activated = false; if(result.bBlockingHit) { - if(_last != result.GetActor()) + if(auto interactable = Cast(result.GetActor())) { - _activated = true; - if(auto interactable = Cast(result.GetActor())) + if(!_sawInteractables.Contains(interactable)) { - _last = interactable; - GEngine->AddOnScreenDebugMessage(10 + i, 0.5f, FColor::Yellow, interactable->GetName()); + _sawInteractables.Add(interactable); + AsyncTask(ENamedThreads::GameThread, [=, this]() + { + interactableInScreenDelegate.Execute(interactable); + }); } + //GEngine->AddOnScreenDebugMessage(10 + i, 0.5f, FColor::Yellow, interactable->GetName()); + GEngine->AddOnScreenDebugMessage(20 + i, 0.5f, FColor::Yellow, FString::Printf(TEXT("dist:%f"), (view.Location - interactable->GetActorLocation()).Length())); } DrawDebugLine(world, startLocation, endLocation, FColor::Green, false, tickInterval, 0, 0.5f); } else { - if(_activated) - { - - _activated = false; - _last = nullptr; - } - DrawDebugLine(world, startLocation, endLocation, FColor::Red, false, tickInterval, 10, 0.5f); } //DrawDebugLine(world, startLocation, endLocation, FColor::Red, false, tickInterval, 0, 0.5f); diff --git a/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.h b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.h index 97f156c..f273685 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.h +++ b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.h @@ -7,6 +7,8 @@ #include "InteractableScreenCapturer.generated.h" +DECLARE_DELEGATE_OneParam(FInteractableInScreen, class AInteractable*); + UCLASS(hidecategories = (Collision, Object, Physics, SceneComponent), ClassGroup = Rendering, editinlinenew, meta = (BlueprintSpawnableComponent), MinimalAPI) class UInteractableScreenCapturer : public USceneCaptureComponent2D { @@ -16,12 +18,12 @@ public: UInteractableScreenCapturer(const FObjectInitializer& ObjectInitializer); virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + FInteractableInScreen interactableInScreenDelegate; + protected: void Process(); private: - FTextureRHIRef _capture; - FBufferRHIRef _output; - UWorld* _world; FMinimalViewInfo _view; + TSet _sawInteractables; }; diff --git a/Source/Lost_Edge/Private/Interactable/SawInteractable.cpp b/Source/Lost_Edge/Private/Interactable/SawInteractable.cpp new file mode 100644 index 0000000..f699ea6 --- /dev/null +++ b/Source/Lost_Edge/Private/Interactable/SawInteractable.cpp @@ -0,0 +1,21 @@ +// Oleg Petruny proprietary. + + +#include "SawInteractable.h" + +#include "InCameraInteractableActivator.h" +#include "InteractableCaller.h" + +const FString USawInteractable::GetName_Implementation() +{ + static auto _name = TEXT("Saw"); + return _name; +} + +const TArray> USawInteractable::GetActivators_Implementation() +{ + static TArray> _array = { + {UInCameraInteractableActivator::StaticClass()} + }; + return _array; +} \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Interactable/SawInteractable.h b/Source/Lost_Edge/Private/Interactable/SawInteractable.h new file mode 100644 index 0000000..81cc5d3 --- /dev/null +++ b/Source/Lost_Edge/Private/Interactable/SawInteractable.h @@ -0,0 +1,23 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "CoreMinimal.h" + +#include "InteractableComponent.h" + +#include "SawInteractable.generated.h" + + +UCLASS(Blueprintable, BlueprintType) +class USawInteractable : public UInteractableComponent +{ + GENERATED_BODY() + +public: + const FString GetName(); + virtual const FString GetName_Implementation() override; + + const TArray> GetActivators(); + virtual const TArray> GetActivators_Implementation() override; +}; \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Interactable/UsableInteractable.cpp b/Source/Lost_Edge/Private/Interactable/UsableInteractable.cpp index a41f49b..6e5d64a 100644 --- a/Source/Lost_Edge/Private/Interactable/UsableInteractable.cpp +++ b/Source/Lost_Edge/Private/Interactable/UsableInteractable.cpp @@ -3,7 +3,6 @@ #include "UsableInteractable.h" -#include "InteractableCaller.h" #include "RaycastInteractableActivator.h" const FString UUsableInteractable::GetName_Implementation() @@ -12,10 +11,10 @@ const FString UUsableInteractable::GetName_Implementation() return _name; } -const TArray UUsableInteractable::GetActivatorsAndCallers_Implementation() +const TArray> UUsableInteractable::GetActivators_Implementation() { - static TArray _array = { - {{URaycastInteractableActivator::StaticClass()}, {UInteractableCaller::StaticClass()}} + static TArray> _array = { + {URaycastInteractableActivator::StaticClass()} }; return _array; } \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Interactable/UsableInteractable.h b/Source/Lost_Edge/Private/Interactable/UsableInteractable.h index 6d03655..cf51761 100644 --- a/Source/Lost_Edge/Private/Interactable/UsableInteractable.h +++ b/Source/Lost_Edge/Private/Interactable/UsableInteractable.h @@ -18,6 +18,6 @@ public: const FString GetName(); virtual const FString GetName_Implementation() override; - const TArray GetActivatorsAndCallers(); - virtual const TArray GetActivatorsAndCallers_Implementation() override; + const TArray> GetActivators(); + virtual const TArray> GetActivators_Implementation() override; }; \ No newline at end of file diff --git a/Source/Lost_Edge/Private/PlayerBase.cpp b/Source/Lost_Edge/Private/PlayerBase.cpp index 5eb62f2..39d864b 100644 --- a/Source/Lost_Edge/Private/PlayerBase.cpp +++ b/Source/Lost_Edge/Private/PlayerBase.cpp @@ -145,31 +145,18 @@ void APlayerBase::LoadInteractable() } TSet> activators; - TMap, UInteractableCaller*> callers; - for(auto& interaction : GI->interactionsCollection) + for(auto& interaction : GI->interactionsActivators) { - auto actAndCallArray = interaction->GetDefaultObject()->GetActivatorsAndCallers_Implementation(); - for(auto& actAndCall : actAndCallArray) + auto actArray = interaction->GetDefaultObject()->GetActivators_Implementation(); + for(auto& act : actArray) { - if(!activators.Contains(actAndCall.activator)) + if(!activators.Contains(act)) { - activators.Add(actAndCall.activator); - auto component = NewObject(this, actAndCall.activator); - component->AttachToComponent(camera, FAttachmentTransformRules::SnapToTargetIncludingScale); + activators.Add(act); + auto component = NewObject(this, act); component->interactableActivatedDelegate.BindUObject(this, &APlayerBase::InteractableActivated); - } - - if(!callers.Contains(actAndCall.caller)) - { - auto component = NewObject(this, actAndCall.caller); - this->AddOwnedComponent(component); - component->Init(); - callers.Add(actAndCall.caller, component); - AddInteractionCallersMapping(interaction, component); - } - else - { - AddInteractionCallersMapping(interaction, callers[actAndCall.caller]); + component->SetupAttachment(camera); + component->RegisterComponent(); } } } @@ -177,17 +164,5 @@ void APlayerBase::LoadInteractable() void APlayerBase::InteractableActivated(AInteractable* interactable) { - GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Yellow, interactable->GetName()); -} - -void APlayerBase::AddInteractionCallersMapping(TSubclassOf interaction, UInteractableCaller* caller) -{ - if(!_interactionsToCallers.Contains(interaction)) - { - _interactionsToCallers.Add(interaction, { caller }); - } - else - { - _interactionsToCallers[interaction].Add(caller); - } + GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Cyan, TEXT("Player activate: ") + interactable->GetName()); } \ No newline at end of file diff --git a/Source/Lost_Edge/Private/PlayerBase.h b/Source/Lost_Edge/Private/PlayerBase.h index 36d6b6f..ff5438a 100644 --- a/Source/Lost_Edge/Private/PlayerBase.h +++ b/Source/Lost_Edge/Private/PlayerBase.h @@ -62,8 +62,4 @@ protected: private: void LoadInteractable(); void InteractableActivated(class AInteractable* interactable); - - void AddInteractionCallersMapping(TSubclassOf interaction, class UInteractableCaller* caller); - - TMap, TSet> _interactionsToCallers; };