replace QueueVibroLevels with SendCustomWaveform

This commit is contained in:
Mamadou Babaei
2025-09-17 08:02:22 +02:00
parent 3819c6e62a
commit cfde08d744
7 changed files with 126 additions and 157 deletions
@@ -103,8 +103,9 @@ USGTouchComponent::USGTouchComponent(const FObjectInitializer& ObjectInitializer
{
ForceFeedbackLevel = 1.0f;
VibrotactileDuration = 0.25f;
VibrotactileLevel = 0.0f;
VibrotactileAmplitude = 1.0f;
VibrotactileDuration = 1.0f;
VibrotactileFrequency= 500.0f;
}
USGTouchComponent::FImpl::FImpl(USGTouchComponent* InOwner)
@@ -36,8 +36,6 @@
#include "SenseGlove/GameFramework/SGPlayerController.h"
#include "Runtime/Launch/Resources/Version.h"
#include "Engine/TimerHandle.h"
#include "TimerManager.h"
#include "SenseGlove/Components/SGTouchComponent.h"
#include "SenseGlove/Components/SGVirtualHandComponent.h"
@@ -45,6 +43,7 @@
#include "SenseGlove/Haptics/SGGrabState.h"
#include "SenseGlove/Haptics/SGTouchState.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGCore/SGCustomWaveform.h"
#include "SGCore/SGHapticGlove.h"
struct ASGPlayerController::FImpl
@@ -55,11 +54,6 @@ struct ASGPlayerController::FImpl
static float GetForceFeedbackLevel(const AActor* Actor);
static float GetVibrotactileDuration(const AActor* ActorThumbTouching, const AActor* ActorIndexTouching,
const AActor* ActorMiddleTouching, const AActor* ActorRingTouching,
const AActor* ActorPinkyTouching);
static float GetVibrotactileLevel(const AActor* Actor);
static TArray<float> GetForceFeedbackLevels(
const AActor* ActorThumbTouching,
const AActor* ActorIndexTouching,
@@ -67,19 +61,10 @@ struct ASGPlayerController::FImpl
const AActor* ActorRingTouching,
const AActor* ActorPinkyTouching);
static TArray<float> GetVibrotactileLevels(
const AActor* ActorThumbTouching,
const AActor* ActorIndexTouching,
const AActor* ActorMiddleTouching,
const AActor* ActorRingTouching,
const AActor* ActorPinkyTouching);
/************************
* Member variables
************************/
FTimerHandle TouchVibrotactileStopTimer;
/************************
* Owner object
************************/
@@ -104,6 +89,8 @@ struct ASGPlayerController::FImpl
* Methods
************************/
USGCustomWaveform* GetCustomWaveform(const AActor* Actor);
void UpdateHapticsFeedback(const FSGTouchState& TouchState);
};
@@ -121,74 +108,6 @@ float ASGPlayerController::FImpl::GetForceFeedbackLevel(const AActor* Actor)
return 0.0f;
}
float ASGPlayerController::FImpl::GetVibrotactileDuration(const AActor* ActorThumbTouching,
const AActor* ActorIndexTouching,
const AActor* ActorMiddleTouching,
const AActor* ActorRingTouching,
const AActor* ActorPinkyTouching)
{
if (IsValid(ActorThumbTouching))
{
const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorThumbTouching);
if (IsValid(TouchComponent))
{
return TouchComponent->GetVibrotactileDuration();
}
}
if (IsValid(ActorIndexTouching))
{
const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorIndexTouching);
if (IsValid(TouchComponent))
{
return TouchComponent->GetVibrotactileDuration();
}
}
if (IsValid(ActorMiddleTouching))
{
const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorMiddleTouching);
if (IsValid(TouchComponent))
{
return TouchComponent->GetVibrotactileDuration();
}
}
if (IsValid(ActorRingTouching))
{
const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorRingTouching);
if (IsValid(TouchComponent))
{
return TouchComponent->GetVibrotactileDuration();
}
}
if (IsValid(ActorPinkyTouching))
{
const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorPinkyTouching);
if (IsValid(TouchComponent))
{
return TouchComponent->GetVibrotactileDuration();
}
}
return 0.0f;
}
float ASGPlayerController::FImpl::GetVibrotactileLevel(const AActor* Actor)
{
if (IsValid(Actor))
{
const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(Actor);
if (IsValid(TouchComponent))
{
return TouchComponent->GetVibrotactileLevel();
}
}
return 0.0f;
}
TArray<float> ASGPlayerController::FImpl::GetForceFeedbackLevels(
const AActor* ActorThumbTouching,
const AActor* ActorIndexTouching,
@@ -213,30 +132,6 @@ TArray<float> ASGPlayerController::FImpl::GetForceFeedbackLevels(
return ForceFeedbackLevels;
}
TArray<float> ASGPlayerController::FImpl::GetVibrotactileLevels(
const AActor* ActorThumbTouching,
const AActor* ActorIndexTouching,
const AActor* ActorMiddleTouching,
const AActor* ActorRingTouching,
const AActor* ActorPinkyTouching)
{
const float ThumbVibrotactileLevel = GetVibrotactileLevel(ActorThumbTouching);
const float IndexVibrotactileLevel = GetVibrotactileLevel(ActorIndexTouching);
const float MiddleVibrotactileLevel = GetVibrotactileLevel(ActorMiddleTouching);
const float RingVibrotactileLevel = GetVibrotactileLevel(ActorRingTouching);
const float PinkyVibrotactileLevel = GetVibrotactileLevel(ActorPinkyTouching);
const TArray<float> ForceFeedbackLevels{
ThumbVibrotactileLevel,
IndexVibrotactileLevel,
MiddleVibrotactileLevel,
RingVibrotactileLevel,
PinkyVibrotactileLevel,
};
return ForceFeedbackLevels;
}
ASGPlayerController::ASGPlayerController(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
@@ -330,6 +225,29 @@ ASGPlayerController::FImpl::FImpl(ASGPlayerController* InOwner)
ASGPlayerController::FImpl::~FImpl() = default;
USGCustomWaveform* ASGPlayerController::FImpl::GetCustomWaveform(const AActor* Actor)
{
float Amplitude = 0.0f;
float Duration = 0.0f;
float Frequency = 0.0f;
if (IsValid(Actor))
{
const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(Actor);
if (IsValid(TouchComponent))
{
Amplitude = TouchComponent->GetVibrotactileAmplitude();
Duration = TouchComponent->GetVibrotactileDuration();
Frequency = TouchComponent->GetVibrotactileFrequency();
}
}
USGCustomWaveform* CustomWaveform{
USGCustomWaveform::NewCustomWaveform(Owner, Amplitude, Duration, Frequency)
};
return CustomWaveform;
}
void ASGPlayerController::FImpl::UpdateHapticsFeedback(const FSGTouchState& TouchState)
{
static const TArray<float> VibrotactileOffCommand{0.0f, 0.0f, 0.0, 0.0, 0.0f};
@@ -359,44 +277,43 @@ void ASGPlayerController::FImpl::UpdateHapticsFeedback(const FSGTouchState& Touc
};
Glove->QueueForceFeedbackLevels(MoveTemp(ForceFeedbackLevels));
// Queue the Vibrotactile command...
TArray<float> VibrotactileLevels{
GetVibrotactileLevels(
TouchState.ActorThumbTouching, TouchState.ActorIndexTouching, TouchState.ActorMiddleTouching,
TouchState.ActorRingTouching, TouchState.ActorPinkyTouching)
};
Glove->QueueVibroLevels(MoveTemp(VibrotactileLevels));
// Send the haptics commands!
Glove->SendHaptics();
// Stop the Vibrotactile command after the timeout if any haptic feedback is ongoing.
const float VibrotactileDuration = FImpl::GetVibrotactileDuration(
TouchState.ActorThumbTouching, TouchState.ActorIndexTouching, TouchState.ActorMiddleTouching,
TouchState.ActorRingTouching, TouchState.ActorPinkyTouching);
Owner->GetWorldTimerManager().ClearTimer(TouchVibrotactileStopTimer);
FTimerDelegate TouchVibrotactileStopHandler;
TouchVibrotactileStopHandler.BindLambda([= SG_CAPTURE_THIS]()-> void
// Send Vibrotactile to the thumb finger if it's touching an actor...
if (IsValid(TouchState.ActorThumbTouching))
{
if (!IsValid(Glove))
{
return;
}
USGCustomWaveform* CustomWaveform(GetCustomWaveform(TouchState.ActorThumbTouching));
Glove->SendCustomWaveform(CustomWaveform, ESGHapticLocation::ThumbTip);
}
const bool bGloveConnected = Glove->IsConnected();
if (!bGloveConnected)
{
return;
}
// Send Vibrotactile to the index finger if it's touching an actor...
if (IsValid(TouchState.ActorIndexTouching))
{
USGCustomWaveform* CustomWaveform(GetCustomWaveform(TouchState.ActorIndexTouching));
Glove->SendCustomWaveform(CustomWaveform, ESGHapticLocation::IndexTip);
}
Glove->QueueVibroLevels(VibrotactileOffCommand);
Glove->SendHaptics();
});
// Send Vibrotactile to the middle finger if it's touching an actor...
if (IsValid(TouchState.ActorMiddleTouching))
{
USGCustomWaveform* CustomWaveform(GetCustomWaveform(TouchState.ActorMiddleTouching));
Glove->SendCustomWaveform(CustomWaveform, ESGHapticLocation::MiddleTip);
}
Owner->GetWorldTimerManager().SetTimer(
TouchVibrotactileStopTimer, TouchVibrotactileStopHandler, VibrotactileDuration, false, -1.0f);
// Send Vibrotactile to the ring finger if it's touching an actor...
if (IsValid(TouchState.ActorRingTouching))
{
USGCustomWaveform* CustomWaveform(GetCustomWaveform(TouchState.ActorRingTouching));
Glove->SendCustomWaveform(CustomWaveform, ESGHapticLocation::RingTip);
}
// Send Vibrotactile to the pinky finger if it's touching an actor...
if (IsValid(TouchState.ActorPinkyTouching))
{
USGCustomWaveform* CustomWaveform(GetCustomWaveform(TouchState.ActorPinkyTouching));
Glove->SendCustomWaveform(CustomWaveform, ESGHapticLocation::PinkyTip);
}
}
void ASGPlayerController::FImplDeleter::operator()(const FImpl* P) const
@@ -57,12 +57,17 @@ private:
meta=(AllowPrivateAccess="false", ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0"))
float ForceFeedbackLevel;
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false", ClampMin = "0.0", UIMin = "0.0"))
UPROPERTY(EditAnywhere, Category="SenseGlove",
meta=(AllowPrivateAccess="false", ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0"))
float VibrotactileAmplitude;
UPROPERTY(EditAnywhere, Category="SenseGlove",
meta=(AllowPrivateAccess="false", ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0"))
float VibrotactileDuration;
UPROPERTY(EditAnywhere, Category="SenseGlove",
meta=(AllowPrivateAccess="false", ClampMin = "0.0", ClampMax = "100.0", UIMin = "0.0", UIMax = "100.0"))
float VibrotactileLevel;
meta=(AllowPrivateAccess="false", ClampMin = "10.0", ClampMax = "500.0", UIMin = "10.0", UIMax = "500.0"))
float VibrotactileFrequency;
private:
struct FImpl;
@@ -86,6 +91,16 @@ public:
ForceFeedbackLevel = Level;
}
FORCEINLINE float GetVibrotactileAmplitude() const
{
return VibrotactileAmplitude;
}
FORCEINLINE void SetVibrotactileAmplitude(const float Amplitude)
{
VibrotactileAmplitude = Amplitude;
}
FORCEINLINE float GetVibrotactileDuration() const
{
return VibrotactileDuration;
@@ -95,13 +110,14 @@ public:
{
VibrotactileDuration = Duration;
}
FORCEINLINE float GetVibrotactileLevel() const
FORCEINLINE float GetVibrotactileFrequency() const
{
return VibrotactileLevel;
return VibrotactileFrequency;
}
FORCEINLINE void SetVibrotactileLevel(const float Level)
FORCEINLINE void SetVibrotactileFrequency(const float Frequency)
{
VibrotactileLevel = Level;
VibrotactileFrequency = Frequency;
}
};
@@ -60,14 +60,14 @@ void UTouchComponentKismetLibrary::SetForceFeedbackLevel(USGTouchComponent* Touc
TouchComponent->SetForceFeedbackLevel(Level);
}
float UTouchComponentKismetLibrary::GetVibrotactileLevel(const USGTouchComponent* TouchComponent)
float UTouchComponentKismetLibrary::GetVibrotactileAmplitude(const USGTouchComponent* TouchComponent)
{
return TouchComponent->GetVibrotactileLevel();
return TouchComponent->GetVibrotactileAmplitude();
}
void UTouchComponentKismetLibrary::SetVibrotactileLevel(USGTouchComponent* TouchComponent, const float Level)
void UTouchComponentKismetLibrary::SetVibrotactileAmplitude(USGTouchComponent* TouchComponent, const float Amplitude)
{
TouchComponent->SetVibrotactileLevel(Level);
TouchComponent->SetVibrotactileAmplitude(Amplitude);
}
float UTouchComponentKismetLibrary::GetVibrotactileDuration(const USGTouchComponent* TouchComponent)
@@ -78,4 +78,15 @@ float UTouchComponentKismetLibrary::GetVibrotactileDuration(const USGTouchCompon
void UTouchComponentKismetLibrary::SetVibrotactileDuration(USGTouchComponent* TouchComponent, const float Duration)
{
TouchComponent->SetVibrotactileDuration(Duration);
}
}
float UTouchComponentKismetLibrary::GetVibrotactileFrequency(const USGTouchComponent* TouchComponent)
{
return TouchComponent->GetVibrotactileFrequency();
}
void UTouchComponentKismetLibrary::SetVibrotactileFrequency(USGTouchComponent* TouchComponent, const float Frequency)
{
TouchComponent->SetVibrotactileFrequency(Frequency);
}
@@ -61,14 +61,20 @@ public:
static void SetForceFeedbackLevel(UPARAM(ref) USGTouchComponent* TouchComponent, float Level);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Touch Component")
static float GetVibrotactileLevel(const USGTouchComponent* TouchComponent);
static float GetVibrotactileAmplitude(const USGTouchComponent* TouchComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component")
static void SetVibrotactileLevel(UPARAM(ref) USGTouchComponent* TouchComponent, float Level);
static void SetVibrotactileAmplitude(UPARAM(ref) USGTouchComponent* TouchComponent, float Amplitude);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Touch Component")
static float GetVibrotactileDuration(const USGTouchComponent* TouchComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component")
static void SetVibrotactileDuration(UPARAM(ref) USGTouchComponent* TouchComponent, float Duration);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Touch Component")
static float GetVibrotactileFrequency(const USGTouchComponent* TouchComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component")
static void SetVibrotactileFrequency(UPARAM(ref) USGTouchComponent* TouchComponent, float Frequency);
};