From 6b484073e2fbc916bc1ef9b668674ac53bbc9496 Mon Sep 17 00:00:00 2001
From: Sebi <pape@vr.rwth-aachen.de>
Date: Mon, 20 Jan 2020 15:40:54 +0100
Subject: [PATCH 1/6] Added dynamic spawning behavior of overlay, which can be
 adjusted in the settings of the project

---
 Source/CAVEOverlay/Private/CAVEOverlay.cpp    | 28 ++++++++++++++++++-
 Source/CAVEOverlay/Public/CAVEOverlay.h       |  4 +++
 .../CAVEOverlay/Public/CAVEOverlaySettings.h  | 25 +++++++++++++++++
 3 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 Source/CAVEOverlay/Public/CAVEOverlaySettings.h

diff --git a/Source/CAVEOverlay/Private/CAVEOverlay.cpp b/Source/CAVEOverlay/Private/CAVEOverlay.cpp
index a980703..35d9987 100644
--- a/Source/CAVEOverlay/Private/CAVEOverlay.cpp
+++ b/Source/CAVEOverlay/Private/CAVEOverlay.cpp
@@ -1,14 +1,40 @@
 // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
 
 #include "CAVEOverlay.h"
+#include "CAVEOverlaySettings.h"
+#include "CAVEOverlayController.h"
+#include "Kismet/GameplayStatics.h"
 
 #define LOCTEXT_NAMESPACE "FCAVEOverlayModule"
 
 void FCAVEOverlayModule::StartupModule()
 {
 	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
+
+	On_Post_World_Initialization_Delegate.BindRaw(this, &FCAVEOverlayModule::OnSessionStart);
+	FWorldDelegates::OnPostWorldInitialization.Add(On_Post_World_Initialization_Delegate);
+}
+
+void FCAVEOverlayModule::OnSessionStart(UWorld* World, const UWorld::InitializationValues)
+{
+	if (!World->IsGameWorld())
+		return;
+
+	const UCAVEOverlaySettings* Settings = GetDefault<UCAVEOverlaySettings>();
+
+	//Test if already in
+	TArray<AActor*> Actors;
+	UGameplayStatics::GetAllActorsOfClass(World, ACAVEOverlayController::StaticClass(), Actors);
+
+	if((Settings->DefaultActivationType == DefaultActivationType_ON
+		^ Settings->excludedMaps.ContainsByPredicate(
+			[World](const FSoftObjectPath& Map)	{return Map.GetAssetName() == World->GetName();}
+		)) && Actors.Num() == 0){
+		World->SpawnActor(ACAVEOverlayController::StaticClass());
+	}
 }
 
