diff --git a/Source/SenseGlove/Private/SenseGlove/Components/SGWristTrackerComponent.cpp b/Source/SenseGlove/Private/SenseGlove/Components/SGWristTrackerComponent.cpp new file mode 100644 index 00000000..f73e6fe0 --- /dev/null +++ b/Source/SenseGlove/Private/SenseGlove/Components/SGWristTrackerComponent.cpp @@ -0,0 +1,697 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2023 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Components/SGWristTrackerComponent.h" + +#include "Animation/Skeleton.h" +#include "Components/SkeletalMeshComponent.h" +#include "Engine/SkeletalMesh.h" +#include "UObject/ConstructorHelpers.h" + +#include "SGConnect/SGConnect.h" +#include "SGCore/SGDeviceList.h" +#include "SGCore/SGHapticGlove.h" +#include "SGCore/SGHapticGloveHandProfiles.h" +#include "SGLog/SGLog.h" +#include "SGSettings/SGSettings.h" + +struct USGWristTrackerComponent::FImpl +{ + /************************ + * Static methods + ************************/ + + /************************ + * Owner object + ************************/ + + USGWristTrackerComponent* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGWristTrackerComponent* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + bool IsEditor() const; + + bool InitializeBackend() const; + bool UninitializeBackend() const; + bool CheckGlove() const; +}; + +USGWristTrackerComponent::USGWristTrackerComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + PrimaryComponentTick.bTickEvenWhenPaused = false; + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + bTickInEditor = true; + bNeverNeedsRenderUpdate = true; + bAllowConcurrentTick = true; + + SetCastShadow(false); + SetCastHiddenShadow(false); + bCastDynamicShadow = false; + SetOnlyOwnerSee(false); + SetReceivesDecals(false); + SetCanEverAffectNavigation(false); + + SetRight(true); + + bOverridePluginWristTrackingSettings = false; + bDrawDebugWristTrackerGizmo = false; + HardwareOffset = ESGPositionalTrackingHardware::None; + HardwareLocationOffset = FVector::ZeroVector; + HardwareLocationOffset = FVector::ZeroVector; + + bOverridePluginWristTrackingDebugSettings = false; + bDrawDebugWristTrackerGizmo = false; + DebugWristTrackerGizmoLength = 1.0f; + DebugWristTrackerGizmoXAxisColor = FColor::Red; + DebugWristTrackerGizmoYAxisColor = FColor::Green; + DebugWristTrackerGizmoZAxisColor = FColor::Blue; + bDebugWristTrackerGizmoPersistentLines = false; + DebugWristTrackerGizmoLifeTimeModifier = 1.1f; + DebugWristTrackerGizmoDepthPriority = 0; + DebugWristTrackerGizmoThickness = 1.0f; + + bBackendInitialized = false; + Glove = nullptr; + WristLocation = FVector::ZeroVector; + WristRotation = FRotator::ZeroRotator; +} + +void USGWristTrackerComponent::SetRight(const bool bRight) +{ + SetTrackingSource(bRight ? EControllerHand::Right : EControllerHand::Left); +} + +ESGPositionalTrackingHardware USGWristTrackerComponent::GetHardwareOffset() const +{ + if (OverridesPluginWristTrackingSettings()) + { + return HardwareOffset; + } + + return USGSettings::GetInstance()->GetHardwareOffset(); +} + +void USGWristTrackerComponent::SetHardwareOffset(const ESGPositionalTrackingHardware InHardwareOffset) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingSettings(), + TEXT( "Setting HardwareOffset is only permitted when bOverridePluginWristTrackingSettings is enabled!")); + + HardwareOffset = InHardwareOffset; +} + +const FVector& USGWristTrackerComponent::GetHardwareLocationOffset() const +{ + ensureAlwaysMsgf( + GetHardwareOffset() == ESGPositionalTrackingHardware::Custom, + TEXT( "Getting HardwareLocationOffset is only permitted when HardwareOffset is set to Custom!")); + + if (OverridesPluginWristTrackingSettings()) + { + return HardwareLocationOffset; + } + + return IsRight() + ? USGSettings::GetInstance()->GetHardwareLocationOffsetRightHand() + : USGSettings::GetInstance()->GetHardwareLocationOffsetLeftHand(); +} + +void USGWristTrackerComponent::SetHardwareLocationOffset(const FVector& InHardwareLocationOffset) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingSettings(), + TEXT( "Setting HardwareLocationOffset is only permitted when bOverridePluginWristTrackingSettings is enabled!" + )); + + ensureAlwaysMsgf( + GetHardwareOffset() == ESGPositionalTrackingHardware::Custom, + TEXT( "Setting HardwareLocationOffset is only permitted when HardwareOffset is set to Custom!")); + + HardwareLocationOffset = InHardwareLocationOffset; +} + +const FRotator& USGWristTrackerComponent::GetHardwareRotationOffset() const +{ + ensureAlwaysMsgf( + GetHardwareOffset() == ESGPositionalTrackingHardware::Custom, + TEXT( "Getting HardwareRotationOffset is only permitted when HardwareOffset is set to Custom!")); + + if (OverridesPluginWristTrackingSettings()) + { + return HardwareRotationOffset; + } + + return IsRight() + ? USGSettings::GetInstance()->GetHardwareRotationOffsetRightHand() + : USGSettings::GetInstance()->GetHardwareRotationOffsetLeftHand(); +} + +void USGWristTrackerComponent::SetHardwareRotationOffset(const FRotator& InHardwareRotationOffset) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingSettings(), + TEXT( "Setting HardwareRotationOffset is only permitted when bOverridePluginWristTrackingSettings is enabled!" + )); + + ensureAlwaysMsgf( + GetHardwareOffset() == ESGPositionalTrackingHardware::Custom, + TEXT("Setting HardwareRotationOffsetRightHand is only permitted when HardwareOffset is set to Custom!")); + + HardwareRotationOffset = InHardwareRotationOffset; +} + +bool USGWristTrackerComponent::GetDrawDebugWristTrackerGizmo() const +{ + if (OverridesPluginWristTrackingDebugSettings()) + { + return !!bDrawDebugWristTrackerGizmo; + } + + return USGSettings::GetInstance()->GetDrawDebugWristTrackerGizmo(); +} + +void USGWristTrackerComponent::SetDrawDebugWristTrackerGizmo(const bool bInDrawDebugWristTrackerGizmo) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT( "Setting bDrawDebugWristTrackerGizmo is only permitted when bOverridePluginWristTrackingDebugSettings is" + " enabled!")); + + bDrawDebugWristTrackerGizmo = bInDrawDebugWristTrackerGizmo; +} + +float USGWristTrackerComponent::GetDebugWristTrackerGizmoLength() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting DebugWristTrackerGizmoLength is only permitted when bDrawDebugWristTrackerGizmo is enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return DebugWristTrackerGizmoLength; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoLength(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoLength(const float InDebugWristTrackerGizmoLength) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoLength is only permitted when bOverridePluginWristTrackingDebugSettings is" + " enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting DebugWristTrackerGizmoLength is only permitted when bDrawDebugWristTrackerGizmo is enabled!")); + + DebugWristTrackerGizmoLength = InDebugWristTrackerGizmoLength; +} + +const FLinearColor& USGWristTrackerComponent::GetDebugWristTrackerGizmoXAxisColor() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting DebugWristTrackerGizmoXAxisColor is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return DebugWristTrackerGizmoXAxisColor; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoXAxisColor(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoXAxisColor( + const FLinearColor& InDebugWristTrackerGizmoXAxisColor) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoXAxisColor is only permitted when bOverridePluginWristTrackingDebugSettings" + " is enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting DebugWristTrackerGizmoXAxisColor is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + DebugWristTrackerGizmoXAxisColor = InDebugWristTrackerGizmoXAxisColor; +} + +const FLinearColor& USGWristTrackerComponent::GetDebugWristTrackerGizmoYAxisColor() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting DebugWristTrackerGizmoYAxisColor is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return DebugWristTrackerGizmoYAxisColor; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoYAxisColor(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoYAxisColor( + const FLinearColor& InDebugWristTrackerGizmoYAxisColor) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoYAxisColor is only permitted when bOverridePluginWristTrackingDebugSettings" + " is enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting DebugWristTrackerGizmoYAxisColor is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + DebugWristTrackerGizmoYAxisColor = InDebugWristTrackerGizmoYAxisColor; +} + +const FLinearColor& USGWristTrackerComponent::GetDebugWristTrackerGizmoZAxisColor() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting DebugWristTrackerGizmoZAxisColor is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return DebugWristTrackerGizmoZAxisColor; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoZAxisColor(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoZAxisColor( + const FLinearColor& InDebugWristTrackerGizmoZAxisColor) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoZAxisColor is only permitted when bOverridePluginWristTrackingDebugSettings" + " is enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting DebugWristTrackerGizmoZAxisColor is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + DebugWristTrackerGizmoZAxisColor = InDebugWristTrackerGizmoZAxisColor; +} + +bool USGWristTrackerComponent::GetDebugWristTrackerGizmoPersistentLines() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting bDebugWristTrackerGizmoPersistentLines is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return !!bDebugWristTrackerGizmoPersistentLines; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoPersistentLines(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoPersistentLines( + const bool bInDebugWristTrackerGizmoPersistentLines) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoPersistentLines is only permitted when" + " bOverridePluginWristTrackingDebugSettings is enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting bDebugWristTrackerGizmoPersistentLines is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + bDebugWristTrackerGizmoPersistentLines = bInDebugWristTrackerGizmoPersistentLines; +} + +float USGWristTrackerComponent::GetDebugWristTrackerGizmoLifeTimeModifier() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting DebugWristTrackerGizmoLifeTimeModifier is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return DebugWristTrackerGizmoLifeTimeModifier; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoLifeTimeModifier(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoLifeTimeModifier( + const float InDebugWristTrackerGizmoLifeTimeModifier) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoLifetimeModifier is only permitted when" + " bOverridePluginWristTrackingDebugSettings is enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting DebugWristTrackerGizmoLifeTimeModifier is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + DebugWristTrackerGizmoLifeTimeModifier = InDebugWristTrackerGizmoLifeTimeModifier; +} + +uint8 USGWristTrackerComponent::GetDebugWristTrackerGizmoDepthPriority() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting DebugWristTrackerGizmoDepthPriority is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return DebugWristTrackerGizmoDepthPriority; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoDepthPriority(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoDepthPriority(const uint8 InDebugWristTrackerGizmoDepthPriority) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoDepthPriority is only permitted when" + " bOverridePluginWristTrackingDebugSettings is enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting DebugWristTrackerGizmoDepthPriority is only permitted when bDrawDebugWristTrackerGizmo is" + " enabled!")); + + DebugWristTrackerGizmoDepthPriority = InDebugWristTrackerGizmoDepthPriority; +} + +float USGWristTrackerComponent::GetDebugWristTrackerGizmoThickness() const +{ + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Getting DebugWristTrackerGizmoThickness is only permitted when bDrawDebugWristTrackerGizmo is enabled!")); + + if (OverridesPluginWristTrackingDebugSettings()) + { + return DebugWristTrackerGizmoThickness; + } + + return USGSettings::GetInstance()->GetDebugWristTrackerGizmoThickness(); +} + +void USGWristTrackerComponent::SetDebugWristTrackerGizmoThickness(float InDebugWristTrackerGizmoThickness) +{ + ensureAlwaysMsgf( + OverridesPluginWristTrackingDebugSettings(), + TEXT("Setting DebugWristTrackerGizmoDepthThickness is only permitted when" + " bOverridePluginWristTrackingDebugSettings is enabled!")); + + ensureAlwaysMsgf( + GetDrawDebugWristTrackerGizmo(), + TEXT("Setting DebugWristTrackerGizmoThickness is only permitted when bDrawDebugWristTrackerGizmo is enabled!")); + + DebugWristTrackerGizmoThickness = InDebugWristTrackerGizmoThickness; +} + +#if WITH_EDITOR +void USGWristTrackerComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + const FName PropertyName{ + PropertyChangedEvent.Property + ? PropertyChangedEvent.Property->GetFName() + : NAME_None + }; + + (void) PropertyName; +} +#endif /* WITH_EDITOR */ + +void USGWristTrackerComponent::InitializeComponent() +{ + Super::InitializeComponent(); + + if (Pimpl->InitializeBackend()) + { + (void) Pimpl->CheckGlove(); + } +} + +void USGWristTrackerComponent::UninitializeComponent() +{ + Super::UninitializeComponent(); + + (void) Pimpl->UninitializeBackend(); +} + +void USGWristTrackerComponent::BeginPlay() +{ + Super::BeginPlay(); + + if (Pimpl->InitializeBackend()) + { + (void) Pimpl->CheckGlove(); + } +} + +void USGWristTrackerComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); + + (void) Pimpl->UninitializeBackend(); +} + +void USGWristTrackerComponent::TickComponent( + const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ +#if WITH_EDITOR + if (Pimpl->IsEditor()) + { + EditorTick(DeltaTime, TickType, ThisTickFunction); + return; + } +#endif /* WITH_EDITOR */ + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + (void) Pimpl->CheckGlove(); +} + + +void USGWristTrackerComponent::EditorTick( + const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + (void) Pimpl->CheckGlove(); +} + +USGWristTrackerComponent::FImpl::FImpl(USGWristTrackerComponent* InOwner) + : Owner(InOwner) +{ +} + +USGWristTrackerComponent::FImpl::~FImpl() = default; + +bool USGWristTrackerComponent::FImpl::IsEditor() const +{ + const UWorld* World{Owner->GetWorld()}; + if (World && (World->WorldType == EWorldType::Editor || World->WorldType == EWorldType::EditorPreview)) + { + return true; + } + + return false; +} + +bool USGWristTrackerComponent::FImpl::InitializeBackend() const +{ + if (!Owner->bBackendInitialized) + { +#if PLATFORM_ANDROID + const int32_t Result = FSGConnect::Init(); + switch (Result) + { + case -3: + SGLOG_ERROR("An Unexpected error occurred. Please try again."); + return false; + case -2: + SGLOG_ERROR("Device Scanning is already running within a different program."); + return false; + case -1: + SGLOG_ERROR("Device Scanning already being initialized (function called twice in short succession)."); + return false; + case 0: + // Do not pollute the logs! + //SGLOG_ERROR("Device Scanning is already running within this program."); + // We must return here in case there are two virtual hand components are present in the scene. + return true; + case 1: + SGLOG("Successfully started up DeviceScanning from the current program."); + break; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled Init return status code!")); + return false; + } +#endif /* PLATFORM_ANDROID */ + + // Ensure that the device list is empty before doing anything. + FSGDeviceList::Dispose(); + FSGDeviceList::Reinitialize(); + + // Load the latest hand profiles. + FSGHapticGloveHandProfiles::TryLoadingFromDisk(); + + Owner->bBackendInitialized = true; + + return true; + } + + return false; +} + +bool USGWristTrackerComponent::FImpl::UninitializeBackend() const +{ + // NOTE + // In Editor builds we should be avoiding dispose, since stopping the game in PIE mode, causes the virtual-hand + // to disappear in the editor as the plugin won't be able to retrieve the glove status anymore. +#if ! WITH_EDITOR + if (Owner->bBackendInitialized) + { + FSGDeviceList::Dispose(); + +#if PLATFORM_ANDROID + const int32_t Result = FSGConnect::Dispose(); + switch (Result) + { + case -3: + SGLOG_ERROR("An Unexpected error occurred. Please try again."); + return false; + case -2: + SGLOG_ERROR("Not allowed to dispose of Device Scanning because this is not the program which started it."); + return false; + case -1: + SGLOG_ERROR("Device Scanning is currently being disposed off. This takes a second or two. (function called twice in short succession)."); + return false; + case 0: + SGLOG_ERROR("There is no deviceScanner running from any program, so disposing is skipped."); + return false; + case 1: + SGLOG("Successfully disposed of DeviceScanner resources."); + break; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled Dispose return status code!")); + return false; + } +#endif /* PLATFORM_ANDROID */ + + Owner->bBackendInitialized = false; + + return true; + } +#endif /* ! WITH_EDITOR */ + + return false; +} + +bool USGWristTrackerComponent::FImpl::CheckGlove() const +{ + if (!Owner->bBackendInitialized) + { + const bool bSucceeded = InitializeBackend(); + if (!bSucceeded) + { + return false; + } + } + + const bool bGloveWasPresent = IsValid(Owner->Glove); + const bool bFoundGlove = USGHapticGlove::GetGlove(Owner, Owner->IsRight(), Owner->Glove); + + if (!bFoundGlove && bGloveWasPresent) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not find a %s glove!"), + (Owner->IsRight() ? TEXT("right-handed") : TEXT("left-handed")))); + } + + if (bFoundGlove) + { + if (Owner->WristLocationChangedEvent.IsBound()) + { + Owner->WristLocationChangedEvent.Broadcast(Owner->WristLocation); + } + if (Owner->WristRotationChangedEvent.IsBound()) + { + Owner->WristRotationChangedEvent.Broadcast(Owner->WristRotation); + } + if (Owner->WristLocationAndRotationChangedEvent.IsBound()) + { + Owner->WristLocationAndRotationChangedEvent.Broadcast(Owner->WristLocation, Owner->WristRotation); + } + } + + return bFoundGlove; +} + +void USGWristTrackerComponent::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp index 28fe0df7..7af05485 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp @@ -36,9 +36,9 @@ #include "SenseGlove/GameFramework/SGPawn.h" #include "Camera/CameraComponent.h" -#include "MotionControllerComponent.h" #include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SenseGlove/Components/SGWristTrackerComponent.h" struct ASGPawn::FImpl { @@ -84,33 +84,41 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer) Camera->SetupAttachment(GetRootComponent()); Camera->SetCanEverAffectNavigation(false); - MotionControllerLeft = ObjectInitializer.CreateDefaultSubobject( - this, TEXT("MotionControllerLeft")); - MotionControllerLeft->SetupAttachment(GetRootComponent()); - MotionControllerLeft->SetCanEverAffectNavigation(false); - MotionControllerLeft->SetWorldLocation(FVector{30.0f, -20.0f, -10.0f}, - false, nullptr, ETeleportType::None); - MotionControllerLeft->SetTrackingSource(EControllerHand::Left); + WristTrackerLeft = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("WristTrackerLeft")); + WristTrackerLeft->SetupAttachment(GetRootComponent()); + WristTrackerLeft->SetRight(false); HandLeft = ObjectInitializer.CreateDefaultSubobject(this, TEXT("HandLeft")); - HandLeft->SetupAttachment(MotionControllerLeft); - HandLeft->SetCanEverAffectNavigation(false); + HandLeft->SetupAttachment(GetRootComponent()); HandLeft->SetRight(false); HandLeft->SetHiddenIfNoGloveDetected(true); + HandLeft->SetWorldLocation(FVector{30.0f, -20.0f, -10.0f}, + false, nullptr, ETeleportType::None); - MotionControllerRight = ObjectInitializer.CreateDefaultSubobject( - this, TEXT("MotionControllerRight")); - MotionControllerRight->SetupAttachment(GetRootComponent()); - MotionControllerRight->SetCanEverAffectNavigation(false); - MotionControllerRight->SetWorldLocation(FVector{30.0f, 20.0f, -10.0f}, - false, nullptr, ETeleportType::None); - MotionControllerRight->SetTrackingSource(EControllerHand::Left); + WristTrackerRight = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("WristTrackerRight")); + WristTrackerRight->SetupAttachment(GetRootComponent()); + WristTrackerRight->SetRight(true); HandRight = ObjectInitializer.CreateDefaultSubobject(this, TEXT("HandRight")); - HandRight->SetupAttachment(MotionControllerRight); - HandRight->SetCanEverAffectNavigation(false); + HandRight->SetupAttachment(GetRootComponent()); HandRight->SetRight(true); HandRight->SetHiddenIfNoGloveDetected(true); + HandRight->SetWorldLocation(FVector{30.0f, 20.0f, -10.0f}, + false, nullptr, ETeleportType::None); +} + +void ASGPawn::BeginPlay() +{ + Super::BeginPlay(); + + ensureAlwaysMsgf( + WristTrackerLeft->IsLeft() && HandLeft->IsLeft(), + TEXT("The left hand and the left wrist do not track the left hand!")); + ensureAlwaysMsgf( + WristTrackerRight->IsRight() && HandRight->IsRight(), + TEXT("The right hand and the right wrist do not track the right hand!")); } ASGPawn::FImpl::FImpl(ASGPawn* InOwner) diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp index b62828d8..7671ee76 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHandActor.cpp @@ -36,6 +36,7 @@ #include "SenseGlove/GameFramework/SGVirtualHandActor.h" #include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SenseGlove/Components/SGWristTrackerComponent.h" struct ASGVirtualHandActor::FImpl { @@ -83,6 +84,19 @@ ASGVirtualHandActor::ASGVirtualHandActor(const FObjectInitializer& ObjectInitial VirtualHand = CreateDefaultSubobject(TEXT("VirtualHand")); VirtualHand->SetupAttachment(RootComponent); + + WristTracker = CreateDefaultSubobject(TEXT("WristTracker")); + WristTracker->SetupAttachment(RootComponent); +} + +void ASGVirtualHandActor::BeginPlay() +{ + Super::BeginPlay(); + + ensureAlwaysMsgf( + (WristTracker->IsLeft() && VirtualHand->IsLeft()) + || (WristTracker->IsRight() && VirtualHand->IsRight()), + TEXT("The virtual hand component and the wrist tracker component do not track the same hand!")); } void ASGVirtualHandActor::Tick(const float DeltaSeconds) @@ -119,12 +133,18 @@ void ASGVirtualHandActor::EditorTick(float DeltaSeconds) bool ASGVirtualHandActor::IsLeft() const { - return GetVirtualHand()->IsLeft(); + return WristTracker->IsLeft() && VirtualHand->IsLeft(); } bool ASGVirtualHandActor::IsRight() const { - return GetVirtualHand()->IsRight(); + return WristTracker->IsRight() && VirtualHand->IsRight(); +} + +void ASGVirtualHandActor::SetRight(const bool bRight) +{ + WristTracker->SetRight(bRight); + VirtualHand->SetRight(bRight); } bool ASGVirtualHandActor::IsGloveConnected() const diff --git a/Source/SenseGlove/Public/SenseGlove/Components/SGWristTrackerComponent.h b/Source/SenseGlove/Public/SenseGlove/Components/SGWristTrackerComponent.h new file mode 100644 index 00000000..ccfd6ed6 --- /dev/null +++ b/Source/SenseGlove/Public/SenseGlove/Components/SGWristTrackerComponent.h @@ -0,0 +1,301 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2023 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "GameFramework/Actor.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" +#include "MotionControllerComponent.h" +#include "Templates/UniquePtr.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGWristTrackerComponent.generated.h" + +class USGHandPose; +class USGHapticGlove; + +UCLASS(Blueprintable, ClassGroup = MotionController, meta = (BlueprintSpawnableComponent)) +class SENSEGLOVE_API USGWristTrackerComponent : public UMotionControllerComponent +{ + GENERATED_UCLASS_BODY() + +public: + DECLARE_EVENT_OneParam(USGWristTrackerComponent, FWristLocationChangedEvent, const FVector&) + + FWristLocationChangedEvent& OnWristLocationChanged() + { + return WristLocationChangedEvent; + }; + + DECLARE_EVENT_OneParam(USGWristTrackerComponent, FWristRotationChangedEvent, const FRotator&) + + FWristRotationChangedEvent& OnWristRotationChanged() + { + return WristRotationChangedEvent; + }; + + DECLARE_EVENT_TwoParams(USGWristTrackerComponent, FWristLocationAndRotationChangedEvent, + const FVector&, const FRotator&) + + FWristLocationAndRotationChangedEvent& OnWristLocationAndRotationChanged() + { + return WristLocationAndRotationChangedEvent; + }; + +private: + FWristLocationChangedEvent WristLocationChangedEvent; + FWristRotationChangedEvent WristRotationChangedEvent; + FWristLocationAndRotationChangedEvent WristLocationAndRotationChangedEvent; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings") + uint8 bOverridePluginWristTrackingSettings : 1; + + /** + * If set to Custom, any desired location and rotation can be specified. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingSettings", EditConditionHides)) + ESGPositionalTrackingHardware HardwareOffset; + + /** + * Valid only if HardwareOffset is set to Custom. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition= + "bOverridePluginWristTrackingSettings && HardwareOffset == ESGPositionalTrackingHardware::Custom", + EditConditionHides)) + FVector HardwareLocationOffset; + + /** + * Valid only if HardwareOffset is set to Custom. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition= + "bOverridePluginWristTrackingSettings && HardwareOffset == ESGPositionalTrackingHardware::Custom", + EditConditionHides)) + FRotator HardwareRotationOffset; + + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings") + uint8 bOverridePluginWristTrackingDebugSettings : 1; + + /** + * If enabled, draws debug Wrist trackers where possible. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings", EditConditionHides)) + uint8 bDrawDebugWristTrackerGizmo : 1; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + float DebugWristTrackerGizmoLength; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + FLinearColor DebugWristTrackerGizmoXAxisColor; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + FLinearColor DebugWristTrackerGizmoYAxisColor; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + FLinearColor DebugWristTrackerGizmoZAxisColor; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + uint8 bDebugWristTrackerGizmoPersistentLines : 1; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + float DebugWristTrackerGizmoLifeTimeModifier; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + uint8 DebugWristTrackerGizmoDepthPriority; + + /** + * Valid only if bDrawDebugWristTrackerGizmo is enabled. + */ + UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings", + meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo", + EditConditionHides)) + float DebugWristTrackerGizmoThickness; + +private: + UPROPERTY(Transient) + uint8 bBackendInitialized : 1; + + UPROPERTY(Transient) + USGHapticGlove* Glove; + + UPROPERTY(Transient) + FVector WristLocation; + + UPROPERTY(Transient) + FRotator WristRotation; + +public: + FORCEINLINE bool OverridesPluginWristTrackingSettings() const + { + return !!bOverridePluginWristTrackingSettings; + } + + FORCEINLINE void OverridePluginWristTrackingSettings(const bool bInOverridePluginWristTrackingSettings) + { + bOverridePluginWristTrackingSettings = bInOverridePluginWristTrackingSettings; + } + + ESGPositionalTrackingHardware GetHardwareOffset() const; + void SetHardwareOffset(ESGPositionalTrackingHardware InHardwareOffset); + + const FVector& GetHardwareLocationOffset() const; + void SetHardwareLocationOffset(const FVector& InHardwareLocationOffset); + + const FRotator& GetHardwareRotationOffset() const; + void SetHardwareRotationOffset(const FRotator& InHardwareRotationOffset); + + FORCEINLINE bool OverridesPluginWristTrackingDebugSettings() const + { + return !!bOverridePluginWristTrackingDebugSettings; + } + + FORCEINLINE void OverridePluginWristTrackingDebugSettings(const bool bInOverridePluginWristTrackingDebugSettings) + { + bOverridePluginWristTrackingDebugSettings = bInOverridePluginWristTrackingDebugSettings; + } + + bool GetDrawDebugWristTrackerGizmo() const; + void SetDrawDebugWristTrackerGizmo(bool bInDrawDebugWristTrackerGizmo); + + float GetDebugWristTrackerGizmoLength() const; + void SetDebugWristTrackerGizmoLength(float InDebugWristTrackerGizmoLength); + + const FLinearColor& GetDebugWristTrackerGizmoXAxisColor() const; + void SetDebugWristTrackerGizmoXAxisColor(const FLinearColor& InDebugWristTrackerGizmoXAxisColor); + + const FLinearColor& GetDebugWristTrackerGizmoYAxisColor() const; + void SetDebugWristTrackerGizmoYAxisColor(const FLinearColor& InDebugWristTrackerGizmoYAxisColor); + + const FLinearColor& GetDebugWristTrackerGizmoZAxisColor() const; + void SetDebugWristTrackerGizmoZAxisColor(const FLinearColor& InDebugWristTrackerGizmoZAxisColor); + + bool GetDebugWristTrackerGizmoPersistentLines() const; + void SetDebugWristTrackerGizmoPersistentLines(bool bInDebugWristTrackerGizmoPersistentLines); + + float GetDebugWristTrackerGizmoLifeTimeModifier() const; + void SetDebugWristTrackerGizmoLifeTimeModifier(float InDebugWristTrackerGizmoLifeTimeModifier); + + uint8 GetDebugWristTrackerGizmoDepthPriority() const; + void SetDebugWristTrackerGizmoDepthPriority(uint8 InDebugWristTrackerGizmoDepthPriority); + + float GetDebugWristTrackerGizmoThickness() const; + void SetDebugWristTrackerGizmoThickness(float InDebugWristTrackerGizmoThickness); + + FORCEINLINE bool IsLeft() const + { + return GetTrackingSource() == EControllerHand::Left; + } + + FORCEINLINE bool IsRight() const + { + return GetTrackingSource() == EControllerHand::Right; + } + + void SetRight(const bool bRight); + +public: +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif /* WITH_EDITOR */ + + virtual void InitializeComponent() override; + + virtual void UninitializeComponent() override; + + virtual void BeginPlay() override; + + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + virtual void TickComponent(float DeltaTime, + enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) override; + +protected: + virtual void EditorTick(float DeltaTime, + enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction); +}; diff --git a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h index 23cbef38..281454f8 100644 --- a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h +++ b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h @@ -41,9 +41,9 @@ #include "SGPawn.generated.h" class UCameraComponent; -class UMotionControllerComponent; class USGVirtualHandComponent; +class USGWristTrackerComponent; UCLASS(Config=Game, BlueprintType, Blueprintable) class SENSEGLOVE_API ASGPawn : public APawn @@ -69,10 +69,10 @@ private: UCameraComponent* Camera; UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) - UMotionControllerComponent* MotionControllerLeft; + USGWristTrackerComponent* WristTrackerLeft; UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) - UMotionControllerComponent* MotionControllerRight; + USGWristTrackerComponent* WristTrackerRight; UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) USGVirtualHandComponent* HandLeft; @@ -86,14 +86,14 @@ public: return Camera; } - FORCEINLINE UMotionControllerComponent* GetMotionControllerLeft() const + FORCEINLINE USGWristTrackerComponent* GetWristTrackerLeft() const { - return MotionControllerLeft; + return WristTrackerLeft; } - FORCEINLINE UMotionControllerComponent* GetMotionControllerRight() const + FORCEINLINE USGWristTrackerComponent* GetWristTrackerRight() const { - return MotionControllerRight; + return WristTrackerRight; } FORCEINLINE USGVirtualHandComponent* GetHandLeft() const @@ -105,4 +105,7 @@ public: { return HandRight; } + +public: + virtual void BeginPlay() override; }; \ No newline at end of file diff --git a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHandActor.h b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHandActor.h index 3d7a49e0..c8097877 100644 --- a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHandActor.h +++ b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHandActor.h @@ -49,6 +49,7 @@ class USceneComponent; class USGHandPose; class USGVirtualHandComponent; +class USGWristTrackerComponent; UCLASS(Config=Game, BlueprintType) class SENSEGLOVE_API ASGVirtualHandActor : public AActor @@ -70,10 +71,18 @@ private: UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) USceneComponent* SceneRoot; + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USGWristTrackerComponent* WristTracker; + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) USGVirtualHandComponent* VirtualHand; public: + FORCEINLINE USGWristTrackerComponent* GetWristTracker() const + { + return WristTracker; + } + FORCEINLINE USGVirtualHandComponent* GetVirtualHand() const { return VirtualHand; @@ -86,6 +95,8 @@ protected: } public: + virtual void BeginPlay() override; + virtual void Tick(float DeltaSeconds) override; virtual bool ShouldTickIfViewportsOnly() const override; @@ -98,6 +109,7 @@ protected: public: bool IsLeft() const; bool IsRight() const; + void SetRight(bool bRight); bool IsGloveConnected() const; }; \ No newline at end of file diff --git a/Source/SenseGlove/SenseGlove.Build.cs b/Source/SenseGlove/SenseGlove.Build.cs index d0fe82aa..4835cb81 100644 --- a/Source/SenseGlove/SenseGlove.Build.cs +++ b/Source/SenseGlove/SenseGlove.Build.cs @@ -59,6 +59,7 @@ public class SenseGlove : ModuleRules "SenseGloveConnect", "SenseGloveCore", "SenseGloveLog", + "SenseGloveSettings", "SenseGloveTypes", } ); diff --git a/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp b/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp index 6b2099b4..0f91e464 100644 --- a/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp +++ b/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp @@ -36,9 +36,9 @@ #include "SGKismet/SGPawnKismetLibrary.h" #include "Camera/CameraComponent.h" -#include "MotionControllerComponent.h" #include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SenseGlove/Components/SGWristTrackerComponent.h" #include "SenseGlove/GameFramework/SGPawn.h" UCameraComponent* UPawnKismetLibrary::GetCamera(const ASGPawn* Pawn) @@ -46,14 +46,14 @@ UCameraComponent* UPawnKismetLibrary::GetCamera(const ASGPawn* Pawn) return Pawn->GetCamera(); } -UMotionControllerComponent* UPawnKismetLibrary::GetMotionControllerLeft(const ASGPawn* Pawn) +USGWristTrackerComponent* UPawnKismetLibrary::GetWristTrackerLeft(const ASGPawn* Pawn) { - return Pawn->GetMotionControllerLeft(); + return Pawn->GetWristTrackerLeft(); } -UMotionControllerComponent* UPawnKismetLibrary::GetMotionControllerRight(const ASGPawn* Pawn) +USGWristTrackerComponent* UPawnKismetLibrary::GetWristTrackerRight(const ASGPawn* Pawn) { - return Pawn->GetMotionControllerRight(); + return Pawn->GetWristTrackerRight(); } USGVirtualHandComponent* UPawnKismetLibrary::GetHandLeft(const ASGPawn* Pawn) diff --git a/Source/SenseGloveKismet/Private/SGKismet/SGVirtualHandActorKismetLibrary.cpp b/Source/SenseGloveKismet/Private/SGKismet/SGVirtualHandActorKismetLibrary.cpp index 63b02886..c649f500 100644 --- a/Source/SenseGloveKismet/Private/SGKismet/SGVirtualHandActorKismetLibrary.cpp +++ b/Source/SenseGloveKismet/Private/SGKismet/SGVirtualHandActorKismetLibrary.cpp @@ -35,6 +35,8 @@ #include "SGKismet/SGVirtualHandActorKismetLibrary.h" +#include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SenseGlove/Components/SGWristTrackerComponent.h" #include "SenseGlove/GameFramework/SGVirtualHandActor.h" USGVirtualHandComponent* UVirtualHandActorKismetLibrary::GetVirtualHand(const ASGVirtualHandActor* VirtualHandActor) @@ -42,6 +44,11 @@ USGVirtualHandComponent* UVirtualHandActorKismetLibrary::GetVirtualHand(const AS return VirtualHandActor->GetVirtualHand(); } +USGWristTrackerComponent* UVirtualHandActorKismetLibrary::GetWristTracker(const ASGVirtualHandActor* VirtualHandActor) +{ + return VirtualHandActor->GetWristTracker(); +} + bool UVirtualHandActorKismetLibrary::IsLeft(const ASGVirtualHandActor* VirtualHandActor) { return VirtualHandActor->IsLeft(); @@ -52,6 +59,11 @@ bool UVirtualHandActorKismetLibrary::IsRight(const ASGVirtualHandActor* VirtualH return VirtualHandActor->IsRight(); } +void UVirtualHandActorKismetLibrary::SetRight(ASGVirtualHandActor* VirtualHandActor, const bool bRight) +{ + VirtualHandActor->SetRight(bRight); +} + bool UVirtualHandActorKismetLibrary::IsGloveConnected(const ASGVirtualHandActor* VirtualHandActor) const { return VirtualHandActor->IsGloveConnected(); diff --git a/Source/SenseGloveKismet/Private/SGKismet/SGWristTrackerComponentKismetLibrary.cpp b/Source/SenseGloveKismet/Private/SGKismet/SGWristTrackerComponentKismetLibrary.cpp new file mode 100644 index 00000000..eda311b1 --- /dev/null +++ b/Source/SenseGloveKismet/Private/SGKismet/SGWristTrackerComponentKismetLibrary.cpp @@ -0,0 +1,222 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2023 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGKismet/SGWristTrackerComponentKismetLibrary.h" + +#include "SenseGlove/Components/SGWristTrackerComponent.h" + +bool UWristTrackerComponentKismetLibrary::OverridesPluginWristTrackingSettings( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->OverridesPluginWristTrackingSettings(); +} + +void UWristTrackerComponentKismetLibrary::OverridePluginWristTrackingSettings( + USGWristTrackerComponent* WristTrackerComponent, const bool bInOverridePluginWristTrackingSettings) +{ + WristTrackerComponent->OverridePluginWristTrackingSettings(bInOverridePluginWristTrackingSettings); +} + +ESGPositionalTrackingHardware UWristTrackerComponentKismetLibrary::GetHardwareOffset( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetHardwareOffset(); +} + +void UWristTrackerComponentKismetLibrary::SetHardwareOffset(USGWristTrackerComponent* WristTrackerComponent, + ESGPositionalTrackingHardware InHardwareOffset) +{ + WristTrackerComponent->SetHardwareOffset(InHardwareOffset); +} + +const FVector& UWristTrackerComponentKismetLibrary::GetHardwareLocationOffset( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetHardwareLocationOffset(); +} + +void UWristTrackerComponentKismetLibrary::SetHardwareLocationOffset(USGWristTrackerComponent* WristTrackerComponent, + const FVector& InHardwareLocationOffset) +{ + WristTrackerComponent->SetHardwareLocationOffset(InHardwareLocationOffset); +} + +const FRotator& UWristTrackerComponentKismetLibrary::GetHardwareRotationOffset( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetHardwareRotationOffset(); +} + +void UWristTrackerComponentKismetLibrary::SetHardwareRotationOffset(USGWristTrackerComponent* WristTrackerComponent, + const FRotator& InHardwareRotationOffset) +{ + WristTrackerComponent->SetHardwareRotationOffset(InHardwareRotationOffset); +} + +bool UWristTrackerComponentKismetLibrary::OverridesPluginWristTrackingDebugSettings( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->OverridesPluginWristTrackingDebugSettings(); +} + +void UWristTrackerComponentKismetLibrary::OverridePluginWristTrackingDebugSettings( + USGWristTrackerComponent* WristTrackerComponent, const bool bInOverridePluginWristTrackingDebugSettings) +{ + WristTrackerComponent->OverridePluginWristTrackingDebugSettings(bInOverridePluginWristTrackingDebugSettings); +} + +bool UWristTrackerComponentKismetLibrary::GetDrawDebugWristTrackerGizmo( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDrawDebugWristTrackerGizmo(); +} + +void UWristTrackerComponentKismetLibrary::SetDrawDebugWristTrackerGizmo(USGWristTrackerComponent* WristTrackerComponent, + const bool bInDrawDebugWristTrackerGizmo) +{ + WristTrackerComponent->SetDrawDebugWristTrackerGizmo(bInDrawDebugWristTrackerGizmo); +} + +float UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoLength( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoLength(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoLength( + USGWristTrackerComponent* WristTrackerComponent, const float InDebugWristTrackerGizmoLength) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoLength(InDebugWristTrackerGizmoLength); +} + +const FLinearColor& UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoXAxisColor( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoXAxisColor(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoXAxisColor( + USGWristTrackerComponent* WristTrackerComponent, const FLinearColor& InDebugWristTrackerGizmoXAxisColor) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoXAxisColor(InDebugWristTrackerGizmoXAxisColor); +} + +const FLinearColor& UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoYAxisColor( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoYAxisColor(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoYAxisColor( + USGWristTrackerComponent* WristTrackerComponent, const FLinearColor& InDebugWristTrackerGizmoYAxisColor) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoYAxisColor(InDebugWristTrackerGizmoYAxisColor); +} + +const FLinearColor& UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoZAxisColor( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoZAxisColor(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoZAxisColor( + USGWristTrackerComponent* WristTrackerComponent, const FLinearColor& InDebugWristTrackerGizmoZAxisColor) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoZAxisColor(InDebugWristTrackerGizmoZAxisColor); +} + +bool UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoPersistentLines( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoPersistentLines(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoPersistentLines( + USGWristTrackerComponent* WristTrackerComponent, const bool bInDebugWristTrackerGizmoPersistentLines) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoPersistentLines(bInDebugWristTrackerGizmoPersistentLines); +} + +float UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoLifeTimeModifier( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoLifeTimeModifier(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoLifeTimeModifier( + USGWristTrackerComponent* WristTrackerComponent, const float InDebugWristTrackerGizmoLifeTimeModifier) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoLifeTimeModifier(InDebugWristTrackerGizmoLifeTimeModifier); +} + +uint8 UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoDepthPriority( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoDepthPriority(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoDepthPriority( + USGWristTrackerComponent* WristTrackerComponent, const uint8 InDebugWristTrackerGizmoDepthPriority) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoDepthPriority(InDebugWristTrackerGizmoDepthPriority); +} + +float UWristTrackerComponentKismetLibrary::GetDebugWristTrackerGizmoThickness( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetDebugWristTrackerGizmoThickness(); +} + +void UWristTrackerComponentKismetLibrary::SetDebugWristTrackerGizmoThickness( + USGWristTrackerComponent* WristTrackerComponent, float InDebugWristTrackerGizmoThickness) +{ + WristTrackerComponent->SetDebugWristTrackerGizmoThickness(InDebugWristTrackerGizmoThickness); +} + +bool UWristTrackerComponentKismetLibrary::IsLeft(const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->IsLeft(); +} + +bool UWristTrackerComponentKismetLibrary::IsRight(const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->IsRight(); +} + +void UWristTrackerComponentKismetLibrary::SetRight(USGWristTrackerComponent* WristTrackerComponent, + const bool bInRight) +{ + WristTrackerComponent->SetRight(bInRight); +} \ No newline at end of file diff --git a/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h b/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h index 090e0746..8d3a9056 100644 --- a/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h +++ b/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h @@ -50,10 +50,10 @@ #include "SGPawnKismetLibrary.generated.h" class UCameraComponent; -class UMotionControllerComponent; class ASGPawn; class USGVirtualHandComponent; +class USGWristTrackerComponent; UCLASS(meta=(ScriptName = "SesneGlovePawnKismetLibrary")) class SENSEGLOVEKISMET_API UPawnKismetLibrary final : public USGBlueprintFunctionLibrary @@ -65,10 +65,10 @@ public: static UCameraComponent* GetCamera(const ASGPawn* Pawn); UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") - static UMotionControllerComponent* GetMotionControllerLeft(const ASGPawn* Pawn); + static USGWristTrackerComponent* GetWristTrackerLeft(const ASGPawn* Pawn); UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") - static UMotionControllerComponent* GetMotionControllerRight(const ASGPawn* Pawn); + static USGWristTrackerComponent* GetWristTrackerRight(const ASGPawn* Pawn); UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") static USGVirtualHandComponent* GetHandLeft(const ASGPawn* Pawn); diff --git a/Source/SenseGloveKismet/Public/SGKismet/SGVirtualHandActorKismetLibrary.h b/Source/SenseGloveKismet/Public/SGKismet/SGVirtualHandActorKismetLibrary.h index b9515cf6..cde550a0 100644 --- a/Source/SenseGloveKismet/Public/SGKismet/SGVirtualHandActorKismetLibrary.h +++ b/Source/SenseGloveKismet/Public/SGKismet/SGVirtualHandActorKismetLibrary.h @@ -43,6 +43,7 @@ class ASGVirtualHandActor; class USGVirtualHandComponent; +class USGWristTrackerComponent; UCLASS(meta=(ScriptName = "SesneGloveVirtualHandActorKismetLibrary")) class SENSEGLOVEKISMET_API UVirtualHandActorKismetLibrary final : public USGBlueprintFunctionLibrary @@ -53,12 +54,18 @@ public: UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Virtual Hand") static USGVirtualHandComponent* GetVirtualHand(const ASGVirtualHandActor* VirtualHandActor); + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Virtual Hand") + static USGWristTrackerComponent* GetWristTracker(const ASGVirtualHandActor* VirtualHandActor); + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Virtual Hand") static bool IsLeft(const ASGVirtualHandActor* VirtualHandActor); UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Virtual Hand") static bool IsRight(const ASGVirtualHandActor* VirtualHandActor); + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Virtual Hand") + static void SetRight(UPARAM(ref) ASGVirtualHandActor* VirtualHandActor, bool bRight); + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Virtual Hand") bool IsGloveConnected(const ASGVirtualHandActor* VirtualHandActor) const; }; \ No newline at end of file diff --git a/Source/SenseGloveKismet/Public/SGKismet/SGWristTrackerComponentKismetLibrary.h b/Source/SenseGloveKismet/Public/SGKismet/SGWristTrackerComponentKismetLibrary.h new file mode 100644 index 00000000..f1303d9d --- /dev/null +++ b/Source/SenseGloveKismet/Public/SGKismet/SGWristTrackerComponentKismetLibrary.h @@ -0,0 +1,165 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2023 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A data class containing the minimum required data for a hand's forward + * kinematics. + * Used in both kinematics and calibration. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGWristTrackerComponentKismetLibrary.generated.h" + +class USkeletalMeshComponent; + +class USGWristTrackerComponent; +class USGHandPose; + +UCLASS(meta=(ScriptName = "SesneGloveWristTrackerComponentKismetLibrary")) +class SENSEGLOVEKISMET_API UWristTrackerComponentKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool OverridesPluginWristTrackingSettings(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void OverridePluginWristTrackingSettings(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + bool bInOverridePluginWristTrackingSettings); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static ESGPositionalTrackingHardware GetHardwareOffset(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetHardwareOffset(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + ESGPositionalTrackingHardware InHardwareOffset); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static const FVector& GetHardwareLocationOffset(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetHardwareLocationOffset(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + const FVector& InHardwareLocationOffset); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static const FRotator& GetHardwareRotationOffset(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetHardwareRotationOffset(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + const FRotator& InHardwareRotationOffset); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool OverridesPluginWristTrackingDebugSettings(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void OverridePluginWristTrackingDebugSettings(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + bool bInOverridePluginWristTrackingDebugSettings); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool GetDrawDebugWristTrackerGizmo(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDrawDebugWristTrackerGizmo(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + bool bInDrawDebugWristTrackerGizmo); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static float GetDebugWristTrackerGizmoLength(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoLength(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + float InDebugWristTrackerGizmoLength); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static const FLinearColor& GetDebugWristTrackerGizmoXAxisColor( + const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoXAxisColor(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + const FLinearColor& InDebugWristTrackerGizmoXAxisColor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static const FLinearColor& GetDebugWristTrackerGizmoYAxisColor( + const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoYAxisColor(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + const FLinearColor& InDebugWristTrackerGizmoYAxisColor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static const FLinearColor& GetDebugWristTrackerGizmoZAxisColor( + const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoZAxisColor(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + const FLinearColor& InDebugWristTrackerGizmoZAxisColor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool GetDebugWristTrackerGizmoPersistentLines(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoPersistentLines(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + bool bInDebugWristTrackerGizmoPersistentLines); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static float GetDebugWristTrackerGizmoLifeTimeModifier(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoLifeTimeModifier(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + float InDebugWristTrackerGizmoLifeTimeModifier); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static uint8 GetDebugWristTrackerGizmoDepthPriority(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoDepthPriority(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + uint8 InDebugWristTrackerGizmoDepthPriority); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static float GetDebugWristTrackerGizmoThickness(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetDebugWristTrackerGizmoThickness(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + float InDebugWristTrackerGizmoThickness); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool IsLeft(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool IsRight(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetRight(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, bool bInRight); +}; \ No newline at end of file