From fc4eda4ec188c733e2687a260bab8075adfc5d9f Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Fri, 7 Mar 2025 14:52:47 +0100 Subject: [PATCH 01/14] feat(pawn): Adds VR scaling functionality --- .../RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 59 +++++++++++++++---- Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h | 4 ++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 812e83ea..4eb03b04 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -41,8 +41,30 @@ ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(Ob LeftHand = CreateDefaultSubobject<UReplicatedMotionControllerComponent>(TEXT("Left Hand MCC")); LeftHand->SetupAttachment(RootComponent); + + GetRootComponent()->TransformUpdated.AddLambda([this](USceneComponent*, EUpdateTransformFlags, ETeleportType) + { + FVector CurrentScale = this->GetActorScale3D(); + if (CurrentScale.X == CurrentScale.Y && CurrentScale.Y == CurrentScale.Z) + { + float expectedScale = GetWorldSettings()->WorldToMeters / InitialWorldToMeters; + float ErrorPrecision = 1E-05; + if (FMath::IsNearlyEqual(CurrentScale.X, expectedScale, ErrorPrecision)) + { + return; + } + } + UE_LOGFMT(Toolkit, Warning, + "ARWTHVRPawn: Do not adjust the scale of the pawn directly. This will not work in VR. Use ARWTHVRPawn::SetScale(float) instead.") + ; + }); +} + +void ARWTHVRPawn::BeginPlay() +{ + Super::BeginPlay(); + InitialWorldToMeters = GetWorldSettings()->WorldToMeters; } -void ARWTHVRPawn::BeginPlay() { Super::BeginPlay(); } void ARWTHVRPawn::Tick(float DeltaSeconds) { @@ -56,6 +78,17 @@ void ARWTHVRPawn::Tick(float DeltaSeconds) EvaluateLivelink(); } +/* + * Scales the Pawn while also adjusting the WorldToMeters ratio to adjust for pupillary distance. + * Only supports uniform scaling. + */ +void ARWTHVRPawn::SetScale(float NewScale) +{ + FVector NewScaleVector = FVector(NewScale, NewScale, NewScale); + GetWorldSettings()->WorldToMeters = InitialWorldToMeters * NewScale; + SetActorScale3D(NewScaleVector); +} + /* * The alternative would be to do this only on the server on possess and check for player state/type, * as connections now send their playertype over. @@ -71,7 +104,7 @@ void ARWTHVRPawn::NotifyControllerChanged() if (HasAuthority()) { UE_LOG(Toolkit, Display, - TEXT("ARWTHVRPawn: Player Controller has changed, trying to change Cluster attachment if possible...")); + TEXT("ARWTHVRPawn: Player Controller has changed, trying to change Cluster attachment if possible...")); if (const ARWTHVRPlayerState* State = GetPlayerState<ARWTHVRPlayerState>()) { const EPlayerType Type = State->GetPlayerType(); @@ -101,7 +134,7 @@ void ARWTHVRPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponen } UE_LOGFMT(Toolkit, Display, "SetupPlayerInputComponent: Player Controller is valid, setting up input for {Pawn}", - GetName()); + GetName()); // Set the control rotation of the PC to zero again. There is a small period of 2 frames where, when the pawn gets @@ -173,7 +206,7 @@ void ARWTHVRPawn::AddInputMappingContext(const APlayerController* PC, const UInp else { UE_LOGFMT(Toolkit, Warning, - "ARWTHVRPawn::AddInputMappingContext: UEnhancedInputLocalPlayerSubsystem is nullptr!"); + "ARWTHVRPawn::AddInputMappingContext: UEnhancedInputLocalPlayerSubsystem is nullptr!"); } } else @@ -201,7 +234,7 @@ void ARWTHVRPawn::EvaluateLivelink() const IModularFeatures::Get().GetModularFeature<ILiveLinkClient>(ILiveLinkClient::ModularFeatureName); FLiveLinkSubjectFrameData SubjectData; const bool bHasValidData = LiveLinkClient.EvaluateFrame_AnyThread(HeadSubjectRepresentation.Subject, - HeadSubjectRepresentation.Role, SubjectData); + HeadSubjectRepresentation.Role, SubjectData); if (!bHasValidData) { @@ -278,12 +311,12 @@ void ARWTHVRPawn::AttachClustertoPawn() bool bAttached = ClusterActor->AttachToComponent(GetRootComponent(), AttachmentRules); // State->GetCorrespondingClusterActor()->OnAttached(); UE_LOGFMT(Toolkit, Display, - "ARWTHVRPawn: Attaching corresponding cluster actor to our pawn returned: {Attached}", bAttached); + "ARWTHVRPawn: Attaching corresponding cluster actor to our pawn returned: {Attached}", bAttached); } else { UE_LOGFMT(Toolkit, Error, - "ARWTHVRPawn::AttachClustertoPawn: No ARWTHVRPlayerState set! This won't work on the Cave."); + "ARWTHVRPawn::AttachClustertoPawn: No ARWTHVRPlayerState set! This won't work on the Cave."); } if (HasAuthority()) // Should always be the case here, but double check @@ -321,19 +354,19 @@ void ARWTHVRPawn::SetCameraOffset() const } void ARWTHVRPawn::ApplyLiveLinkTransform(const FTransform& Transform, - const FLiveLinkTransformStaticData& StaticData) const + const FLiveLinkTransformStaticData& StaticData) const { if (StaticData.bIsLocationSupported) { if (bWorldTransform) { HeadCameraComponent->SetWorldLocation(Transform.GetLocation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } else { HeadCameraComponent->SetRelativeLocation(Transform.GetLocation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } } @@ -342,12 +375,12 @@ void ARWTHVRPawn::ApplyLiveLinkTransform(const FTransform& Transform, if (bWorldTransform) { HeadCameraComponent->SetWorldRotation(Transform.GetRotation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } else { HeadCameraComponent->SetRelativeRotation(Transform.GetRotation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } } @@ -362,4 +395,4 @@ void ARWTHVRPawn::ApplyLiveLinkTransform(const FTransform& Transform, HeadCameraComponent->SetRelativeScale3D(Transform.GetScale3D()); } } -} +} \ No newline at end of file diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h index cd81e497..eaf24745 100644 --- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h +++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h @@ -31,6 +31,9 @@ public: virtual void NotifyControllerChanged() override; + UFUNCTION(BlueprintCallable) + void SetScale(float NewScale); + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Pawn|Input") TArray<UInputMappingContext*> InputMappingContexts; @@ -111,4 +114,5 @@ protected: private: UInputComponent* ActivePlayerInputComponent; + float InitialWorldToMeters; }; -- GitLab From 9b1eb745890b8e34f447ecc96eac826efbd57d7d Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Tue, 11 Mar 2025 15:42:58 +0100 Subject: [PATCH 02/14] feat(pawn): Adds OnScaleChanged callback --- .../RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 29 ++++++++++--------- Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h | 13 +++++++-- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 4eb03b04..7e32a90d 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -42,21 +42,16 @@ ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(Ob LeftHand = CreateDefaultSubobject<UReplicatedMotionControllerComponent>(TEXT("Left Hand MCC")); LeftHand->SetupAttachment(RootComponent); + UniformScale = GetActorScale3D().X; GetRootComponent()->TransformUpdated.AddLambda([this](USceneComponent*, EUpdateTransformFlags, ETeleportType) { FVector CurrentScale = this->GetActorScale3D(); - if (CurrentScale.X == CurrentScale.Y && CurrentScale.Y == CurrentScale.Z) + if (CurrentScale.X != UniformScale || CurrentScale.Y != UniformScale || CurrentScale.Z != UniformScale) { - float expectedScale = GetWorldSettings()->WorldToMeters / InitialWorldToMeters; - float ErrorPrecision = 1E-05; - if (FMath::IsNearlyEqual(CurrentScale.X, expectedScale, ErrorPrecision)) - { - return; - } + UE_LOGFMT(Toolkit, Warning, + "ARWTHVRPawn: Do not adjust the scale of the pawn directly. This will not work in VR. Use ARWTHVRPawn::SetScale(float) instead.") + ; } - UE_LOGFMT(Toolkit, Warning, - "ARWTHVRPawn: Do not adjust the scale of the pawn directly. This will not work in VR. Use ARWTHVRPawn::SetScale(float) instead.") - ; }); } @@ -84,9 +79,17 @@ void ARWTHVRPawn::Tick(float DeltaSeconds) */ void ARWTHVRPawn::SetScale(float NewScale) { - FVector NewScaleVector = FVector(NewScale, NewScale, NewScale); - GetWorldSettings()->WorldToMeters = InitialWorldToMeters * NewScale; - SetActorScale3D(NewScaleVector); + FVector OldScale = GetActorScale(); + UniformScale = NewScale; + FVector NewScaleVector = FVector(UniformScale, UniformScale, UniformScale); + GetWorldSettings()->WorldToMeters = InitialWorldToMeters * UniformScale; + SetActorRelativeScale3D(NewScaleVector); + OnScaleChanged.Broadcast(OldScale, NewScale); +} + +float ARWTHVRPawn::GetScale() +{ + return UniformScale; } /* diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h index eaf24745..bad99461 100644 --- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h +++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h @@ -14,6 +14,8 @@ class UCameraComponent; class UMotionControllerComponent; struct FLiveLinkTransformStaticData; +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnScaleChangedDelegate, FVector, OldScale, float, NewUniformScale); + /** * Pawn implementation with additional VR functionality, can be used in the Cave, with an HMD and on desktop. */ @@ -30,10 +32,16 @@ public: virtual void Tick(float DeltaSeconds) override; virtual void NotifyControllerChanged() override; - + UFUNCTION(BlueprintCallable) void SetScale(float NewScale); - + + UFUNCTION(BlueprintCallable) + float GetScale(); + + UPROPERTY(BlueprintAssignable) + FOnScaleChangedDelegate OnScaleChanged; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Pawn|Input") TArray<UInputMappingContext*> InputMappingContexts; @@ -115,4 +123,5 @@ protected: private: UInputComponent* ActivePlayerInputComponent; float InitialWorldToMeters; + float UniformScale; }; -- GitLab From e3e150ba6f616a0521ec7863450b392438dd995e Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Mon, 17 Mar 2025 15:20:17 +0100 Subject: [PATCH 03/14] fix(movement): Scales the CollisionHandlingMovement capsule to counteract pawn scaling --- .../Private/Pawn/Navigation/CollisionHandlingMovement.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp index 62bfa460..0effb261 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp @@ -3,6 +3,7 @@ #include "Kismet/KismetSystemLibrary.h" #include "Logging/StructuredLog.h" #include "Utility/RWTHVRUtilities.h" +#include "DrawDebugHelpers.h" UCollisionHandlingMovement::UCollisionHandlingMovement(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) @@ -189,6 +190,9 @@ void UCollisionHandlingMovement::SetCapsuleColliderToUserSize() const } CapsuleColliderComponent->SetWorldRotation(FRotator::ZeroRotator); + + // Counteract Pawn Scaling + CapsuleColliderComponent->SetWorldScale3D(FVector::One()); } void UCollisionHandlingMovement::CheckAndRevertCollisionSinceLastTick() -- GitLab From 5fff5b7ee76a2026588cec9439674a21de7840e3 Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Mon, 17 Mar 2025 15:42:51 +0100 Subject: [PATCH 04/14] style(pawn): fixes clang format in RWTHVRPawn.cpp and RWTHVRPawn.h --- .../RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 46 +++++++++---------- Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h | 2 +- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 7e32a90d..f773fa9f 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -43,16 +43,17 @@ ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(Ob LeftHand->SetupAttachment(RootComponent); UniformScale = GetActorScale3D().X; - GetRootComponent()->TransformUpdated.AddLambda([this](USceneComponent*, EUpdateTransformFlags, ETeleportType) - { - FVector CurrentScale = this->GetActorScale3D(); - if (CurrentScale.X != UniformScale || CurrentScale.Y != UniformScale || CurrentScale.Z != UniformScale) + GetRootComponent()->TransformUpdated.AddLambda( + [this](USceneComponent*, EUpdateTransformFlags, ETeleportType) { - UE_LOGFMT(Toolkit, Warning, - "ARWTHVRPawn: Do not adjust the scale of the pawn directly. This will not work in VR. Use ARWTHVRPawn::SetScale(float) instead.") - ; - } - }); + FVector CurrentScale = this->GetActorScale3D(); + if (CurrentScale.X != UniformScale || CurrentScale.Y != UniformScale || CurrentScale.Z != UniformScale) + { + UE_LOGFMT(Toolkit, Warning, + "ARWTHVRPawn: Do not adjust the scale of the pawn directly. This will not work in VR. Use " + "ARWTHVRPawn::SetScale(float) instead."); + } + }); } void ARWTHVRPawn::BeginPlay() @@ -87,10 +88,7 @@ void ARWTHVRPawn::SetScale(float NewScale) OnScaleChanged.Broadcast(OldScale, NewScale); } -float ARWTHVRPawn::GetScale() -{ - return UniformScale; -} +float ARWTHVRPawn::GetScale() { return UniformScale; } /* * The alternative would be to do this only on the server on possess and check for player state/type, @@ -107,7 +105,7 @@ void ARWTHVRPawn::NotifyControllerChanged() if (HasAuthority()) { UE_LOG(Toolkit, Display, - TEXT("ARWTHVRPawn: Player Controller has changed, trying to change Cluster attachment if possible...")); + TEXT("ARWTHVRPawn: Player Controller has changed, trying to change Cluster attachment if possible...")); if (const ARWTHVRPlayerState* State = GetPlayerState<ARWTHVRPlayerState>()) { const EPlayerType Type = State->GetPlayerType(); @@ -137,7 +135,7 @@ void ARWTHVRPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponen } UE_LOGFMT(Toolkit, Display, "SetupPlayerInputComponent: Player Controller is valid, setting up input for {Pawn}", - GetName()); + GetName()); // Set the control rotation of the PC to zero again. There is a small period of 2 frames where, when the pawn gets @@ -209,7 +207,7 @@ void ARWTHVRPawn::AddInputMappingContext(const APlayerController* PC, const UInp else { UE_LOGFMT(Toolkit, Warning, - "ARWTHVRPawn::AddInputMappingContext: UEnhancedInputLocalPlayerSubsystem is nullptr!"); + "ARWTHVRPawn::AddInputMappingContext: UEnhancedInputLocalPlayerSubsystem is nullptr!"); } } else @@ -237,7 +235,7 @@ void ARWTHVRPawn::EvaluateLivelink() const IModularFeatures::Get().GetModularFeature<ILiveLinkClient>(ILiveLinkClient::ModularFeatureName); FLiveLinkSubjectFrameData SubjectData; const bool bHasValidData = LiveLinkClient.EvaluateFrame_AnyThread(HeadSubjectRepresentation.Subject, - HeadSubjectRepresentation.Role, SubjectData); + HeadSubjectRepresentation.Role, SubjectData); if (!bHasValidData) { @@ -314,12 +312,12 @@ void ARWTHVRPawn::AttachClustertoPawn() bool bAttached = ClusterActor->AttachToComponent(GetRootComponent(), AttachmentRules); // State->GetCorrespondingClusterActor()->OnAttached(); UE_LOGFMT(Toolkit, Display, - "ARWTHVRPawn: Attaching corresponding cluster actor to our pawn returned: {Attached}", bAttached); + "ARWTHVRPawn: Attaching corresponding cluster actor to our pawn returned: {Attached}", bAttached); } else { UE_LOGFMT(Toolkit, Error, - "ARWTHVRPawn::AttachClustertoPawn: No ARWTHVRPlayerState set! This won't work on the Cave."); + "ARWTHVRPawn::AttachClustertoPawn: No ARWTHVRPlayerState set! This won't work on the Cave."); } if (HasAuthority()) // Should always be the case here, but double check @@ -357,19 +355,19 @@ void ARWTHVRPawn::SetCameraOffset() const } void ARWTHVRPawn::ApplyLiveLinkTransform(const FTransform& Transform, - const FLiveLinkTransformStaticData& StaticData) const + const FLiveLinkTransformStaticData& StaticData) const { if (StaticData.bIsLocationSupported) { if (bWorldTransform) { HeadCameraComponent->SetWorldLocation(Transform.GetLocation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } else { HeadCameraComponent->SetRelativeLocation(Transform.GetLocation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } } @@ -378,12 +376,12 @@ void ARWTHVRPawn::ApplyLiveLinkTransform(const FTransform& Transform, if (bWorldTransform) { HeadCameraComponent->SetWorldRotation(Transform.GetRotation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } else { HeadCameraComponent->SetRelativeRotation(Transform.GetRotation(), false, nullptr, - ETeleportType::TeleportPhysics); + ETeleportType::TeleportPhysics); } } diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h index bad99461..40eb174f 100644 --- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h +++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h @@ -32,7 +32,7 @@ public: virtual void Tick(float DeltaSeconds) override; virtual void NotifyControllerChanged() override; - + UFUNCTION(BlueprintCallable) void SetScale(float NewScale); -- GitLab From 4e8d0770cd8145ca9e682e630798dfde0b36f9e1 Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Mon, 17 Mar 2025 15:45:30 +0100 Subject: [PATCH 05/14] style(pawn): fixes clang format in RWTHVRPawn.cpp and RWTHVRPawn.h again --- Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index f773fa9f..dc9c9022 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -88,7 +88,7 @@ void ARWTHVRPawn::SetScale(float NewScale) OnScaleChanged.Broadcast(OldScale, NewScale); } -float ARWTHVRPawn::GetScale() { return UniformScale; } +float ARWTHVRPawn::GetScale() { return UniformScale; } /* * The alternative would be to do this only on the server on possess and check for player state/type, -- GitLab From b53030de656fc241154cd842753d02b7f2f16ff2 Mon Sep 17 00:00:00 2001 From: David Gilbert <gilbert@vr.rwth-aachen.de> Date: Thu, 20 Mar 2025 15:50:31 +0100 Subject: [PATCH 06/14] style(movement): removes unnecessary include --- .../Private/Pawn/Navigation/CollisionHandlingMovement.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp index 0effb261..912fe0c1 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp @@ -3,7 +3,6 @@ #include "Kismet/KismetSystemLibrary.h" #include "Logging/StructuredLog.h" #include "Utility/RWTHVRUtilities.h" -#include "DrawDebugHelpers.h" UCollisionHandlingMovement::UCollisionHandlingMovement(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) -- GitLab From 8dd3010c03bbd82aa1d6df3e4c40d6d6a8469db7 Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Tue, 8 Apr 2025 13:03:11 +0200 Subject: [PATCH 07/14] refactor(pawn): changes from a delegate approach to an interface approach --- Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index dc9c9022..31874d9f 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -18,6 +18,10 @@ #include "Utility/RWTHVRUtilities.h" #if PLATFORM_SUPPORTS_CLUSTER +#include "DisplayClusterRootActor.h" +#include "ScalableConfigInterface.h" +#include "IDisplayCluster.h" +#include "Game/IDisplayClusterGameManager.h" #include "Components/DisplayClusterSceneComponentSyncParent.h" #endif @@ -85,7 +89,16 @@ void ARWTHVRPawn::SetScale(float NewScale) FVector NewScaleVector = FVector(UniformScale, UniformScale, UniformScale); GetWorldSettings()->WorldToMeters = InitialWorldToMeters * UniformScale; SetActorRelativeScale3D(NewScaleVector); - OnScaleChanged.Broadcast(OldScale, NewScale); + +#if PLATFORM_SUPPORTS_CLUSTER + const ARWTHVRPlayerState* State = GetPlayerState<ARWTHVRPlayerState>(); + if (URWTHVRUtilities::IsHeadMountedMode() && State && State->GetCorrespondingClusterActor()) + { + const auto ClusterRootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor(); + IScalableConfigInterface* ConfigInterface = Cast<IScalableConfigInterface>(ClusterRootActor); + ConfigInterface->OnScaleChanged(NewScale); + } +#endif } float ARWTHVRPawn::GetScale() { return UniformScale; } -- GitLab From 043d07fa7933e1873f87c21b9eb91d2dc8cba97f Mon Sep 17 00:00:00 2001 From: Kris Tabea Helwig <helwig@vr.rwth-aachen.de> Date: Tue, 8 Apr 2025 13:50:07 +0200 Subject: [PATCH 08/14] Sets correct branch --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 93d693e4..dce45555 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -83,7 +83,7 @@ Generate_Project: RUN_SETUP: "false" GEN_DEPENDENCIES: "( [master@UnrealDTrackPlugin]='https://github.com/VRGroupRWTH/UnrealDTrackPlugin.git' - [dev/5.4@RWTHVRCluster]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-cluster-plugin.git' + [feature/scaling@RWTHVRCluster]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-cluster-plugin.git' )" Generate_Project_Without_Cluster: -- GitLab From a5eeaa493ded672a665d49c74918845afd131fbc Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Tue, 8 Apr 2025 16:29:31 +0200 Subject: [PATCH 09/14] clang --- Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 31874d9f..b79168b6 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -89,7 +89,7 @@ void ARWTHVRPawn::SetScale(float NewScale) FVector NewScaleVector = FVector(UniformScale, UniformScale, UniformScale); GetWorldSettings()->WorldToMeters = InitialWorldToMeters * UniformScale; SetActorRelativeScale3D(NewScaleVector); - + #if PLATFORM_SUPPORTS_CLUSTER const ARWTHVRPlayerState* State = GetPlayerState<ARWTHVRPlayerState>(); if (URWTHVRUtilities::IsHeadMountedMode() && State && State->GetCorrespondingClusterActor()) -- GitLab From 193a009aab78ea8af1f4415ffe5d022b546b14ec Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Fri, 11 Apr 2025 09:45:06 +0200 Subject: [PATCH 10/14] Fix(Pawn): Fixed config interface casting --- .../RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index b79168b6..8f0ecb46 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -84,7 +84,6 @@ void ARWTHVRPawn::Tick(float DeltaSeconds) */ void ARWTHVRPawn::SetScale(float NewScale) { - FVector OldScale = GetActorScale(); UniformScale = NewScale; FVector NewScaleVector = FVector(UniformScale, UniformScale, UniformScale); GetWorldSettings()->WorldToMeters = InitialWorldToMeters * UniformScale; @@ -92,11 +91,24 @@ void ARWTHVRPawn::SetScale(float NewScale) #if PLATFORM_SUPPORTS_CLUSTER const ARWTHVRPlayerState* State = GetPlayerState<ARWTHVRPlayerState>(); - if (URWTHVRUtilities::IsHeadMountedMode() && State && State->GetCorrespondingClusterActor()) + if (URWTHVRUtilities::IsRoomMountedMode() && State && State->GetCorrespondingClusterActor()) { - const auto ClusterRootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor(); - IScalableConfigInterface* ConfigInterface = Cast<IScalableConfigInterface>(ClusterRootActor); - ConfigInterface->OnScaleChanged(NewScale); + if (const auto GameMgr = IDisplayCluster::Get().GetGameMgr()) + { + if (const auto ClusterRootActor = GameMgr->GetRootActor()) + { + if (ClusterRootActor->Implements<UScalableConfigInterface>()) + { + IScalableConfigInterface::Execute_OnScaleChanged(ClusterRootActor, NewScale); + } + else + { + UE_LOGFMT(Toolkit, Warning, + "The ClusterRootActor {0} does not implement the ScalableConfigInterface. Scaling the Pawn on the cluster will lead to unintended behavior.", + ClusterRootActor->GetName()); + } + } + } } #endif } -- GitLab From bbed2d2c4c47e59ea760d42cb7456623bc162c57 Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Fri, 11 Apr 2025 09:48:14 +0200 Subject: [PATCH 11/14] clang(Pawn) --- Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 8f0ecb46..9becddbd 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -104,7 +104,8 @@ void ARWTHVRPawn::SetScale(float NewScale) else { UE_LOGFMT(Toolkit, Warning, - "The ClusterRootActor {0} does not implement the ScalableConfigInterface. Scaling the Pawn on the cluster will lead to unintended behavior.", + "The ClusterRootActor {0} does not implement the ScalableConfigInterface. Scaling the " + "Pawn on the cluster will lead to unintended behavior.", ClusterRootActor->GetName()); } } -- GitLab From 01a12211c2261f05b4b1af206b390cc380c91459 Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Thu, 12 Jun 2025 09:36:16 +0200 Subject: [PATCH 12/14] docs(pawn): updates comment for clarity --- Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 9becddbd..3298a60c 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -79,7 +79,7 @@ void ARWTHVRPawn::Tick(float DeltaSeconds) } /* - * Scales the Pawn while also adjusting the WorldToMeters ratio to adjust for pupillary distance. + * Scales the Pawn while also adjusting the WorldToMeters ratio for size relative movement speed. * Only supports uniform scaling. */ void ARWTHVRPawn::SetScale(float NewScale) -- GitLab From 794e5ac7d495d76174e2a22958a9495b76cda537 Mon Sep 17 00:00:00 2001 From: Kris Helwig <helwig@vr.rwth-aachen.de> Date: Thu, 12 Jun 2025 10:48:22 +0200 Subject: [PATCH 13/14] fix(pawn): removes worldtometers scaling --- Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp | 10 ++-------- Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h | 1 - 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 3298a60c..f8d78c33 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -60,11 +60,7 @@ ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(Ob }); } -void ARWTHVRPawn::BeginPlay() -{ - Super::BeginPlay(); - InitialWorldToMeters = GetWorldSettings()->WorldToMeters; -} +void ARWTHVRPawn::BeginPlay() { Super::BeginPlay(); } void ARWTHVRPawn::Tick(float DeltaSeconds) { @@ -79,14 +75,12 @@ void ARWTHVRPawn::Tick(float DeltaSeconds) } /* - * Scales the Pawn while also adjusting the WorldToMeters ratio for size relative movement speed. - * Only supports uniform scaling. + * Scales the Pawn. Only supports uniform scaling. */ void ARWTHVRPawn::SetScale(float NewScale) { UniformScale = NewScale; FVector NewScaleVector = FVector(UniformScale, UniformScale, UniformScale); - GetWorldSettings()->WorldToMeters = InitialWorldToMeters * UniformScale; SetActorRelativeScale3D(NewScaleVector); #if PLATFORM_SUPPORTS_CLUSTER diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h index 40eb174f..dcd506b1 100644 --- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h +++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h @@ -122,6 +122,5 @@ protected: private: UInputComponent* ActivePlayerInputComponent; - float InitialWorldToMeters; float UniformScale; }; -- GitLab From 594b471789873da5c9abeac3baec641cdfe8a416 Mon Sep 17 00:00:00 2001 From: Kris Tabea Helwig <helwig@vr.rwth-aachen.de> Date: Thu, 12 Jun 2025 13:16:01 +0200 Subject: [PATCH 14/14] Edit .gitlab-ci.yml --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dce45555..93d693e4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -83,7 +83,7 @@ Generate_Project: RUN_SETUP: "false" GEN_DEPENDENCIES: "( [master@UnrealDTrackPlugin]='https://github.com/VRGroupRWTH/UnrealDTrackPlugin.git' - [feature/scaling@RWTHVRCluster]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-cluster-plugin.git' + [dev/5.4@RWTHVRCluster]='https://git-ce.rwth-aachen.de/vr-vis/VR-Group/unreal-development/plugins/rwth-vr-cluster-plugin.git' )" Generate_Project_Without_Cluster: -- GitLab