add a partial workaround for a bug when the virtual hand inside the game is not visible but still have collisions with other objects inside the scene

This commit is contained in:
Mamadou Babaei
2024-08-16 18:02:05 +02:00
parent 246c78ff2f
commit 2e691c96c9
7 changed files with 81 additions and 52 deletions
+5 -1
View File
@@ -26,6 +26,10 @@ This is a minor release focusing mainly on bringing OpenXR-compatible hand track
- Added the SenseGloveDebugKismet module in order to allow drawing of debugging gizmos and virtual hands from Blueprint.
- Added a new static Draw() method overload to DebugGizmo which allows passing an FQuat instead of a FRotator.
### Fixed
- Fixed a bug when the virtual hand inside the game is not visible but still have collisions with other objects inside the scene.
### Changed
- The SGSettings has been fully revamped with more customizations added and categorized in a different manner.
@@ -33,7 +37,7 @@ This is a minor release focusing mainly on bringing OpenXR-compatible hand track
- The SenseGlove libraries have been updated to v2.103.0-4a8bd81d.
- GetHandPose() has been replaced by GetMotionControllerData inside USGVirtualHandComponent (see the relevant entry in the Added and Removed sections).
- Many functions inside USGVirtualHandComponent for retrieving bone names or reference transforms has been renamed to return different data types; e.g. GetLeftHandFingerBoneNames(), GetRightHandFingerBoneNames(), GetLeftHandFingerBoneName(), and GetRightHandFingerBoneName() renamed to GetLeftHandBoneNames(), GetRightHandBoneNames(), GetLeftHandBoneName(), and GetRightHandBoneName() respectively.
- bHiddenInGameIfNoGloveDetected UPROPERTY from USGVirtualHandComponent has been renamed to bHiddenInGameIfNoHandDataAvailable and accordingly all of its getters and setters.
- bHiddenInGameIfNoGloveDetected UPROPERTY from USGVirtualHandComponent has been renamed to bVisibleWhenHandDataUnavailable and accordingly all of its getters and setters; bVisibleWhenHandDataUnavailable = false now acts as bHiddenInGameIfNoGloveDetected = true, and vice-versa.
- SGWristTrackerComponent now uses FXRMotionControllerData for wrist tracking instead of caluclating the wrist location by calling the SenseGlove API.
- FSGVirtualHandAnimInstanceProxy now relies on FXRMotionControllerData to animate the hands instead of a TMap of bone names and rotations which allows it to also apply the bone locations.
- FSGDebugVirtualHand::Draw now accepts a FXRMotionControllerData parameter instead of all WristLocation, WristRotation, JointPositions, and JointRotations parameters.
@@ -88,6 +88,12 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
return FAnimInstanceProxy::Evaluate(Output);
}
const bool bIsVisible = VirtualHand->IsVisible() && VirtualHand->GetVisibleFlag();
if (!bIsVisible)
{
return FAnimInstanceProxy::Evaluate(Output);
}
const USkeletalMesh* HandMesh{VirtualHand->GetSkeletalMeshAsset()};
if (!IsValid(HandMesh))
{
@@ -39,6 +39,7 @@
#include "Animation/Skeleton.h"
#include "Components/SkeletalMeshComponent.h"
#include "Engine/Engine.h"
#include "Engine/EngineTypes.h"
#include "Engine/SkeletalMesh.h"
#include "InputCoreTypes.h"
#include "IXRTrackingSystem.h"
@@ -94,6 +95,12 @@ struct USGVirtualHandComponent::FImpl
return Settings->GetTrackingSettings().VirtualHandTrackingSettings;
}
/************************
* Member variables
************************/
FCollisionResponseContainer CachedCollisionResponse;
/************************
* Owner object
************************/
@@ -130,12 +137,11 @@ struct USGVirtualHandComponent::FImpl
USkeleton* GetSkeleton() const;
const FReferenceSkeleton& GetRefSkeleton() const;
void UpdateGloveVisibility() const;
void DisableCollisionResponse();
void RestoreCollisionResponse() const;
FORCEINLINE void SetVisibility(const bool bInVisible) const
{
Owner->SetVisibility(bInVisible, true);
}
void SetVisibility(const bool bInVisible);
void UpdateVisibility();
void DrawDebugVirtualHand() const;
};
@@ -202,7 +208,7 @@ USGVirtualHandComponent::USGVirtualHandComponent(const FObjectInitializer& Objec
Super::SetAnimClass(USGVirtualHandAnimInstance::StaticClass());
bRight = true;
bHiddenInGameIfNoHandDataAvailable = false;
bVisibleWhenHandDataUnavailable = false;
AnimationBoneRotationCorrectionOffset = FRotator{0.0f, 90.0f, 90.0f};
bAnimationShouldApplyBoneLocation = true;
@@ -289,7 +295,7 @@ void USGVirtualHandComponent::InitializeComponent()
Pimpl->SetDefaultMesh();
}
Pimpl->UpdateGloveVisibility();
Pimpl->UpdateVisibility();
}
void USGVirtualHandComponent::UninitializeComponent()
@@ -308,7 +314,7 @@ void USGVirtualHandComponent::BeginPlay()
{
Super::BeginPlay();
Pimpl->UpdateGloveVisibility();
Pimpl->UpdateVisibility();
}
void USGVirtualHandComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
@@ -336,7 +342,7 @@ void USGVirtualHandComponent::TickComponent(
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
Pimpl->UpdateGloveVisibility();
Pimpl->UpdateVisibility();
if (DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
{
@@ -359,7 +365,7 @@ void USGVirtualHandComponent::SetSkeletalMesh(USkeletalMesh* NewMesh, const bool
void USGVirtualHandComponent::EditorTick(
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Pimpl->UpdateGloveVisibility();
Pimpl->UpdateVisibility();
if (DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
{
@@ -582,36 +588,49 @@ const FReferenceSkeleton& USGVirtualHandComponent::FImpl::GetRefSkeleton() const
return Mesh->GetRefSkeleton();
}
void USGVirtualHandComponent::FImpl::UpdateGloveVisibility() const
void USGVirtualHandComponent::FImpl::DisableCollisionResponse()
{
FXRMotionControllerData MotionControllerData;
const bool bGotMotionControllerData = Owner->GetMotionControllerData(MotionControllerData);
const bool bIsHandDataAvailable = bGotMotionControllerData && MotionControllerData.bValid;
const bool bIsVisible = Owner->IsVisible();
CachedCollisionResponse = Owner->GetCollisionResponseToChannels();
Owner->SetCollisionResponseToAllChannels(ECR_Ignore);
}
if (Owner->bHiddenInGameIfNoHandDataAvailable)
void USGVirtualHandComponent::FImpl::RestoreCollisionResponse() const
{
Owner->SetCollisionResponseToChannels(CachedCollisionResponse);
}
void USGVirtualHandComponent::FImpl::SetVisibility(const bool bInVisible)
{
Owner->SetVisibility(bInVisible, true);
if (bInVisible)
{
if (bIsHandDataAvailable)
{
if (!bIsVisible)
{
SetVisibility(true);
}
}
else
{
if (bIsVisible)
{
SetVisibility(false);
}
}
RestoreCollisionResponse();
}
else
{
if (!bIsVisible)
{
SetVisibility(true);
}
DisableCollisionResponse();
}
}
void USGVirtualHandComponent::FImpl::UpdateVisibility()
{
const bool bUpdateVisibility = !Owner->IsVisibleWhenHandDataUnavailable();
if (!bUpdateVisibility)
{
return;
}
FXRMotionControllerData MotionControllerData;
const bool bGotMotionControllerData = Owner->GetMotionControllerData(MotionControllerData);
const bool bHandDataAvailable = bGotMotionControllerData && MotionControllerData.bValid;
const bool bVisibleHand = Owner->GetVisibleFlag();
const bool bSetNewVisibility =
(bHandDataAvailable && !bVisibleHand) || (!bHandDataAvailable && bVisibleHand);
if (bSetNewVisibility)
{
SetVisibility(bHandDataAvailable);
}
}
@@ -208,7 +208,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
HandLeft->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
HandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
HandLeft->SetRight(false);
HandLeft->SetHiddenIfNoHandDataAvailable(true);
HandLeft->SetVisibleWhenHandDataUnavailable(false);
HandLeft->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
HandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f},
@@ -232,7 +232,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
RealHandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap);
RealHandLeft->SetRight(false);
Pimpl->SetVisibility(RealHandLeft, false);
RealHandLeft->SetHiddenIfNoHandDataAvailable(true);
RealHandLeft->SetVisibleWhenHandDataUnavailable(false);
RealHandLeft->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
RealHandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f},
@@ -430,7 +430,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
HandRight->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
HandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
HandRight->SetRight(true);
HandRight->SetHiddenIfNoHandDataAvailable(true);
HandRight->SetVisibleWhenHandDataUnavailable(false);
HandRight->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
HandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f},
@@ -454,7 +454,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
RealHandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap);
RealHandRight->SetRight(true);
Pimpl->SetVisibility(RealHandRight, false);
RealHandRight->SetHiddenIfNoHandDataAvailable(true);
RealHandRight->SetVisibleWhenHandDataUnavailable(false);
RealHandRight->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
RealHandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f},
@@ -85,7 +85,7 @@ private:
uint8 bRight : 1;
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
uint8 bHiddenInGameIfNoHandDataAvailable : 1;
uint8 bVisibleWhenHandDataUnavailable : 1;
UPROPERTY(EditAnywhere, Category="SenseGlove | Animation", meta=(AllowPrivateAccess="false"))
FRotator AnimationBoneRotationCorrectionOffset;
@@ -290,14 +290,14 @@ public:
DebugVirtualHandSettings = InDebugVirtualHandSettings;
}
FORCEINLINE bool IsHiddenInGameIfNoHandDataAvailable() const
FORCEINLINE bool IsVisibleWhenHandDataUnavailable() const
{
return !!bHiddenInGameIfNoHandDataAvailable;
return !!bVisibleWhenHandDataUnavailable;
}
FORCEINLINE void SetHiddenIfNoHandDataAvailable(const bool bInHiddenIfNoHandDataAvailable)
FORCEINLINE void SetVisibleWhenHandDataUnavailable(const bool bInVisibleWhenHandDataUnavailable)
{
bHiddenInGameIfNoHandDataAvailable = bInHiddenIfNoHandDataAvailable;
bVisibleWhenHandDataUnavailable = bInVisibleWhenHandDataUnavailable;
}
FORCEINLINE void SetWristTracker(USGWristTrackerComponent* InWristTracker)
@@ -74,16 +74,16 @@ void UVirtualHandComponentKismetLibrary::SetRight(
VirtualHandComponent->SetRight(bInRight);
}
bool UVirtualHandComponentKismetLibrary::IsHiddenInGameIfNoHandDataAvailable(
bool UVirtualHandComponentKismetLibrary::IsVisibleWhenHandDataUnavailable(
const USGVirtualHandComponent* VirtualHandComponent)
{
return VirtualHandComponent->IsHiddenInGameIfNoHandDataAvailable();
return VirtualHandComponent->IsVisibleWhenHandDataUnavailable();
}
void UVirtualHandComponentKismetLibrary::SetHiddenIfNoHandDataAvailable(
USGVirtualHandComponent* VirtualHandComponent, const bool bInHiddenIfNoHandDataAvailable)
void UVirtualHandComponentKismetLibrary::SetVisibleWhenHandDataUnavailable(
USGVirtualHandComponent* VirtualHandComponent, const bool bInIsVisibleWhenHandDataUnavailable)
{
VirtualHandComponent->SetHiddenIfNoHandDataAvailable(bInHiddenIfNoHandDataAvailable);
VirtualHandComponent->SetVisibleWhenHandDataUnavailable(bInIsVisibleWhenHandDataUnavailable);
}
const FRotator& UVirtualHandComponentKismetLibrary::GetAnimationBoneRotationCorrectionOffset(
@@ -81,11 +81,11 @@ public:
static void SetRight(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent, bool bInRight);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static bool IsHiddenInGameIfNoHandDataAvailable(const USGVirtualHandComponent* VirtualHandComponent);
static bool IsVisibleWhenHandDataUnavailable(const USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static void SetHiddenIfNoHandDataAvailable(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
bool bInHiddenIfNoHandDataAvailable);
static void SetVisibleWhenHandDataUnavailable(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
bool bInIsVisibleWhenHandDataUnavailable);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static const FRotator& GetAnimationBoneRotationCorrectionOffset(