+
 void FCAVEOverlayModule::ShutdownModule()
 {
 	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
@@ -17,4 +43,4 @@ void FCAVEOverlayModule::ShutdownModule()
 
 #undef LOCTEXT_NAMESPACE
 	
-IMPLEMENT_MODULE(FCAVEOverlayModule, CAVEOverlay)
\ No newline at end of file
+IMPLEMENT_MODULE(FCAVEOverlayModule, CAVEOverlay)
diff --git a/Source/CAVEOverlay/Public/CAVEOverlay.h b/Source/CAVEOverlay/Public/CAVEOverlay.h
index 9c40bae..0265d6c 100644
--- a/Source/CAVEOverlay/Public/CAVEOverlay.h
+++ b/Source/CAVEOverlay/Public/CAVEOverlay.h
@@ -4,6 +4,7 @@
 
 #include "CoreMinimal.h"
 #include "Modules/ModuleManager.h"
+#include "Engine/World.h"
 
 class FCAVEOverlayModule : public IModuleInterface
 {
@@ -12,4 +13,7 @@ public:
 	/** IModuleInterface implementation */
 	virtual void StartupModule() override;
 	virtual void ShutdownModule() override;
+private:
+	TBaseDelegate<void, UWorld*, const UWorld::InitializationValues> On_Post_World_Initialization_Delegate;
+	void OnSessionStart(UWorld* World, UWorld::InitializationValues);
 };
diff --git a/Source/CAVEOverlay/Public/CAVEOverlaySettings.h b/Source/CAVEOverlay/Public/CAVEOverlaySettings.h
new file mode 100644
index 0000000..90bdf48
--- /dev/null
+++ b/Source/CAVEOverlay/Public/CAVEOverlaySettings.h
@@ -0,0 +1,25 @@
+#pragma once
+#include "CoreMinimal.h"
+#include "Engine/EngineTypes.h"
+#include "Engine/DeveloperSettings.h"
+#include "CAVEOverlaySettings.generated.h"
+
+UENUM(BlueprintType)
+enum DefaultActivationType
+{
+	DefaultActivationType_OFF UMETA(DisplayName = "Off by default"),
+	DefaultActivationType_ON UMETA(DisplayName = "On by default")
+};
+
+UCLASS(config=Game, defaultconfig, meta=(DisplayName="CAVE Overlay"))
+class UCAVEOverlaySettings : public UDeveloperSettings
+{
+	GENERATED_BODY()
+
+public:
+	UPROPERTY(EditAnywhere, config, Category = "General", meta = (DisplayName = "Default Activation Type"))
+	TEnumAsByte<DefaultActivationType> DefaultActivationType = DefaultActivationType_ON;
+
+	UPROPERTY(EditAnywhere, config, Category = Maps, meta=(AllowedClasses="World"))
+	TArray<FSoftObjectPath> excludedMaps;
+};
-- 
GitLab


From 62ee2f55804ef3d7ecbe438eb87f775ab972afe0 Mon Sep 17 00:00:00 2001
From: Sebastian Pape <pape@vr.rwth-aachen.de>
Date: Mon, 20 Jan 2020 16:39:14 +0100
Subject: [PATCH 2/6] Explicitly taking shutter glasses instead of head

---
 Source/CAVEOverlay/Private/CAVEOverlayController.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
index 6910a04..ecff03b 100644
--- a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
+++ b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
@@ -279,7 +279,7 @@ bool ACAVEOverlayController::PositionInDoorOpening(FVector Position)
 void ACAVEOverlayController::RefreshPawnComponents()
 {
 	Cave_Origin = Player_Pawn->GetTrackingOriginComponent();
-	Shutter_Glasses = Player_Pawn->GetHeadComponent();
+	Shutter_Glasses = Player_Pawn->GetShutterGlassesComponent();
 }
 
 // Called every frame
-- 
GitLab


From 0177b0c242fd612203126eabda5f0913689a7257 Mon Sep 17 00:00:00 2001
From: Sebi <pape@vr.rwth-aachen.de>
Date: Tue, 21 Jan 2020 17:07:14 +0100
Subject: [PATCH 3/6] Removed dependency and updated head translation
 calculation

---
 Source/CAVEOverlay/Private/CAVEOverlayController.cpp | 11 +++++------
 Source/CAVEOverlay/Public/CAVEOverlayController.h    |  9 ++++-----
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
index ecff03b..d18b4b7 100644
--- a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
+++ b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
@@ -21,8 +21,7 @@
 
 DEFINE_LOG_CATEGORY(LogCAVEOverlay);
 
-template <std::size_t S>
-bool ContainsFString(const std::array<FString, S>& Array, const FString& Entry)
+bool ContainsFString(const TArray<FString>& Array, const FString& Entry)
 {
 	for (FString Current_Entry : Array)
 	{
@@ -279,7 +278,7 @@ bool ACAVEOverlayController::PositionInDoorOpening(FVector Position)
 void ACAVEOverlayController::RefreshPawnComponents()
 {
 	Cave_Origin = Player_Pawn->GetTrackingOriginComponent();
-	Shutter_Glasses = Player_Pawn->GetShutterGlassesComponent();
+	Head = Player_Pawn->GetHeadComponent();
 }
 
 // Called every frame
@@ -289,7 +288,7 @@ void ACAVEOverlayController::Tick(float DeltaTime)
 
 	if (!bCAVE_Mode) return; // Not our business
 
-	if (!Cave_Origin || !Shutter_Glasses)
+	if (!Cave_Origin || !Head)
 	{
 		RefreshPawnComponents();
 	}
@@ -313,10 +312,10 @@ void ACAVEOverlayController::Tick(float DeltaTime)
 		}
 	}
 
-	if (!Shutter_Glasses) return; //Display Cluster not initialized
+	if (!Head) return; //Display Cluster not initialized
 
 	//Tape Logic
-	FVector Shutter_Position = Shutter_Glasses->GetRelativeTransform().GetLocation();
+	FVector Shutter_Position = Cave_Origin->GetComponentLocation() - Head->GetComponentLocation();
 	bool bOverlay_Visible = FMath::IsWithinInclusive(Shutter_Position.GetAbsMax(), Wall_Distance - Wall_Close_Distance, Wall_Distance);
 
 	if (bOverlay_Visible && !PositionInDoorOpening(Shutter_Position))
diff --git a/Source/CAVEOverlay/Public/CAVEOverlayController.h b/Source/CAVEOverlay/Public/CAVEOverlayController.h
index 73760b6..0a335f0 100644
--- a/Source/CAVEOverlay/Public/CAVEOverlayController.h
+++ b/Source/CAVEOverlay/Public/CAVEOverlayController.h
@@ -6,7 +6,6 @@
 #include "GameFramework/Actor.h"
 #include "DoorOverlayData.h"
 #include "Engine/Engine.h"
-#include <array>
 #include "Components/StaticMeshComponent.h"
 #include "Materials/Material.h"
 #include "Materials/MaterialInstanceDynamic.h"
@@ -39,9 +38,9 @@ private:
 	enum EScreen_Type { SCREEN_MASTER, SCREEN_NORMAL, SCREEN_DOOR_PARTIAL, SCREEN_DOOR };
 
 	EScreen_Type Screen_Type = SCREEN_NORMAL;
-	const std::array<FString, 4> Screens_Door = {"node_bul_left_eye", "node_bul_right_eye", "node_bll_left_eye", "node_bll_right_eye"};
-	const std::array<FString, 4> Screens_Door_Partial = {"node_bur_left_eye", "node_bur_right_eye", "node_blr_left_eye", "node_blr_right_eye"};
-	const std::array<FString, 5> Screens_FPS = {"node_rur_left_eye", "node_rur_right_eye", "node_lur_left_eye", "node_lur_right_eye", "node_main"};
+	const TArray<FString> Screens_Door = {"node_bul_left_eye", "node_bul_right_eye", "node_bll_left_eye", "node_bll_right_eye"};
+	const TArray<FString> Screens_Door_Partial = {"node_bur_left_eye", "node_bur_right_eye", "node_blr_left_eye", "node_blr_right_eye"};
+	const TArray<FString> Screens_FPS = {"node_rur_left_eye", "node_rur_right_eye", "node_lur_left_eye", "node_lur_right_eye", "node_main"};
 	const FString Screen_Main = "node_main";
 
 	//Door Mode
@@ -73,7 +72,7 @@ private:
 	void RefreshPawnComponents();
 	AVirtualRealityPawn* Player_Pawn;
 	USceneComponent* Cave_Origin;
-	USceneComponent* Shutter_Glasses;
+	USceneComponent* Head;
 
 	//Cluster Events
 	FOnClusterEventListener ClusterEventListenerDelegate;
-- 
GitLab


From 75487b11bb3b19d6b6c5c9727ddc7c88c2f6b3f9 Mon Sep 17 00:00:00 2001
From: Sebi <pape@vr.rwth-aachen.de>
Date: Wed, 22 Jan 2020 08:51:20 +0100
Subject: [PATCH 4/6] Fixing Nullptr dereference

---
 Source/CAVEOverlay/Private/CAVEOverlayController.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
index d18b4b7..9c9662a 100644
--- a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
+++ b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
@@ -312,7 +312,7 @@ void ACAVEOverlayController::Tick(float DeltaTime)
 		}
 	}
 
