implement the OpenXR-compatible hand tracking (XR_EXT_hand_tracking) support

This commit is contained in:
Mamadou Babaei
2024-05-03 11:29:17 +02:00
parent 9b32ee589b
commit c5adee47ce
51 changed files with 4151 additions and 307 deletions
@@ -43,11 +43,11 @@
#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h"
#include "SenseGlove/Components/SGWristTrackerComponent.h"
#include "SGBackend/SGBackend.h"
#include "SGCore/SGHandPose.h"
#include "SGCore/SGHapticGlove.h"
#include "SGDebug/SGDebugVirtualHand.h"
#include "SGLog/SGLog.h"
#include "SGTracking/SGGloveTracker.h"
struct USGVirtualHandComponent::FImpl
{
@@ -119,7 +119,7 @@ struct USGVirtualHandComponent::FImpl
USkeleton* GetSkeleton() const;
const FReferenceSkeleton& GetRefSkeleton() const;
bool CheckGlove() const;
void UpdateGloveVisibility() const;
FORCEINLINE void SetVisibility(const bool bInVisible) const
{
@@ -227,21 +227,10 @@ USGVirtualHandComponent::USGVirtualHandComponent(const FObjectInitializer& Objec
RingFingertipTouchSocketName = FName{TEXT("TouchRingFingertip")};
PinkyFingertipTouchSocketName = FName{TEXT("TouchPinkyFingertip")};
DebugVirtualHandSettings = FSGDebugVirtualHandSettings{
false,
ESGDebugVirtualHandDrawingMode::None,
FVector(0.5f, 0.5f, 0.5f),
FColor(255, 0, 0, 255),
0.1f, 1.0f, 1.0f,
FColor(255, 0, 0, 255),
FColor(0, 255, 0, 255),
FColor(0, 0, 255, 255),
false, 1.1f, 0
};
DebugVirtualHandSettings = FSGDebugVirtualHandSettings{};
Super::SetSkeletalMesh(nullptr, true);
Glove = nullptr;
WristTracker = nullptr;
}
@@ -302,13 +291,15 @@ void USGVirtualHandComponent::InitializeComponent()
Pimpl->SetDefaultMesh();
}
(void) Pimpl->CheckGlove();
Pimpl->UpdateGloveVisibility();
}
void USGVirtualHandComponent::UninitializeComponent()
{
Super::UninitializeComponent();
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && AutoStopsAllHapticsOnEndPlay())
{
Glove->StopHaptics();
@@ -319,13 +310,15 @@ void USGVirtualHandComponent::BeginPlay()
{
Super::BeginPlay();
(void) Pimpl->CheckGlove();
Pimpl->UpdateGloveVisibility();
}
void USGVirtualHandComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && AutoStopsAllHapticsOnEndPlay())
{
Glove->StopHaptics();
@@ -345,8 +338,10 @@ void USGVirtualHandComponent::TickComponent(
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
(void) Pimpl->CheckGlove();
Pimpl->UpdateGloveVisibility();
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
{
Pimpl->DrawDebugVirtualHand();
@@ -368,8 +363,10 @@ void USGVirtualHandComponent::SetSkeletalMesh(USkeletalMesh* NewMesh, const bool
void USGVirtualHandComponent::EditorTick(
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
(void) Pimpl->CheckGlove();
Pimpl->UpdateGloveVisibility();
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
{
Pimpl->DrawDebugVirtualHand();
@@ -378,13 +375,24 @@ void USGVirtualHandComponent::EditorTick(
bool USGVirtualHandComponent::IsGloveConnected() const
{
return Pimpl->CheckGlove();
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
const USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
return IsValid(Glove);
}
USGHapticGlove* USGVirtualHandComponent::GetConnectedGlove() const
{
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
return Glove;
}
USGHandPose* USGVirtualHandComponent::GetHandPose()
{
USGHandPose* HandPose{nullptr};
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove))
{
Glove->GetHandPose(this, HandPose);
@@ -587,62 +595,38 @@ const FReferenceSkeleton& USGVirtualHandComponent::FImpl::GetRefSkeleton() const
return Mesh->GetRefSkeleton();
}
bool USGVirtualHandComponent::FImpl::CheckGlove() const
void USGVirtualHandComponent::FImpl::UpdateGloveVisibility() const
{
if (!USGBackend::GetInstance()->IsBackendInitialized())
{
const bool bSucceeded = USGBackend::GetInstance()->InitializeBackend();
if (!bSucceeded)
{
return false;
}
}
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
const USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(Owner->IsRight()) : nullptr};
bool bGloveConnected;
if (!IsValid(Owner->Glove) || !Owner->Glove->IsConnected())
{
bGloveConnected = USGHapticGlove::GetGlove(Owner, Owner->IsRight(), Owner->Glove);
if (!bGloveConnected)
{
Owner->Glove = nullptr;
}
}
else
{
bGloveConnected = true;
}
const bool bConnected = IsValid(Glove);
const bool bIsVisible = Owner->IsVisible();
const bool bIsEditor = IsEditor();
if (!bIsEditor)
if (Owner->bHiddenInGameIfNoGloveDetected)
{
const bool bIsVisible = Owner->IsVisible();
if (Owner->bHiddenInGameIfNoGloveDetected)
{
if (bGloveConnected)
{
if (!bIsVisible)
{
SetVisibility(true);
}
}
else
{
if (bIsVisible)
{
SetVisibility(false);
}
}
}
else
if (bConnected)
{
if (!bIsVisible)
{
SetVisibility(true);
}
}
else
{
if (bIsVisible)
{
SetVisibility(false);
}
}
}
else
{
if (!bIsVisible)
{
SetVisibility(true);
}
}
return bGloveConnected;
}
void USGVirtualHandComponent::FImpl::DrawDebugVirtualHand() const
@@ -40,12 +40,12 @@
#include "Engine/SkeletalMesh.h"
#include "UObject/ConstructorHelpers.h"
#include "SenseGlove/SGHeadMountedDisplay.h"
#include "SGBackend/SGBackend.h"
#include "SGCore/SGHapticGlove.h"
#include "SGDebug/SGDebugGizmo.h"
#include "SGLog/SGLog.h"
#include "SGSettings/SGSettings.h"
#include "SGTracking/SGGloveTracker.h"
#include "SGTracking/SGHMDTracker.h"
struct USGWristTrackerComponent::FImpl
{
@@ -79,11 +79,9 @@ struct USGWristTrackerComponent::FImpl
bool IsEditor() const;
bool CheckGlove() const;
void UpdateMotionSource() const;
void UpdateWristTrackingData() const;
void DrawDebugGizmo();
void DrawDebugGizmo() const;
};
USGWristTrackerComponent::USGWristTrackerComponent(const FObjectInitializer& ObjectInitializer)
@@ -105,27 +103,10 @@ USGWristTrackerComponent::USGWristTrackerComponent(const FObjectInitializer& Obj
SetCanEverAffectNavigation(false);
bOverridePluginWristTrackingSettings = false;
WristTrackingSettings = FSGWristTrackingSettings(
ESGPositionalTrackingHardware::None,
FVector::ZeroVector,
FVector::ZeroVector,
FRotator::ZeroRotator,
FRotator::ZeroRotator,
EControllerHand::Left,
EControllerHand::Right,
false,
FSGDebugGizmoSettings(
4.0f, 1.0f,
FColor(255, 0, 0, 255),
FColor(0, 255, 0, 255),
FColor(0, 0, 255, 255),
false, 1.1f, 0
)
);
WristTrackingSettings = FSGWristTrackingSettings{};
bRight = true;
Glove = nullptr;
WristLocation = FVector::ZeroVector;
WristRotation = FRotator::ZeroRotator;
}
@@ -149,7 +130,7 @@ const FSGWristTrackingSettings& USGWristTrackerComponent::GetWristTrackingSettin
return WristTrackingSettings;
}
return Settings->GetWristTrackingSettings();
return Settings->GetTrackingSettings().WristTrackingSettings;
}
void USGWristTrackerComponent::SetWristTrackingSettings(const FSGWristTrackingSettings& InWristTrackingSettings)
@@ -180,7 +161,7 @@ void USGWristTrackerComponent::InitializeComponent()
{
Super::InitializeComponent();
(void) Pimpl->CheckGlove();
Pimpl->UpdateWristTrackingData();
Pimpl->UpdateMotionSource();
}
@@ -189,7 +170,7 @@ void USGWristTrackerComponent::BeginPlay()
{
Super::BeginPlay();
(void) Pimpl->CheckGlove();
Pimpl->UpdateWristTrackingData();
Pimpl->UpdateMotionSource();
}
@@ -207,19 +188,19 @@ void USGWristTrackerComponent::TickComponent(
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (!!WristTrackingSettings.bDrawWristTrackerDebugGizmo)
if (!!WristTrackingSettings.bDrawDebugGizmo)
{
Pimpl->DrawDebugGizmo();
}
(void) Pimpl->CheckGlove();
Pimpl->UpdateWristTrackingData();
}
void USGWristTrackerComponent::EditorTick(
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
(void) Pimpl->CheckGlove();
Pimpl->UpdateWristTrackingData();
}
USGWristTrackerComponent::FImpl::FImpl(USGWristTrackerComponent* InOwner)
@@ -240,35 +221,6 @@ bool USGWristTrackerComponent::FImpl::IsEditor() const
return false;
}
bool USGWristTrackerComponent::FImpl::CheckGlove() const
{
if (!USGBackend::GetInstance()->IsBackendInitialized())
{
const bool bSucceeded = USGBackend::GetInstance()->InitializeBackend();
if (!bSucceeded)
{
return false;
}
}
bool bGloveConnected;
if (!IsValid(Owner->Glove) || !Owner->Glove->IsConnected())
{
bGloveConnected = USGHapticGlove::GetGlove(Owner, Owner->IsRight(), Owner->Glove);
if (!bGloveConnected)
{
Owner->Glove = nullptr;
}
}
else
{
bGloveConnected = true;
UpdateWristTrackingData();
}
return bGloveConnected;
}
void USGWristTrackerComponent::FImpl::UpdateMotionSource() const
{
if (GEngine)
@@ -281,7 +233,12 @@ void USGWristTrackerComponent::FImpl::UpdateMotionSource() const
void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
{
ensureAlwaysMsgf(Owner->Glove, TEXT("Invalid Glove!"));
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
const USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(Owner->IsRight()) : nullptr};
if (!IsValid(Glove))
{
return;
}
FVector TrackerLocation{Owner->GetComponentLocation()};
FRotator TrackerRotation{Owner->GetComponentRotation()};
@@ -289,7 +246,7 @@ void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
ESGPositionalTrackingHardware TrackerHardware = Owner->GetWristTrackingSettings().TrackingHardware;
if (TrackerHardware == ESGPositionalTrackingHardware::None)
{
const ESGHeadMountedDisplayDevice HmdDevice = FSGHeadMountedDisplay::GetDeviceType();
const ESGHeadMountedDisplayDevice HmdDevice = FSGHMDTracker::GetDeviceType();
switch (HmdDevice)
{
case ESGHeadMountedDisplayDevice::MetaQuest2:
@@ -330,8 +287,8 @@ void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
FVector NewWristLocation;
FRotator NewWristRotation;
Owner->Glove->GetWristLocation(TrackerLocation, TrackerRotation, TrackerHardware,
NewWristLocation, NewWristRotation);
Glove->GetWristLocation(TrackerLocation, TrackerRotation, TrackerHardware,
NewWristLocation, NewWristRotation);
const bool bLocationUpdated = !Owner->WristLocation.Equals(NewWristLocation, SMALL_NUMBER);
const bool bRotationUpdated = !Owner->WristRotation.Equals(NewWristRotation, SMALL_NUMBER);
@@ -362,12 +319,12 @@ void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
}
}
void USGWristTrackerComponent::FImpl::DrawDebugGizmo()
void USGWristTrackerComponent::FImpl::DrawDebugGizmo() const
{
const UWorld* World{Owner->GetWorld()};
const FVector& Location{Owner->GetComponentLocation()};
const FRotator& Rotation{Owner->GetComponentRotation()};
const FSGDebugGizmoSettings& DebugGizmoSettings{Owner->GetWristTrackingSettings().WristTrackerDebugGizmoSettings};
const FSGDebugGizmoSettings& DebugGizmoSettings{Owner->GetWristTrackingSettings().DebugGizmoSettings};
FSGDebugGizmo::Draw(World, Location, Rotation, DebugGizmoSettings);
}
@@ -236,7 +236,6 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
FSGDebugVirtualHandSettings RealHandLeftDebugSettings;
RealHandLeftDebugSettings.bDrawDebugVirtualHand = true;
RealHandLeftDebugSettings.DrawingMode = ESGDebugVirtualHandDrawingMode::GizmoJoints;
RealHandLeftDebugSettings.GizmoThickness = 0.5f;
RealHandLeft->SetDebugVirtualHandSettings(MoveTemp(RealHandLeftDebugSettings));
LeftThumbFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject<USphereComponent>(
@@ -463,7 +462,6 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
FSGDebugVirtualHandSettings RealHandRightDebugSettings;
RealHandRightDebugSettings.bDrawDebugVirtualHand = true;
RealHandRightDebugSettings.DrawingMode = ESGDebugVirtualHandDrawingMode::GizmoJoints;
RealHandRightDebugSettings.GizmoThickness = 0.5f;
RealHandRight->SetDebugVirtualHandSettings(MoveTemp(RealHandRightDebugSettings));
RightThumbFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject<USphereComponent>(
@@ -127,9 +127,6 @@ private:
FSGDebugVirtualHandSettings DebugVirtualHandSettings;
private:
UPROPERTY(Transient)
USGHapticGlove* Glove;
UPROPERTY(Transient)
USGWristTrackerComponent* WristTracker;
@@ -311,12 +308,7 @@ protected:
public:
bool IsGloveConnected() const;
FORCEINLINE USGHapticGlove* GetConnectedGlove() const
{
return Glove;
}
USGHapticGlove* GetConnectedGlove() const;
USGHandPose* GetHandPose();
public:
@@ -111,9 +111,6 @@ private:
FSGWristTrackingSettings WristTrackingSettings;
private:
UPROPERTY(Transient)
USGHapticGlove* Glove;
UPROPERTY(Transient)
FVector WristLocation;
+1 -2
View File
@@ -58,12 +58,11 @@ public class SenseGlove : ModuleRules
#if UE_5_3_OR_LATER
"XRBase",
#endif
"SenseGloveBackend",
"SenseGloveConnect",
"SenseGloveCore",
"SenseGloveDebug",
"SenseGloveLog",
"SenseGloveSettings",
"SenseGloveTracking",
"SenseGloveTypes",
}
);
@@ -35,10 +35,27 @@
#include "SGSettings/SGDebugGizmoSettings.h"
FSGDebugGizmoSettings::FSGDebugGizmoSettings()
: Length(4.0f),
Thickness(0.4f),
XAxisColor(255, 0, 0, 255),
YAxisColor(0, 255, 0, 255),
ZAxisColor(0, 0, 255, 255),
bPersistentLines(false),
LifeTimeModifier(1.1),
DepthPriority(0.0f)
{
}
FSGDebugGizmoSettings::FSGDebugGizmoSettings(
const float InLength, const float InThickness,
const FColor& InXAxisColor, const FColor& InYAxisColor, const FColor& InZAxisColor,
const bool bInPersistentLines, const float InLifeTimeModifier, const uint8 InDepthPriority)
const float InLength,
const float InThickness,
const FColor& InXAxisColor,
const FColor& InYAxisColor,
const FColor& InZAxisColor,
const bool bInPersistentLines,
const float InLifeTimeModifier,
const uint8 InDepthPriority)
: Length(InLength),
Thickness(InThickness),
XAxisColor(InXAxisColor),
@@ -40,9 +40,9 @@ FSGDebugVirtualHandSettings::FSGDebugVirtualHandSettings()
DrawingMode(ESGDebugVirtualHandDrawingMode::None),
CubeExtent(FVector(0.5f, 0.5f, 0.5f)),
CubeColor(255, 0, 0, 255),
CubeThickness(0.1f),
CubeThickness(0.2f),
GizmoLength(1.0f),
GizmoThickness(1.0f),
GizmoThickness(0.25f),
GizmoXAxisColor(255, 0, 0, 255),
GizmoYAxisColor(0, 255, 0, 255),
GizmoZAxisColor(0, 0, 255, 255),
@@ -55,10 +55,17 @@ FSGDebugVirtualHandSettings::FSGDebugVirtualHandSettings()
FSGDebugVirtualHandSettings::FSGDebugVirtualHandSettings(
const bool bInDrawDebugVirtualHand,
const ESGDebugVirtualHandDrawingMode InDrawingMode,
const FVector& InCubeExtent, const FColor& InCubeColor, const float InCubeThickness,
const float InGizmoLength, const float InGizmoThickness,
const FColor& InGizmoXAxisColor, const FColor& InGizmoYAxisColor, const FColor& InGizmoZAxisColor,
const bool bInPersistentLines, const float InLifeTimeModifier, const uint8 InDepthPriority)
const FVector& InCubeExtent,
const FColor& InCubeColor,
const float InCubeThickness,
const float InGizmoLength,
const float InGizmoThickness,
const FColor& InGizmoXAxisColor,
const FColor& InGizmoYAxisColor,
const FColor& InGizmoZAxisColor,
const bool bInPersistentLines,
const float InLifeTimeModifier,
const uint8 InDepthPriority)
: bDrawDebugVirtualHand(bInDrawDebugVirtualHand),
DrawingMode(InDrawingMode),
CubeExtent(InCubeExtent),
@@ -0,0 +1,47 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGSettings/SGGloveTrackingSettings.h"
FSGGloveTrackingSettings::FSGGloveTrackingSettings()
: GloveConnectivityCheckInterval(0.125f)
{
}
FSGGloveTrackingSettings::FSGGloveTrackingSettings(
const float InGloveConnectivityCheckInterval)
: GloveConnectivityCheckInterval(InGloveConnectivityCheckInterval)
{
}
@@ -0,0 +1,47 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGSettings/SGHMDTrackingSettings.h"
FSGHMDTrackingSettings::FSGHMDTrackingSettings()
: ViveHMDDetectionPriority(ESGViveHMDDetectionPriority::HtcViveFocus3First)
{
}
FSGHMDTrackingSettings::FSGHMDTrackingSettings(
const ESGViveHMDDetectionPriority InViveHmdDetectionPriority)
: ViveHMDDetectionPriority(InViveHmdDetectionPriority)
{
}
@@ -0,0 +1,50 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGSettings/SGHandTrackingSettings.h"
FSGHandTrackingSettings::FSGHandTrackingSettings()
: bUseMoreSpecificMotionSourceNames(false),
bSupportLegacyControllerMotionSources(true)
{
}
FSGHandTrackingSettings::FSGHandTrackingSettings(
const bool bInUseMoreSpecificMotionSourceNames,
const bool bInSupportLegacyControllerMotionSources)
: bUseMoreSpecificMotionSourceNames(bInUseMoreSpecificMotionSourceNames),
bSupportLegacyControllerMotionSources(bInSupportLegacyControllerMotionSources)
{
}
@@ -77,23 +77,7 @@ USGSettings* USGSettings::GetInstance()
USGSettings::USGSettings()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
WristTrackingSettings = FSGWristTrackingSettings(
ESGPositionalTrackingHardware::None,
FVector::ZeroVector,
FVector::ZeroVector,
FRotator::ZeroRotator,
FRotator::ZeroRotator,
EControllerHand::Left,
EControllerHand::Right,
false,
FSGDebugGizmoSettings(
4.0f, 1.0f,
FColor(255, 0, 0, 255),
FColor(0, 255, 0, 255),
FColor(0, 0, 255, 255),
false, 1.1f, 0
)
);
TrackingSettings = FSGTrackingSettings{};
}
bool USGSettings::ShouldCreateSubsystem(UObject* Outer) const
@@ -116,7 +100,7 @@ void USGSettings::Deinitialize()
Super::Deinitialize();
(void)Pimpl.Release();
(void) Pimpl.Release();
SGLOG("The SenseGlove settings singleton has been successfully de-initialized!");
}
@@ -1,4 +1,4 @@
/**
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
@@ -33,46 +33,23 @@
*/
#include "SGKismet/SGHeadMountedDisplayKismetLibrary.h"
#include "SGSettings/SGTrackingSettings.h"
#include "SenseGlove/SGHeadMountedDisplay.h"
FName UHeadMountedDisplayKismetLibrary::GetDeviceName()
FSGTrackingSettings::FSGTrackingSettings()
: bFallbackToHandTrackingIfNoGloveDetected(true)
{
return FSGHeadMountedDisplay::GetDeviceName();
}
bool UHeadMountedDisplayKismetLibrary::IsMetaQuest2()
FSGTrackingSettings::FSGTrackingSettings(
const bool bInFallbackToHandTrackingIfNoGloveDetected,
const FSGGloveTrackingSettings& InGloveTrackingSettings,
const FSGHandTrackingSettings& InHandTrackingSettings,
const FSGHMDTrackingSettings& InHmdTrackingSettings,
const FSGWristTrackingSettings& InWristTrackingSettings)
: bFallbackToHandTrackingIfNoGloveDetected(bInFallbackToHandTrackingIfNoGloveDetected),\
GloveTrackingSettings(InGloveTrackingSettings),
HandTrackingSettings(InHandTrackingSettings),
HMDTrackingSettings(InHmdTrackingSettings),
WristTrackingSettings(InWristTrackingSettings)
{
return FSGHeadMountedDisplay::IsMetaQuest2();
}
bool UHeadMountedDisplayKismetLibrary::IsMetaQuestPro()
{
return FSGHeadMountedDisplay::IsMetaQuestPro();
}
bool UHeadMountedDisplayKismetLibrary::IsMetaQuest3()
{
return FSGHeadMountedDisplay::IsMetaQuest3();
}
bool UHeadMountedDisplayKismetLibrary::IsHtcVivePro()
{
return FSGHeadMountedDisplay::IsHtcVivePro();
}
bool UHeadMountedDisplayKismetLibrary::IsHtcViveFocus3()
{
return FSGHeadMountedDisplay::IsHtcViveFocus3();
}
bool UHeadMountedDisplayKismetLibrary::IsHtcViveXRElite()
{
return FSGHeadMountedDisplay::IsHtcViveXRElite();
}
ESGHeadMountedDisplayDevice UHeadMountedDisplayKismetLibrary::GetDeviceType()
{
return FSGHeadMountedDisplay::GetDeviceType();
}
@@ -43,8 +43,8 @@ FSGWristTrackingSettings::FSGWristTrackingSettings()
TrackingHardwareRotationOffsetRightHand(FRotator::ZeroRotator),
LeftHandMotionSource(EControllerHand::Left),
RightHandMotionSource(EControllerHand::Right),
bDrawWristTrackerDebugGizmo(false),
WristTrackerDebugGizmoSettings(FSGDebugGizmoSettings())
bDrawDebugGizmo(false),
DebugGizmoSettings(FSGDebugGizmoSettings{})
{
}
@@ -56,8 +56,8 @@ FSGWristTrackingSettings::FSGWristTrackingSettings(
const FRotator& InTrackingHardwareRotationOffsetRightHand,
const EControllerHand InLeftHandMotionSource,
const EControllerHand InRightHandMotionSource,
const bool bInDrawWristTrackerDebugGizmo,
const FSGDebugGizmoSettings& InWristTrackerDebugGizmoSettings)
const bool bInDrawDebugGizmo,
const FSGDebugGizmoSettings& InDebugGizmoSettings)
: TrackingHardware(InTrackingHardware),
TrackingHardwareLocationOffsetLeftHand(InTrackingHardwareLocationOffsetLeftHand),
TrackingHardwareLocationOffsetRightHand(InTrackingHardwareLocationOffsetRightHand),
@@ -65,7 +65,7 @@ FSGWristTrackingSettings::FSGWristTrackingSettings(
TrackingHardwareRotationOffsetRightHand(InTrackingHardwareRotationOffsetRightHand),
LeftHandMotionSource(InLeftHandMotionSource),
RightHandMotionSource(InRightHandMotionSource),
bDrawWristTrackerDebugGizmo(bInDrawWristTrackerDebugGizmo),
WristTrackerDebugGizmoSettings(InWristTrackerDebugGizmoSettings)
bDrawDebugGizmo(bInDrawDebugGizmo),
DebugGizmoSettings(InDebugGizmoSettings)
{
}
@@ -70,12 +70,14 @@ public:
uint8 DepthPriority;
public:
explicit FSGDebugGizmoSettings(float InLength = 1.0f,
float InThickness = 1.0f,
const FColor& InXAxisColor = FColor(255, 0, 0, 255),
const FColor& InYAxisColor = FColor(0, 255, 0, 255),
const FColor& InZAxisColor = FColor(0, 0, 255, 255),
bool bInPersistentLines = false,
float InLifeTimeModifier = 1.1f,
uint8 InDepthPriority = 0);
FSGDebugGizmoSettings();
FSGDebugGizmoSettings(float InLength,
float InThickness,
const FColor& InXAxisColor,
const FColor& InYAxisColor,
const FColor& InZAxisColor,
bool bInPersistentLines,
float InLifeTimeModifier,
uint8 InDepthPriority);
};
@@ -55,64 +55,75 @@ public:
ESGDebugVirtualHandDrawingMode DrawingMode;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints",
EditConditionHides))
FVector CubeExtent;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints",
EditConditionHides))
FColor CubeColor;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints",
EditConditionHides))
float CubeThickness;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
float GizmoLength;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
float GizmoThickness;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
FColor GizmoXAxisColor;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
FColor GizmoYAxisColor;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
FColor GizmoZAxisColor;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
uint8 bPersistentLines : 1;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
float LifeTimeModifier;
UPROPERTY(EditAnywhere, Category = "Debug Virtual Hand Settings",
meta=(EditCondition="DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", EditConditionHides))
meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints",
EditConditionHides))
uint8 DepthPriority;
public:
FSGDebugVirtualHandSettings();
explicit FSGDebugVirtualHandSettings(
FSGDebugVirtualHandSettings(
bool bInDrawDebugVirtualHand,
ESGDebugVirtualHandDrawingMode InDrawingMode = ESGDebugVirtualHandDrawingMode::None,
const FVector& InCubeExtent = FVector(0.5f, 0.5f, 0.5f),
const FColor& InCubeColor = FColor(255, 0, 0, 255),
float InCubeThickness = 0.1f,
float InGizmoLength = 1.0f,
float InGizmoThickness = 0.2f,
const FColor& InGizmoXAxisColor = FColor(255, 0, 0, 255),
const FColor& InGizmoYAxisColor = FColor(0, 255, 0, 255),
const FColor& InGizmoZAxisColor = FColor(0, 0, 255, 255),
bool bInPersistentLines = false,
float InLifeTimeModifier = 1.1f,
uint8 InDepthPriority = 0);
ESGDebugVirtualHandDrawingMode InDrawingMode,
const FVector& InCubeExtent,
const FColor& InCubeColor,
float InCubeThickness,
float InGizmoLength,
float InGizmoThickness,
const FColor& InGizmoXAxisColor,
const FColor& InGizmoYAxisColor,
const FColor& InGizmoZAxisColor,
bool bInPersistentLines,
float InLifeTimeModifier,
uint8 InDepthPriority);
};
@@ -0,0 +1,62 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "UObject/ObjectMacros.h"
#include "SGGloveTrackingSettings.generated.h"
/**
* Implements the glove tracking settings for the SenseGlove Tracking module.
*/
USTRUCT(BlueprintType)
struct SENSEGLOVESETTINGS_API FSGGloveTrackingSettings
{
GENERATED_USTRUCT_BODY()
public:
/**
* The interval to check for glove connectivity. The default is 0.125f which means 8 times in each second.
*/
UPROPERTY(Config, EditDefaultsOnly, Category="Glove Tracking")
float GloveConnectivityCheckInterval;
public:
FSGGloveTrackingSettings();
explicit FSGGloveTrackingSettings(
float InGloveConnectivityCheckInterval);
};
@@ -0,0 +1,65 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "UObject/ObjectMacros.h"
#include "SGTypes/SGTrackingTypes.h"
#include "SGHMDTrackingSettings.generated.h"
/**
* Implements the hand tracking settings for the SenseGlove Tracking module.
*/
USTRUCT(BlueprintType)
struct SENSEGLOVESETTINGS_API FSGHMDTrackingSettings
{
GENERATED_USTRUCT_BODY()
public:
/**
* Used to determine which VIVE HMD should we try to detect first, since we cannot distinguish between
* HTC VIVE Focus 3 and HTC VIVE XR Elite.
*/
UPROPERTY(Config, EditDefaultsOnly, Category="HMD Tracking")
ESGViveHMDDetectionPriority ViveHMDDetectionPriority;
public:
FSGHMDTrackingSettings();
explicit FSGHMDTrackingSettings(
ESGViveHMDDetectionPriority InViveHmdDetectionPriority);
};
@@ -0,0 +1,72 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "UObject/ObjectMacros.h"
#include "SGHandTrackingSettings.generated.h"
/**
* Implements the hand tracking settings for the SenseGlove Tracking module.
*/
USTRUCT(BlueprintType)
struct SENSEGLOVESETTINGS_API FSGHandTrackingSettings
{
GENERATED_USTRUCT_BODY()
public:
/**
* If false (the default) the motion sources for hand tracking will be of the form '[Left|Right][Keypoint]'. If
* true they will be of the form 'HandTracking[Left|Right][Keypoint]'. True is recommended to avoid collisions
* between motion sources from different device types.
*/
UPROPERTY(Config, EditDefaultsOnly, Category="Hand Tracking")
uint8 bUseMoreSpecificMotionSourceNames : 1;
/**
* If true hand tracking supports the 'Left' and 'Right' legacy motion sources. If false it does not. False is
* recommended unless you need legacy compatibility in an older unreal projects.
*/
UPROPERTY(Config, EditDefaultsOnly, Category="Hand Tracking")
uint8 bSupportLegacyControllerMotionSources : 1;
public:
FSGHandTrackingSettings();
FSGHandTrackingSettings(
bool bInUseMoreSpecificMotionSourceNames,
bool bInSupportLegacyControllerMotionSources);
};
@@ -42,10 +42,13 @@
#include "Templates/UniquePtr.h"
#include "UObject/ObjectMacros.h"
#include "SGSettings/SGWristTrackingSettings.h"
#include "SGSettings/SGTrackingSettings.h"
#include "SGSettings.generated.h"
/**
* Implements the settings for the SenseGlove Unreal Engine Plugin.
*/
UCLASS(config = SenseGloveSettings)
class SENSEGLOVESETTINGS_API USGSettings : public UEngineSubsystem
{
@@ -67,20 +70,20 @@ private:
private:
UPROPERTY(Config, EditDefaultsOnly, Category = "SenseGlove")
FSGWristTrackingSettings WristTrackingSettings;
FSGTrackingSettings TrackingSettings;
private:
USGSettings();
public:
FORCEINLINE const FSGWristTrackingSettings& GetWristTrackingSettings() const
FORCEINLINE const FSGTrackingSettings& GetTrackingSettings() const
{
return WristTrackingSettings;
return TrackingSettings;
}
void SetWristTrackingSettings(const FSGWristTrackingSettings& InWristTrackingSettings)
void SetTrackingSettings(const FSGTrackingSettings& InTrackingSettings)
{
WristTrackingSettings = InWristTrackingSettings;
TrackingSettings = InTrackingSettings;
}
public:
@@ -0,0 +1,85 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "UObject/ObjectMacros.h"
#include "SGSettings/SGGloveTrackingSettings.h"
#include "SGSettings/SGHandTrackingSettings.h"
#include "SGSettings/SGHMDTrackingSettings.h"
#include "SGSettings/SGWristTrackingSettings.h"
#include "SGTrackingSettings.generated.h"
/**
* Implements the settings for the SenseGlove Tracking module.
*/
USTRUCT(BlueprintType)
struct SENSEGLOVESETTINGS_API FSGTrackingSettings
{
GENERATED_USTRUCT_BODY()
public:
/**
* If false, only a real glove will be tracked, otherwise will fall back to hand tracking if available and
* supported by the HMD device.
*/
UPROPERTY(Config, EditDefaultsOnly, Category="Tracking")
uint8 bFallbackToHandTrackingIfNoGloveDetected : 1;
UPROPERTY(Config, EditDefaultsOnly, Category="Tracking")
FSGGloveTrackingSettings GloveTrackingSettings;
UPROPERTY(Config, EditDefaultsOnly, Category="Tracking",
meta=(EditCondition="bFallbackToHandTrackingIfNoGloveDetected", EditConditionHides))
FSGHandTrackingSettings HandTrackingSettings;
UPROPERTY(Config, EditDefaultsOnly, Category="Tracking")
FSGHMDTrackingSettings HMDTrackingSettings;
UPROPERTY(Config, EditDefaultsOnly, Category="Tracking")
FSGWristTrackingSettings WristTrackingSettings;
public:
FSGTrackingSettings();
FSGTrackingSettings(
bool bInFallbackToHandTrackingIfNoGloveDetected,
const FSGGloveTrackingSettings& InGloveTrackingSettings,
const FSGHandTrackingSettings& InHandTrackingSettings,
const FSGHMDTrackingSettings& InHmdTrackingSettings,
const FSGWristTrackingSettings& InWristTrackingSettings);
};
@@ -100,20 +100,20 @@ public:
/**
* If enabled, draws debug Wrist trackers where possible.
*/
UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Wrist Tracking")
uint8 bDrawWristTrackerDebugGizmo : 1;
UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking | Debug")
uint8 bDrawDebugGizmo : 1;
/**
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
* Valid only if bDrawDebugGizmo is enabled.
*/
UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Wrist Tracking",
meta=(EditCondition="bDrawWristTrackerDebugGizmo", EditConditionHides))
FSGDebugGizmoSettings WristTrackerDebugGizmoSettings;
UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking | Debug",
meta=(EditCondition="bDrawDebugGizmo", EditConditionHides))
FSGDebugGizmoSettings DebugGizmoSettings;
public:
FSGWristTrackingSettings();
explicit FSGWristTrackingSettings(
FSGWristTrackingSettings(
ESGPositionalTrackingHardware InTrackingHardware,
const FVector& InTrackingHardwareLocationOffsetLeftHand,
const FVector& InTrackingHardwareLocationOffsetRightHand,
@@ -121,6 +121,6 @@ public:
const FRotator& InTrackingHardwareRotationOffsetRightHand,
EControllerHand InLeftHandMotionSource,
EControllerHand InRightHandMotionSource,
bool bInDrawWristTrackerDebugGizmo,
const FSGDebugGizmoSettings& InWristTrackerDebugGizmoSettings);
bool bInDrawDebugGizmo,
const FSGDebugGizmoSettings& InDebugGizmoSettings);
};
@@ -42,13 +42,13 @@ USGSettings* USGSettingsKismetLibrary::GetInstance()
return USGSettings::GetInstance();
}
const FSGWristTrackingSettings& USGSettingsKismetLibrary::GetWristTrackingSettings(const USGSettings* Settings)
const FSGTrackingSettings& USGSettingsKismetLibrary::GetTrackingSettings(const USGSettings* Settings)
{
return Settings->GetWristTrackingSettings();
return Settings->GetTrackingSettings();
}
void USGSettingsKismetLibrary::SetWristTrackingSettings(
USGSettings* Settings, const FSGWristTrackingSettings& InWristTrackingSettings)
void USGSettingsKismetLibrary::SetTrackingSettings(
USGSettings* Settings, const FSGTrackingSettings& InTrackingSettings)
{
Settings->SetWristTrackingSettings(InWristTrackingSettings);
}
Settings->SetTrackingSettings(InTrackingSettings);
}
@@ -37,6 +37,7 @@
#include "SGKismet/SGBlueprintFunctionLibrary.h"
#include "SGSettings/SGWristTrackingSettings.h"
#include "SGSettings/SGTrackingSettings.h"
#include "SGSettingsKismetLibrary.generated.h"
@@ -52,9 +53,9 @@ public:
static USGSettings* GetInstance();
UFUNCTION(BlueprintPure, Category="SenseGlove | Settings")
static const FSGWristTrackingSettings& GetWristTrackingSettings(const USGSettings* Settings);
static const FSGTrackingSettings& GetTrackingSettings(const USGSettings* Settings);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Settings")
static void SetWristTrackingSettings(UPARAM(ref) USGSettings* Settings,
const FSGWristTrackingSettings& InWristTrackingSettings);
static void SetTrackingSettings(UPARAM(ref) USGSettings* Settings,
const FSGTrackingSettings& InTrackingSettings);
};
@@ -0,0 +1,279 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGTracking/SGGloveTracker.h"
#if WITH_EDITOR
#include "Editor.h"
#endif /* WITH_EDITOR */
#include "Engine/Engine.h"
#include "Engine/TimerHandle.h"
#include "Engine/World.h"
#include "Subsystems/UnrealEditorSubsystem.h"
#include "TimerManager.h"
#include "SGBackend/SGBackend.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGCore/SGHapticGlove.h"
#include "SGLog/SGLog.h"
#include "SGSettings/SGSettings.h"
#include "SGSettings/SGTrackingSettings.h"
struct USGGloveTracker::FImpl
{
/************************
* Static methods
************************/
static UWorld* GetWorld();
FORCEINLINE static float GetGloveConnectivityCheckInterval()
{
const USGSettings* Settings{USGSettings::GetInstance()};
ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!"));
return Settings->GetTrackingSettings().GloveTrackingSettings.GloveConnectivityCheckInterval;
}
/************************
* Member variables
************************/
FTimerHandle GloveConnectivityCheckTimer;
/************************
* Owner object
************************/
USGGloveTracker* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(USGGloveTracker* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
/************************
* Methods
************************/
void UpdateGloves() const;
};
UWorld* USGGloveTracker::FImpl::GetWorld()
{
UWorld* World{nullptr};
#if WITH_EDITOR
if (GIsEditor)
{
if (IsValid(GEditor))
{
const bool bIsPIE = GPlayInEditorID != -1;
if (!bIsPIE)
{
const FWorldContext* WorldContext{GEditor->GetPIEWorldContext(1)};
if (WorldContext)
{
World = WorldContext->World();
}
}
else
{
const FWorldContext* WorldContext{GEditor->GetPIEWorldContext(GPlayInEditorID)};
if (WorldContext)
{
World = WorldContext->World();
}
}
if (!IsValid(World))
{
UUnrealEditorSubsystem* UnrealEditorSubsystem{GEditor->GetEditorSubsystem<UUnrealEditorSubsystem>()};
if (IsValid(UnrealEditorSubsystem))
{
World = UnrealEditorSubsystem->GetEditorWorld();
}
}
}
if (!IsValid(World) && IsValid(GEngine))
{
const UGameViewportClient* Viewport{GEngine->GameViewport};
if (IsValid(Viewport))
{
World = Viewport->GetWorld();
}
}
}
else
{
if (IsValid(GEngine))
{
World = GEngine->GetCurrentPlayWorld(nullptr);
}
}
#else /* WITH_EDITOR */
if (IsValid(GEngine))
{
World = GEngine->GetCurrentPlayWorld(nullptr);
}
#endif /* WITH_EDITOR */
if (!IsValid(World) && IsValid(GEngine))
{
UEngineSubsystem* EngineSubsystem{GEngine->GetEngineSubsystem<UEngineSubsystem>()};
if (IsValid(EngineSubsystem))
{
World = EngineSubsystem->GetWorld();
}
}
return World;
}
USGGloveTracker* USGGloveTracker::GetInstance()
{
UWorld* World{FImpl::GetWorld()};
USGGloveTracker* Instance{IsValid(World) ? World->GetSubsystem<USGGloveTracker>() : nullptr};
return Instance;
}
USGGloveTracker::USGGloveTracker()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter)),
LeftGlove(nullptr),
RightGlove(nullptr)
{
}
bool USGGloveTracker::ShouldCreateSubsystem(UObject* Outer) const
{
return true;
}
void USGGloveTracker::Initialize(FSubsystemCollectionBase& Collection)
{
SGLOG("Initializing the SenseGlove tracking singleton with the world lifetime...");
Super::Initialize(Collection);
const UWorld* World{GetWorld()};
if (ensureAlwaysMsgf(World, TEXT("Invalid world!")))
{
SGLOG("Starting the glove connectivity check timer...");
const float GloveConnectivityCheckInterval = FImpl::GetGloveConnectivityCheckInterval();
FTimerDelegate GloveConnectivityCheckHandler;
GloveConnectivityCheckHandler.BindLambda([= SG_CAPTURE_THIS]()-> void
{
Pimpl->UpdateGloves();
});
FTimerManager& TimerManager = World->GetTimerManager();
TimerManager.SetTimer(
Pimpl->GloveConnectivityCheckTimer, GloveConnectivityCheckHandler, GloveConnectivityCheckInterval,
true, -1.0f);
SGLOG("The glove connectivity check timer has been started successfully!");
}
SGLOG("The SenseGlove tracking singleton has been successfully initialized with the world lifetime!");
}
void USGGloveTracker::Deinitialize()
{
SGLOG("De-initializing the SenseGlove tracking singleton due to the world lifetime expiration...");
Super::Deinitialize();
const UWorld* World{GetWorld()};
if (ensureAlwaysMsgf(World, TEXT("Invalid world!")))
{
SGLOG("Stopping the glove connectivity check timer...");
FTimerManager& TimerManager = World->GetTimerManager();
TimerManager.ClearTimer(Pimpl->GloveConnectivityCheckTimer);
SGLOG("The glove connectivity check timer has been stopped successfully!");
}
(void) Pimpl.Release();
SGLOG("The SenseGlove tracking singleton has been successfully de-initialized!");
}
USGGloveTracker::FImpl::FImpl(USGGloveTracker* InOwner)
: Owner(InOwner)
{
}
USGGloveTracker::FImpl::~FImpl() = default;
void USGGloveTracker::FImpl::UpdateGloves() const
{
if (!USGBackend::GetInstance()->IsBackendInitialized())
{
const bool bSucceeded = USGBackend::GetInstance()->InitializeBackend();
if (!bSucceeded)
{
return;
}
}
const bool bIsLeftGloveConnected = USGHapticGlove::GetGlove(Owner, false, Owner->LeftGlove);
if (!bIsLeftGloveConnected)
{
Owner->LeftGlove = nullptr;
}
const bool bIsRightGloveConnected = USGHapticGlove::GetGlove(Owner, true, Owner->RightGlove);
if (!bIsRightGloveConnected)
{
Owner->RightGlove = nullptr;
}
}
void USGGloveTracker::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -33,13 +33,15 @@
*/
#include "SenseGlove/SGHeadMountedDisplay.h"
#include "SGTracking/SGHMDTracker.h"
#include "Engine/Engine.h"
#include "IHeadMountedDisplay.h"
#include "IXRTrackingSystem.h"
FName FSGHeadMountedDisplay::GetDeviceName()
#include "SGSettings/SGSettings.h"
FName FSGHMDTracker::GetDeviceName()
{
if (GEngine && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed())
{
@@ -53,7 +55,7 @@ FName FSGHeadMountedDisplay::GetDeviceName()
return NAME_None;
}
bool FSGHeadMountedDisplay::IsMetaQuest2()
bool FSGHMDTracker::IsMetaQuest2()
{
static const FName MetaQuest2DeviceIdentifier{TEXT("Meta Quest 2")};
static const FName OculusQuest2DeviceIdentifier{TEXT("Oculus Quest2")};
@@ -72,7 +74,7 @@ bool FSGHeadMountedDisplay::IsMetaQuest2()
return bMatched;
}
bool FSGHeadMountedDisplay::IsMetaQuestPro()
bool FSGHMDTracker::IsMetaQuestPro()
{
static const FName MetaQuestProDeviceIdentifier{TEXT("Meta Quest Pro")};
static const FName OculusQuestProDeviceIdentifier{TEXT("Oculus QuestPro")};
@@ -91,7 +93,7 @@ bool FSGHeadMountedDisplay::IsMetaQuestPro()
return bMatched;
}
bool FSGHeadMountedDisplay::IsMetaQuest3()
bool FSGHMDTracker::IsMetaQuest3()
{
static const FName MetaQuest3DeviceIdentifier{TEXT("Meta Quest 3")};
static const FName OculusQuest3DeviceIdentifier{TEXT("Oculus Quest3")};
@@ -110,7 +112,7 @@ bool FSGHeadMountedDisplay::IsMetaQuest3()
return bMatched;
}
bool FSGHeadMountedDisplay::IsHtcVivePro()
bool FSGHMDTracker::IsHtcVivePro()
{
#if PLATFORM_ANDROID
return false;
@@ -165,7 +167,7 @@ bool FSGHeadMountedDisplay::IsHtcVivePro()
#endif /* PLATFORM_ANDROID */
}
bool FSGHeadMountedDisplay::IsHtcViveFocus3()
bool FSGHMDTracker::IsHtcViveFocus3()
{
static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")};
static const FString ViveDeviceIdentifier{TEXT("Vive")};
@@ -225,7 +227,7 @@ bool FSGHeadMountedDisplay::IsHtcViveFocus3()
return bMatched;
}
bool FSGHeadMountedDisplay::IsHtcViveXRElite()
bool FSGHMDTracker::IsHtcViveXRElite()
{
static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")};
static const FString ViveDeviceIdentifier{TEXT("Vive")};
@@ -285,7 +287,7 @@ bool FSGHeadMountedDisplay::IsHtcViveXRElite()
return bMatched;
}
ESGHeadMountedDisplayDevice FSGHeadMountedDisplay::GetDeviceType()
ESGHeadMountedDisplayDevice FSGHMDTracker::GetDeviceType()
{
if (IsMetaQuest2())
{
@@ -307,14 +309,32 @@ ESGHeadMountedDisplayDevice FSGHeadMountedDisplay::GetDeviceType()
return ESGHeadMountedDisplayDevice::HtcVivePro;
}
if (IsHtcViveFocus3())
const USGSettings* Settings{USGSettings::GetInstance()};
ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!"));
if (Settings->GetTrackingSettings().HMDTrackingSettings.ViveHMDDetectionPriority ==
ESGViveHMDDetectionPriority::HtcViveFocus3First)
{
return ESGHeadMountedDisplayDevice::HtcViveFocus3;
}
if (IsHtcViveFocus3())
{
return ESGHeadMountedDisplayDevice::HtcViveFocus3;
}
if (IsHtcViveXRElite())
if (IsHtcViveXRElite())
{
return ESGHeadMountedDisplayDevice::HtcViveXRElite;
}
}
else
{
return ESGHeadMountedDisplayDevice::HtcViveXRElite;
if (IsHtcViveXRElite())
{
return ESGHeadMountedDisplayDevice::HtcViveXRElite;
}
if (IsHtcViveFocus3())
{
return ESGHeadMountedDisplayDevice::HtcViveFocus3;
}
}
return ESGHeadMountedDisplayDevice::None;
@@ -0,0 +1,70 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGTracking/SGXRHandState.h"
FSGXRHandState::FSGXRHandState()
: HandTracker{},
JointLocations{},
JointVelocities{},
Velocities{XR_TYPE_HAND_JOINT_VELOCITIES_EXT},
Locations{XR_TYPE_HAND_JOINT_LOCATIONS_EXT},
KeypointTransforms{},
Radii{},
bReceivedJointPoses(false)
{
Velocities.jointCount = XR_HAND_JOINT_COUNT_EXT;
Velocities.jointVelocities = JointVelocities;
Locations.next = &Velocities;
Locations.jointCount = XR_HAND_JOINT_COUNT_EXT;
Locations.jointLocations = JointLocations;
}
FSGXRHandState::~FSGXRHandState() = default;
bool FSGXRHandState::GetTransform(const EHandKeypoint Keypoint, FTransform& OutTransform) const
{
check(static_cast<int32>(Keypoint) < EHandKeypointCount);
OutTransform = KeypointTransforms[static_cast<uint32>(Keypoint)];
return !!bReceivedJointPoses;
}
const FTransform& FSGXRHandState::GetTransform(const EHandKeypoint Keypoint) const
{
check(static_cast<int32>(Keypoint) < EHandKeypointCount);
return KeypointTransforms[static_cast<uint32>(Keypoint)];
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,42 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SenseGloveTracking.h"
#include "Modules/ModuleManager.h"
#include "SenseGloveTrackingModule.h"
IMPLEMENT_MODULE(FSenseGloveTrackingModule, SenseGloveTracking)
@@ -0,0 +1,38 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "CoreMinimal.h"
@@ -0,0 +1,181 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SenseGloveTrackingModule.h"
#include "SGLog/SGLog.h"
#include "SGTracking/SGXRTracker.h"
#define LOCTEXT_NAMESPACE "FSenseGloveTrackingModule"
struct FSenseGloveTrackingModule::FImpl
{
/************************
* Member variables
************************/
TSharedPtr<FSGXRTracker> InputDevice;
/************************
* Owner object
************************/
FSenseGloveTrackingModule* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSenseGloveTrackingModule* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSenseGloveTrackingModule::FSenseGloveTrackingModule()
: IInputDeviceModule(),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSenseGloveTrackingModule::FSenseGloveTrackingModule(const FSenseGloveTrackingModule& Rhs)
: IInputDeviceModule(Rhs),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSenseGloveTrackingModule::FSenseGloveTrackingModule(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT = default;
FSenseGloveTrackingModule::~FSenseGloveTrackingModule() = default;
FSenseGloveTrackingModule& FSenseGloveTrackingModule::operator=(const FSenseGloveTrackingModule& Rhs)
{
IInputDeviceModule::operator=(Rhs);
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSenseGloveTrackingModule& FSenseGloveTrackingModule::operator=(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT = default;
void FSenseGloveTrackingModule::StartupModule()
{
SGLOG("Starting up SenseGloveTracking module...");
IInputDeviceModule::StartupModule();
/// HACK!
// Generic Application might not be instantiated at this point so we create the input device with a dummy message
// handler. When the Generic Application creates the input device it passes a valid message handler to it which is
// further on used for all the controller events. This hack fixes issues caused by using a custom input device
// before the Generic Application has instantiated it. Eg. within BeginPlay().
// This also fixes the warnings that pop up on the custom input keys when the blueprint loads. Those warnings are
// caused because Unreal loads the Blueprints before the input device has been instantiated and has added its keys,
// thus leading Unreal to believe that those keys don't exist. This hack causes an earlier instantiation of the
// input device, and consequently, the custom keys.
TSharedPtr<FGenericApplicationMessageHandler> DummyMessageHandler(new FGenericApplicationMessageHandler());
CreateInputDevice(DummyMessageHandler.ToSharedRef());
}
void FSenseGloveTrackingModule::PreUnloadCallback()
{
SGLOG("Unloading SenseGloveTracking module...");
IInputDeviceModule::PreUnloadCallback();
}
void FSenseGloveTrackingModule::PostLoadCallback()
{
SGLOG("Loading of SenseGloveTracking module has succeeded!");
IInputDeviceModule::PostLoadCallback();
}
void FSenseGloveTrackingModule::ShutdownModule()
{
SGLOG("Shutting down SenseGloveTracking module...");
IInputDeviceModule::ShutdownModule();
}
TSharedPtr<IInputDevice> FSenseGloveTrackingModule::CreateInputDevice(
const TSharedRef<FGenericApplicationMessageHandler>& InMessageHandler)
{
SGLOG("Creating the SenseGloveTracking input device...");
if (!Pimpl->InputDevice.IsValid())
{
TSharedPtr<FSGXRTracker> HandTrackingInputDevice(new FSGXRTracker(InMessageHandler));
Pimpl->InputDevice = HandTrackingInputDevice;
}
else
{
Pimpl->InputDevice.Get()->SetMessageHandler(InMessageHandler);
}
return Pimpl->InputDevice;
}
TSharedPtr<IInputDevice> FSenseGloveTrackingModule::GetInputDevice()
{
if (!Pimpl->InputDevice.IsValid())
{
CreateInputDevice(FSlateApplication::Get().GetPlatformApplication()->GetMessageHandler());
}
return Pimpl->InputDevice;
}
FSenseGloveTrackingModule::FImpl::FImpl(FSenseGloveTrackingModule* InOwner)
: InputDevice(nullptr),
Owner(InOwner)
{
}
FSenseGloveTrackingModule::FImpl::~FImpl() = default;
void FSenseGloveTrackingModule::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,116 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "IInputDeviceModule.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#define LOCTEXT_NAMESPACE "SenseGloveTracking"
class FSenseGloveTrackingModule : public IInputDeviceModule
{
public:
static FORCEINLINE FSenseGloveTrackingModule& Get()
{
return FModuleManager::LoadModuleChecked<FSenseGloveTrackingModule>("SenseGloveTracking");
}
static FORCEINLINE bool IsAvailable()
{
return FModuleManager::Get().IsModuleLoaded("SenseGloveTracking");
}
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
/**
* The default constructor.
*/
FSenseGloveTrackingModule();
public:
/**
* The copy constructor.
*/
FSenseGloveTrackingModule(const FSenseGloveTrackingModule& Rhs);
/**
* The move constructor.
*/
FSenseGloveTrackingModule(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSenseGloveTrackingModule() override;
public:
/**
* The copy assignment operator.
*/
FSenseGloveTrackingModule& operator=(const FSenseGloveTrackingModule& Rhs);
/**
* The move assignment operator.
*/
FSenseGloveTrackingModule& operator=(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT;
public:
virtual void StartupModule() override;
virtual void PreUnloadCallback() override;
virtual void PostLoadCallback() override;
virtual void ShutdownModule() override;
public:
virtual TSharedPtr<class IInputDevice> CreateInputDevice(
const TSharedRef<FGenericApplicationMessageHandler>& InMessageHandler) override;
virtual TSharedPtr<IInputDevice> GetInputDevice();
};
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,117 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "Subsystems/WorldSubsystem.h"
#include "Templates/UniquePtr.h"
#include "UObject/Object.h"
#include "UObject/ObjectMacros.h"
#include "SGCore/SGHapticGlove.h"
#include "SGGloveTracker.generated.h"
UCLASS()
class SENSEGLOVETRACKING_API USGGloveTracker : public UWorldSubsystem
{
GENERATED_BODY()
public:
static USGGloveTracker* GetInstance();
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
private:
UPROPERTY(Transient)
USGHapticGlove* LeftGlove;
UPROPERTY(Transient)
USGHapticGlove* RightGlove;
private:
USGGloveTracker();
public:
FORCEINLINE USGHapticGlove* GetGlove(const bool bRight) const
{
return bRight ? RightGlove : LeftGlove;
}
FORCEINLINE USGHapticGlove* GetLeftGlove() const
{
return LeftGlove;
}
FORCEINLINE USGHapticGlove* GetRightGlove() const
{
return RightGlove;
}
FORCEINLINE bool IsGloveConnected(const bool bRight) const
{
return IsValid(GetGlove(bRight));
}
FORCEINLINE bool IsLeftGloveConnected() const
{
return IsValid(GetLeftGlove());
}
FORCEINLINE bool IsRightGloveConnected() const
{
return IsValid(GetRightGlove());
}
FORCEINLINE bool IsAnyGloveConnected() const
{
return IsLeftGloveConnected() || IsRightGloveConnected();
}
public:
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
};
@@ -39,15 +39,15 @@
#include "UObject/NameTypes.h"
#include "UObject/ObjectMacros.h"
#include "SGTypes/SGTypes.h"
#include "SGTypes/SGTrackingTypes.h"
#include "SGHeadMountedDisplay.generated.h"
#include "SGHMDTracker.generated.h"
/**
*
*/
USTRUCT()
struct SENSEGLOVE_API FSGHeadMountedDisplay
struct SENSEGLOVETRACKING_API FSGHMDTracker
{
GENERATED_BODY()
@@ -0,0 +1,68 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "HeadMountedDisplayTypes.h"
#include "IOpenXRExtensionPlugin.h"
#include "Math/MathFwd.h"
#include "Templates/UnrealTemplate.h"
struct SENSEGLOVETRACKING_API FSGXRHandState final : public FNoncopyable
{
public:
XrHandTrackerEXT HandTracker;
XrHandJointLocationEXT JointLocations[XR_HAND_JOINT_COUNT_EXT];
XrHandJointVelocityEXT JointVelocities[XR_HAND_JOINT_COUNT_EXT];
XrHandJointVelocitiesEXT Velocities;
XrHandJointLocationsEXT Locations;
// Transforms are cached in Unreal Tracking Space
FTransform KeypointTransforms[EHandKeypointCount];
float Radii[EHandKeypointCount];
uint8_t bReceivedJointPoses : 1;
public:
FSGXRHandState();
virtual ~FSGXRHandState();
public:
bool GetTransform(EHandKeypoint Keypoint, FTransform& OutTransform) const;
const FTransform& GetTransform(EHandKeypoint Keypoint) const;
};
@@ -0,0 +1,165 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "HeadMountedDisplayTypes.h"
#include "IHandTracker.h"
#include "IInputDevice.h"
#include "IOpenXRExtensionPlugin.h"
#include "Math/MathFwd.h"
#include "Runtime/Launch/Resources/Version.h"
#include "Templates/UniquePtr.h"
#include "UObject/NameTypes.h"
#include "XRMotionControllerBase.h"
#include "SGBuildHacks/SGPlatform.h"
struct SENSEGLOVETRACKING_API FSGXRHandState;
class SENSEGLOVETRACKING_API FSGXRTracker final : public IOpenXRExtensionPlugin,
public IInputDevice,
public FXRMotionControllerBase,
public IHandTracker
{
/**
* Parses the enum name removing the prefix.
*/
static FName ParseEOpenXRHandKeypointEnumName(const FName& EnumName);
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
private:
FSGXRTracker() = delete;
public:
FSGXRTracker(const TSharedRef<FGenericApplicationMessageHandler>& InMessageHandler);
public:
/**
* The copy constructor.
*/
FSGXRTracker(const FSGXRTracker& Rhs) = delete;
/**
* The move constructor.
*/
FSGXRTracker(FSGXRTracker&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGXRTracker() override;
public:
/**
* The copy assignment operator.
*/
FSGXRTracker& operator=(const FSGXRTracker& Rhs) = delete;
/**
* The move assignment operator.
*/
FSGXRTracker& operator=(FSGXRTracker&& Rhs) SG_NOEXCEPT;
public:
bool IsHandTrackingSupportedByDevice() const;
const FSGXRHandState& GetLeftHandState() const;
const FSGXRHandState& GetRightHandState() const;
public:
// The IOpenXRExtensionPlugin interface.
virtual FString GetDisplayName() override;
virtual bool GetRequiredExtensions(TArray<const ANSICHAR*>& OutExtensions) override;
virtual const void* OnGetSystem(XrInstance InInstance, const void* InNext) override;
virtual const void* OnCreateSession(XrInstance InInstance, XrSystemId InSystem, const void* InNext) override;
virtual const void* OnBeginSession(XrSession InSession, const void* InNext) override;
virtual void UpdateDeviceLocations(XrSession InSession, XrTime DisplayTime, XrSpace TrackingSpace) override;
public:
// The IMotionController interface.
#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3
virtual bool GetControllerOrientationAndPosition(const int32 ControllerIndex, const FName MotionSource,
FRotator& OutOrientation, FVector& OutPosition,
float WorldToMetersScale) const override;
virtual ETrackingStatus GetControllerTrackingStatus(const int32 ControllerIndex,
const FName MotionSource) const override;
#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */
virtual bool GetControllerOrientationAndPosition(const int32 ControllerIndex, const EControllerHand DeviceHand,
FRotator& OutOrientation, FVector& OutPosition,
float WorldToMetersScale) const override;
virtual ETrackingStatus GetControllerTrackingStatus(const int32 ControllerIndex,
const EControllerHand DeviceHand) const override;
#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */
virtual FName GetMotionControllerDeviceTypeName() const override;
virtual void EnumerateSources(TArray<FMotionControllerSource>& SourcesOut) const override;
public:
// The IInputDevice interface.
virtual void Tick(float DeltaTime) override;
virtual void SendControllerEvents() override;
virtual void SetMessageHandler(const TSharedRef<FGenericApplicationMessageHandler>& InMessageHandler) override;
virtual bool Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) override;
virtual void SetChannelValue(int32 ControllerId, FForceFeedbackChannelType ChannelType, float Value) override;
virtual void SetChannelValues(int32 ControllerId, const FForceFeedbackValues& Values) override;
virtual bool SupportsForceFeedback(int32 ControllerId) override;
virtual bool IsGamepadAttached() const override;
public:
// The IHandTracker interface.
virtual FName GetHandTrackerDeviceTypeName() const override;
virtual bool IsHandTrackingStateValid() const override;
virtual bool GetKeypointState(
EControllerHand Hand,
EHandKeypoint Keypoint, FTransform& OutTransform, float& OutRadius) const override;
virtual bool GetAllKeypointStates(
EControllerHand Hand,
TArray<FVector>& OutPositions, TArray<FQuat>& OutRotations, TArray<float>& OutRadii) const override;
};
@@ -0,0 +1,93 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
using System;
using UnrealBuildTool;
public class SenseGloveTracking : ModuleRules
{
public SenseGloveTracking(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PrivateDependencyModuleNames.AddRange(
new string[]
{
"ApplicationCore",
"Core",
"CoreUObject",
"Engine",
"HeadMountedDisplay",
"InputCore",
"InputDevice",
"OpenXRHMD",
"OpenXRInput",
// NOTE
// Only UE 5.3+ provides the XRBase plugin.
#if UE_5_3_OR_LATER
"XRBase",
#else
"OpenXR",
#endif
"Slate",
"SlateCore",
"SenseGloveBackend",
"SenseGloveCore",
"SenseGloveLog",
"SenseGloveSettings",
"SenseGloveTypes",
}
);
if (Target.bBuildEditor)
{
PrivateDependencyModuleNames.AddRange(
new string[]
{
"UnrealEd",
}
);
}
PrivateIncludePathModuleNames.AddRange(
new string[]
{
"SenseGloveBuildHacks",
}
);
AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenXR");
}
}
@@ -0,0 +1,79 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGTrackingKismet/SGGloveTrackerKismetLibrary.h"
#include "SGCore/SGHapticGlove.h"
#include "SGTracking/SGGloveTracker.h"
USGGloveTracker* USGGloveTrackerKismetLibrary::GetInstance()
{
return USGGloveTracker::GetInstance();
}
USGHapticGlove* USGGloveTrackerKismetLibrary::GetGlove(const USGGloveTracker* GloveTracker, const bool bRight)
{
return GloveTracker->GetGlove(bRight);
}
USGHapticGlove* USGGloveTrackerKismetLibrary::GetLeftGlove(const USGGloveTracker* GloveTracker)
{
return GloveTracker->GetLeftGlove();
}
USGHapticGlove* USGGloveTrackerKismetLibrary::GetRightGlove(const USGGloveTracker* GloveTracker)
{
return GloveTracker->GetRightGlove();
}
bool USGGloveTrackerKismetLibrary::IsGloveConnected(const USGGloveTracker* GloveTracker, const bool bRight)
{
return GloveTracker->IsGloveConnected(bRight);
}
bool USGGloveTrackerKismetLibrary::IsLeftGloveConnected(const USGGloveTracker* GloveTracker)
{
return GloveTracker->IsLeftGloveConnected();
}
bool USGGloveTrackerKismetLibrary::IsRightGloveConnected(const USGGloveTracker* GloveTracker)
{
return GloveTracker->IsRightGloveConnected();
}
bool USGGloveTrackerKismetLibrary::IsAnyGloveConnected(const USGGloveTracker* GloveTracker)
{
return GloveTracker->IsAnyGloveConnected();
}
@@ -0,0 +1,78 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGTrackingKismet/SGHMDTrackerKismetLibrary.h"
#include "SGTracking/SGHMDTracker.h"
FName USGHMDTrackerKismetLibrary::GetDeviceName()
{
return FSGHMDTracker::GetDeviceName();
}
bool USGHMDTrackerKismetLibrary::IsMetaQuest2()
{
return FSGHMDTracker::IsMetaQuest2();
}
bool USGHMDTrackerKismetLibrary::IsMetaQuestPro()
{
return FSGHMDTracker::IsMetaQuestPro();
}
bool USGHMDTrackerKismetLibrary::IsMetaQuest3()
{
return FSGHMDTracker::IsMetaQuest3();
}
bool USGHMDTrackerKismetLibrary::IsHtcVivePro()
{
return FSGHMDTracker::IsHtcVivePro();
}
bool USGHMDTrackerKismetLibrary::IsHtcViveFocus3()
{
return FSGHMDTracker::IsHtcViveFocus3();
}
bool USGHMDTrackerKismetLibrary::IsHtcViveXRElite()
{
return FSGHMDTracker::IsHtcViveXRElite();
}
ESGHeadMountedDisplayDevice USGHMDTrackerKismetLibrary::GetDeviceType()
{
return FSGHMDTracker::GetDeviceType();
}
@@ -0,0 +1,40 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SenseGloveTrackingKismet.h"
#include "Modules/ModuleManager.h"
#include "SenseGloveTrackingKismetModule.h"
IMPLEMENT_MODULE(FSenseGloveTrackingKismetModule, SenseGloveTrackingKismet)
@@ -0,0 +1,38 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "CoreMinimal.h"
@@ -0,0 +1,62 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SenseGloveTrackingKismetModule.h"
#include "SGLog/SGLog.h"
#define LOCTEXT_NAMESPACE "FSenseGloveTrackingKismetModule"
void FSenseGloveTrackingKismetModule::StartupModule()
{
SGLOG("Starting up the SenseGloveTrackingKismet module...");
}
void FSenseGloveTrackingKismetModule::PreUnloadCallback()
{
SGLOG("Unloading the SenseGloveTrackingKismet module...");
}
void FSenseGloveTrackingKismetModule::PostLoadCallback()
{
SGLOG("Loading of SenseGloveTrackingKismet module has succeeded!");
}
void FSenseGloveTrackingKismetModule::ShutdownModule()
{
SGLOG("Shutting down the SenseGloveTrackingKismet module...");
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,51 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "Modules/ModuleInterface.h"
#define LOCTEXT_NAMESPACE "SenseGloveTrackingKismet"
class FSenseGloveTrackingKismetModule : public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void PreUnloadCallback() override;
virtual void PostLoadCallback() override;
virtual void ShutdownModule() override;
};
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,75 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 "SGKismet/SGBlueprintFunctionLibrary.h"
#include "SGGloveTrackerKismetLibrary.generated.h"
class USGGloveTracker;
class USGHapticGlove;
UCLASS(meta=(ScriptName = "SesneGloveTrackerKismetLibrary"))
class SENSEGLOVETRACKINGKISMET_API USGGloveTrackerKismetLibrary final : public USGBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | Glove Tracker",
meta=(WorldContext="WorldContextObject"))
static USGGloveTracker* GetInstance();
UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker")
static USGHapticGlove* GetGlove(const USGGloveTracker* GloveTracker, const bool bRight);
UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker")
static USGHapticGlove* GetLeftGlove(const USGGloveTracker* GloveTracker);
UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker")
static USGHapticGlove* GetRightGlove(const USGGloveTracker* GloveTracker);
UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker")
static bool IsGloveConnected(const USGGloveTracker* GloveTracker, const bool bRight);
UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker")
static bool IsLeftGloveConnected(const USGGloveTracker* GloveTracker);
UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker")
static bool IsRightGloveConnected(const USGGloveTracker* GloveTracker);
UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker")
static bool IsAnyGloveConnected(const USGGloveTracker* GloveTracker);
};
@@ -1,4 +1,4 @@
/**
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
@@ -38,41 +38,41 @@
#include "UObject/NameTypes.h"
#include "SGKismet/SGBlueprintFunctionLibrary.h"
#include "SGTypes/SGTypes.h"
#include "SGTypes/SGTrackingTypes.h"
#include "SGHeadMountedDisplayKismetLibrary.generated.h"
#include "SGHMDTrackerKismetLibrary.generated.h"
UCLASS(meta=(ScriptName = "SesneGloveHeadMountedDisplayKismetLibrary"))
class SENSEGLOVEKISMET_API UHeadMountedDisplayKismetLibrary final : public USGBlueprintFunctionLibrary
UCLASS(meta=(ScriptName = "SesneGloveHeadMountDisplayKismetLibrary"))
class SENSEGLOVETRACKINGKISMET_API USGHMDTrackerKismetLibrary final : public USGBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static FName GetDeviceName();
/**
* Checks whether the HMD device is Meta Quest 2, or not.
*/
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static bool IsMetaQuest2();
/**
* Checks whether the HMD device is Meta Quest Pro, or not.
*/
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static bool IsMetaQuestPro();
/**
* Checks whether the HMD device is Meta Quest 3, or not.
*/
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static bool IsMetaQuest3();
/**
* Checks whether the HMD device is HTC VIVE Pro, or not.
*/
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static bool IsHtcVivePro();
/**
@@ -81,7 +81,7 @@ public:
* @remark At the moment, VIVE Focus 3 cannot be distinguished from VIVE XR Elite, so when IsHtcViveFocus3 returns
* true, IsHtcViveXRElite will return true as well; thus we cannot know for sure which headset we are running on.
*/
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static bool IsHtcViveFocus3();
/**
@@ -90,9 +90,9 @@ public:
* @remark At the moment, VIVE Focus 3 cannot be distinguished from VIVE XR Elite, so when IsHtcViveXRElite returns
* true, IsHtcViveFocus3 will return true as well; thus we cannot know for sure which headset we are running on.
*/
UFUNCTION(BlueprintCallable, Category = "SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static bool IsHtcViveXRElite();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head-mounted Display")
UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker")
static ESGHeadMountedDisplayDevice GetDeviceType();
};
@@ -0,0 +1,59 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
using System;
using UnrealBuildTool;
public class SenseGloveTrackingKismet : ModuleRules
{
public SenseGloveTrackingKismet(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PrivateDependencyModuleNames.AddRange(
new string[]
{
"Core",
"CoreUObject",
"Engine",
"SenseGloveCore",
"SenseGloveLog",
"SenseGloveKismet",
"SenseGloveTracking",
"SenseGloveTypes",
}
);
}
}
@@ -33,4 +33,4 @@
*/
#include "SGTypes/SGTypes.h"
#include "SGTypes/SGTrackingTypes.h"
@@ -38,7 +38,9 @@
#include "CoreTypes.h"
#include "UObject/ObjectMacros.h"
/* The Head-mounted Display device enum to determine the HMD device type. */
/**
* The Head-mounted Display device enum to determine the HMD device type.
*/
UENUM(BlueprintType)
enum class ESGHeadMountedDisplayDevice : uint8
{
@@ -62,4 +64,17 @@ enum class ESGHeadMountedDisplayDevice : uint8
/* The HTC VIVE XR Elite HMD. */
HtcViveXRElite UMETA(DisplayName = "HTC VIVE XR Elite"),
};
};
/*
* The
*/
UENUM(BlueprintType)
enum class ESGViveHMDDetectionPriority : uint8
{
/* First try to detect HTC VIVE Focus 3. */
HtcViveFocus3First UMETA(DisplayName = "HTC VIVE Focus 3 First"),
/* First try to detect HTC VIVE XR Elite. */
HtcViveXREliteFirst UMETA(DisplayName = "HTC VIVE XR Elite First"),
};