diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp index f2196aff..6c72335e 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp @@ -39,6 +39,7 @@ #include "Components/PrimitiveComponent.h" #include "Components/SphereComponent.h" #include "Kismet/KismetMathLibrary.h" +#include "UObject/UObjectGlobals.h" #include "SenseGlove/Components/SGGrabComponent.h" #include "SenseGlove/Components/SGTouchComponent.h" @@ -76,6 +77,9 @@ struct ASGPawn::FImpl * Methods ************************/ + void BindRealHandsOverlapEvents(); + void UnbindRealHandsOverlapEvents(); + void BindFingerGrabOverlapEvents(); void UnbindFingerGrabOverlapEvents(); @@ -466,23 +470,29 @@ void ASGPawn::BeginPlay() WristTrackerLeft->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void { HandLeft->SetWorldLocation(Location); + RealHandLeft->SetWorldLocation(Location); }); WristTrackerLeft->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void { HandLeft->SetWorldRotation(Rotation); + RealHandLeft->SetWorldRotation(Rotation); }); WristTrackerRight->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void { HandRight->SetWorldLocation(Location); + RealHandRight->SetWorldLocation(Location); }); WristTrackerRight->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void { HandRight->SetWorldRotation(Rotation); + RealHandRight->SetWorldRotation(Rotation); }); + Pimpl->BindRealHandsOverlapEvents(); + Pimpl->BindFingerGrabOverlapEvents(); Pimpl->BindFingerTouchOverlapEvents(); } @@ -491,6 +501,8 @@ void ASGPawn::EndPlay(const EEndPlayReason::Type EndPlayReason) { Super::EndPlay(EndPlayReason); + Pimpl->UnbindRealHandsOverlapEvents(); + Pimpl->UnbindFingerGrabOverlapEvents(); Pimpl->UnbindFingerTouchOverlapEvents(); } @@ -511,6 +523,93 @@ void ASGPawn::PreInitializeComponents() WristTrackerRight->SetRight(HandRight->IsRight()); } +void ASGPawn::PostInitializeComponents() +{ + Super::PostInitializeComponents(); + + RealHandLeft = DuplicateObject(HandLeft, this, FName(TEXT("RealHandLeft"))); + if (ensureAlwaysMsgf(IsValid(RealHandLeft), TEXT("failed to duplicate the left hand!"))) + { + RealHandLeft->SetupAttachment(GetRootComponent()); + RealHandLeft->SetCanEverAffectNavigation(false); + RealHandLeft->SetCollisionObjectType(ECC_WorldDynamic); + RealHandLeft->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + RealHandLeft->SetCollisionResponseToAllChannels(ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Visibility, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap); + } + + RealHandRight = DuplicateObject(HandRight, this, FName(TEXT("RealHandRight"))); + if (ensureAlwaysMsgf(IsValid(RealHandRight), TEXT("failed to duplicate the right hand!"))) + { + RealHandRight->SetupAttachment(GetRootComponent()); + RealHandRight->SetCanEverAffectNavigation(false); + RealHandRight->SetCollisionObjectType(ECC_WorldDynamic); + RealHandRight->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + RealHandRight->SetCollisionResponseToAllChannels(ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Visibility, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap); + } +} + +void ASGPawn::OnRealLeftHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; +} + +void ASGPawn::OnRealLeftHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherBodyIndex; +} + +void ASGPawn::OnRealRightHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; +} + +void ASGPawn::OnRealRightHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherBodyIndex; +} + void ASGPawn::OnLeftThumbFingertipGrabColliderOverlapBegins( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, @@ -1214,6 +1313,22 @@ ASGPawn::FImpl::FImpl(ASGPawn* InOwner) { } +void ASGPawn::FImpl::BindRealHandsOverlapEvents() +{ + Owner->RealHandLeft->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRealLeftHandOverlapBegins); + Owner->RealHandRight->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRealRightHandOverlapBegins); +} + +void ASGPawn::FImpl::UnbindRealHandsOverlapEvents() +{ + Owner->RealHandLeft->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRealLeftHandOverlapEnds); + Owner->RealHandRight->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRealRightHandOverlapEnds); +} + void ASGPawn::FImpl::BindFingerGrabOverlapEvents() { Owner->LeftThumbFingertipGrabCollider->OnComponentBeginOverlap.AddDynamic( diff --git a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h index 21bb6769..4e790303 100644 --- a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h +++ b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h @@ -157,6 +157,12 @@ private: int32 MaxNumberOfHandVelocitySamples; private: + UPROPERTY(Transient) + USGVirtualHandComponent* RealHandLeft; + + UPROPERTY(Transient) + USGVirtualHandComponent* RealHandRight; + UPROPERTY(Transient) FSGGrabState LeftHandGrabState; @@ -290,8 +296,41 @@ public: virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void Tick(float DeltaSeconds) override; virtual void PreInitializeComponents() override; + virtual void PostInitializeComponents() override; protected: + UFUNCTION() + virtual void OnRealLeftHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRealLeftHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRealRightHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRealRightHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + UFUNCTION() virtual void OnLeftThumbFingertipGrabColliderOverlapBegins( UPrimitiveComponent* OverlappedComponent,