diff --git a/Source/DisplayClusterExtensions/Private/UniversalTrackedComponent.cpp b/Source/DisplayClusterExtensions/Private/UniversalTrackedComponent.cpp index d16ea030b4a11c02691add12a4c18ae581313025..27ca536dc0cacabbbe94cc0eac715845d8c98c6c 100644 --- a/Source/DisplayClusterExtensions/Private/UniversalTrackedComponent.cpp +++ b/Source/DisplayClusterExtensions/Private/UniversalTrackedComponent.cpp @@ -13,15 +13,53 @@ UUniversalTrackedComponent::UUniversalTrackedComponent() // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features // off to improve performance if you don't need them. PrimaryComponentTick.bCanEverTick = true; +} + + +void UUniversalTrackedComponent::SetShowDeviceModel(const bool bShowControllerModel) +{ + if (!UVirtualRealityUtilities::IsHeadMountedMode() || TrackedComponent == nullptr) return; - // ... + ShowDeviceModelInHMD = bShowControllerModel; + Cast<UMotionControllerComponent>(TrackedComponent)->SetShowDeviceModel(ShowDeviceModelInHMD); } +void UUniversalTrackedComponent::BeginPlay() +{ + Super::BeginPlay(); + + /* Spawn Motion Controller Components in HMD Mode */ + if (UVirtualRealityUtilities::IsHeadMountedMode()) + { + UMotionControllerComponent* MotionController = Cast<UMotionControllerComponent>(GetOwner()->AddComponentByClass(UMotionControllerComponent::StaticClass(), false, FTransform::Identity, false)); + + switch(ProxyType) + { + case ETrackedComponentType::TCT_TRACKER_1: + MotionController->SetTrackingMotionSource(FName("Special_1")); + break; + case ETrackedComponentType::TCT_TRACKER_2: + MotionController->SetTrackingMotionSource(FName("Special_2")); + break; + case ETrackedComponentType::TCT_RIGHT_HAND: + MotionController->SetTrackingMotionSource(FName("Right")); + break; + case ETrackedComponentType::TCT_LEFT_HAND: + MotionController->SetTrackingMotionSource(FName("Left")); + break; + default: break; + } + MotionController->SetShowDeviceModel(ShowDeviceModelInHMD); + + TrackedComponent = MotionController; + AttachToComponent(TrackedComponent, FAttachmentTransformRules::SnapToTargetIncludingScale); + } +} void UUniversalTrackedComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - + if(TrackedComponent) return; //Already attached if (UVirtualRealityUtilities::IsRoomMountedMode()) diff --git a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp index b8db910e976c940c5fff8489594fed37e7cb85c9..5a05c6bcb6c51ecc56f6d4e7a60868cc2e936a76 100644 --- a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp +++ b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp @@ -3,3 +3,114 @@ #include "VirtualRealityPawn.h" + + +#include "GameFramework/InputSettings.h" +#include "GameFramework/PlayerInput.h" +#include "UniversalTrackedComponent.h" +#include "VirtualRealityUtilities.h" +#include "VRPawnMovement.h" + +AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bUseControllerRotationYaw = true; + bUseControllerRotationPitch = true; + bUseControllerRotationRoll = true; + BaseEyeHeight = 160.0f; + + AutoPossessPlayer = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events. + + PawnMovement = CreateDefaultSubobject<UVRPawnMovement>(TEXT("Pawn Movement")); + PawnMovement->UpdatedComponent = RootComponent; + + Head = CreateDefaultSubobject<UUniversalTrackedComponent>(TEXT("Head")); + Head->ProxyType = ETrackedComponentType::TCT_HEAD; + Head->SetupAttachment(RootComponent); + + RightHand = CreateDefaultSubobject<UUniversalTrackedComponent>(TEXT("Right Hand")); + RightHand->ProxyType = ETrackedComponentType::TCT_RIGHT_HAND; + RightHand->AttachementType = EAttachementType::AT_FLYSTICK; + RightHand->SetupAttachment(RootComponent); + + LeftHand = CreateDefaultSubobject<UUniversalTrackedComponent>(TEXT("Left Hand")); + LeftHand->ProxyType = ETrackedComponentType::TCT_LEFT_HAND; + LeftHand->AttachementType = EAttachementType::AT_HANDTARGET; + LeftHand->SetupAttachment(RootComponent); + + Tracker1 = CreateDefaultSubobject<UUniversalTrackedComponent>(TEXT("Vive Tracker 1")); + Tracker1->ProxyType = ETrackedComponentType::TCT_TRACKER_1; + Tracker1->SetupAttachment(RootComponent); + + Tracker2 = CreateDefaultSubobject<UUniversalTrackedComponent>(TEXT("Vive Tracker 2")); + Tracker2->ProxyType = ETrackedComponentType::TCT_TRACKER_2; + Tracker2->SetupAttachment(RootComponent); + + BasicVRInteraction = CreateDefaultSubobject<UBasicVRInteractionComponent>(TEXT("Basic VR Interaction")); + BasicVRInteraction->Initialize(RightHand); +} + +void AVirtualRealityPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) +{ + Super::SetupPlayerInputComponent(PlayerInputComponent); + if (PlayerInputComponent) + { + PlayerInputComponent->BindAxis("MoveForward", this, &AVirtualRealityPawn::OnForward); + PlayerInputComponent->BindAxis("MoveRight", this, &AVirtualRealityPawn::OnRight); + PlayerInputComponent->BindAxis("TurnRate", this, &AVirtualRealityPawn::OnTurnRate); + PlayerInputComponent->BindAxis("LookUpRate", this, &AVirtualRealityPawn::OnLookUpRate); + + // function bindings for grabbing and releasing + PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AVirtualRealityPawn::OnBeginFire); + PlayerInputComponent->BindAction("Fire", IE_Released, this, &AVirtualRealityPawn::OnEndFire); + } +} + +void AVirtualRealityPawn::BeginPlay() +{ + if(!UVirtualRealityUtilities::IsDesktopMode()) /* Disable to not get cyber sick as fast */ + { + UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX)); + UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY)); + } +} + +void AVirtualRealityPawn::OnForward_Implementation(float Value) +{ + if (RightHand) + { + AddMovementInput(RightHand->GetForwardVector(), Value); + } +} + +void AVirtualRealityPawn::OnRight_Implementation(float Value) +{ + if (RightHand) + { + AddMovementInput(RightHand->GetRightVector(), Value); + } +} + +void AVirtualRealityPawn::OnTurnRate_Implementation(float Rate) +{ + AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation); +} + +void AVirtualRealityPawn::OnLookUpRate_Implementation(float Rate) +{ + // User-centered projection causes simulation sickness on look up interaction hence not implemented. + if (!UVirtualRealityUtilities::IsRoomMountedMode()) + { + AddControllerPitchInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation); + } +} + +void AVirtualRealityPawn::OnBeginFire_Implementation() +{ + BasicVRInteraction->BeginInteraction(); +} + +void AVirtualRealityPawn::OnEndFire_Implementation() +{ + BasicVRInteraction->EndInteraction(); +} diff --git a/Source/DisplayClusterExtensions/Private/VirtualRealityPawnOld.cpp b/Source/DisplayClusterExtensions/Private/VirtualRealityPawnOld.cpp deleted file mode 100644 index f07c9c18851e3ce141de3d704a92bc59e4c5d1d4..0000000000000000000000000000000000000000 --- a/Source/DisplayClusterExtensions/Private/VirtualRealityPawnOld.cpp +++ /dev/null @@ -1,604 +0,0 @@ -#include "VirtualRealityPawnOld.h" - -#include "Camera/CameraComponent.h" -#include "Engine/Engine.h" -#include "Engine/World.h" -#include "Game/IDisplayClusterGameManager.h" -#include "GameFramework/InputSettings.h" -#include "GameFramework/WorldSettings.h" -#include "Kismet/GameplayStatics.h" -#include "IDisplayCluster.h" -#include "Components/SphereComponent.h" -#include "DrawDebugHelpers.h" -#include "Math/Vector.h" -#include "VirtualRealityUtilities.h" - -#include "GrabbingBehaviorComponent.h" -#include "Grabable.h" -#include "Clickable.h" - - -AVirtualRealityPawnOld::AVirtualRealityPawnOld(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) -{ - bUseControllerRotationYaw = true; - bUseControllerRotationPitch = true; - bUseControllerRotationRoll = true; - - AutoPossessPlayer = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events. - - Movement = CreateDefaultSubobject<UFloatingPawnMovement>(TEXT("Movement")); - Movement->UpdatedComponent = RootComponent; - - RotatingMovement = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotatingMovement")); - RotatingMovement->UpdatedComponent = RootComponent; - RotatingMovement->bRotationInLocalSpace = false; - RotatingMovement->PivotTranslation = FVector::ZeroVector; - RotatingMovement->RotationRate = FRotator::ZeroRotator; - - Head = CreateDefaultSubobject<USceneComponent>(TEXT("Head")); - Head->SetupAttachment(RootComponent); - RightHand = CreateDefaultSubobject<USceneComponent>(TEXT("RightHand")); - RightHand->SetupAttachment(RootComponent); - LeftHand = CreateDefaultSubobject<USceneComponent>(TEXT("LeftHand")); - LeftHand->SetupAttachment(RootComponent); - - HmdLeftMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdLeftMotionController")); - HmdLeftMotionController->SetupAttachment(RootComponent); - HmdLeftMotionController->SetTrackingSource(EControllerHand::Left); - HmdLeftMotionController->SetShowDeviceModel(true); - HmdLeftMotionController->SetVisibility(false); - - HmdRightMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdRightMotionController")); - HmdRightMotionController->SetupAttachment(RootComponent); - HmdRightMotionController->SetTrackingSource(EControllerHand::Right); - HmdRightMotionController->SetShowDeviceModel(true); - HmdRightMotionController->SetVisibility(false); - - CapsuleColliderComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleCollider")); - CapsuleColliderComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); - CapsuleColliderComponent->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); - CapsuleColliderComponent->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block); - //CapsuleColliderComponent->SetupAttachment(CameraComponent); - CapsuleColliderComponent->SetCapsuleSize(40.0f, 96.0f); - - HmdTracker1 = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdTracker1")); - HmdTracker1->SetupAttachment(RootComponent); - HmdTracker1->SetTrackingSource(EControllerHand::Special_1); - HmdTracker1->SetShowDeviceModel(true); - HmdTracker1->SetVisibility(false); - - HmdTracker2 = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdTracker2")); - HmdTracker2->SetupAttachment(RootComponent); - HmdTracker2->SetTrackingSource(EControllerHand::Special_2); - HmdTracker2->SetShowDeviceModel(true); - HmdTracker2->SetVisibility(false); -} - -void AVirtualRealityPawnOld::OnForward_Implementation(float Value) -{ - if (RightHand) - { - HandleMovementInput(Value, RightHand->GetForwardVector()); - } -} - -void AVirtualRealityPawnOld::OnRight_Implementation(float Value) -{ - if (RightHand) - { - HandleMovementInput(Value, RightHand->GetRightVector()); - } -} - -void AVirtualRealityPawnOld::OnTurnRate_Implementation(float Rate) -{ - AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation); -} - -void AVirtualRealityPawnOld::OnLookUpRate_Implementation(float Rate) -{ - if (UVirtualRealityUtilities::IsRoomMountedMode()) - { - // User-centered projection causes simulation sickness on look up interaction hence not implemented. - } - else - { - AddControllerPitchInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation); - } -} - -float AVirtualRealityPawnOld::GetBaseTurnRate() const -{ - return BaseTurnRate; -} - -void AVirtualRealityPawnOld::SetBaseTurnRate(float Value) -{ - BaseTurnRate = Value; -} - -UFloatingPawnMovement* AVirtualRealityPawnOld::GetFloatingPawnMovement() -{ - return Movement; -} - -URotatingMovementComponent* AVirtualRealityPawnOld::GetRotatingMovementComponent() -{ - return RotatingMovement; -} - -UDisplayClusterSceneComponent* AVirtualRealityPawnOld::GetFlystickComponent() -{ - return Flystick; -} - -UDisplayClusterSceneComponent* AVirtualRealityPawnOld::GetRightHandtargetComponent() -{ - return RightHandTarget; -} - -UDisplayClusterSceneComponent* AVirtualRealityPawnOld::GetLeftHandtargetComponent() -{ - return LeftHandTarget; -} - -UMotionControllerComponent* AVirtualRealityPawnOld::GetHmdLeftMotionControllerComponent() -{ - return HmdLeftMotionController; -} - -UMotionControllerComponent* AVirtualRealityPawnOld::GetHmdRightMotionControllerComponent() -{ - return HmdRightMotionController; -} - -UMotionControllerComponent* AVirtualRealityPawnOld::GetHmdTracker1MotionControllerComponent() -{ - return HmdTracker1; -} - -UMotionControllerComponent* AVirtualRealityPawnOld::GetHmdTracker2MotionControllerComponent() -{ - return HmdTracker2; -} - -USceneComponent* AVirtualRealityPawnOld::GetHeadComponent() -{ - return Head; -} - -USceneComponent* AVirtualRealityPawnOld::GetLeftHandComponent() -{ - return LeftHand; -} - -USceneComponent* AVirtualRealityPawnOld::GetRightHandComponent() -{ - return RightHand; -} - -USceneComponent* AVirtualRealityPawnOld::GetTrackingOriginComponent() -{ - return TrackingOrigin; -} - -USceneComponent* AVirtualRealityPawnOld::GetCaveCenterComponent() -{ - return CaveCenter; -} - -USceneComponent* AVirtualRealityPawnOld::GetShutterGlassesComponent() -{ - return ShutterGlasses; -} - -void AVirtualRealityPawnOld::BeginPlay() -{ - Super::BeginPlay(); - - // Display cluster settings apply to all setups (PC, HMD, CAVE/ROLV) despite the unfortunate name due to being an UE4 internal. - //TArray<AActor*> SettingsActors; - //UGameplayStatics::GetAllActorsOfClass(GetWorld(), ADisplayClusterSettings::StaticClass(), SettingsActors); - //if (SettingsActors.Num() > 0) - //{ - // //ADisplayClusterSettings* Settings = Cast<ADisplayClusterSettings>(SettingsActors[0]); - // //Movement->MaxSpeed = Settings->MovementMaxSpeed; - // //Movement->Acceleration = Settings->MovementAcceleration; - // //Movement->Deceleration = Settings->MovementDeceleration; - // //Movement->TurningBoost = Settings->MovementTurningBoost; - // //BaseTurnRate = Settings->RotationSpeed; - //} - - if (UVirtualRealityUtilities::IsRoomMountedMode()) - { - UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX)); - UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY)); - - InitRoomMountedComponentReferences(); - } - else if (UVirtualRealityUtilities::IsHeadMountedMode()) - { - UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX)); - UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY)); - - HmdLeftMotionController->SetVisibility(ShowHMDControllers); - HmdRightMotionController->SetVisibility(ShowHMDControllers); - if (HmdTracker1->IsActive()) { - HmdTracker1->SetVisibility(ShowHMDControllers); - } - if (HmdTracker2->IsActive()) { - HmdTracker2->SetVisibility(ShowHMDControllers); - } - - LeftHand->AttachToComponent(HmdLeftMotionController, FAttachmentTransformRules::SnapToTargetIncludingScale); - RightHand->AttachToComponent(HmdRightMotionController, FAttachmentTransformRules::SnapToTargetIncludingScale); - // Head->AttachToComponent(GetCameraComponent(), FAttachmentTransformRules::SnapToTargetIncludingScale); - } - else //Desktop - { - // Head->AttachToComponent(GetCameraComponent(), FAttachmentTransformRules::SnapToTargetIncludingScale); - - //also attach the hands to the camera component so we can use them for interaction - // LeftHand->AttachToComponent(GetCameraComponent(), FAttachmentTransformRules::SnapToTargetIncludingScale); - // RightHand->AttachToComponent(GetCameraComponent(), FAttachmentTransformRules::SnapToTargetIncludingScale); - - - //move to eyelevel - // GetCameraComponent()->SetRelativeLocation(FVector(0, 0, 160)); - } - - //In ADisplayClusterPawn::BeginPlay() input is disabled on all slaves, so we cannot react to button presses, e.g. on the flystick correctly. - //Therefore, we activate it again: - UWorld* World = GetWorld(); - if (World) - { - APlayerController* PlayerController = World->GetFirstPlayerController(); - if (PlayerController) - { - this->EnableInput(PlayerController); - } - } - - //CollisionComponent->SetCollisionProfileName(FName("NoCollision")); - //CollisionComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision); - - //LastCameraPosition = CameraComponent->GetComponentLocation(); -} - -void AVirtualRealityPawnOld::EndPlay(const EEndPlayReason::Type EndPlayReason) -{ - Super::EndPlay(EndPlayReason); -} - -void AVirtualRealityPawnOld::Tick(float DeltaSeconds) -{ - Super::Tick(DeltaSeconds); - //if the walking-mode is activated - if (NavigationMode == EVRNavigationModes::nav_mode_walk) - { - DeltaTime = DeltaSeconds; - SetCapsuleColliderCharacterSizeVR(); - MoveByGravityOrStepUp(DeltaSeconds); - CheckForPhysWalkingCollision(); - } - - // if an actor is grabbed and a behavior is defined move move him accordingly - if (GrabbedActor != nullptr) - { - UGrabbingBehaviorComponent* Behavior = GrabbedActor->FindComponentByClass<UGrabbingBehaviorComponent>(); - - // if our Grabable Actor is not constrained - if (Behavior != nullptr) - { - // specifies the hand in space - FVector HandPos = this->RightHand->GetComponentLocation(); - FQuat HandQuat = this->RightHand->GetComponentQuat(); - - Behavior->HandleNewPositionAndDirection(HandPos, HandQuat); - } - } - - //Flystick might not be available at start, hence is checked every frame. - InitRoomMountedComponentReferences(); - - //LastCameraPosition = CameraComponent->GetComponentLocation(); -} - -void AVirtualRealityPawnOld::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) -{ - Super::SetupPlayerInputComponent(PlayerInputComponent); - if (PlayerInputComponent) - { - PlayerInputComponent->BindAxis("MoveForward", this, &AVirtualRealityPawnOld::OnForward); - PlayerInputComponent->BindAxis("MoveRight", this, &AVirtualRealityPawnOld::OnRight); - PlayerInputComponent->BindAxis("TurnRate", this, &AVirtualRealityPawnOld::OnTurnRate); - PlayerInputComponent->BindAxis("LookUpRate", this, &AVirtualRealityPawnOld::OnLookUpRate); - - // function bindings for grabbing and releasing - PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AVirtualRealityPawnOld::OnBeginFire); - PlayerInputComponent->BindAction("Fire", IE_Released, this, &AVirtualRealityPawnOld::OnEndFire); - } -} - -void AVirtualRealityPawnOld::OnBeginFire_Implementation() -{ - // start and end point for raytracing - FTwoVectors StartEnd = GetHandRay(MaxClickDistance); - FVector Start = StartEnd.v1; - FVector End = StartEnd.v2; - - // will be filled by the Line Trace Function - FHitResult Hit; - AActor* HitActor; - - //if hit was not found return - FCollisionObjectQueryParams Params; - if (!GetWorld()->LineTraceSingleByObjectType(Hit, Start, End, Params)) - return; - - HitActor = Hit.GetActor(); - - // try to cast HitActor int a Grabable if not succeeded will become a nullptr - IGrabable* GrabableActor = Cast<IGrabable>(HitActor); - IClickable* ClickableActor = Cast<IClickable>(HitActor); - - if (GrabableActor != nullptr && Hit.Distance < MaxGrabDistance) - { - // call grabable actors function so he reacts to our grab - GrabableActor->OnGrabbed_Implementation(); - - - UGrabbingBehaviorComponent* Behavior = HitActor->FindComponentByClass<UGrabbingBehaviorComponent>(); - if ( Behavior == nullptr) - HandlePhysicsAndAttachActor(HitActor); - - // we save the grabbedActor in a general form to access all of AActors functions easily later - GrabbedActor = HitActor; - } - else if (ClickableActor != nullptr && Hit.Distance < MaxClickDistance) - { - ClickableActor->OnClicked_Implementation(Hit.Location); - } -} - -void AVirtualRealityPawnOld::HandlePhysicsAndAttachActor(AActor* HitActor) -{ - UPrimitiveComponent* PhysicsComp = HitActor->FindComponentByClass<UPrimitiveComponent>(); - - bDidSimulatePhysics = PhysicsComp->IsSimulatingPhysics(); // remember if we need to tun physics back on or not - PhysicsComp->SetSimulatePhysics(false); - FAttachmentTransformRules Rules = FAttachmentTransformRules::KeepWorldTransform; - Rules.bWeldSimulatedBodies = true; - HitActor->AttachToComponent(this->RightHand, Rules); -} - -void AVirtualRealityPawnOld::OnEndFire_Implementation() { - - // if we didnt grab anyone there is no need to release - if (GrabbedActor == nullptr) - return; - - // let the grabbed object reacot to release - Cast<IGrabable>(GrabbedActor)->OnReleased_Implementation(); - - // Detach the Actor - - UPrimitiveComponent* PhysicsComp = GrabbedActor->FindComponentByClass<UPrimitiveComponent>(); - UGrabbingBehaviorComponent* Behavior = GrabbedActor->FindComponentByClass<UGrabbingBehaviorComponent>(); - if (Behavior == nullptr) - { - GrabbedActor->GetRootComponent()->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); - PhysicsComp->SetSimulatePhysics(bDidSimulatePhysics); - } - - // forget about the actor - GrabbedActor = nullptr; -} - -FTwoVectors AVirtualRealityPawnOld::GetHandRay(float Length) -{ - FVector Start = this->RightHand->GetComponentLocation(); - FVector Direction = this->RightHand->GetForwardVector(); - FVector End = Start + Length * Direction; - - return FTwoVectors(Start, End); -} - - -UPawnMovementComponent* AVirtualRealityPawnOld::GetMovementComponent() const -{ - return Movement; -} - -void AVirtualRealityPawnOld::SetCapsuleColliderCharacterSizeVR() -{ - float CharachterSize = 0; //abs(RootComponent->GetComponentLocation().Z - CameraComponent->GetComponentLocation().Z); - - if (CharachterSize > MaxStepHeight) - { - float ColliderHeight = CharachterSize - MaxStepHeight; - float ColliderHalfHeight = ColliderHeight / 2.0f; - float ColliderRadius = 40.0f; - if (ColliderHalfHeight <= ColliderRadius) - {//Make the collider to a Sphere - CapsuleColliderComponent->SetCapsuleSize(ColliderHalfHeight, ColliderHalfHeight); - } - else - {//Make the collider to a Capsule - CapsuleColliderComponent->SetCapsuleSize(ColliderRadius, ColliderHalfHeight); - } - - //CapsuleColliderComponent->SetWorldLocation(CameraComponent->GetComponentLocation()); - CapsuleColliderComponent->AddWorldOffset(FVector(0, 0, -ColliderHalfHeight)); - CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1)); - } - else - { - //CapsuleColliderComponent->SetWorldLocation(CameraComponent->GetComponentLocation()); - CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1)); - } -} - -void AVirtualRealityPawnOld::CheckForPhysWalkingCollision() -{ - FVector CurrentCameraPosition = FVector(0);//CameraComponent->GetComponentLocation(); - FVector Direction = CurrentCameraPosition - LastCameraPosition; - FHitResult FHitResultPhys; - CapsuleColliderComponent->AddWorldOffset(Direction, true, &FHitResultPhys); - - if (FHitResultPhys.bBlockingHit) - { - RootComponent->AddLocalOffset(FHitResultPhys.Normal*FHitResultPhys.PenetrationDepth); - } -} - -void AVirtualRealityPawnOld::HandleMovementInput(float Value, FVector Direction) -{ - if (NavigationMode == EVRNavigationModes::nav_mode_walk) - { - VRWalkingMode(Value, Direction); - } - else if (NavigationMode == EVRNavigationModes::nav_mode_fly) - { - VRFlyingMode(Value, Direction); - } -} - -void AVirtualRealityPawnOld::VRWalkingMode(float Value, FVector Direction) -{ - Direction.Z = 0.0f;//walking - FVector End = (Direction * GetFloatingPawnMovement()->GetMaxSpeed()); - FHitResult FHitResultVR; - CapsuleColliderComponent->AddWorldOffset(End* DeltaTime*Value, true, &FHitResultVR); - - if (FVector::Distance(FHitResultVR.Location, CapsuleColliderComponent->GetComponentLocation()) > CapsuleColliderComponent->GetScaledCapsuleRadius()) - { - AddMovementInput(Direction, Value); - } -} - -void AVirtualRealityPawnOld::VRFlyingMode(float Value, FVector Direction) -{ - AddMovementInput(Direction, Value); -} - -void AVirtualRealityPawnOld::MoveByGravityOrStepUp(float DeltaSeconds) -{ - FVector StartLineTraceUnderCollider = CapsuleColliderComponent->GetComponentLocation(); - StartLineTraceUnderCollider.Z -= CapsuleColliderComponent->GetScaledCapsuleHalfHeight(); - FHitResult HitDetailsMultiLineTrace = CreateMultiLineTrace(FVector(0, 0, -1), StartLineTraceUnderCollider, CapsuleColliderComponent->GetScaledCapsuleRadius() / 4.0f, false); - float DiffernceDistance = abs(MaxStepHeight - HitDetailsMultiLineTrace.Distance); - //Going up - if ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance < MaxStepHeight)) - { - ShiftVertically(DiffernceDistance, UpSteppingAcceleration, DeltaSeconds, 1); - } - //Falling, Gravity, Going down - else if ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance > MaxStepHeight) || (HitDetailsMultiLineTrace.Actor == nullptr && HitDetailsMultiLineTrace.Distance != -1.0f)) - { - ShiftVertically(DiffernceDistance, GravityAcceleration, DeltaSeconds, -1); - } -} - -void AVirtualRealityPawnOld::ShiftVertically(float DiffernceDistance, float Acceleration, float DeltaSeconds, int Direction) -{ - VerticalSpeed += Acceleration * DeltaSeconds; - if (VerticalSpeed*DeltaSeconds < DiffernceDistance) - { - RootComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * VerticalSpeed * DeltaSeconds)); - } - else - { - RootComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * DiffernceDistance)); - VerticalSpeed = 0; - } -} - -void AVirtualRealityPawnOld::InitRoomMountedComponentReferences() -{ - if (!UVirtualRealityUtilities::IsRoomMountedMode()) return; - - //check whether the nodes already exist (otherwise GetClusterComponent() returns nullptr and prints a warning) and assign them - if (!TrackingOrigin) TrackingOrigin = UVirtualRealityUtilities::GetClusterComponent("cave_origin"); - if (!TrackingOrigin) TrackingOrigin = UVirtualRealityUtilities::GetClusterComponent("rolv_origin"); - if (!CaveCenter) CaveCenter = UVirtualRealityUtilities::GetClusterComponent("cave_center"); - if (!ShutterGlasses) - { - ShutterGlasses = UVirtualRealityUtilities::GetClusterComponent("shutter_glasses"); - Head->AttachToComponent(ShutterGlasses, FAttachmentTransformRules::SnapToTargetIncludingScale); - } - if (!Flystick) - { - Flystick = UVirtualRealityUtilities::GetClusterComponent("flystick"); - if (AttachRightHandInCAVE == EAttachementType::AT_FLYSTICK) - RightHand->AttachToComponent(Flystick, FAttachmentTransformRules::SnapToTargetIncludingScale); - if (AttachLeftHandInCAVE == EAttachementType::AT_FLYSTICK) - LeftHand->AttachToComponent(Flystick, FAttachmentTransformRules::SnapToTargetIncludingScale); - } - if (!LeftHandTarget) - { - LeftHandTarget = UVirtualRealityUtilities::GetClusterComponent("left_hand_target"); - if (AttachLeftHandInCAVE == EAttachementType::AT_HANDTARGET) - LeftHand->AttachToComponent(LeftHandTarget, FAttachmentTransformRules::SnapToTargetIncludingScale); - } - if (!RightHandTarget) - { - RightHandTarget = UVirtualRealityUtilities::GetClusterComponent("right_hand_target"); - if (AttachRightHandInCAVE == EAttachementType::AT_HANDTARGET) - RightHand->AttachToComponent(RightHandTarget, FAttachmentTransformRules::SnapToTargetIncludingScale); - } -} - - -FHitResult AVirtualRealityPawnOld::CreateLineTrace(FVector Direction, const FVector Start, bool Visibility) -{ - //Re-initialize hit info - FHitResult HitDetails = FHitResult(ForceInit); - - FVector End = ((Direction * 1000.f) + Start); - // additional trace parameters - FCollisionQueryParams TraceParams(FName(TEXT("InteractTrace")), true, NULL); - TraceParams.bTraceComplex = true; //to use complex collision on whatever we interact with to provide better precision. - TraceParams.bReturnPhysicalMaterial = true; //to provide details about the physical material, if one exists on the thing we hit, to come back in our hit result. - - if (Visibility) - DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1); - - if (GetWorld()->LineTraceSingleByChannel(HitDetails, Start, End, ECC_Visibility, TraceParams)) - { - if (HitDetails.bBlockingHit) - { - } - } - return HitDetails; -} - -FHitResult AVirtualRealityPawnOld::CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility) -{ - TArray<FVector> StartVectors; - TArray<FHitResult> OutHits; - FHitResult HitDetailsMultiLineTrace; - HitDetailsMultiLineTrace.Distance = -1.0f;//(Distance=-1) not existing, but to know if this Variable not Initialized(when all Traces not compatible) - - StartVectors.Add(Start); //LineTraceCenter - StartVectors.Add(Start + FVector(0, -Radius, 0)); //LineTraceLeft - StartVectors.Add(Start + FVector(0, +Radius, 0)); //LineTraceRight - StartVectors.Add(Start + FVector(+Radius, 0, 0)); //LineTraceFront - StartVectors.Add(Start + FVector(-Radius, 0, 0)); //LineTraceBehind - - bool IsBlockingHitAndSameActor = true; - bool IsAllNothingHiting = true; - // loop through TArray - for (FVector& Vector : StartVectors) - { - FHitResult OutHit = CreateLineTrace(Direction, Vector, Visibility); - OutHits.Add(OutHit); - IsBlockingHitAndSameActor &= (OutHit.Actor == OutHits[0].Actor); //If all Hiting the same Object, then you are (going up/down) or (walking) - IsAllNothingHiting &= (OutHit.Actor == nullptr); //If all Hiting nothing, then you are falling - } - - if (IsBlockingHitAndSameActor || IsAllNothingHiting) - HitDetailsMultiLineTrace = OutHits[0]; - - return HitDetailsMultiLineTrace; -} diff --git a/Source/DisplayClusterExtensions/Public/UniversalTrackedComponent.h b/Source/DisplayClusterExtensions/Public/UniversalTrackedComponent.h index 13addbdcf104c973165a9276b580cd283465278a..778ff21f7e9ee0d89482cc0c772a666595b1c8c7 100644 --- a/Source/DisplayClusterExtensions/Public/UniversalTrackedComponent.h +++ b/Source/DisplayClusterExtensions/Public/UniversalTrackedComponent.h @@ -41,9 +41,13 @@ public: UUniversalTrackedComponent(); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking") ETrackedComponentType ProxyType = ETrackedComponentType::TCT_HEAD; - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking") EAttachementType AttachementType = EAttachementType::AT_FLYSTICK; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking|nDisplay") EAttachementType AttachementType = EAttachementType::AT_NONE; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking|HMD", BlueprintSetter=SetShowDeviceModel) bool ShowDeviceModelInHMD = true; - // Called every frame + UFUNCTION(BlueprintSetter) + void SetShowDeviceModel(const bool bShowControllerModel); + + virtual void BeginPlay() override; virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; private: diff --git a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h index 251536067a7bc35ebc5cc982417913cb34fba102..c80414d6f1a3170d169c0da1aaa325029f580ac3 100644 --- a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h +++ b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h @@ -2,16 +2,47 @@ #pragma once +#include "BasicVRInteractionComponent.h" #include "CoreMinimal.h" #include "GameFramework/DefaultPawn.h" +#include "GameFramework/RotatingMovementComponent.h" +#include "UniversalTrackedComponent.h" +#include "VRPawnMovement.h" #include "VirtualRealityPawn.generated.h" /** * */ UCLASS() -class DISPLAYCLUSTEREXTENSIONS_API AVirtualRealityPawn : public ADefaultPawn +class DISPLAYCLUSTEREXTENSIONS_API AVirtualRealityPawn : public APawn { GENERATED_BODY() +public: + AVirtualRealityPawn(const FObjectInitializer& ObjectInitializer); + /* Proxy Components */ + UPROPERTY() UUniversalTrackedComponent* Head; + UPROPERTY() UUniversalTrackedComponent* RightHand; + UPROPERTY() UUniversalTrackedComponent* LeftHand; + UPROPERTY() UUniversalTrackedComponent* Tracker1; + UPROPERTY() UUniversalTrackedComponent* Tracker2; + UPROPERTY() UBasicVRInteractionComponent* BasicVRInteraction; + + /* Movement */ + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|Movement") UVRPawnMovement* PawnMovement; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn|Movement") float BaseTurnRate = 45.0f; + +protected: + virtual void BeginPlay() override; + virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override; + + /* Movement */ + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn|Movement") void OnForward(float Value); + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn|Movement") void OnRight(float Value); + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn|Movement") void OnTurnRate(float Rate); + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn|Movement") void OnLookUpRate(float Rate); + + /* Interaction */ + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn|Interaction") void OnBeginFire(); + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn|Interaction") void OnEndFire(); }; diff --git a/Source/DisplayClusterExtensions/Public/VirtualRealityPawnOld.h b/Source/DisplayClusterExtensions/Public/VirtualRealityPawnOld.h deleted file mode 100644 index 959f4bbee21c5b69ebe3ff2170016695d96396a1..0000000000000000000000000000000000000000 --- a/Source/DisplayClusterExtensions/Public/VirtualRealityPawnOld.h +++ /dev/null @@ -1,139 +0,0 @@ -#pragma once - -#include "CoreMinimal.h" -#include "Cluster/DisplayClusterClusterEvent.h" -#include "Cluster/IDisplayClusterClusterManager.h" -#include "Components/DisplayClusterSceneComponent.h" -#include "Components/CapsuleComponent.h" -#include "GameFramework/FloatingPawnMovement.h" -#include "GameFramework/PawnMovementComponent.h" -#include "GameFramework/RotatingMovementComponent.h" -#include "UniversalTrackedComponent.h" - -#include "MotionControllerComponent.h" -#include "VirtualRealityPawnOld.generated.h" - -UENUM(BlueprintType) -enum class EVRNavigationModes : uint8 -{ - nav_mode_none UMETA(DisplayName = "Navigation Mode None"), - nav_mode_walk UMETA(DisplayName = "Navigation Mode Walk"), - nav_mode_fly UMETA(DisplayName = "Navigation Mode Fly") -}; - -UCLASS() -class DISPLAYCLUSTEREXTENSIONS_API AVirtualRealityPawnOld : public APawn -{ - GENERATED_UCLASS_BODY() - -public: - UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnForward(float Value); - UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnRight(float Value); - UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnTurnRate(float Rate); - UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnLookUpRate(float Rate); - UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnBeginFire(); - UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnEndFire(); - - UFUNCTION(Category = "Pawn") float GetBaseTurnRate() const; - UFUNCTION(Category = "Pawn") void SetBaseTurnRate(float Value); - UFUNCTION(Category = "Pawn") UFloatingPawnMovement* GetFloatingPawnMovement(); - UFUNCTION(Category = "Pawn") URotatingMovementComponent* GetRotatingMovementComponent(); - - //Bunch of Getter Functions for components to avoid users having to know the names - UFUNCTION(Category = "Pawn") UDisplayClusterSceneComponent* GetFlystickComponent(); - UFUNCTION(Category = "Pawn") UDisplayClusterSceneComponent* GetRightHandtargetComponent(); - UFUNCTION(Category = "Pawn") UDisplayClusterSceneComponent* GetLeftHandtargetComponent(); - UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdLeftMotionControllerComponent(); - UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdRightMotionControllerComponent(); - UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdTracker1MotionControllerComponent(); - UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdTracker2MotionControllerComponent(); - - UFUNCTION(Category = "Pawn") USceneComponent* GetHeadComponent(); - UFUNCTION(Category = "Pawn") USceneComponent* GetLeftHandComponent(); - UFUNCTION(Category = "Pawn") USceneComponent* GetRightHandComponent(); - - - UFUNCTION(Category = "Pawn") USceneComponent* GetTrackingOriginComponent(); - -private: - UFUNCTION(Category = "Pawn") USceneComponent* GetCaveCenterComponent(); - UFUNCTION(Category = "Pawn") USceneComponent* GetShutterGlassesComponent(); - UFUNCTION(Category = "Pawn") FTwoVectors GetHandRay(float Distance); - UFUNCTION(Category = "Pawn") void HandlePhysicsAndAttachActor(AActor* HitActor); - -public: - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EVRNavigationModes NavigationMode = EVRNavigationModes::nav_mode_fly; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") float MaxStepHeight = 40.0f; -protected: - - virtual void BeginPlay() override; - virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; - virtual void Tick(float DeltaSeconds) override; - virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override; - virtual UPawnMovementComponent* GetMovementComponent() const override; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn", meta = (AllowPrivateAccess = "true")) float BaseTurnRate = 45.0f; - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UFloatingPawnMovement* Movement = nullptr; - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) URotatingMovementComponent* RotatingMovement = nullptr; - - // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. CAVE/ROLV flystick. - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UDisplayClusterSceneComponent* Flystick = nullptr; - // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. CAVE/ROLV flystick. - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UDisplayClusterSceneComponent* RightHandTarget = nullptr; - // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. CAVE/ROLV flystick. - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UDisplayClusterSceneComponent* LeftHandTarget = nullptr; - - // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD left motion controller. - UPROPERTY() UMotionControllerComponent* HmdLeftMotionController = nullptr; - // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD right motion controller. - UPROPERTY() UMotionControllerComponent* HmdRightMotionController = nullptr; - - // used only for HMDs, tested with the additional Vive Trackers - UPROPERTY() UMotionControllerComponent* HmdTracker1 = nullptr; - UPROPERTY() UMotionControllerComponent* HmdTracker2 = nullptr; - - // PC: Camera, HMD: Camera, CAVE/ROLV: Shutter glasses. - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent* Head = nullptr; - // PC: RootComponent, HMD: HmdLeftMotionController , CAVE/ROLV: regarding to AttachRightHandInCAVE. Useful for line trace (e.g. for holding objects). - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent* RightHand = nullptr; - // PC: RootComponent, HMD: HmdRightMotionController, CAVE/ROLV: regarding to AttachLeftHandInCAVE. Useful for line trace (e.g. for holding objects). - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent* LeftHand = nullptr; - - // Holding the Cave/rolv Origin Component that is attached to this Pawn - UPROPERTY() USceneComponent* TrackingOrigin = nullptr; - // Holding the Cave Center Component that is attached to this Pawn, it is needed for the internal transform of nDisplay - UPROPERTY() USceneComponent* CaveCenter = nullptr; - // Holding the Shutter Glasses Component that is attached to this Pawn - UPROPERTY() USceneComponent* ShutterGlasses = nullptr; - - // Holding a reference to the actor that is currently being grabbed - UPROPERTY() AActor* GrabbedActor; - // indicates if the grabbed actor was simulating physics before we grabbed it - UPROPERTY() bool bDidSimulatePhysics; - UPROPERTY(EditAnywhere) float MaxGrabDistance = 50; - UPROPERTY(EditAnywhere) float MaxClickDistance = 500; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") bool ShowHMDControllers = true; - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachRightHandInCAVE = EAttachementType::AT_FLYSTICK; - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachLeftHandInCAVE = EAttachementType::AT_NONE; - - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UCapsuleComponent* CapsuleColliderComponent = nullptr; -private: - float DeltaTime = 0.0f; - float VerticalSpeed = 0.0f; - UPROPERTY() float GravityAcceleration = 981.0f; - UPROPERTY() float UpSteppingAcceleration = 500.0f; - FVector LastCameraPosition; - - FHitResult CreateLineTrace(FVector Direction, const FVector Start, bool Visibility); - FHitResult CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility); - void SetCapsuleColliderCharacterSizeVR(); - void CheckForPhysWalkingCollision(); - void HandleMovementInput(float Value, FVector Direction); - void VRWalkingMode(float Value, FVector Direction); - void VRFlyingMode(float Value, FVector Direction); - void MoveByGravityOrStepUp(float DeltaSeconds); - void ShiftVertically(float DiffernceDistance, float Acceleration, float DeltaSeconds, int Direction);//(direction = Down = -1), (direction = Up = 1) - void InitRoomMountedComponentReferences(); -};