diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp index 62bfa4602491506185646dfd769a3876ca4b8ccb..912fe0c1d74a99afb6a7ae6dfd9cd33a40771088 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp @@ -189,6 +189,9 @@ void UCollisionHandlingMovement::SetCapsuleColliderToUserSize() const } CapsuleColliderComponent->SetWorldRotation(FRotator::ZeroRotator); + + // Counteract Pawn Scaling + CapsuleColliderComponent->SetWorldScale3D(FVector::One()); } void UCollisionHandlingMovement::CheckAndRevertCollisionSinceLastTick() diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp index 812e83ea74b96709e72b7768dbbd5d90bc041f52..dc9c9022a86fc6e57b1dd6e19927519bca283161 100644 --- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp +++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp @@ -41,8 +41,26 @@ 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 != 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() +{ + Super::BeginPlay(); + InitialWorldToMeters = GetWorldSettings()->WorldToMeters; } -void ARWTHVRPawn::BeginPlay() { Super::BeginPlay(); } void ARWTHVRPawn::Tick(float DeltaSeconds) { @@ -56,6 +74,22 @@ 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 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; } + /* * 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. @@ -362,4 +396,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 cd81e497181dcfef757b067ccae8c862c022fa34..40eb174f5f82b11a9c30b3130fca1f702a687409 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. */ @@ -31,6 +33,15 @@ public: 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; @@ -111,4 +122,6 @@ protected: private: UInputComponent* ActivePlayerInputComponent; + float InitialWorldToMeters; + float UniformScale; };