From fde8f4d152eef52ae591bda1f6d12111748d95a4 Mon Sep 17 00:00:00 2001
From: David Gilbert <david.gilbert@rwth-aachen.de>
Date: Fri, 31 Jan 2025 15:58:02 +0100
Subject: [PATCH 1/3] fix(ci): Fixes wrong merge for Unreal version

---
 .gitlab-ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e4a8b57..5ad065f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -40,7 +40,7 @@ include:
 # Use the UNREAL_VERSION variable to adjust to your preferred Unreal version.
 
 variables:
-    UNREAL_VERSION: "5.5"
+    UNREAL_VERSION: "5.4"
 
 stages:
   - analyze
@@ -81,7 +81,7 @@ Generate_Project:
         RUN_SETUP: "false"
         GEN_DEPENDENCIES: "(
             [master@UnrealDTrackPlugin]='https://github.com/VRGroupRWTH/UnrealDTrackPlugin.git'
-            [dev/5.5@RWTHVRToolkit]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-toolkit.git'
+            [dev/5.4@RWTHVRToolkit]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-toolkit.git'
             )"
 
 Generate_Project_Without_Toolkit:
-- 
GitLab


From 3c410aea27b55efbc2c612ce47056ee2b1ac6514 Mon Sep 17 00:00:00 2001
From: David Gilbert <gilbert@vr.rwth-aachen.de>
Date: Wed, 5 Mar 2025 10:51:22 +0100
Subject: [PATCH 2/3] fix(Cave): Modifies CaveOverlay to be able to handle Pawn
 changes

---
 .../CAVEOverlay/CAVEOverlayController.cpp     | 51 +++++++++++++++----
 .../CAVEOverlay/CAVEOverlayController.h       |  6 +++
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp b/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
index 6553ad4..5e61b83 100644
--- a/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
+++ b/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
@@ -149,6 +149,10 @@ void ACAVEOverlayController::BeginPlay()
 	if (GetNetMode() != NM_Standalone)
 		return;
 
+	// If we're not in room-mounted mode, return as well
+	if (!URWTHVRClusterUtilities::IsRoomMountedMode())
+		return;
+
 	// This should return the respective client's local playercontroller or, if we're a listen server, our own PC.
 	auto* PC = GetWorld() ? GetWorld()->GetFirstPlayerController() : nullptr;
 
@@ -157,9 +161,9 @@ void ACAVEOverlayController::BeginPlay()
 	// Not sure which place would be best...
 	const bool bValidPC = PC && PC->GetLocalPlayer();
 
-	if (!bValidPC || !URWTHVRClusterUtilities::IsRoomMountedMode())
+	if (!bValidPC)
 		return;
-
+	
 	// Input config
 	if (URWTHVRClusterUtilities::IsPrimaryNode())
 	{
@@ -223,11 +227,36 @@ void ACAVEOverlayController::BeginPlay()
 		return;
 	}
 
