From 2552da9b108886edc173820a59c469c24713e44d Mon Sep 17 00:00:00 2001 From: Mamadou Babaei Date: Thu, 3 Aug 2023 17:53:39 +0200 Subject: [PATCH] alternative velocity calculation for released actors based on the hand's cached position history --- .../SenseGlove/GameFramework/SGPawn.cpp | 47 ++++++++----------- .../GameFramework/SGVirtualHandActor.cpp | 2 +- .../SenseGlove/Haptics/SGGrabState.cpp | 18 +++---- .../Public/SenseGlove/GameFramework/SGPawn.h | 10 ++-- .../Public/SenseGlove/Haptics/SGGrabState.h | 18 +++---- 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp index 133ea7f9..f2196aff 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp @@ -91,7 +91,7 @@ struct ASGPawn::FImpl void SetLeftHandGrabbedActor(AActor* Actor) const; void SetRightHandGrabbedActor(AActor* Actor) const; - void RecordGrabbedActorVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const; + void RecordHandVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const; void Release(FSGGrabState& GrabState) const; }; @@ -443,12 +443,12 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer) RightPinkyFingertipTouchCollider->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap); RightPinkyFingertipTouchCollider->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap); - MaxNumberOfReleaseVelocities = 10; + MaxNumberOfHandVelocitySamples = 10; - LeftHandGrabState = FSGGrabState(HandLeft, nullptr, nullptr, nullptr, nullptr, FVector::Zero(), {}); + LeftHandGrabState = FSGGrabState(HandLeft, FVector::Zero(), {}, nullptr, nullptr, nullptr, nullptr); LeftHandTouchState = FSGTouchState(HandLeft, nullptr, nullptr, nullptr, nullptr, nullptr); - RightHandGrabState = FSGGrabState(HandRight, nullptr, nullptr, nullptr, nullptr, FVector::Zero(), {}); + RightHandGrabState = FSGGrabState(HandRight, FVector::Zero(), {}, nullptr, nullptr, nullptr, nullptr); RightHandTouchState = FSGTouchState(HandRight, nullptr, nullptr, nullptr, nullptr, nullptr); } @@ -499,15 +499,8 @@ void ASGPawn::Tick(const float DeltaSeconds) { Super::Tick(DeltaSeconds); - if (IsValid(LeftHandGrabState.GrabbedActor)) - { - Pimpl->RecordGrabbedActorVelocity(LeftHandGrabState, DeltaSeconds); - } - - if (IsValid(RightHandGrabState.GrabbedActor)) - { - Pimpl->RecordGrabbedActorVelocity(RightHandGrabState, DeltaSeconds); - } + Pimpl->RecordHandVelocity(LeftHandGrabState, DeltaSeconds); + Pimpl->RecordHandVelocity(RightHandGrabState, DeltaSeconds); } void ASGPawn::PreInitializeComponents() @@ -1457,17 +1450,15 @@ void ASGPawn::FImpl::ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabSta return; } - FVector ActorVelocity{UKismetMathLibrary::GetVectorArrayAverage(GrabState.ReleaseVelocities)}; + FVector HandVelocity{UKismetMathLibrary::GetVectorArrayAverage(GrabState.HandVelocityHistory)}; - ActorRootComponent->SetPhysicsLinearVelocity(ActorVelocity); - ActorRootComponent->AddImpulse(MoveTemp(ActorVelocity), NAME_None, true); + ActorRootComponent->SetPhysicsLinearVelocity(HandVelocity); + ActorRootComponent->AddImpulse(MoveTemp(HandVelocity), NAME_None, true); } void ASGPawn::FImpl::SetGrabbedActor(FSGGrabState& GrabState, AActor* Actor) const { GrabState.GrabbedActor = Actor; - GrabState.PreviousLocation = IsValid(Actor) ? Actor->GetActorLocation() : FVector::Zero(); - GrabState.ReleaseVelocities.Empty(); } void ASGPawn::FImpl::SetLeftHandGrabbedActor(AActor* Actor) const @@ -1480,31 +1471,31 @@ void ASGPawn::FImpl::SetRightHandGrabbedActor(AActor* Actor) const SetGrabbedActor(Owner->RightHandGrabState, Actor); } -void ASGPawn::FImpl::RecordGrabbedActorVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const +void ASGPawn::FImpl::RecordHandVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const { - if (!IsValid(GrabState.GrabbedActor)) + if (!IsValid(GrabState.Hand)) { return; } - FVector ActorVelocity{ - (GrabState.GrabbedActor->GetActorLocation() - GrabState.PreviousLocation) / DeltaSeconds + FVector HandVelocity{ + (GrabState.Hand->GetComponentLocation() - GrabState.PreviousHandLocation) / DeltaSeconds }; - if (GrabState.ReleaseVelocities.Num() >= Owner->MaxNumberOfReleaseVelocities) + if (GrabState.HandVelocityHistory.Num() >= Owner->MaxNumberOfHandVelocitySamples) { - if (GrabState.ReleaseVelocities.IsValidIndex(0)) + if (GrabState.HandVelocityHistory.IsValidIndex(0)) { - GrabState.ReleaseVelocities.RemoveAt(0, 1, false); - GrabState.ReleaseVelocities.Emplace(MoveTemp(ActorVelocity)); + GrabState.HandVelocityHistory.RemoveAt(0, 1, false); + GrabState.HandVelocityHistory.Emplace(MoveTemp(HandVelocity)); } } else { - GrabState.ReleaseVelocities.Emplace(MoveTemp(ActorVelocity)); + GrabState.HandVelocityHistory.Emplace(MoveTemp(HandVelocity)); } - GrabState.PreviousLocation = GrabState.GrabbedActor->GetActorLocation(); + GrabState.PreviousHandLocation = GrabState.Hand->GetComponentLocation(); } void ASGPawn::FImpl::Release(FSGGrabState& GrabState) const diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp index ca787b60..7b1daded 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp @@ -249,7 +249,7 @@ ASGVirtualHandActor::ASGVirtualHandActor(const FObjectInitializer& ObjectInitial WristTracker->SetRight(VirtualHand->IsRight()); - GrabState = FSGGrabState(VirtualHand, nullptr, nullptr, nullptr, nullptr, FVector::Zero(), {}); + GrabState = FSGGrabState(VirtualHand, FVector::Zero(), {}, nullptr, nullptr, nullptr, nullptr); TouchState = FSGTouchState(VirtualHand, nullptr, nullptr, nullptr, nullptr, nullptr); } diff --git a/Source/SenseGlove/Private/SenseGlove/Haptics/SGGrabState.cpp b/Source/SenseGlove/Private/SenseGlove/Haptics/SGGrabState.cpp index 58afe4d7..d682a75f 100644 --- a/Source/SenseGlove/Private/SenseGlove/Haptics/SGGrabState.cpp +++ b/Source/SenseGlove/Private/SenseGlove/Haptics/SGGrabState.cpp @@ -41,28 +41,28 @@ FSGGrabState::FSGGrabState() : Hand(nullptr), + PreviousHandLocation(FVector::Zero()), + HandVelocityHistory{}, ActorThumbCanGrab(nullptr), ActorIndexCanGrab(nullptr), ActorMiddleCanGrab(nullptr), - GrabbedActor(nullptr), - PreviousLocation(FVector::Zero()), - ReleaseVelocities{} + GrabbedActor(nullptr) { } FSGGrabState::FSGGrabState(USGVirtualHandComponent* InHand, + const FVector& InPreviousHandLocation, + const TArray& InHandVelocityHistory, AActor* InActorThumbCanGrab, AActor* InActorIndexCanGrab, AActor* InActorMiddleCanGrab, - AActor* InGrabbedActor, - const FVector& InPreviousLocation, - const TArray& InReleaseVelocities) + AActor* InGrabbedActor) : Hand(InHand), + PreviousHandLocation(InPreviousHandLocation), + HandVelocityHistory(InHandVelocityHistory), ActorThumbCanGrab(InActorThumbCanGrab), ActorIndexCanGrab(InActorIndexCanGrab), ActorMiddleCanGrab(InActorMiddleCanGrab), - GrabbedActor(InGrabbedActor), - PreviousLocation(InPreviousLocation), - ReleaseVelocities(InReleaseVelocities) + GrabbedActor(InGrabbedActor) { } \ No newline at end of file diff --git a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h index 16a3dfb1..21bb6769 100644 --- a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h +++ b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h @@ -154,7 +154,7 @@ private: USphereComponent* RightPinkyFingertipTouchCollider; UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) - int32 MaxNumberOfReleaseVelocities; + int32 MaxNumberOfHandVelocitySamples; private: UPROPERTY(Transient) @@ -275,14 +275,14 @@ public: return RightPinkyFingertipTouchCollider; } - FORCEINLINE int32 GetMaxNumberOfReleaseVelocities() const + FORCEINLINE int32 GetMaxNumberOfHandVelocitySamples() const { - return MaxNumberOfReleaseVelocities; + return MaxNumberOfHandVelocitySamples; } - FORCEINLINE void SetMaxNumberOfReleaseVelocities(const int32 InMaxNumberOfReleaseVelocities) + FORCEINLINE void SetMaxNumberOfHandVelocitySamples(const int32 InMaxNumberOfHandVelocitySamples) { - MaxNumberOfReleaseVelocities = InMaxNumberOfReleaseVelocities; + MaxNumberOfHandVelocitySamples = InMaxNumberOfHandVelocitySamples; } public: diff --git a/Source/SenseGlove/Public/SenseGlove/Haptics/SGGrabState.h b/Source/SenseGlove/Public/SenseGlove/Haptics/SGGrabState.h index 0206c47f..7aca4a8e 100644 --- a/Source/SenseGlove/Public/SenseGlove/Haptics/SGGrabState.h +++ b/Source/SenseGlove/Public/SenseGlove/Haptics/SGGrabState.h @@ -55,6 +55,12 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") USGVirtualHandComponent* Hand; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + FVector PreviousHandLocation; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + TArray HandVelocityHistory; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") AActor* ActorThumbCanGrab; @@ -67,20 +73,14 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") AActor* GrabbedActor; - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") - FVector PreviousLocation; - - UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") - TArray ReleaseVelocities; - public: FSGGrabState(); explicit FSGGrabState(USGVirtualHandComponent* InHand, + const FVector& InPreviousHandLocation, + const TArray& InHandVelocityHistory, AActor* InActorThumbCanGrab, AActor* InActorIndexCanGrab, AActor* InActorMiddleCanGrab, - AActor* InGrabbedActor, - const FVector& InPreviousLocation, - const TArray& InReleaseVelocities); + AActor* InGrabbedActor); }; \ No newline at end of file