diff --git a/.vsconfig b/.vsconfig index 1a9d718..7f5f4b3 100644 --- a/.vsconfig +++ b/.vsconfig @@ -2,9 +2,9 @@ "version": "1.0", "components": [ "Microsoft.Net.Component.4.6.2.TargetingPack", - "Microsoft.VisualStudio.Component.VC.14.36.17.6.x86.x64", + "Microsoft.VisualStudio.Component.VC.14.38.17.8.x86.x64", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", - "Microsoft.VisualStudio.Component.Windows10SDK.22000", + "Microsoft.VisualStudio.Component.Windows10SDK.22621", "Microsoft.VisualStudio.Workload.CoreEditor", "Microsoft.VisualStudio.Workload.ManagedDesktop", "Microsoft.VisualStudio.Workload.NativeDesktop", diff --git a/Config/DefaultEditor.ini b/Config/DefaultEditor.ini index f38756e..162636e 100644 --- a/Config/DefaultEditor.ini +++ b/Config/DefaultEditor.ini @@ -1,2 +1,5 @@ [/Script/AdvancedPreviewScene.SharedProfiles] +[/Script/UnrealEd.EditorPerformanceProjectSettings] +MaxViewportRenderingResolution=720 + diff --git a/Content/Blueprints/Characters/BP_CameraMode.uasset b/Content/Blueprints/Characters/BP_CameraMode.uasset index 538b093..fe3cce2 100644 Binary files a/Content/Blueprints/Characters/BP_CameraMode.uasset and b/Content/Blueprints/Characters/BP_CameraMode.uasset differ diff --git a/Content/Blueprints/Other/BP_CustomGameInstance.uasset b/Content/Blueprints/Other/BP_CustomGameInstance.uasset index 9a1d396..c2fc893 100644 Binary files a/Content/Blueprints/Other/BP_CustomGameInstance.uasset and b/Content/Blueprints/Other/BP_CustomGameInstance.uasset differ diff --git a/Content/tempStaff/Input.uasset b/Content/tempStaff/Input.uasset new file mode 100644 index 0000000..85e327b Binary files /dev/null and b/Content/tempStaff/Input.uasset differ diff --git a/Lost_Edge.uproject b/Lost_Edge.uproject index 13b827c..1c0f94b 100644 --- a/Lost_Edge.uproject +++ b/Lost_Edge.uproject @@ -1,6 +1,6 @@ { "FileVersion": 3, - "EngineAssociation": "{1596D39D-4A14-8FE8-BC5C-21A6B54321BE}", + "EngineAssociation": "{0DD41C75-443A-77B1-7C02-5F9B73D04B7B}", "Category": "", "Description": "", "Modules": [ @@ -14,6 +14,14 @@ "SlateCore", "UMG" ] + }, + { + "Name": "Lost_EdgeShaders", + "Type": "Runtime", + "LoadingPhase": "PostConfigInit", + "AdditionalDependencies": [ + "Engine" + ] } ], "Plugins": [ @@ -342,6 +350,15 @@ { "Name": "RiderSourceCodeAccess", "Enabled": false + }, + { + "Name": "OpenCV", + "Enabled": true + }, + { + "Name": "AutoSizeComments", + "Enabled": false, + "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/ae89a2c4ab384de0a3f213b23de324f3" } ], "TargetPlatforms": [ diff --git a/Shaders/Private/InteractableScreenCapturerBitMapCS.usf b/Shaders/Private/InteractableScreenCapturerBitMapCS.usf new file mode 100644 index 0000000..97059f8 --- /dev/null +++ b/Shaders/Private/InteractableScreenCapturerBitMapCS.usf @@ -0,0 +1,23 @@ +// Oleg Petruny proprietary. + + +#include "/Engine/Public/Platform.ush" + +Buffer Input; +RWBuffer Output; + +[numthreads(THREADGROUPSIZE_X, 1, 1)] +void InteractableScreenCapturerBitMapCS( + uint3 dti : SV_DispatchThreadID) +{ + switch (Input[dti.x]) + { + case 0xFF00FFFF: + //Output[dti.x / 4] = Output[dti.x / 4] | (0xFF << 8 * (3 - (dti.x % 4))); // sets n-th byte to 0xFF + break; + default: + //Output[dti.x / 4] = Output[dti.x / 4] & ~(0xFF << 8 * (3 - (dti.x % 4))); // sets n-th byte to 0x00 + break; + } + //Output[0] = 1; +} \ No newline at end of file diff --git a/Source/Lost_Edge.Target.cs b/Source/Lost_Edge.Target.cs index e782bf0..7ca225a 100644 --- a/Source/Lost_Edge.Target.cs +++ b/Source/Lost_Edge.Target.cs @@ -1,15 +1,12 @@ // Copyright Epic Games, Inc. All Rights Reserved. using UnrealBuildTool; -using System.Collections.Generic; -public class Lost_EdgeTarget : TargetRules -{ - public Lost_EdgeTarget( TargetInfo Target) : base(Target) - { - Type = TargetType.Game; - DefaultBuildSettings = BuildSettingsVersion.V2; - IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; - ExtraModuleNames.Add("Lost_Edge"); - } +public class Lost_EdgeTarget : TargetRules { + public Lost_EdgeTarget(TargetInfo Target) : base(Target) { + Type = TargetType.Game; + DefaultBuildSettings = BuildSettingsVersion.Latest; + IncludeOrderVersion = EngineIncludeOrderVersion.Latest; + ExtraModuleNames.AddRange(new string[] { "Lost_Edge", "Lost_EdgeShaders" }); + } } diff --git a/Source/Lost_Edge/Lost_Edge.Build.cs b/Source/Lost_Edge/Lost_Edge.Build.cs index abe6f48..3b65c26 100644 --- a/Source/Lost_Edge/Lost_Edge.Build.cs +++ b/Source/Lost_Edge/Lost_Edge.Build.cs @@ -6,15 +6,19 @@ public class Lost_Edge : ModuleRules { public Lost_Edge(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OpenCV" }); // "OpenCVHelper" - PrivateDependencyModuleNames.AddRange(new string[] { "EnhancedInput", "UMG" }); //"Slate", "SlateCore" + //PrivateIncludePaths.AddRange(new string[] { "OpenCV/Private" }); + PrivateDependencyModuleNames.AddRange(new string[] { "EnhancedInput", "UMG", "RHI", "RenderCore", "Lost_EdgeShaders", "TextureCompressor" }); // "Slate", "SlateCore" // Uncomment if you are using online features // PrivateDependencyModuleNames.Add("OnlineSubsystem"); // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true + // UE_LOG(LogTemp, Log, TEXT("capture: %s"), (capture ? TEXT("true") : TEXT("false"))); + // GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("1")); // GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("Rescaled: %f"), scale)); } + } diff --git a/Source/Lost_Edge/Private/CustomGameInstanceBase.h b/Source/Lost_Edge/Private/CustomGameInstanceBase.h index e4ff7bc..1753c45 100644 --- a/Source/Lost_Edge/Private/CustomGameInstanceBase.h +++ b/Source/Lost_Edge/Private/CustomGameInstanceBase.h @@ -18,6 +18,7 @@ public: UFUNCTION(BlueprintCallable, Category = Settings) void ApplyMouseSettings(); + UPROPERTY(EditDefaultsOnly) TArray> interactionsCollection; protected: diff --git a/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.cpp b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.cpp new file mode 100644 index 0000000..2b1c289 --- /dev/null +++ b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.cpp @@ -0,0 +1,5 @@ +// Oleg Petruny proprietary. + + +#include "Interactable/InCameraInteractableActivator.h" + diff --git a/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.h b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.h new file mode 100644 index 0000000..2961490 --- /dev/null +++ b/Source/Lost_Edge/Private/Interactable/InCameraInteractableActivator.h @@ -0,0 +1,15 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "CoreMinimal.h" +#include "InteractableActivator.h" + +#include "InCameraInteractableActivator.generated.h" + +UCLASS() +class UInCameraInteractableActivator : public UInteractableActivator +{ + GENERATED_BODY() + +}; diff --git a/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp b/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp index 79387a3..f706301 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp +++ b/Source/Lost_Edge/Private/Interactable/InteractableActivator.cpp @@ -44,13 +44,12 @@ UInteractableActivator::UInteractableActivator(const FObjectInitializer& ObjectI void UInteractableActivator::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { - USceneComponent::TickComponent(DeltaTime, TickType, ThisTickFunction); - switch(TickType) { case ELevelTick::LEVELTICK_TimeOnly: case ELevelTick::LEVELTICK_ViewportsOnly: case ELevelTick::LEVELTICK_All: + USceneComponent::TickComponent(DeltaTime, TickType, ThisTickFunction); Scan_Implementation(); break; default: diff --git a/Source/Lost_Edge/Private/Interactable/InteractableActivator.h b/Source/Lost_Edge/Private/Interactable/InteractableActivator.h index be3a19f..6db0a17 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableActivator.h +++ b/Source/Lost_Edge/Private/Interactable/InteractableActivator.h @@ -7,9 +7,10 @@ #include "InteractableActivator.generated.h" -DECLARE_DELEGATE(FInteractableActivated); +DECLARE_DELEGATE_OneParam(FInteractableActivated, class AInteractable*); +DECLARE_DELEGATE_OneParam(FInteractableDeactivated, class AInteractable*); -UCLASS(Blueprintable, BlueprintType) +UCLASS(Abstract, Blueprintable, BlueprintType) class UInteractableActivator : public USceneComponent { GENERATED_BODY() @@ -18,6 +19,9 @@ public: UInteractableActivator(const FObjectInitializer& ObjectInitializer); virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + FInteractableActivated interactableActivatedDelegate; + FInteractableActivated interactableDeactivatedDelegate; + protected: UFUNCTION(BlueprintNativeEvent, BlueprintCallable) inline void Scan(); @@ -30,5 +34,4 @@ protected: class APlayerBase* player; bool isTrace = true; enum ECollisionChannel collisionChannel; - FInteractableActivated interactableActivatedDelegate; }; diff --git a/Source/Lost_Edge/Private/Interactable/InteractableCaller.cpp b/Source/Lost_Edge/Private/Interactable/InteractableCaller.cpp index c520bfd..2c2a03f 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableCaller.cpp +++ b/Source/Lost_Edge/Private/Interactable/InteractableCaller.cpp @@ -3,4 +3,18 @@ #include "InteractableCaller.h" +UInteractableCaller::UInteractableCaller(const FObjectInitializer& ObjectInitializer) + : UActorComponent(ObjectInitializer) +{ + if(HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject)) + { + return; + } + RegisterComponent(); +} + +void UInteractableCaller::Init() +{ + //GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, GetOwner()->GetName()); +} \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Interactable/InteractableCaller.h b/Source/Lost_Edge/Private/Interactable/InteractableCaller.h index 656415c..a3f8018 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableCaller.h +++ b/Source/Lost_Edge/Private/Interactable/InteractableCaller.h @@ -7,11 +7,13 @@ #include "InteractableCaller.generated.h" -UCLASS(Abstract, MinimalAPI, Blueprintable, BlueprintType) +UCLASS(Abstract, Blueprintable, BlueprintType) class UInteractableCaller : public UActorComponent { GENERATED_BODY() public: + UInteractableCaller(const FObjectInitializer& ObjectInitializer); + void Init(); }; \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Interactable/InteractableComponent.cpp b/Source/Lost_Edge/Private/Interactable/InteractableComponent.cpp index 8906d63..5a6caa3 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableComponent.cpp +++ b/Source/Lost_Edge/Private/Interactable/InteractableComponent.cpp @@ -3,4 +3,3 @@ #include "InteractableComponent.h" -// Add default functionality here for any IInteractableInterface functions that are not pure virtual. diff --git a/Source/Lost_Edge/Private/Interactable/InteractableComponent.h b/Source/Lost_Edge/Private/Interactable/InteractableComponent.h index 0dc7a31..3a1aa2d 100644 --- a/Source/Lost_Edge/Private/Interactable/InteractableComponent.h +++ b/Source/Lost_Edge/Private/Interactable/InteractableComponent.h @@ -30,7 +30,7 @@ public: TSubclassOf caller; }; -UCLASS() +UCLASS(Abstract, Blueprintable, BlueprintType) class UInteractableComponent : public UActorComponent { GENERATED_BODY() @@ -41,11 +41,6 @@ public: virtual const FString GetName_Implementation() PURE_VIRTUAL(UInteractableComponent::GetInteractionName_Implementation, return "NONE";); - UFUNCTION(BlueprintNativeEvent, BlueprintCallable) - const UInputMappingContext* GetInputMapping(); - virtual const UInputMappingContext* GetInputMapping_Implementation() - PURE_VIRTUAL(UInteractableComponent::GetInputMapping_Implementation, static UInputMappingContext _inputMapping{}; return &_inputMapping;); - UFUNCTION(BlueprintNativeEvent, BlueprintCallable) const TArray GetActivatorsAndCallers(); virtual const TArray GetActivatorsAndCallers_Implementation() diff --git a/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.cpp b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.cpp new file mode 100644 index 0000000..2991cf6 --- /dev/null +++ b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.cpp @@ -0,0 +1,234 @@ +// Oleg Petruny proprietary. + + +#include "InteractableScreenCapturer.h" + +#include "Engine/Texture.h" +#include "Interactable.h" +#include "Kismet/GameplayStatics.h" +#include "opencv2/imgproc.hpp" +#include "RHIResources.h" +#include "SceneView.h" +#include "TextureCompressorModule.h" + +constexpr float tickInterval = 1.0f / 5; + +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(); + + PrimitiveRenderMode = ESceneCapturePrimitiveRenderMode::PRM_LegacySceneCapture; + bCaptureEveryFrame = 0; + bCaptureOnMovement = 0; + LODDistanceFactor = 100; + bUseRayTracingIfEnabled = false; + CaptureSource = ESceneCaptureSource::SCS_BaseColor; + + CompositeMode = ESceneCaptureCompositeMode::SCCM_Overwrite; + PostProcessBlendWeight = 0; + bUseCustomProjectionMatrix = false; + bAlwaysPersistRenderingState = true; + + ShowFlags = { EShowFlagInitMode::ESFIM_All0 }; + ShowFlags.SetBSP(true); + ShowFlags.SetLandscape(true); + ShowFlags.SetSkeletalMeshes(true); + ShowFlags.SetStaticMeshes(true); + ShowFlags.SetInstancedFoliage(true); + ShowFlags.SetInstancedGrass(true); + ShowFlags.SetInstancedStaticMeshes(true); + ShowFlags.SetPaper2DSprites(true); + ShowFlags.SetGame(true); + ShowFlags.SetMaterials(true); + ShowFlags.SetRendering(true); + + PrimaryComponentTick.TickInterval = tickInterval; + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; +} + +void UInteractableScreenCapturer::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + switch(TickType) + { + case ELevelTick::LEVELTICK_TimeOnly: + case ELevelTick::LEVELTICK_ViewportsOnly: + case ELevelTick::LEVELTICK_All: + { + USceneCaptureComponent2D::TickComponent(DeltaTime, TickType, ThisTickFunction); + CaptureScene(); + GetCameraView(DeltaTime, _view); + Process(); + } + break; + default: + break; + } +} + +void UInteractableScreenCapturer::Process() +{ + static FThreadSafeBool running = false; + if(!running) + { + running = true; + ENQUEUE_RENDER_COMMAND(GetInteractablesFromScreen)( + [ + capture = _capture, + output = _output, + world = _world, + view = _view + ] + (FRHICommandListImmediate& RHICmdList) + { + double StartTime = FPlatformTime::Seconds(); + 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; + FColor* data = (FColor*)RHICmdList.LockTexture2D( + capture, + 0, + RLM_ReadOnly, + stride, + false); + for(uint32 i = 0; i < _size; ++i) + { + switch(data[i].R) + { + case 0xFF: + switch(data[i].G) + { + case 0x00: + switch(data[i].B) + { + case 0xFF: + _bitMap[i] = static_cast(0xFF); + continue; + default: + break; + } + [[fallthrough]]; + default: + break; + } + [[fallthrough]]; + default: + _bitMap[i] = static_cast(0x00); + break; + } + } + RHICmdList.UnlockTexture2D(capture, 0, false); + + cv::Mat componentsMap, componentsStats, componentsCentroids; + static cv::Mat bitMapCVProxy{ _extent.Y, _extent.X, CV_8UC1, _bitMap }; + auto components = cv::connectedComponentsWithStats( + bitMapCVProxy, + componentsMap, + componentsStats, + componentsCentroids, + 4, + CV_16U + ); + + //static FVector _oldLocation; + //static FRotator _oldRotation; + //static FMatrix _invProjection; + //if(view.Location != _oldLocation || view.Rotation != _oldRotation) + //{ + // _oldLocation = view.Location; + // _oldRotation = view.Rotation; + // _invProjection = + // (FTranslationMatrix(-(view.Location)) + // * (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(); + //} + FMatrix _invProjection = + (FTranslationMatrix(-(view.Location)) + * (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(); + + FVector worldLoc, worldDir; + for(int i = 1; i < components; ++i) + { + FVector2D screenPos = { ((double*)componentsCentroids.data)[i * 2], ((double*)componentsCentroids.data)[i * 2 + 1] }; + FSceneView::DeprojectScreenToWorld(screenPos, FIntRect{ {0, 0}, _extent }, _invProjection, worldLoc, worldDir); + //GEngine->AddOnScreenDebugMessage(66 + i, 0.5f, FColor::Yellow, FString::Printf(TEXT("x:%f, y:%f"), screenPos.X, screenPos.Y)); + + FHitResult result{}; + FVector startLocation = view.Location; + FVector endLocation = worldLoc + worldDir * 1000000; + world->LineTraceSingleByChannel( + result, + startLocation, + endLocation, + ECC_GameTraceChannel1 + ); + static AInteractable* _last = nullptr; + static bool _activated = false; + if(result.bBlockingHit) + { + if(_last != result.GetActor()) + { + _activated = true; + if(auto interactable = Cast(result.GetActor())) + { + _last = interactable; + GEngine->AddOnScreenDebugMessage(10 + i, 0.5f, FColor::Yellow, interactable->GetName()); + } + } + + 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); + } + GEngine->AddOnScreenDebugMessage(667, 0.5f, FColor::Yellow, FString::Printf(TEXT("time:%f"), FPlatformTime::Seconds() - StartTime)); + running = false; + } + ); + } +} \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.h b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.h new file mode 100644 index 0000000..97f156c --- /dev/null +++ b/Source/Lost_Edge/Private/Interactable/InteractableScreenCapturer.h @@ -0,0 +1,27 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "Components/SceneCaptureComponent2D.h" +#include "CoreMinimal.h" + +#include "InteractableScreenCapturer.generated.h" + +UCLASS(hidecategories = (Collision, Object, Physics, SceneComponent), ClassGroup = Rendering, editinlinenew, meta = (BlueprintSpawnableComponent), MinimalAPI) +class UInteractableScreenCapturer : public USceneCaptureComponent2D +{ + GENERATED_BODY() + +public: + UInteractableScreenCapturer(const FObjectInitializer& ObjectInitializer); + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + +protected: + void Process(); + +private: + FTextureRHIRef _capture; + FBufferRHIRef _output; + UWorld* _world; + FMinimalViewInfo _view; +}; diff --git a/Source/Lost_Edge/Private/Interactable/RaycastInteractableActivator.cpp b/Source/Lost_Edge/Private/Interactable/RaycastInteractableActivator.cpp index a00633a..59516e0 100644 --- a/Source/Lost_Edge/Private/Interactable/RaycastInteractableActivator.cpp +++ b/Source/Lost_Edge/Private/Interactable/RaycastInteractableActivator.cpp @@ -6,6 +6,8 @@ #include "DrawDebugHelpers.h" #include "Engine/World.h" +#include "Interactable.h" + void URaycastInteractableActivator::Scan_Implementation() { FHitResult result{}; @@ -19,8 +21,37 @@ void URaycastInteractableActivator::Scan_Implementation() collisionChannel ); + static AInteractable* _last = nullptr; + static bool _activated = false; if(result.bBlockingHit) - DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Green, false, 0.5f, 0, 1.0f); + { + if(_last != result.GetActor()) + { + _activated = true; + if(auto interactable = Cast(result.GetActor())) + { + _last = interactable; + if(interactableActivatedDelegate.IsBound()) + { + interactableActivatedDelegate.Execute(interactable); + } + } + } + + //DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Green, false, 0.5f, 0, 1.0f); + } else - DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Red, false, 0.5f, 10, 1.0f); + { + if(_activated) + { + if(interactableDeactivatedDelegate.IsBound()) + { + interactableDeactivatedDelegate.Execute(_last); + } + _activated = false; + _last = nullptr; + } + + //DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Red, false, 0.5f, 10, 1.0f); + } } \ 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 361cd95..a41f49b 100644 --- a/Source/Lost_Edge/Private/Interactable/UsableInteractable.cpp +++ b/Source/Lost_Edge/Private/Interactable/UsableInteractable.cpp @@ -12,12 +12,6 @@ const FString UUsableInteractable::GetName_Implementation() return _name; } -const UInputMappingContext* UUsableInteractable::GetInputMapping_Implementation() -{ - static auto _mapping = UInputMappingContext{}; - return &_mapping; -} - const TArray UUsableInteractable::GetActivatorsAndCallers_Implementation() { static TArray _array = { diff --git a/Source/Lost_Edge/Private/Interactable/UsableInteractable.h b/Source/Lost_Edge/Private/Interactable/UsableInteractable.h index b39b388..6d03655 100644 --- a/Source/Lost_Edge/Private/Interactable/UsableInteractable.h +++ b/Source/Lost_Edge/Private/Interactable/UsableInteractable.h @@ -9,7 +9,7 @@ #include "UsableInteractable.generated.h" -UCLASS() +UCLASS(Blueprintable, BlueprintType) class UUsableInteractable : public UInteractableComponent { GENERATED_BODY() @@ -18,9 +18,6 @@ public: const FString GetName(); virtual const FString GetName_Implementation() override; - const UInputMappingContext* GetInputMapping(); - virtual const UInputMappingContext* GetInputMapping_Implementation() override; - const TArray GetActivatorsAndCallers(); virtual const TArray GetActivatorsAndCallers_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 05a9732..5eb62f2 100644 --- a/Source/Lost_Edge/Private/PlayerBase.cpp +++ b/Source/Lost_Edge/Private/PlayerBase.cpp @@ -11,6 +11,7 @@ #include "Kismet/KismetMathLibrary.h" #include "CustomGameInstanceBase.h" +#include "Interactable/Interactable.h" #include "Interactable/InteractableActivator.h" #include "Interactable/InteractableCaller.h" #include "Interactable/InteractableComponent.h" @@ -144,18 +145,49 @@ void APlayerBase::LoadInteractable() } TSet> activators; + TMap, UInteractableCaller*> callers; for(auto& interaction : GI->interactionsCollection) { auto actAndCallArray = interaction->GetDefaultObject()->GetActivatorsAndCallers_Implementation(); for(auto& actAndCall : actAndCallArray) { - activators.Add(actAndCall.activator); + if(!activators.Contains(actAndCall.activator)) + { + activators.Add(actAndCall.activator); + auto component = NewObject(this, actAndCall.activator); + component->AttachToComponent(camera, FAttachmentTransformRules::SnapToTargetIncludingScale); + 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]); + } } } - - for(auto& activator : activators) - { - auto component = NewObject(this, activator); - component->AttachToComponent(camera, FAttachmentTransformRules::SnapToTargetIncludingScale); - } } + +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); + } +} \ No newline at end of file diff --git a/Source/Lost_Edge/Private/PlayerBase.h b/Source/Lost_Edge/Private/PlayerBase.h index 194b3fb..36d6b6f 100644 --- a/Source/Lost_Edge/Private/PlayerBase.h +++ b/Source/Lost_Edge/Private/PlayerBase.h @@ -61,4 +61,9 @@ protected: private: void LoadInteractable(); + void InteractableActivated(class AInteractable* interactable); + + void AddInteractionCallersMapping(TSubclassOf interaction, class UInteractableCaller* caller); + + TMap, TSet> _interactionsToCallers; }; diff --git a/Source/Lost_EdgeEditor.Target.cs b/Source/Lost_EdgeEditor.Target.cs index b36475d..49b23a9 100644 --- a/Source/Lost_EdgeEditor.Target.cs +++ b/Source/Lost_EdgeEditor.Target.cs @@ -1,15 +1,12 @@ // Copyright Epic Games, Inc. All Rights Reserved. using UnrealBuildTool; -using System.Collections.Generic; -public class Lost_EdgeEditorTarget : TargetRules -{ - public Lost_EdgeEditorTarget( TargetInfo Target) : base(Target) - { - Type = TargetType.Editor; - DefaultBuildSettings = BuildSettingsVersion.V2; - IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; - ExtraModuleNames.Add("Lost_Edge"); - } +public class Lost_EdgeEditorTarget : TargetRules { + public Lost_EdgeEditorTarget(TargetInfo Target) : base(Target) { + Type = TargetType.Editor; + DefaultBuildSettings = BuildSettingsVersion.Latest; + IncludeOrderVersion = EngineIncludeOrderVersion.Latest; + ExtraModuleNames.AddRange(new string[] { "Lost_Edge", "Lost_EdgeShaders" }); + } } diff --git a/Source/Lost_EdgeShaders/Lost_EdgeShaders.Build.cs b/Source/Lost_EdgeShaders/Lost_EdgeShaders.Build.cs new file mode 100644 index 0000000..660a4d6 --- /dev/null +++ b/Source/Lost_EdgeShaders/Lost_EdgeShaders.Build.cs @@ -0,0 +1,17 @@ +// Oleg Petruny proprietary. + +using UnrealBuildTool; + +public class Lost_EdgeShaders : ModuleRules { + public Lost_EdgeShaders(ReadOnlyTargetRules Target) : base(Target) { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + PublicDependencyModuleNames.AddRange(new string[] { }); + PrivateDependencyModuleNames.AddRange(new string[] { "Core", + "CoreUObject", + "Engine", + "Renderer", + "RenderCore", + "RHI", + "Projects" }); + } +} diff --git a/Source/Lost_EdgeShaders/Private/InteractableScreenCapturerBitMapCS.cpp b/Source/Lost_EdgeShaders/Private/InteractableScreenCapturerBitMapCS.cpp new file mode 100644 index 0000000..e691a2c --- /dev/null +++ b/Source/Lost_EdgeShaders/Private/InteractableScreenCapturerBitMapCS.cpp @@ -0,0 +1,6 @@ +// Oleg Petruny proprietary. + + +#include "InteractableScreenCapturerBitMapCS.h" + +IMPLEMENT_GLOBAL_SHADER(FInteractableScreenCapturerBitMapCS, "/Lost_EdgeShaders/InteractableScreenCapturerBitMapCS.usf", "InteractableScreenCapturerBitMapCS", SF_Compute); diff --git a/Source/Lost_EdgeShaders/Private/Lost_EdgeShaders.cpp b/Source/Lost_EdgeShaders/Private/Lost_EdgeShaders.cpp new file mode 100644 index 0000000..52098da --- /dev/null +++ b/Source/Lost_EdgeShaders/Private/Lost_EdgeShaders.cpp @@ -0,0 +1,20 @@ +// Oleg Petruny proprietary. + +#include "Lost_EdgeShaders.h" + +#include "GlobalShader.h" +#include "Misc/Paths.h" +#include "Modules/ModuleManager.h" + +IMPLEMENT_GAME_MODULE(FLost_EdgeShaders, Lost_EdgeShaders); + + +void FLost_EdgeShaders::StartupModule() +{ + // Maps virtual shader source directory to actual shaders directory on disk. + FString ShaderDirectory = FPaths::Combine(FPaths::ProjectDir(), TEXT("Shaders/Private")); + AddShaderSourceDirectoryMapping("/Lost_EdgeShaders", ShaderDirectory); +} + +void FLost_EdgeShaders::ShutdownModule() +{} \ No newline at end of file diff --git a/Source/Lost_EdgeShaders/Public/InteractableScreenCapturerBitMapCS.h b/Source/Lost_EdgeShaders/Public/InteractableScreenCapturerBitMapCS.h new file mode 100644 index 0000000..fc976c8 --- /dev/null +++ b/Source/Lost_EdgeShaders/Public/InteractableScreenCapturerBitMapCS.h @@ -0,0 +1,38 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "CoreMinimal.h" +#include "DataDrivenShaderPlatformInfo.h" +#include "GlobalShader.h" +#include "ShaderParameterStruct.h" + + +class LOST_EDGESHADERS_API FInteractableScreenCapturerBitMapCS : public FGlobalShader +{ +public: + DECLARE_GLOBAL_SHADER(FInteractableScreenCapturerBitMapCS); + SHADER_USE_PARAMETER_STRUCT(FInteractableScreenCapturerBitMapCS, FGlobalShader); + + BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) + + SHADER_PARAMETER_SRV(Buffer, Input) + SHADER_PARAMETER_UAV(RWBuffer, Output) + + END_SHADER_PARAMETER_STRUCT() + +public: + static constexpr int32 shader_threads_per_group_count = 64; + + static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) + { + return true; + } + + static inline void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) + { + FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); + + OutEnvironment.SetDefine(TEXT("THREADGROUPSIZE_X"), shader_threads_per_group_count); + } +}; diff --git a/Source/Lost_EdgeShaders/Public/Lost_EdgeShaders.h b/Source/Lost_EdgeShaders/Public/Lost_EdgeShaders.h new file mode 100644 index 0000000..0ec9fa0 --- /dev/null +++ b/Source/Lost_EdgeShaders/Public/Lost_EdgeShaders.h @@ -0,0 +1,26 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "CoreMinimal.h" + +#include "Modules/ModuleInterface.h" +#include "Modules/ModuleManager.h" + +class FLost_EdgeShaders : public IModuleInterface +{ +public: + static inline FLost_EdgeShaders& Get() + { + return FModuleManager::LoadModuleChecked("Lost_EdgeShaders"); + } + + static inline bool IsAvailable() + { + return FModuleManager::Get().IsModuleLoaded("Lost_EdgeShaders"); + } + +public: + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; \ No newline at end of file