+	PC->OnPossessedPawnChanged.AddUniqueDynamic(this, &ACAVEOverlayController::UpdatePossessedPawn);
+	
+	// I think this breaks in multiplayer mode
+	InitFromPawn(PC->GetPawn());
+
+	// Create dynamic material for tape
+	TapeMaterialDynamic = Tape->CreateDynamicMaterialInstance(0);
+
+	UE_LOGFMT(LogCAVEOverlay, Display, "CaveOverlay Initialization was successfull.");
+}
+
+void ACAVEOverlayController::UpdatePossessedPawn(APawn* OldPawn, APawn* NewPawn)
+{
+	InitFromPawn(NewPawn);
+}
+
+
+void ACAVEOverlayController::InitFromPawn(const APawn* CurrentPawn)
+{
+	// Clear previous properties. We could reuse the SMCs and MIDs, clearing them might be dangerous.
+	// Too much in a hurry here to make this better.
+	MotionControllers.Empty();
+	SignsStaticMeshComponents.Empty();
+	SignsMIDs.Empty();
+	
 	// Get the pawn so we can have access to head and hand positions
-	if (const auto* VRPawn = Cast<APawn>(PC->GetPawnOrSpectator()))
+	if (CurrentPawn)
 	{
-		PawnCamera = VRPawn->GetComponentByClass<UCameraComponent>();
-		auto FoundMotionControllers = VRPawn->K2_GetComponentsByClass(UMotionControllerComponent::StaticClass());
+		PawnCamera = CurrentPawn->GetComponentByClass<UCameraComponent>();
+		auto FoundMotionControllers = CurrentPawn->K2_GetComponentsByClass(UMotionControllerComponent::StaticClass());
 
 		for (const auto FoundMotionController : FoundMotionControllers)
 		{
@@ -261,13 +290,9 @@ void ACAVEOverlayController::BeginPlay()
 	}
 	else
 	{
+		bInitialized = false;
 		UE_LOGFMT(LogCAVEOverlay, Error, "No VirtualRealityPawn found which we could attach to!");
 	}
-
-	// Create dynamic material for tape
-	TapeMaterialDynamic = Tape->CreateDynamicMaterialInstance(0);
-
-	UE_LOGFMT(LogCAVEOverlay, Display, "CaveOverlay Initialization was successfull.");
 }
 
 void ACAVEOverlayController::EndPlay(const EEndPlayReason::Type EndPlayReason)
@@ -386,6 +411,12 @@ void ACAVEOverlayController::Tick(float DeltaTime)
 	// Hand Logic
 	for (int i = 0; i < MotionControllers.Num(); i++)
 	{
+		if (MotionControllers[i] == nullptr)
+		{
+			UE_LOGFMT(LogCAVEOverlay, Error, "Motion Controller was nullptr, disabling overlay!");
+			bInitialized = false;
+			return;
+		}
 		const FVector HandPosition = MotionControllers[i]->GetRelativeLocation();
 
 		// Set the position rotation, opacity, visibility of the hand warning signs.
diff --git a/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h b/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h
index 0e8c09f..c46cabc 100644
--- a/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h
+++ b/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h
@@ -78,6 +78,12 @@ private:
 	const float WallWarningDistance = 40; // cm, distance on which the tape turns red, measured from wall
 	float DoorCurrentOpeningWidthAbsolute = 0;
 
+	// Function that initializes things from the currently possessed pawn
+	void InitFromPawn(const APawn* CurrentPawn);
+
+	UFUNCTION()
+	void UpdatePossessedPawn(APawn* OldPawn, APawn* NewPawn);
+
 	// Helper function to create a mesh component in the constructor
 	UStaticMeshComponent* CreateMeshComponent(const FName& Name, USceneComponent* Parent);
 
-- 
GitLab


From 14df091a335d30b48b6237175b70df9fa9de1af6 Mon Sep 17 00:00:00 2001
From: Kris Helwig <helwig@vr.rwth-aachen.de>
Date: Mon, 17 Mar 2025 10:26:01 +0100
Subject: [PATCH 3/3] format(Cave): fixes clang errors

---
 .../Private/CAVEOverlay/CAVEOverlayController.cpp     | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp b/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
index 5e61b83..4805e43 100644
--- a/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
+++ b/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
@@ -163,7 +163,7 @@ void ACAVEOverlayController::BeginPlay()
 
 	if (!bValidPC)
 		return;
-	
+
 	// Input config
 	if (URWTHVRClusterUtilities::IsPrimaryNode())
 	{
@@ -228,7 +228,7 @@ void ACAVEOverlayController::BeginPlay()
 	}
 
 	PC->OnPossessedPawnChanged.AddUniqueDynamic(this, &ACAVEOverlayController::UpdatePossessedPawn);
-	
+
 	// I think this breaks in multiplayer mode
 	InitFromPawn(PC->GetPawn());
 
@@ -238,10 +238,7 @@ void ACAVEOverlayController::BeginPlay()
 	UE_LOGFMT(LogCAVEOverlay, Display, "CaveOverlay Initialization was successfull.");
 }
 
-void ACAVEOverlayController::UpdatePossessedPawn(APawn* OldPawn, APawn* NewPawn)
-{
-	InitFromPawn(NewPawn);
-}
+void ACAVEOverlayController::UpdatePossessedPawn(APawn* OldPawn, APawn* NewPawn) { InitFromPawn(NewPawn); }
 
 
 void ACAVEOverlayController::InitFromPawn(const APawn* CurrentPawn)
@@ -251,7 +248,7 @@ void ACAVEOverlayController::InitFromPawn(const APawn* CurrentPawn)
 	MotionControllers.Empty();
 	SignsStaticMeshComponents.Empty();
 	SignsMIDs.Empty();
-	
+
 	// Get the pawn so we can have access to head and hand positions
 	if (CurrentPawn)
 	{
-- 
GitLab