alternative velocity calculation for released actors based on a cached position history

This commit is contained in:
Mamadou Babaei
2023-08-03 17:21:40 +02:00
parent ad5d701a48
commit 2cdc78131a
5 changed files with 87 additions and 12 deletions
@@ -38,6 +38,7 @@
#include "Camera/CameraComponent.h"
#include "Components/PrimitiveComponent.h"
#include "Components/SphereComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "SenseGlove/Components/SGGrabComponent.h"
#include "SenseGlove/Components/SGTouchComponent.h"
@@ -90,6 +91,8 @@ struct ASGPawn::FImpl
void SetLeftHandGrabbedActor(AActor* Actor) const;
void SetRightHandGrabbedActor(AActor* Actor) const;
void RecordGrabbedActorVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const;
void Release(FSGGrabState& GrabState) const;
};
@@ -440,10 +443,12 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
RightPinkyFingertipTouchCollider->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap);
RightPinkyFingertipTouchCollider->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap);
LeftHandGrabState = FSGGrabState(HandLeft, nullptr, nullptr, nullptr, nullptr);
MaxNumberOfReleaseVelocities = 10;
LeftHandGrabState = FSGGrabState(HandLeft, nullptr, nullptr, nullptr, nullptr, FVector::Zero(), {});
LeftHandTouchState = FSGTouchState(HandLeft, nullptr, nullptr, nullptr, nullptr, nullptr);
RightHandGrabState = FSGGrabState(HandRight, nullptr, nullptr, nullptr, nullptr);
RightHandGrabState = FSGGrabState(HandRight, nullptr, nullptr, nullptr, nullptr, FVector::Zero(), {});
RightHandTouchState = FSGTouchState(HandRight, nullptr, nullptr, nullptr, nullptr, nullptr);
}
@@ -490,6 +495,21 @@ void ASGPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
Pimpl->UnbindFingerTouchOverlapEvents();
}
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);
}
}
void ASGPawn::PreInitializeComponents()
{
Super::PreInitializeComponents();
@@ -1437,11 +1457,7 @@ void ASGPawn::FImpl::ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabSta
return;
}
/// NOTE: this produces almost the same values
// FVector ActorVelocity{
// (GrabState.GrabbedActor->GetActorLocation() - GrabState.PreviousLocation) / DeltaSeconds
// };
FVector ActorVelocity{GrabState.GrabbedActor->GetVelocity()};
FVector ActorVelocity{UKismetMathLibrary::GetVectorArrayAverage(GrabState.ReleaseVelocities)};
ActorRootComponent->SetPhysicsLinearVelocity(ActorVelocity);
ActorRootComponent->AddImpulse(MoveTemp(ActorVelocity), NAME_None, true);
@@ -1450,6 +1466,8 @@ void ASGPawn::FImpl::ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabSta
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
@@ -1462,6 +1480,33 @@ void ASGPawn::FImpl::SetRightHandGrabbedActor(AActor* Actor) const
SetGrabbedActor(Owner->RightHandGrabState, Actor);
}
void ASGPawn::FImpl::RecordGrabbedActorVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const
{
if (!IsValid(GrabState.GrabbedActor))
{
return;
}
FVector ActorVelocity{
(GrabState.GrabbedActor->GetActorLocation() - GrabState.PreviousLocation) / DeltaSeconds
};
if (GrabState.ReleaseVelocities.Num() >= Owner->MaxNumberOfReleaseVelocities)
{
if (GrabState.ReleaseVelocities.IsValidIndex(0))
{
GrabState.ReleaseVelocities.RemoveAt(0, 1, false);
GrabState.ReleaseVelocities.Emplace(MoveTemp(ActorVelocity));
}
}
else
{
GrabState.ReleaseVelocities.Emplace(MoveTemp(ActorVelocity));
}
GrabState.PreviousLocation = GrabState.GrabbedActor->GetActorLocation();
}
void ASGPawn::FImpl::Release(FSGGrabState& GrabState) const
{
if (!IsValid(GrabState.GrabbedActor))
@@ -249,7 +249,7 @@ ASGVirtualHandActor::ASGVirtualHandActor(const FObjectInitializer& ObjectInitial
WristTracker->SetRight(VirtualHand->IsRight());
GrabState = FSGGrabState(VirtualHand, nullptr, nullptr, nullptr, nullptr);
GrabState = FSGGrabState(VirtualHand, nullptr, nullptr, nullptr, nullptr, FVector::Zero(), {});
TouchState = FSGTouchState(VirtualHand, nullptr, nullptr, nullptr, nullptr, nullptr);
}
@@ -44,7 +44,9 @@ FSGGrabState::FSGGrabState()
ActorThumbCanGrab(nullptr),
ActorIndexCanGrab(nullptr),
ActorMiddleCanGrab(nullptr),
GrabbedActor(nullptr)
GrabbedActor(nullptr),
PreviousLocation(FVector::Zero()),
ReleaseVelocities{}
{
}
@@ -52,11 +54,15 @@ FSGGrabState::FSGGrabState(USGVirtualHandComponent* InHand,
AActor* InActorThumbCanGrab,
AActor* InActorIndexCanGrab,
AActor* InActorMiddleCanGrab,
AActor* InGrabbedActor)
AActor* InGrabbedActor,
const FVector& InPreviousLocation,
const TArray<FVector>& InReleaseVelocities)
: Hand(InHand),
ActorThumbCanGrab(InActorThumbCanGrab),
ActorIndexCanGrab(InActorIndexCanGrab),
ActorMiddleCanGrab(InActorMiddleCanGrab),
GrabbedActor(InGrabbedActor)
GrabbedActor(InGrabbedActor),
PreviousLocation(InPreviousLocation),
ReleaseVelocities(InReleaseVelocities)
{
}
@@ -153,6 +153,9 @@ private:
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
USphereComponent* RightPinkyFingertipTouchCollider;
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
int32 MaxNumberOfReleaseVelocities;
private:
UPROPERTY(Transient)
FSGGrabState LeftHandGrabState;
@@ -272,9 +275,20 @@ public:
return RightPinkyFingertipTouchCollider;
}
FORCEINLINE int32 GetMaxNumberOfReleaseVelocities() const
{
return MaxNumberOfReleaseVelocities;
}
FORCEINLINE void SetMaxNumberOfReleaseVelocities(const int32 InMaxNumberOfReleaseVelocities)
{
MaxNumberOfReleaseVelocities = InMaxNumberOfReleaseVelocities;
}
public:
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void Tick(float DeltaSeconds) override;
virtual void PreInitializeComponents() override;
protected:
@@ -35,6 +35,8 @@
#pragma once
#include "Containers/Array.h"
#include "Math/Vector.h"
#include "UObject/ObjectMacros.h"
#include "SGGrabState.generated.h"
@@ -65,6 +67,12 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
AActor* GrabbedActor;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
FVector PreviousLocation;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
TArray<FVector> ReleaseVelocities;
public:
FSGGrabState();
@@ -72,5 +80,7 @@ public:
AActor* InActorThumbCanGrab,
AActor* InActorIndexCanGrab,
AActor* InActorMiddleCanGrab,
AActor* InGrabbedActor);
AActor* InGrabbedActor,
const FVector& InPreviousLocation,
const TArray<FVector>& InReleaseVelocities);
};