diff --git a/Content/Input/Default_IMC/IMC_General.uasset b/Content/Input/Default_IMC/IMC_General.uasset index 4b74905bb2a24bd5cad5ddb52693c01da084dc76..8de5bc1e14890320eb9d9781c7f5c683ee22b42f 100644 Binary files a/Content/Input/Default_IMC/IMC_General.uasset and b/Content/Input/Default_IMC/IMC_General.uasset differ diff --git a/RWTHVRToolkit.uplugin b/RWTHVRToolkit.uplugin index 9cee822208bd6643aa5e9d370483c968cb25eb44..3629dc720c75269dace2ffe6649b067e63900e3a 100644 --- a/RWTHVRToolkit.uplugin +++ b/RWTHVRToolkit.uplugin @@ -27,6 +27,15 @@ } ], "Plugins": [ + { + "Name": "RWTHVRCluster", + "Enabled": true, + "Optional": true, + "SupportedTargetPlatforms": [ + "Win64", + "Linux" + ] + }, { "Name": "LiveLink", "Enabled": true diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 5a84da66b664d3070c5c71bd6242d42f96ab6910..28eb764a59ca38694d676b5e0809c9a9622a14b1 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -16,6 +16,10 @@ #include "Roles/LiveLinkTransformTypes.h" #include "Utility/RWTHVRUtilities.h" +#if PLATFORM_SUPPORTS_CLUSTER +#include "Components/DisplayClusterSceneComponentSyncParent.h" +#endif + ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { BaseEyeHeight = 160.0f; @@ -36,15 +40,19 @@ ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(Ob LeftHand = CreateDefaultSubobject<UReplicatedMotionControllerComponent>(TEXT("Left Hand MCC")); LeftHand->SetupAttachment(RootComponent); - -#if 0 +} +void ARWTHVRPawn::BeginPlay() +{ + Super::BeginPlay(); + +#if PLATFORM_SUPPORTS_CLUSTER // Add an nDisplay Parent Sync Component. It syncs the parent's transform from master to clients. // This is required because for collision based movement, it can happen that the physics engine // for some reason acts different on the nodes, therefore leading to a potential desync when // e.g. colliding with an object while moving. - SyncComponent = - CreateDefaultSubobject<UDisplayClusterSceneComponentSyncParent>(TEXT("Parent Display Cluster Sync Component")); + SyncComponent = NewObject<UDisplayClusterSceneComponentSyncParent>(); SyncComponent->SetupAttachment(RootComponent); + SyncComponent->RegisterComponent(); #endif } diff --git a/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp b/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp index 77330f037057bdf8852c2a3b712876d5b2cd98bf..f43fc658f2d5ce7b6ca66c409d9b30583bbcc99e 100644 --- a/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp +++ b/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp @@ -1,15 +1,5 @@ #include "Utility/RWTHVRUtilities.h" -#if PLATFORM_SUPPORTS_NDISPLAY -#include "DisplayClusterConfigurationTypes.h" -#include "DisplayClusterRootActor.h" -#include "IDisplayCluster.h" -#include "Cluster/IDisplayClusterClusterManager.h" -#include "Components/DisplayClusterCameraComponent.h" -#include "Config/IDisplayClusterConfigManager.h" -#include "Game/IDisplayClusterGameManager.h" -#endif - #include "AudioDevice.h" #include "IHeadMountedDisplay.h" #include "IXRTrackingSystem.h" @@ -17,6 +7,10 @@ #include "Engine/LocalPlayer.h" #include "Kismet/GameplayStatics.h" +#if PLATFORM_SUPPORTS_CLUSTER +#include "Utility/RWTHVRClusterUtilities.h" +#endif + DEFINE_LOG_CATEGORY(Toolkit); @@ -25,15 +19,6 @@ bool URWTHVRUtilities::IsDesktopMode() return !IsRoomMountedMode() && !IsHeadMountedMode(); } -bool URWTHVRUtilities::IsRoomMountedMode() -{ -#if PLATFORM_SUPPORTS_NDISPLAY - return IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster; -#else - return false; -#endif -} - bool URWTHVRUtilities::IsHeadMountedMode() { // In editor builds: checks for EdEngine->IsVRPreviewActive() @@ -41,65 +26,20 @@ bool URWTHVRUtilities::IsHeadMountedMode() return FAudioDevice::CanUseVRAudioDevice(); } -bool URWTHVRUtilities::IsCave() +bool URWTHVRUtilities::IsRoomMountedMode() { -#if PLATFORM_SUPPORTS_NDISPLAY - if (!IsRoomMountedMode()) - return false; - - const UDisplayClusterConfigurationData* ClusterConfig = IDisplayCluster::Get().GetConfigMgr()->GetConfig(); - return ClusterConfig->CustomParameters.Contains("Hardware_Platform") - && ClusterConfig->CustomParameters.Find("Hardware_Platform")->Equals("aixcave", ESearchCase::IgnoreCase); -#else - return false; +#if PLATFORM_SUPPORTS_CLUSTER + URWTHVRClusterUtilities::IsRoomMountedMode(); #endif -} - -bool URWTHVRUtilities::IsRolv() -{ -#if PLATFORM_SUPPORTS_NDISPLAY - if (!IsRoomMountedMode()) - return false; - - const UDisplayClusterConfigurationData* ClusterConfig = IDisplayCluster::Get().GetConfigMgr()->GetConfig(); - return ClusterConfig->CustomParameters.Contains("Hardware_Platform") - && ClusterConfig->CustomParameters.Find("Hardware_Platform")->Equals("ROLV", ESearchCase::IgnoreCase); -#else return false; -#endif } -/* Return true on the Primary in cluster mode and in a normal desktop session. Otherwise false */ bool URWTHVRUtilities::IsPrimaryNode() { -#if PLATFORM_SUPPORTS_NDISPLAY - if (!IDisplayCluster::IsAvailable()) - { - return true; - } - IDisplayClusterClusterManager* Manager = IDisplayCluster::Get().GetClusterMgr(); - if (Manager == nullptr) - { - return true; // if we are not in cluster mode, we are always the primary node - } - return Manager->IsPrimary() || !Manager->IsSecondary(); -#else - return true; -#endif -} - -bool URWTHVRUtilities::IsSecondaryNode() -{ - return !IsPrimaryNode(); -} - -FString URWTHVRUtilities::GetNodeName() -{ -#if PLATFORM_SUPPORTS_NDISPLAY - return IsRoomMountedMode() ? IDisplayCluster::Get().GetClusterMgr()->GetNodeId() : FString(TEXT("Localhost")); -#else - return FString(TEXT("Localhost")); +#if PLATFORM_SUPPORTS_CLUSTER + URWTHVRClusterUtilities::IsPrimaryNode(); #endif + return false; } float URWTHVRUtilities::GetEyeDistance() @@ -108,71 +48,7 @@ float URWTHVRUtilities::GetEyeDistance() { return GEngine->XRSystem->GetHMDDevice()->GetInterpupillaryDistance(); } - else - { -#if PLATFORM_SUPPORTS_NDISPLAY - const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor(); - return (RootActor) ? RootActor->GetDefaultCamera()->GetInterpupillaryDistance() : 0.0f; -#else - return 0.0f; -#endif - } -} - -EEyeStereoOffset URWTHVRUtilities::GetNodeEyeType() -{ -#if PLATFORM_SUPPORTS_NDISPLAY - const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor(); - return static_cast<EEyeStereoOffset>((RootActor) - ? RootActor->GetDefaultCamera()->GetStereoOffset() - : EDisplayClusterEyeStereoOffset::None); -#else - return EEyeStereoOffset::None; -#endif -} - -USceneComponent* URWTHVRUtilities::GetClusterComponent(const FString& Name) -{ -#if PLATFORM_SUPPORTS_NDISPLAY - const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor(); - return (RootActor) ? RootActor->GetComponentByName<USceneComponent>(Name) : nullptr; -#else - return nullptr; -#endif -} - -USceneComponent* URWTHVRUtilities::GetNamedClusterComponent(const ENamedClusterComponent& Component) -{ - switch (Component) - { - case ENamedClusterComponent::NCC_CAVE_ORIGIN: - return GetClusterComponent("cave_origin"); - case ENamedClusterComponent::NCC_CAVE_CENTER: - return GetClusterComponent("cave_center"); - case ENamedClusterComponent::NCC_CAVE_LHT: - return GetClusterComponent("left_hand_target"); - case ENamedClusterComponent::NCC_CAVE_RHT: - return GetClusterComponent("right_hand_target"); - case ENamedClusterComponent::NCC_SHUTTERGLASSES: - return GetClusterComponent("shutter_glasses"); - case ENamedClusterComponent::NCC_ROLV_ORIGIN: - return GetClusterComponent("rolv_origin"); - case ENamedClusterComponent::NCC_FLYSTICK: - return GetClusterComponent("flystick"); - case ENamedClusterComponent::NCC_CALIBRATIO: - return GetClusterComponent("calibratio"); - case ENamedClusterComponent::NCC_TRACKING_ORIGIN: - USceneComponent* Result; - if ((Result = GetClusterComponent("cave_origin"))) - return Result; - if ((Result = GetClusterComponent("rolv_origin"))) - return Result; - if ((Result = GetClusterComponent("tdw_origin_floor"))) - return Result; - return nullptr; - default: - return nullptr; - } + return 0; } void URWTHVRUtilities::ShowErrorAndQuit(UWorld* WorldContext, const FString& Message) diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h index b171d3f1f9213744628e9c1501bc52a3248418dc..5b67bd31bd46e4187a17f1849187df5aae059beb 100644 --- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h +++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h @@ -6,10 +6,6 @@ #include "LiveLinkRole.h" #include "Pawn/Navigation/CollisionHandlingMovement.h" -#if 0 -#include "Components/DisplayClusterSceneComponentSyncParent.h" -#endif - #include "RWTHVRPawn.generated.h" class UInputMappingContext; @@ -29,6 +25,8 @@ class RWTHVRTOOLKIT_API ARWTHVRPawn : public APawn public: ARWTHVRPawn(const FObjectInitializer& ObjectInitializer); + virtual void BeginPlay() override; + virtual void Tick(float DeltaSeconds) override; virtual void NotifyControllerChanged() override; @@ -56,7 +54,7 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|Camera") UCameraComponent* HeadCameraComponent; - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|Camera") + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn") USceneComponent* SyncComponent; // LiveLink functionality diff --git a/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h b/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h index e0f6d7e4e6adf0735007004cbfd9b5d0ae8064f8..ef9f3f0c6f22a8249f488cbf90bc443300ce9428 100644 --- a/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h +++ b/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h @@ -2,7 +2,6 @@ #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" -#include "UObject/ConstructorHelpers.h" #include "RWTHVRUtilities.generated.h" @@ -12,33 +11,6 @@ */ DECLARE_LOG_CATEGORY_EXTERN(Toolkit, Log, All); -UENUM(BlueprintType) -enum class ENamedClusterComponent : uint8 -{ - /* CAVE Specific */ - NCC_CAVE_ORIGIN UMETA(DisplayName = "CAVE Origin"), - NCC_CAVE_CENTER UMETA(DisplayName = "CAVE Center"), - NCC_CAVE_LHT UMETA(DisplayName = "CAVE Left Hand Target"), - NCC_CAVE_RHT UMETA(DisplayName = "CAVE Right Hand Target"), - - /* ROLV Specific */ - NCC_ROLV_ORIGIN UMETA(DisplayName = "ROLV Origin"), - - /* Non Specific */ - NCC_CALIBRATIO UMETA(DisplayName = "Calibratio Motion to Photon Measurement Device"), - NCC_SHUTTERGLASSES UMETA(DisplayName = "CAVE/ROLV/TDW Shutter Glasses"), - NCC_FLYSTICK UMETA(DisplayName = "CAVE/ROLV/TDW Flystick"), - NCC_TRACKING_ORIGIN UMETA(DisplayName = "CAVE/ROLV/TDW Origin") -}; - -UENUM() -enum class EEyeStereoOffset -{ - None, - Left, - Right -}; - UCLASS() class RWTHVRTOOLKIT_API URWTHVRUtilities : public UBlueprintFunctionLibrary { @@ -48,37 +20,16 @@ public: UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform") static bool IsDesktopMode(); UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform") - static bool IsRoomMountedMode(); - UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform") static bool IsHeadMountedMode(); UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform") - static bool IsCave(); + static bool IsRoomMountedMode(); UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform") - static bool IsRolv(); - - UFUNCTION(BlueprintPure, Category = "DisplayCluster") static bool IsPrimaryNode(); - UFUNCTION(BlueprintPure, Category = "DisplayCluster") - static bool IsSecondaryNode(); - UFUNCTION(BlueprintPure, Category = "DisplayCluster") - static FString GetNodeName(); /* Distance in meters */ UFUNCTION(BlueprintPure, Category = "DisplayCluster") static float GetEyeDistance(); - UFUNCTION(BlueprintPure, Category = "DisplayCluster") - static EEyeStereoOffset GetNodeEyeType(); - - //Get Component of Display Cluster by it's name, which is specified in the nDisplay config - UE_DEPRECATED(5.4, "GetClusterComponent has been removed because it is obsolete.") - UFUNCTION(BlueprintPure, BlueprintCallable, Category = "DisplayCluster", meta = (DeprecatedFunction)) - static USceneComponent* GetClusterComponent(const FString& Name); - - UE_DEPRECATED(5.4, "GetNamedClusterComponent has been removed because it is obsolete.") - UFUNCTION(BlueprintPure, BlueprintCallable, Category = "DisplayCluster", meta = (DeprecatedFunction)) - static USceneComponent* GetNamedClusterComponent(const ENamedClusterComponent& Component); - UFUNCTION(BlueprintCallable) static void ShowErrorAndQuit(UWorld* WorldContext, const FString& Message); }; diff --git a/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs b/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs index ba27e93d92e385c204cb2609041a7a445c756d60..a949553aaa90bd704c53e9ace2f749073a5441bf 100644 --- a/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs +++ b/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs @@ -50,9 +50,16 @@ public class RWTHVRToolkit : ModuleRules new string[]{} ); - PublicDefinitions.Add(IsPluginEnabledForTarget("nDisplay", base.Target) - ? "PLATFORM_SUPPORTS_NDISPLAY=1" - : "PLATFORM_SUPPORTS_NDISPLAY=0"); + if (IsPluginEnabledForTarget("RWTHVRCluster", base.Target)) + { + PrivateDependencyModuleNames.Add("RWTHVRCluster"); + PrivateDependencyModuleNames.Add("DisplayCluster"); + PublicDefinitions.Add("PLATFORM_SUPPORTS_CLUSTER=1"); + } + else + { + PublicDefinitions.Add("PLATFORM_SUPPORTS_CLUSTER=0"); + } } private static bool IsPluginEnabledForTarget(string PluginName, ReadOnlyTargetRules Target)