Compare commits

...
6 Commits
5 changed files with 57 additions and 56 deletions
+20
View File
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.3.2] - 2025-01-28
This patch release addresses a critical issue backported from the upcoming `2.4.x` release to `2.3.x`.
### Fixed
- Fix a critical issue backported from the upcoming `2.4.x` release where `HandStates->GetTransform(KeyPoint)` was incorrectly resolving to `(&HandStates[0])->GetTransform(KeyPoint)`, causing both hands to use the left hand's wrist transform under specific conditions. This occurred when the `bFallbackToHandTrackingIfNoGloveDetected` option was enabled, two gloves were present, and no hardware wrist-tracking device was active, resulting in both hands overlapping at the same transform.
## [2.3.1] - 2024-11-27
This patch release addresses a few issues with SenseGlove Sockets Editor.
### Fixed
- Additional minor fixes and improvements that may not be listed here.
### Changed
- The SenseGlove Sockets Editor now calculates hand bone reference transforms using the current virtual hand mesh being edited, rather than the reference mesh, when adding SenseGlove sockets.
## [2.3.0] - 2024-11-13
This minor release includes some improvements and adds official Unreal Engine `5.5` Fab support.
@@ -2,10 +2,10 @@
| | **Windows (MSVC 2017)** | **Windows (MSVC 2019)** | **Windows (MSVC 2022)** | **Linux x86-64 (Native Toolchain)** | **Linux AArch64 (Native Toolchain)** | **Meta Quest Stand-alone (Android NDK)** | **HTC VIVE Stand-alone (Android NDK)** | **Fab** | **Azure DevOps Version** |
|:--------:|:-----------------------:|:-----------------------:|:-----------------------:|:-----------------------------------:|:------------------------------------:|:----------------------------------------:|:--------------------------------------:|:--------:|:------------------------:|
| **5.5** | ❌ | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.0 | ✅ v2.3.0 |
| **5.4** | ❌ | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.0 | ✅ v2.3.0 |
| **5.3** | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.0 | ✅ v2.3.0 |
| **5.2** | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.0 | ✅ v2.3.0 |
| **5.5** | ❌ | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.2 | ✅ v2.3.2 |
| **5.4** | ❌ | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.2 | ✅ v2.3.2 |
| **5.3** | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.2 | ✅ v2.3.2 |
| **5.2** | ❌ | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x | ✅ v2.3.x (r25b) | ❓ | ✅ v2.3.2 | ✅ v2.3.2 |
| **5.1** | ❌ | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x (r25b) | ❓ | ⚠️ v2.0.0 | ⚠️ v2.0.2 |
| **5.0** | ❌ | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x (r21e) | ❓ | ⚠️ v1.6.1 | ⚠️ v1.6.1 |
| **4.27** | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x (r21e) | ❓ | ⚠️ v1.3.1 | ⚠️ v1.4.3 |
+1 -1
View File
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "2.3.0",
"VersionName": "2.3.2",
"FriendlyName": "SenseGlove",
"Description": "Integrating the SenseGlove haptic controller into Unreal Engine",
"Category": "Virtual Reality",
@@ -99,7 +99,7 @@ struct FSGAssetUtils::FImpl
static bool IsLeftHandMesh(const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh);
static bool IsRightHandMesh(const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh);
static FTransform GetHandBoneBoneRefTransform(bool bRight, const FName& BoneName);
static FTransform GetHandBoneRefTransform(const USkeletalMesh* SkeletalMesh, const FName& BoneName);
static bool AddSocket(
const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh,
@@ -310,48 +310,32 @@ bool FSGAssetUtils::FImpl::IsRightHandMesh(
return true;
}
FTransform FSGAssetUtils::FImpl::GetHandBoneBoneRefTransform(const bool bRight, const FName& BoneName)
FTransform FSGAssetUtils::FImpl::GetHandBoneRefTransform(
const USkeletalMesh* SkeletalMesh, const FName& BoneName)
{
const FSGVirtualHandMeshSettings& MeshSettings{GetVirtualHandSettings().MeshSettings};
const TSoftObjectPtr<USkeletalMesh>& HandMesh{
bRight
? MeshSettings.LeftHandReferenceMesh
: MeshSettings.RightHandReferenceMesh
};
if (HandMesh.IsValid())
if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh")))
{
const FReferenceSkeleton& ReferenceSkeleton{HandMesh->GetRefSkeleton()};
const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(BoneName);
if (BoneIndex == INDEX_NONE)
{
SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for the '%s' joint!"),
*BoneName.ToString()));
}
const TArray<FTransform> Transforms{ReferenceSkeleton.GetRefBonePose()};
ensureAlwaysMsgf(Transforms.Num() > 0 && Transforms.Num() > BoneIndex,
TEXT("Invalid bone index '%d' or no transforms found!"), BoneIndex);
const FTransform& Transform{Transforms[BoneIndex]};
return Transform;
return FTransform::Identity;
}
ensureAlwaysMsgf(
bRight
? MeshSettings.RightHandDefaultReferenceBoneTransforms.Contains(BoneName)
: MeshSettings.LeftHandDefaultReferenceBoneTransforms.Contains(BoneName),
TEXT("Invalid bone name '%s'!"), *BoneName.ToString());
const FReferenceSkeleton& ReferenceSkeleton{SkeletalMesh->GetRefSkeleton()};
const FTransform& Transform{
bRight
? MeshSettings.RightHandDefaultReferenceBoneTransforms[BoneName]
: MeshSettings.LeftHandDefaultReferenceBoneTransforms[BoneName]
};
const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(BoneName);
if (!ensureAlwaysMsgf(BoneIndex != INDEX_NONE,
TEXT("Could not find a bone index for the '%s' joint!"), *BoneName.ToString()))
{
return FTransform::Identity;
}
const TArray<FTransform> Transforms{ReferenceSkeleton.GetRefBonePose()};
if (!ensureAlwaysMsgf(Transforms.Num() > 0 && Transforms.Num() > BoneIndex,
TEXT("Invalid bone index '%d' or no transforms found!"), BoneIndex))
{
return FTransform::Identity;
}
const FTransform& Transform{Transforms[BoneIndex]};
return Transform;
}
bool FSGAssetUtils::FImpl::AddSocket(
@@ -468,7 +452,7 @@ bool FSGAssetUtils::FImpl::AddFingertipColliderSocket(
};
FTransform SocketTransform{
GetHandBoneBoneRefTransform(bRight, BoneName)
GetHandBoneRefTransform(SkeletalMesh, BoneName)
};
const bool bAddedSocket = AddSocket(
@@ -490,7 +474,7 @@ bool FSGAssetUtils::FImpl::AddGrabThumbColliderSocket(
const FSGVirtualHandGrabSettings GrabSettings{GetVirtualHandGrabSettings()};
const FName& SocketName{GrabSettings.ThumbColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::ThumbDistal, SocketName);
bRight, EHandKeypoint::ThumbDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddGrabIndexColliderSocket(
@@ -499,7 +483,7 @@ bool FSGAssetUtils::FImpl::AddGrabIndexColliderSocket(
const FSGVirtualHandGrabSettings GrabSettings{GetVirtualHandGrabSettings()};
const FName& SocketName{GrabSettings.IndexColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::IndexDistal, SocketName);
bRight, EHandKeypoint::IndexDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddGrabMiddleColliderSocket(
@@ -508,7 +492,7 @@ bool FSGAssetUtils::FImpl::AddGrabMiddleColliderSocket(
const FSGVirtualHandGrabSettings GrabSettings{GetVirtualHandGrabSettings()};
const FName& SocketName{GrabSettings.MiddleColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::MiddleDistal, SocketName);
bRight, EHandKeypoint::MiddleDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddTouchThumbColliderSocket(
@@ -517,7 +501,7 @@ bool FSGAssetUtils::FImpl::AddTouchThumbColliderSocket(
const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()};
const FName& SocketName{TouchSettings.ThumbColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::ThumbDistal, SocketName);
bRight, EHandKeypoint::ThumbDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddTouchIndexColliderSocket(
@@ -526,7 +510,7 @@ bool FSGAssetUtils::FImpl::AddTouchIndexColliderSocket(
const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()};
const FName& SocketName{TouchSettings.IndexColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::IndexDistal, SocketName);
bRight, EHandKeypoint::IndexDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddTouchMiddleColliderSocket(
@@ -535,7 +519,7 @@ bool FSGAssetUtils::FImpl::AddTouchMiddleColliderSocket(
const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()};
const FName& SocketName{TouchSettings.MiddleColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::MiddleDistal, SocketName);
bRight, EHandKeypoint::MiddleDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddTouchRingColliderSocket(
@@ -544,7 +528,7 @@ bool FSGAssetUtils::FImpl::AddTouchRingColliderSocket(
const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()};
const FName& SocketName{TouchSettings.RingColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::RingDistal, SocketName);
bRight, EHandKeypoint::RingDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddTouchLittleColliderSocket(
@@ -553,7 +537,7 @@ bool FSGAssetUtils::FImpl::AddTouchLittleColliderSocket(
const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()};
const FName& SocketName{TouchSettings.PinkyColliderSocketName};
return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh,
bRight, EHandKeypoint::LittleDistal, SocketName);
bRight, EHandKeypoint::LittleDistal, SocketName);
}
bool FSGAssetUtils::FImpl::AddSenseGloveSockets(const ISkeletalMeshEditor* SkeletalMeshEditor,
@@ -651,7 +635,6 @@ bool FSGAssetUtils::FImpl::AddSenseGloveSockets(const ISkeletalMeshEditor* Skele
return false;
}
const bool TouchLittleCollider = AddTouchLittleColliderSocket(
SkeletalMeshEditor, SkeletalMesh, bIsRight);
if (!TouchLittleCollider)
@@ -661,7 +644,6 @@ bool FSGAssetUtils::FImpl::AddSenseGloveSockets(const ISkeletalMeshEditor* Skele
return false;
}
return true;
}
@@ -786,7 +768,6 @@ bool FSGAssetUtils::FImpl::AddSenseGloveSockets(USkeletalMesh* SkeletalMesh, USk
return true;
}
bool FSGAssetUtils::FImpl::ClearExistingSockets(USkeletalMesh* SkeletalMesh, USkeleton* Skeleton)
{
if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!")))
@@ -2075,7 +2075,7 @@ bool FSGXRTracker::FImpl::UpdateXRHandTrackingData(
XR_ENSURE(XRLocateHandJointsEXT(OutHandState.HandTracker, &LocateInfo, &OutHandState.Locations));
OutHandState.bTracked = OutHandState.Locations.isActive == XR_TRUE;
OutHandState.bHasReceivedJointPoses |= HandStates->bTracked;
OutHandState.bHasReceivedJointPoses |= OutHandState.bTracked;
if (!OutHandState.bTracked)
{
return false;
@@ -2209,7 +2209,7 @@ bool FSGXRTracker::FImpl::GetControllerTransform(
}
const EHandKeypoint KeyPoint = KeyPointInfoPtr->Key;
const FTransform& ControllerTransform{HandStates->GetTransform(KeyPoint)};
const FTransform& ControllerTransform{HandState.GetTransform(KeyPoint)};
OutTransform = ControllerTransform;
bOutMotionSourceHandTracking = true;
bTracked = HandState.bTracked;