-	if (!Head) return; //Display Cluster not initialized
+	if (!Head || !Cave_Origin) return; //Display Cluster not initialized
 
 	//Tape Logic
 	FVector Shutter_Position = Cave_Origin->GetComponentLocation() - Head->GetComponentLocation();
-- 
GitLab


From a09dba3b4bc1f25107997d67d399929246eddf66 Mon Sep 17 00:00:00 2001
From: Sebi <pape@vr.rwth-aachen.de>
Date: Wed, 22 Jan 2020 15:26:27 +0100
Subject: [PATCH 5/6] Fixing Position calculation

---
 Source/CAVEOverlay/Private/CAVEOverlayController.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
index 9c9662a..9c16ab7 100644
--- a/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
+++ b/Source/CAVEOverlay/Private/CAVEOverlayController.cpp
@@ -315,7 +315,7 @@ void ACAVEOverlayController::Tick(float DeltaTime)
 	if (!Head || !Cave_Origin) return; //Display Cluster not initialized
 
 	//Tape Logic
-	FVector Shutter_Position = Cave_Origin->GetComponentLocation() - Head->GetComponentLocation();
+	FVector Shutter_Position = Head->GetComponentLocation() - Cave_Origin->GetComponentLocation();
 	bool bOverlay_Visible = FMath::IsWithinInclusive(Shutter_Position.GetAbsMax(), Wall_Distance - Wall_Close_Distance, Wall_Distance);
 
 	if (bOverlay_Visible && !PositionInDoorOpening(Shutter_Position))
-- 
GitLab


From b63fcbf097ca96385e82d506e9e4649f88f00fe1 Mon Sep 17 00:00:00 2001
From: Sebastian Pape <pape@vr.rwth-aachen.de>
Date: Wed, 26 Feb 2020 15:26:20 +0100
Subject: [PATCH 6/6] Changed XOR to Not-Equals for better readability

---
 Source/CAVEOverlay/Private/CAVEOverlay.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/CAVEOverlay/Private/CAVEOverlay.cpp b/Source/CAVEOverlay/Private/CAVEOverlay.cpp
index 35d9987..01e45d7 100644
--- a/Source/CAVEOverlay/Private/CAVEOverlay.cpp
+++ b/Source/CAVEOverlay/Private/CAVEOverlay.cpp
@@ -27,7 +27,7 @@ void FCAVEOverlayModule::OnSessionStart(UWorld* World, const UWorld::Initializat
 	UGameplayStatics::GetAllActorsOfClass(World, ACAVEOverlayController::StaticClass(), Actors);
 
 	if((Settings->DefaultActivationType == DefaultActivationType_ON
-		^ Settings->excludedMaps.ContainsByPredicate(
+		!= Settings->excludedMaps.ContainsByPredicate(
 			[World](const FSoftObjectPath& Map)	{return Map.GetAssetName() == World->GetName();}
 		)) && Actors.Num() == 0){
 		World->SpawnActor(ACAVEOverlayController::StaticClass());
-- 
GitLab