#include "DisplayClusterPawnCAVE.h" #include "Cluster/IDisplayClusterClusterManager.h" #include "Engine/World.h" #include "Game/IDisplayClusterGameManager.h" #include "GameFramework/WorldSettings.h" #include "Input/IDisplayClusterInputManager.h" #include "Kismet/GameplayStatics.h" #include "DisplayClusterSettings.h" #include "HeadMountedDisplayFunctionLibrary.h" #include "IDisplayCluster.h" ADisplayClusterPawnCAVE::ADisplayClusterPawnCAVE(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { MovementComponent = CreateDefaultSubobject<UFloatingPawnMovement> (TEXT("MovementComponent0")); MovementComponent->UpdatedComponent = RootComponent; RotatingComponent = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotatingComponent0")); RotatingComponent->UpdatedComponent = RootComponent; RotatingComponent->bRotationInLocalSpace = false; RotatingComponent->PivotTranslation = FVector::ZeroVector; RotatingComponent->RotationRate = FRotator::ZeroRotator; TranslationDirection = RootComponent; AutoPossessPlayer = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events. } void ADisplayClusterPawnCAVE::OnForward_Implementation (float Value) { AddMovementInput(TranslationDirection->GetForwardVector(), Value); } void ADisplayClusterPawnCAVE::OnRight_Implementation (float Value) { AddMovementInput(TranslationDirection->GetRightVector (), Value); } void ADisplayClusterPawnCAVE::OnTurnRate_Implementation (float Rate ) { if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster) { if (!RotatingComponent->UpdatedComponent || !IDisplayCluster::Get().GetGameMgr() || !IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()) return; const FVector CameraLocation = IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()->GetComponentLocation(); RotatingComponent->PivotTranslation = RotatingComponent->UpdatedComponent->GetComponentTransform().InverseTransformPositionNoScale(CameraLocation); RotatingComponent->RotationRate = FRotator(RotatingComponent->RotationRate.Pitch, Rate * BaseTurnRate, 0.0f); } else { AddControllerYawInput(BaseTurnRate * Rate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation); } } void ADisplayClusterPawnCAVE::OnLookUpRate_Implementation(float Rate ) { if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster) { // User-centered projection causes motion sickness on look up interaction hence not implemented. } else { AddControllerPitchInput(BaseTurnRate * Rate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation); } } void ADisplayClusterPawnCAVE::OnFire_Implementation (bool Pressed) { } void ADisplayClusterPawnCAVE::OnAction_Implementation (bool Pressed, int32 Index) { } void ADisplayClusterPawnCAVE::BeginPlay () { Super::BeginPlay(); if (!IDisplayCluster::Get().IsModuleInitialized() || !IDisplayCluster::Get().IsAvailable()) return; auto IsCluster = (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster); bUseControllerRotationYaw = !IsCluster; bUseControllerRotationPitch = !IsCluster; bUseControllerRotationRoll = !IsCluster; TArray<AActor*> SettingsActors; UGameplayStatics::GetAllActorsOfClass(GetWorld(), ADisplayClusterSettings::StaticClass(), SettingsActors); if (SettingsActors.Num() == 0) return; ADisplayClusterSettings* Settings = Cast<ADisplayClusterSettings>(SettingsActors[0]); MovementComponent->MaxSpeed = Settings->MovementMaxSpeed ; MovementComponent->Acceleration = Settings->MovementAcceleration; MovementComponent->Deceleration = Settings->MovementDeceleration; MovementComponent->TurningBoost = Settings->MovementTurningBoost; BaseTurnRate = Settings->RotationSpeed ; if (UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayEnabled()) { LeftMotionControllerComponent = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("LeftMotionControllerComponent")); LeftMotionControllerComponent->SetTrackingSource (EControllerHand::Left); LeftMotionControllerComponent->SetShowDeviceModel(true); RightMotionControllerComponent = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("RightMotionControllerComponent")); RightMotionControllerComponent->SetTrackingSource (EControllerHand::Right); RightMotionControllerComponent->SetShowDeviceModel(true); } } void ADisplayClusterPawnCAVE::Tick (float DeltaSeconds) { Super::Tick(DeltaSeconds); if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster && !Flystick) { Flystick = IDisplayCluster::Get().GetGameMgr()->GetNodeById(TEXT("flystick")); // Note: Requires a scene node called flystick in the config. Make settable. if (Flystick) TranslationDirection = Flystick; } } void ADisplayClusterPawnCAVE::BeginDestroy () { Super::BeginDestroy(); } void ADisplayClusterPawnCAVE::SetupPlayerInputComponent (UInputComponent* PlayerInputComponent) { check(PlayerInputComponent); Super::SetupPlayerInputComponent(PlayerInputComponent); if (PlayerInputComponent) { PlayerInputComponent->BindAxis ("MoveForward" , this, &ADisplayClusterPawnCAVE::OnForward ); PlayerInputComponent->BindAxis ("MoveRight" , this, &ADisplayClusterPawnCAVE::OnRight ); PlayerInputComponent->BindAxis ("TurnRate" , this, &ADisplayClusterPawnCAVE::OnTurnRate ); PlayerInputComponent->BindAxis ("LookUpRate" , this, &ADisplayClusterPawnCAVE::OnLookUpRate ); PlayerInputComponent->BindAction<FFireDelegate> ("Fire" , IE_Pressed , this, &ADisplayClusterPawnCAVE::OnFire , true ); PlayerInputComponent->BindAction<FActionDelegate>("Action1" , IE_Pressed , this, &ADisplayClusterPawnCAVE::OnAction , true , 1); PlayerInputComponent->BindAction<FActionDelegate>("Action2" , IE_Pressed , this, &ADisplayClusterPawnCAVE::OnAction , true , 2); PlayerInputComponent->BindAction<FActionDelegate>("Action3" , IE_Pressed , this, &ADisplayClusterPawnCAVE::OnAction , true , 3); PlayerInputComponent->BindAction<FActionDelegate>("Action4" , IE_Pressed , this, &ADisplayClusterPawnCAVE::OnAction , true , 4); PlayerInputComponent->BindAction<FActionDelegate>("Action5" , IE_Pressed , this, &ADisplayClusterPawnCAVE::OnAction , true , 5); PlayerInputComponent->BindAction<FFireDelegate> ("Fire" , IE_Released, this, &ADisplayClusterPawnCAVE::OnFire , false ); PlayerInputComponent->BindAction<FActionDelegate>("Action1" , IE_Released, this, &ADisplayClusterPawnCAVE::OnAction , false, 1); PlayerInputComponent->BindAction<FActionDelegate>("Action2" , IE_Released, this, &ADisplayClusterPawnCAVE::OnAction , false, 2); PlayerInputComponent->BindAction<FActionDelegate>("Action3" , IE_Released, this, &ADisplayClusterPawnCAVE::OnAction , false, 3); PlayerInputComponent->BindAction<FActionDelegate>("Action4" , IE_Released, this, &ADisplayClusterPawnCAVE::OnAction , false, 4); PlayerInputComponent->BindAction<FActionDelegate>("Action5" , IE_Released, this, &ADisplayClusterPawnCAVE::OnAction , false, 5); } } UPawnMovementComponent* ADisplayClusterPawnCAVE::GetMovementComponent () const { return MovementComponent; }