alternative velocity calculation for released actors based on the hand's cached position history

This commit is contained in:
Mamadou Babaei
2023-08-14 17:25:49 +02:00
parent a5a8e7149f
commit 43bdec8601
5 changed files with 43 additions and 52 deletions
@@ -91,7 +91,7 @@ struct ASGPawn::FImpl
void SetLeftHandGrabbedActor(AActor* Actor) const; void SetLeftHandGrabbedActor(AActor* Actor) const;
void SetRightHandGrabbedActor(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; void Release(FSGGrabState& GrabState) const;
}; };
@@ -443,12 +443,12 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
RightPinkyFingertipTouchCollider->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap); RightPinkyFingertipTouchCollider->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap);
RightPinkyFingertipTouchCollider->SetCollisionResponseToChannel(ECC_Destructible, 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); 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); RightHandTouchState = FSGTouchState(HandRight, nullptr, nullptr, nullptr, nullptr, nullptr);
} }
@@ -499,15 +499,8 @@ void ASGPawn::Tick(const float DeltaSeconds)
{ {
Super::Tick(DeltaSeconds); Super::Tick(DeltaSeconds);
if (IsValid(LeftHandGrabState.GrabbedActor)) Pimpl->RecordHandVelocity(LeftHandGrabState, DeltaSeconds);
{ Pimpl->RecordHandVelocity(RightHandGrabState, DeltaSeconds);
Pimpl->RecordGrabbedActorVelocity(LeftHandGrabState, DeltaSeconds);
}
if (IsValid(RightHandGrabState.GrabbedActor))
{
Pimpl->RecordGrabbedActorVelocity(RightHandGrabState, DeltaSeconds);
}
} }
void ASGPawn::PreInitializeComponents() void ASGPawn::PreInitializeComponents()
@@ -1457,17 +1450,15 @@ void ASGPawn::FImpl::ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabSta
return; return;
} }
FVector ActorVelocity{UKismetMathLibrary::GetVectorArrayAverage(GrabState.ReleaseVelocities)}; FVector HandVelocity{UKismetMathLibrary::GetVectorArrayAverage(GrabState.HandVelocityHistory)};
ActorRootComponent->SetPhysicsLinearVelocity(ActorVelocity); ActorRootComponent->SetPhysicsLinearVelocity(HandVelocity);
ActorRootComponent->AddImpulse(MoveTemp(ActorVelocity), NAME_None, true); ActorRootComponent->AddImpulse(MoveTemp(HandVelocity), NAME_None, true);
} }
void ASGPawn::FImpl::SetGrabbedActor(FSGGrabState& GrabState, AActor* Actor) const void ASGPawn::FImpl::SetGrabbedActor(FSGGrabState& GrabState, AActor* Actor) const
{ {
GrabState.GrabbedActor = Actor; GrabState.GrabbedActor = Actor;
GrabState.PreviousLocation = IsValid(Actor) ? Actor->GetActorLocation() : FVector::Zero();
GrabState.ReleaseVelocities.Empty();
} }
void ASGPawn::FImpl::SetLeftHandGrabbedActor(AActor* Actor) const void ASGPawn::FImpl::SetLeftHandGrabbedActor(AActor* Actor) const
@@ -1480,31 +1471,31 @@ void ASGPawn::FImpl::SetRightHandGrabbedActor(AActor* Actor) const
SetGrabbedActor(Owner->RightHandGrabState, Actor); 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; return;
} }
FVector ActorVelocity{ FVector HandVelocity{
(GrabState.GrabbedActor->GetActorLocation() - GrabState.PreviousLocation) / DeltaSeconds (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.HandVelocityHistory.RemoveAt(0, 1, false);
GrabState.ReleaseVelocities.Emplace(MoveTemp(ActorVelocity)); GrabState.HandVelocityHistory.Emplace(MoveTemp(HandVelocity));
} }
} }
else 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 void ASGPawn::FImpl::Release(FSGGrabState& GrabState) const
@@ -249,7 +249,7 @@ ASGVirtualHandActor::ASGVirtualHandActor(const FObjectInitializer& ObjectInitial
WristTracker->SetRight(VirtualHand->IsRight()); 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); TouchState = FSGTouchState(VirtualHand, nullptr, nullptr, nullptr, nullptr, nullptr);
} }
@@ -41,28 +41,28 @@
FSGGrabState::FSGGrabState() FSGGrabState::FSGGrabState()
: Hand(nullptr), : Hand(nullptr),
PreviousHandLocation(FVector::Zero()),
HandVelocityHistory{},
ActorThumbCanGrab(nullptr), ActorThumbCanGrab(nullptr),
ActorIndexCanGrab(nullptr), ActorIndexCanGrab(nullptr),
ActorMiddleCanGrab(nullptr), ActorMiddleCanGrab(nullptr),
GrabbedActor(nullptr), GrabbedActor(nullptr)
PreviousLocation(FVector::Zero()),
ReleaseVelocities{}
{ {
} }
FSGGrabState::FSGGrabState(USGVirtualHandComponent* InHand, FSGGrabState::FSGGrabState(USGVirtualHandComponent* InHand,
const FVector& InPreviousHandLocation,
const TArray<FVector>& InHandVelocityHistory,
AActor* InActorThumbCanGrab, AActor* InActorThumbCanGrab,
AActor* InActorIndexCanGrab, AActor* InActorIndexCanGrab,
AActor* InActorMiddleCanGrab, AActor* InActorMiddleCanGrab,
AActor* InGrabbedActor, AActor* InGrabbedActor)
const FVector& InPreviousLocation,
const TArray<FVector>& InReleaseVelocities)
: Hand(InHand), : Hand(InHand),
PreviousHandLocation(InPreviousHandLocation),
HandVelocityHistory(InHandVelocityHistory),
ActorThumbCanGrab(InActorThumbCanGrab), ActorThumbCanGrab(InActorThumbCanGrab),
ActorIndexCanGrab(InActorIndexCanGrab), ActorIndexCanGrab(InActorIndexCanGrab),
ActorMiddleCanGrab(InActorMiddleCanGrab), ActorMiddleCanGrab(InActorMiddleCanGrab),
GrabbedActor(InGrabbedActor), GrabbedActor(InGrabbedActor)
PreviousLocation(InPreviousLocation),
ReleaseVelocities(InReleaseVelocities)
{ {
} }
@@ -154,7 +154,7 @@ private:
USphereComponent* RightPinkyFingertipTouchCollider; USphereComponent* RightPinkyFingertipTouchCollider;
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
int32 MaxNumberOfReleaseVelocities; int32 MaxNumberOfHandVelocitySamples;
private: private:
UPROPERTY(Transient) UPROPERTY(Transient)
@@ -275,14 +275,14 @@ public:
return RightPinkyFingertipTouchCollider; 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: public:
@@ -55,6 +55,12 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
USGVirtualHandComponent* Hand; USGVirtualHandComponent* Hand;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
FVector PreviousHandLocation;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
TArray<FVector> HandVelocityHistory;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
AActor* ActorThumbCanGrab; AActor* ActorThumbCanGrab;
@@ -67,20 +73,14 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
AActor* GrabbedActor; AActor* GrabbedActor;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
FVector PreviousLocation;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove")
TArray<FVector> ReleaseVelocities;
public: public:
FSGGrabState(); FSGGrabState();
explicit FSGGrabState(USGVirtualHandComponent* InHand, explicit FSGGrabState(USGVirtualHandComponent* InHand,
const FVector& InPreviousHandLocation,
const TArray<FVector>& InHandVelocityHistory,
AActor* InActorThumbCanGrab, AActor* InActorThumbCanGrab,
AActor* InActorIndexCanGrab, AActor* InActorIndexCanGrab,
AActor* InActorMiddleCanGrab, AActor* InActorMiddleCanGrab,
AActor* InGrabbedActor, AActor* InGrabbedActor);
const FVector& InPreviousLocation,
const TArray<FVector>& InReleaseVelocities);
}; };