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:28:25 +02:00
parent 5f53937a69
commit b9574734d3
5 changed files with 43 additions and 52 deletions
@@ -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
@@ -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);
}
@@ -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<FVector>& InHandVelocityHistory,
AActor* InActorThumbCanGrab,
AActor* InActorIndexCanGrab,
AActor* InActorMiddleCanGrab,
AActor* InGrabbedActor,
const FVector& InPreviousLocation,
const TArray<FVector>& InReleaseVelocities)
AActor* InGrabbedActor)
: Hand(InHand),
PreviousHandLocation(InPreviousHandLocation),
HandVelocityHistory(InHandVelocityHistory),
ActorThumbCanGrab(InActorThumbCanGrab),
ActorIndexCanGrab(InActorIndexCanGrab),
ActorMiddleCanGrab(InActorMiddleCanGrab),
GrabbedActor(InGrabbedActor),
PreviousLocation(InPreviousLocation),
ReleaseVelocities(InReleaseVelocities)
GrabbedActor(InGrabbedActor)
{
}
@@ -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:
@@ -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<FVector> 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<FVector> ReleaseVelocities;
public:
FSGGrabState();
explicit FSGGrabState(USGVirtualHandComponent* InHand,
const FVector& InPreviousHandLocation,
const TArray<FVector>& InHandVelocityHistory,
AActor* InActorThumbCanGrab,
AActor* InActorIndexCanGrab,
AActor* InActorMiddleCanGrab,
AActor* InGrabbedActor,
const FVector& InPreviousLocation,
const TArray<FVector>& InReleaseVelocities);
AActor* InGrabbedActor);
};