implement hmd and wrist tracker hardware auto-detection fallback when it's not set explicitly

This commit is contained in:
Mamadou Babaei
2024-08-16 18:02:02 +02:00
parent 3389686e98
commit 97ee90052d
9 changed files with 455 additions and 10 deletions
+7
View File
@@ -78,6 +78,13 @@ This is a patch release with no code changes.
This is a bugfix release. This is a bugfix release.
### Added
- A fallback to HMD and wrist tracker hardware auto-detection mechanism has been added to be triggered in situations when automatic detection of the wrist tracker hardware is desired, e.g., either by not setting it explicitly, or setting it to the default None value (still not fully reliable for HTC hardware as it's not able to distinguish VIVE Pro and VIVE Focus 3).
- Added the SGHeadMountDisplay utility class, exposed to both C++ and Blueprint, in order to easily gather information about the HMD at runtime.
- Added the SGTypes header to the SenseGloveTypes module in order to define and share SenseGlove module types through this header across the plugin modules.
- Added ESGHeadMountDisplayDevice enum with supported HMDs list.
### Fixed ### Fixed
- Fix a bug inside both SGVirtualHandComponent and SGWristTrackerComponent where the connected glove's UObject instance gets destroyed and re-instantiated every frame. With this fix now the glove instance will be created or destroyed only when a glove connects to or disconnects from the system. - Fix a bug inside both SGVirtualHandComponent and SGWristTrackerComponent where the connected glove's UObject instance gets destroyed and re-instantiated every frame. With this fix now the glove instance will be created or destroyed only when a glove connects to or disconnects from the system.
+2 -9
View File
@@ -84,15 +84,8 @@ Please note that modules postfixed with **Impl** are intended for interal use an
### Upcoming features planned for the v2.1.0 release ### Upcoming features planned for the v2.1.0 release
- [ ] A fallback to HMD and wrist tracker hardware auto-detection mechanism when automatic detection of the wrist tracker hardware is desired. - [ ] Hand tracking compatible with OpenXR (or other generic hand tracking format).
- [ ] OpenXR-compatible hand tracking (XR_EXT_hand_tracking) support. - [X] A fallback to HMD and wrist tracker hardware auto-detection mechanism when automatic detection of the wrist tracker hardware is desired.
- [ ] FXRMotionControllerData compatible hand animation system.
- [ ] FXRMotionControllerData compatible wrist tracking system.
- [ ] FXRMotionControllerData compatible hand interaction manipulation system.
- [ ] Ability to fallback to hand tracking when a glove is not present and use the bare hands for interactions, or a combination of glove and hand tracking if no motion controller input is detected.
- [ ] The SenseGlove grab/touch sockets one-click-setup ability on any Epic-compliant virtual hand mesh from within the Unreal Editor's Content Browser, Skeleton Editor, or Skeletal Mesh Editor.
- [ ] A flexible virtual hand animation system that can take the mesh bone's transforms into account for a more reliable hand animation.
- [ ] Ability to manage the Engine Scalability Settings through the SenseGlove plugin in order to change the graphics settings on the fly.
### Planned features long-term ### Planned features long-term
@@ -40,6 +40,7 @@
#include "Engine/SkeletalMesh.h" #include "Engine/SkeletalMesh.h"
#include "UObject/ConstructorHelpers.h" #include "UObject/ConstructorHelpers.h"
#include "SenseGlove/SGHeadMountDisplay.h"
#include "SGBackend/SGBackend.h" #include "SGBackend/SGBackend.h"
#include "SGCore/SGHapticGlove.h" #include "SGCore/SGHapticGlove.h"
#include "SGDebug/SGDebugGizmo.h" #include "SGDebug/SGDebugGizmo.h"
@@ -288,7 +289,28 @@ void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
ESGPositionalTrackingHardware TrackerHardware = Owner->GetWristTrackingSettings().TrackingHardware; ESGPositionalTrackingHardware TrackerHardware = Owner->GetWristTrackingSettings().TrackingHardware;
if (TrackerHardware == ESGPositionalTrackingHardware::None) if (TrackerHardware == ESGPositionalTrackingHardware::None)
{ {
TrackerHardware = ESGPositionalTrackingHardware::Custom; const ESGHeadMountDisplayDevice HmdDevice = FSGHeadMountDisplay::GetDeviceType();
switch (HmdDevice)
{
case ESGHeadMountDisplayDevice::MetaQuest2:
TrackerHardware = ESGPositionalTrackingHardware::Quest2Controller;
break;
case ESGHeadMountDisplayDevice::MetaQuestPro:
TrackerHardware = ESGPositionalTrackingHardware::QuestProController;
break;
case ESGHeadMountDisplayDevice::MetaQuest3:
TrackerHardware = ESGPositionalTrackingHardware::Quest3Controller;
break;
case ESGHeadMountDisplayDevice::HtcVivePro:
TrackerHardware = ESGPositionalTrackingHardware::ViveTracker;
break;
case ESGHeadMountDisplayDevice::HtcViveFocus3:
TrackerHardware = ESGPositionalTrackingHardware::ViveFocus3WristTracker;
break;
default:
TrackerHardware = ESGPositionalTrackingHardware::Custom;
break;
}
} }
else if (TrackerHardware == ESGPositionalTrackingHardware::Custom) else if (TrackerHardware == ESGPositionalTrackingHardware::Custom)
{ {
@@ -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
*
*
*/
#include "SenseGlove/SGHeadMountDisplay.h"
#include "Engine/Engine.h"
#include "IHeadMountedDisplay.h"
#include "IXRTrackingSystem.h"
FName FSGHeadMountDisplay::GetDeviceName()
{
if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed())
{
const IHeadMountedDisplay* Device{GEngine->XRSystem->GetHMDDevice()};
const FName DeviceName{Device->GetHMDName()};
return DeviceName;
}
return NAME_None;
}
ESGHeadMountDisplayDevice FSGHeadMountDisplay::GetDeviceType()
{
if (IsMetaQuest2())
{
return ESGHeadMountDisplayDevice::MetaQuest2;
}
if (IsMetaQuestPro())
{
return ESGHeadMountDisplayDevice::MetaQuestPro;
}
if (IsMetaQuest3())
{
return ESGHeadMountDisplayDevice::MetaQuest3;
}
/// TODO
// WE NEED A MORE RELIABLE WAY TO DISTINGUISH VIVE Pro from VIVE Focus 3.
if (IsHtcVivePro())
{
return ESGHeadMountDisplayDevice::HtcVivePro;
}
/// TODO
// WE NEED A MORE RELIABLE WAY TO DISTINGUISH VIVE Pro from VIVE Focus 3.
if (IsHtcViveFocus3())
{
return ESGHeadMountDisplayDevice::HtcViveFocus3;
}
return ESGHeadMountDisplayDevice::None;
}
@@ -0,0 +1,96 @@
/**
* @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 "HAL/Platform.h"
#include "UObject/NameTypes.h"
#include "UObject/ObjectMacros.h"
#include "SGTypes/SGTypes.h"
#include "SGHeadMountDisplay.generated.h"
/**
*
*/
USTRUCT()
struct SENSEGLOVE_API FSGHeadMountDisplay
{
GENERATED_BODY()
public:
static FName GetDeviceName();
FORCEINLINE static bool IsMetaQuest2()
{
static const FName DeviceIdentifier{TEXT("Meta Quest 2")};
return GetDeviceName() == DeviceIdentifier;
}
FORCEINLINE static bool IsMetaQuestPro()
{
static const FName DeviceIdentifier{TEXT("Meta Quest Pro")};
return GetDeviceName() == DeviceIdentifier;
}
FORCEINLINE static bool IsMetaQuest3()
{
static const FName DeviceIdentifier{TEXT("Meta Quest 3")};
return GetDeviceName() == DeviceIdentifier;
}
FORCEINLINE static bool IsHtcVivePro()
{
/// TODO
// WE NEED A MORE RELIABLE WAY TO DISTINGUISH VIVE Pro from VIVE Focus 3.
#if PLATFORM_ANDROID
return false;
#else /* PLATFORM_ANDROID */
static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")};
return GetDeviceName() == DeviceIdentifier;
#endif /* PLATFORM_ANDROID */
}
FORCEINLINE static bool IsHtcViveFocus3()
{
/// TODO
// WE NEED A MORE RELIABLE WAY TO DISTINGUISH VIVE Pro from VIVE Focus 3.
static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")};
return GetDeviceName() == DeviceIdentifier;
}
static ESGHeadMountDisplayDevice GetDeviceType();
};
@@ -0,0 +1,73 @@
/**
* @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 "SGKismet/SGHeadMountDisplayKismetLibrary.h"
#include "SenseGlove/SGHeadMountDisplay.h"
FName UHeadMountDisplayKismetLibrary::GetDeviceName()
{
return FSGHeadMountDisplay::GetDeviceName();
}
bool UHeadMountDisplayKismetLibrary::IsMetaQuest2()
{
return FSGHeadMountDisplay::IsMetaQuest2();
}
bool UHeadMountDisplayKismetLibrary::IsMetaQuestPro()
{
return FSGHeadMountDisplay::IsMetaQuestPro();
}
bool UHeadMountDisplayKismetLibrary::IsMetaQuest3()
{
return FSGHeadMountDisplay::IsMetaQuest3();
}
bool UHeadMountDisplayKismetLibrary::IsHtcVivePro()
{
return FSGHeadMountDisplay::IsHtcVivePro();
}
bool UHeadMountDisplayKismetLibrary::IsHtcViveFocus3()
{
return FSGHeadMountDisplay::IsHtcViveFocus3();
}
ESGHeadMountDisplayDevice UHeadMountDisplayKismetLibrary::GetDeviceType()
{
return FSGHeadMountDisplay::GetDeviceType();
}
@@ -0,0 +1,71 @@
/**
* @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/NameTypes.h"
#include "SGKismet/SGBlueprintFunctionLibrary.h"
#include "SGTypes/SGTypes.h"
#include "SGHeadMountDisplayKismetLibrary.generated.h"
UCLASS(meta=(ScriptName = "SesneGloveHeadMountDisplayKismetLibrary"))
class SENSEGLOVEKISMET_API UHeadMountDisplayKismetLibrary final : public USGBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
static FName GetDeviceName();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
static bool IsMetaQuest2();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
static bool IsMetaQuestPro();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
static bool IsMetaQuest3();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
static bool IsHtcVivePro();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
static bool IsHtcViveFocus3();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
static ESGHeadMountDisplayDevice GetDeviceType();
};
@@ -0,0 +1,36 @@
/**
* @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 "SGTypes/SGTypes.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
*
*
*/
#pragma once
#include "CoreTypes.h"
#include "UObject/ObjectMacros.h"
/* The Head Mount Display device enum to determine the device type. */
UENUM(BlueprintType)
enum class ESGHeadMountDisplayDevice : uint8
{
/* The default none value. */
None UMETA(DisplayName = "None"),
/* The Meta Quest 2 HMD. */
MetaQuest2 UMETA(DisplayName = "Meta Quest 2"),
/* The Meta Quest Pro HMD. */
MetaQuestPro UMETA(DisplayName = "Meta Quest Pro"),
/* The Meta Quest 3 HMD. */
MetaQuest3 UMETA(DisplayName = "Meta Quest 3"),
/* The HTC VIVE Pro HMD. */
HtcVivePro UMETA(DisplayName = "HTC VIVE Pro"),
/* The HTC VIVE Focus 3 HMD. */
HtcViveFocus3 UMETA(DisplayName = "HTC VIVE Focus 3"),
};