add vive xr elite hmd auto-detection checkes and other vive headset detection bug fixes and improvements
This commit is contained in:
+4
-52
@@ -9,58 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
This is a bugfix release that contains a somewhat important bugfix backported from the next release of the plugin as documented below.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix a bug where the SGPawn right-hand grab colliders' default size is mistakenly set to the default value for the left-hand grab colliders at CDO initialization time.
|
||||
|
||||
## [2.0.7] - 2024-05-29
|
||||
|
||||
This is a bugfix release with no actual plugin code changes, only fixing issues with binary assets incompatible with UE versions earlier than 5.4.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Make the Allbreaker assets compatible with UE5.1+ again as the v2.0.5 update breaks compatibility with UE versions earlier than 5.4, thus leaving the engine unable to load those assets.
|
||||
|
||||
## [2.0.6] - 2024-05-29
|
||||
|
||||
This is a bugfix release with no actual plugin code changes, only removing development/test assets from UE 5.3 that were never meant to be shipped.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed the dev/test virtual hand models that leaked into the 5.3 branch.
|
||||
|
||||
### Fixed
|
||||
|
||||
## [2.0.5] - 2024-05-22
|
||||
|
||||
This is a bugfix release with no actual plugin code changes, only focusing on fixing the Allbreaker virtual hand model issues.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the wrong palm bone names on the Allbreaker virtual hand models.
|
||||
|
||||
## [2.0.4] - 2024-05-17
|
||||
|
||||
This is a bugfix release with no actual plugin's code change.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix our in-house Unreal Engine Marketplace submission tool's configurations where the Content folder (containing the Allbreaker hand model) is mistakenly ignored during the submission. This release reintroduces the Virtual Hand Model and its material missing from the previous release.
|
||||
- Fix the SenseGlove.uproject's wrong versioning submitted to the Unreal Engine Marketplace.
|
||||
|
||||
## [2.0.3] - 2024-05-15
|
||||
|
||||
This is a bugfix release addressing mostly RunUAT build issues on Unreal Engine 5.4.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix UE 5.4 RunUAT build issue: "Asking CppCompileEnvironment for a single Architecture, but it has multiple Architectures (arm64, x64)", affecting SenseGloveConnectImpl and SenseGloveCoreImpl modues.
|
||||
- Improved target platform detection when building SenseGloveConnectImpl and SenseGloveCoreImpl modules and also distinguishing the x64 builds from arm64 on Microsoft Windows.
|
||||
- Fix other UE 5.4 RunUAT build issues, mostly caused by missing headers.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed support for Android armeabi-v7a and x86 architectures as they are no longer supported by the supported engine versions.
|
||||
- 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. Please note that this is still highly experimental and HTC VIVE Focus 3 and HTC XR Elite cannot be distinguished in the current iteration. Though, since the tracker devices and offsets for both headsets are the same in the end it does not make a difference if both headsets are detected as each other.
|
||||
- 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.
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -305,6 +305,8 @@ void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
|
||||
TrackerHardware = ESGPositionalTrackingHardware::ViveTracker;
|
||||
break;
|
||||
case ESGHeadMountDisplayDevice::HtcViveFocus3:
|
||||
// Fall through
|
||||
case ESGHeadMountDisplayDevice::HtcViveXRElite:
|
||||
TrackerHardware = ESGPositionalTrackingHardware::ViveFocus3WristTracker;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -121,15 +121,17 @@ bool FSGHeadMountDisplay::IsHtcVivePro()
|
||||
|
||||
const FName DeviceName{GetDeviceName()};
|
||||
|
||||
bool bMatched = DeviceName == DeviceIdentifier;
|
||||
if (!bMatched)
|
||||
bool bNameMatches = DeviceName == DeviceIdentifier;
|
||||
if (!bNameMatches)
|
||||
{
|
||||
const FString DeviceNameString{GetDeviceName().ToString()};
|
||||
bMatched = DeviceNameString.Contains(ViveDeviceIdentifier)
|
||||
bNameMatches = DeviceNameString.Contains(ViveDeviceIdentifier)
|
||||
|| DeviceNameString.Contains(SRanipalDeviceIdentifier);
|
||||
}
|
||||
|
||||
if (bMatched)
|
||||
bool bResolutionMatches = false;
|
||||
|
||||
if (bNameMatches)
|
||||
{
|
||||
if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed())
|
||||
{
|
||||
@@ -146,19 +148,23 @@ bool FSGHeadMountDisplay::IsHtcVivePro()
|
||||
// VIVE Focus 3:
|
||||
// - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined)
|
||||
// - Unreal OpenXR Resolution: 5016 x 2508
|
||||
// VIVE XR Elite
|
||||
// - Official Spec: 1920 x 1920 pixels per eye (3840 x 1920 pixels combined)
|
||||
// - Unreal OpenXR Resolution: 5016 x 2508
|
||||
if (HmdMonitorInfo.ResolutionX < 5000 && HmdMonitorInfo.ResolutionY > 2700)
|
||||
{
|
||||
bMatched = true;
|
||||
bResolutionMatches = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool bMatched = bNameMatches && bResolutionMatches;
|
||||
|
||||
return bMatched;
|
||||
#endif /* PLATFORM_ANDROID */
|
||||
}
|
||||
|
||||
|
||||
bool FSGHeadMountDisplay::IsHtcViveFocus3()
|
||||
{
|
||||
static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")};
|
||||
@@ -167,18 +173,24 @@ bool FSGHeadMountDisplay::IsHtcViveFocus3()
|
||||
|
||||
const FName DeviceName{GetDeviceName()};
|
||||
|
||||
bool bMatched = DeviceName == DeviceIdentifier;
|
||||
if (!bMatched)
|
||||
bool bNameMatches = DeviceName == DeviceIdentifier;
|
||||
if (!bNameMatches)
|
||||
{
|
||||
const FString DeviceNameString{GetDeviceName().ToString()};
|
||||
bMatched = DeviceNameString.Contains(ViveDeviceIdentifier)
|
||||
bNameMatches = DeviceNameString.Contains(ViveDeviceIdentifier)
|
||||
|| DeviceNameString.Contains(SRanipalDeviceIdentifier);
|
||||
}
|
||||
|
||||
/// NOTE
|
||||
/// For the time being since we cannot distinguish between VIVE Focus 3 and VIVE XR Elite using resolution checks,
|
||||
/// we skip the resolution checks altogether and assume it's not a VIVE Pro, as VIVE Pro won't come with Android
|
||||
/// support.
|
||||
#if PLATFORM_ANDROID
|
||||
return bMatched;
|
||||
#else /* PLATFORM_ANDROID */
|
||||
if (bMatched)
|
||||
bool bResolutionMatches = true;
|
||||
#else /* PLATFORM_ANDROID */
|
||||
bool bResolutionMatches = false;
|
||||
|
||||
if (bNameMatches)
|
||||
{
|
||||
if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed())
|
||||
{
|
||||
@@ -195,17 +207,82 @@ bool FSGHeadMountDisplay::IsHtcViveFocus3()
|
||||
// VIVE Focus 3:
|
||||
// - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined)
|
||||
// - Unreal OpenXR Resolution: 5016 x 2508
|
||||
// VIVE XR Elite
|
||||
// - Official Spec: 1920 x 1920 pixels per eye (3840 x 1920 pixels combined)
|
||||
// - Unreal OpenXR Resolution: 5016 x 2508
|
||||
if (HmdMonitorInfo.ResolutionX > 5000
|
||||
&& (HmdMonitorInfo.ResolutionY > 2500 && HmdMonitorInfo.ResolutionY < 2700))
|
||||
{
|
||||
bMatched = true;
|
||||
bResolutionMatches = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_ANDROID */
|
||||
|
||||
const bool bMatched = bNameMatches && bResolutionMatches;
|
||||
|
||||
return bMatched;
|
||||
}
|
||||
|
||||
bool FSGHeadMountDisplay::IsHtcViveXRElite()
|
||||
{
|
||||
static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")};
|
||||
static const FString ViveDeviceIdentifier{TEXT("Vive")};
|
||||
static const FString SRanipalDeviceIdentifier{TEXT("SRanipal")};
|
||||
|
||||
const FName DeviceName{GetDeviceName()};
|
||||
|
||||
bool bNameMatches = DeviceName == DeviceIdentifier;
|
||||
if (!bNameMatches)
|
||||
{
|
||||
const FString DeviceNameString{GetDeviceName().ToString()};
|
||||
bNameMatches = DeviceNameString.Contains(ViveDeviceIdentifier)
|
||||
|| DeviceNameString.Contains(SRanipalDeviceIdentifier);
|
||||
}
|
||||
|
||||
/// NOTE
|
||||
/// For the time being since we cannot distinguish between VIVE Focus 3 and VIVE XR Elite using resolution checks,
|
||||
/// we skip the resolution checks altogether and assume it's not a VIVE Pro, as VIVE Pro won't come with Android
|
||||
/// support.
|
||||
#if PLATFORM_ANDROID
|
||||
bool bResolutionMatches = true;
|
||||
#else /* PLATFORM_ANDROID */
|
||||
bool bResolutionMatches = false;
|
||||
|
||||
if (bNameMatches)
|
||||
{
|
||||
if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed())
|
||||
{
|
||||
IHeadMountedDisplay* Device{GEngine->XRSystem->GetHMDDevice()};
|
||||
if (Device)
|
||||
{
|
||||
IHeadMountedDisplay::MonitorInfo HmdMonitorInfo;
|
||||
Device->GetHMDMonitorInfo(HmdMonitorInfo);
|
||||
|
||||
/// NOTE
|
||||
// VIVE Pro:
|
||||
// - Official Spec: 1440 x 1600 pixels per eye (2880 x 1600 pixels combined)
|
||||
// - Unreal OpenXR Resolution: 4936 x 2740
|
||||
// VIVE Focus 3:
|
||||
// - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined)
|
||||
// - Unreal OpenXR Resolution: 5016 x 2508
|
||||
// VIVE XR Elite
|
||||
// - Official Spec: 1920 x 1920 pixels per eye (3840 x 1920 pixels combined)
|
||||
// - Unreal OpenXR Resolution: 5016 x 2508
|
||||
if (HmdMonitorInfo.ResolutionX > 5000 &&
|
||||
(HmdMonitorInfo.ResolutionY > 2500 && HmdMonitorInfo.ResolutionY < 2700))
|
||||
{
|
||||
bResolutionMatches = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_ANDROID */
|
||||
|
||||
const bool bMatched = bNameMatches && bResolutionMatches;
|
||||
|
||||
return bMatched;
|
||||
}
|
||||
|
||||
ESGHeadMountDisplayDevice FSGHeadMountDisplay::GetDeviceType()
|
||||
@@ -235,5 +312,10 @@ ESGHeadMountDisplayDevice FSGHeadMountDisplay::GetDeviceType()
|
||||
return ESGHeadMountDisplayDevice::HtcViveFocus3;
|
||||
}
|
||||
|
||||
if (IsHtcViveXRElite())
|
||||
{
|
||||
return ESGHeadMountDisplayDevice::HtcViveXRElite;
|
||||
}
|
||||
|
||||
return ESGHeadMountDisplayDevice::None;
|
||||
}
|
||||
@@ -54,12 +54,41 @@ struct SENSEGLOVE_API FSGHeadMountDisplay
|
||||
public:
|
||||
static FName GetDeviceName();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is Meta Quest 2, or not.
|
||||
*/
|
||||
static bool IsMetaQuest2();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is Meta Quest Pro, or not.
|
||||
*/
|
||||
static bool IsMetaQuestPro();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is Meta Quest 3, or not.
|
||||
*/
|
||||
static bool IsMetaQuest3();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is HTC VIVE Pro, or not.
|
||||
*/
|
||||
static bool IsHtcVivePro();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is HTC VIVE Focus 3, or not.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
static bool IsHtcViveFocus3();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is HTC VIVE XR Elite, or not.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
static bool IsHtcViveXRElite();
|
||||
|
||||
static ESGHeadMountDisplayDevice GetDeviceType();
|
||||
};
|
||||
@@ -67,6 +67,11 @@ bool UHeadMountDisplayKismetLibrary::IsHtcViveFocus3()
|
||||
return FSGHeadMountDisplay::IsHtcViveFocus3();
|
||||
}
|
||||
|
||||
bool UHeadMountDisplayKismetLibrary::IsHtcViveXRElite()
|
||||
{
|
||||
return FSGHeadMountDisplay::IsHtcViveXRElite();
|
||||
}
|
||||
|
||||
ESGHeadMountDisplayDevice UHeadMountDisplayKismetLibrary::GetDeviceType()
|
||||
{
|
||||
return FSGHeadMountDisplay::GetDeviceType();
|
||||
|
||||
@@ -51,21 +51,48 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
|
||||
static FName GetDeviceName();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is Meta Quest 2, or not.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
|
||||
static bool IsMetaQuest2();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is Meta Quest Pro, or not.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
|
||||
static bool IsMetaQuestPro();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is Meta Quest 3, or not.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
|
||||
static bool IsMetaQuest3();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is HTC VIVE Pro, or not.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
|
||||
static bool IsHtcVivePro();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is HTC VIVE Focus 3, or not.
|
||||
*
|
||||
* @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 Mount Display")
|
||||
static bool IsHtcViveFocus3();
|
||||
|
||||
/**
|
||||
* Checks whether the HMD device is HTC VIVE XR Elite, or not.
|
||||
*
|
||||
* @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 Mount Display")
|
||||
static bool IsHtcViveXRElite();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="SenseGlove | Head Mount Display")
|
||||
static ESGHeadMountDisplayDevice GetDeviceType();
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "CoreTypes.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
|
||||
/* The Head Mount Display device enum to determine the device type. */
|
||||
/* The Head Mount Display device enum to determine the HMD device type. */
|
||||
UENUM(BlueprintType)
|
||||
enum class ESGHeadMountDisplayDevice : uint8
|
||||
{
|
||||
@@ -59,4 +59,7 @@ enum class ESGHeadMountDisplayDevice : uint8
|
||||
|
||||
/* The HTC VIVE Focus 3 HMD. */
|
||||
HtcViveFocus3 UMETA(DisplayName = "HTC VIVE Focus 3"),
|
||||
|
||||
/* The HTC VIVE XR Elite HMD. */
|
||||
HtcViveXRElite UMETA(DisplayName = "HTC VIVE XR Elite"),
|
||||
};
|
||||
Reference in New Issue
Block a user